1 #LyX 1.6.4 created this file. For more info see http://www.lyx.org/
8 %\definecolor{darkgreen}{rgb}{0,0.5,0}
9 \lstset{numbers=left, stepnumber=1, numbersep=5pt, breaklines=false,
10 basicstyle=\footnotesize\ttfamily,
11 %keywordstyle=\color{darkgreen},
12 numberstyle=\tiny,language=C,columns=fullflexible,
15 \use_default_options true
24 \font_typewriter default
25 \font_default_family default
32 \paperfontsize default
35 \pdf_title "Newfangle"
36 \pdf_author "Sam Liddicott"
37 \pdf_subject "Literate Programing"
38 \pdf_keywords "notangle noweb noweave literate programming cweb"
40 \pdf_bookmarksnumbered false
41 \pdf_bookmarksopen false
42 \pdf_bookmarksopenlevel 1
54 \paperorientation portrait
57 \paragraph_separation skip
59 \quotes_language english
62 \paperpagestyle default
63 \tracking_changes false
83 \begin_layout Chapter*
87 \begin_layout Standard
92 is a tool for newfangled literate programming.
93 Newfangled is defined as
95 New and often needlessly novel
104 \begin_layout Standard
105 In this case, newfangled means yet another new and improved method for literate
109 \begin_layout Standard
114 has a long history starting with the great
118 whose literate programming tools seem to make use of as many escaped abbreviati
119 ons for semantic markup as TeX itself.
122 \begin_layout Standard
131 set of tools (notangle, noweave and noroots) and helpfully reduced the
132 amount of magic character sequences to just
133 \begin_inset Flex CharStyle:Code
136 \begin_layout Plain Layout
143 \begin_inset Flex CharStyle:Code
146 \begin_layout Plain Layout
152 , and in doing so brought the wonders of literate programming within my
156 \begin_layout Standard
157 Using LyX for LaTeX editing, I had various troubles with the noweb tools,
158 some of which were my fault, some of which were noweb's fault and some
159 of which were LyX's fault.
162 \begin_layout Standard
167 generally brought literate programming to the masses through removing some
168 of the complexity of the original literate programming, but this would
169 be of no advantage to me if the LyX --- LaTeX combination brought more
170 complications in their place.
173 \begin_layout Standard
178 was thus born --- as an awk replacement for notangle, adding some important
179 features, like better integration with LyX and LaTeX, multiple output format
180 conversions, and fixing notangle bugs like indenting when using -L for
184 \begin_layout Standard
185 Significantly, newfangle is just one program which replaces various programs
187 Specifically noweave is done away with and implemented directly as LaTeX
188 macros, and noroots is implemented as a function of the untangler
195 \begin_layout Standard
196 Newfangle is written in awk for portability reasons, awk being available
198 A python conversion will probably be attempted for the benefit of LyX.
199 (Hasn't anyone implemented awk in python yet?)
202 \begin_layout Section*
206 \begin_layout Enumerate
207 ^^ is always going to be a problem, see texbytopic 1.2.2 (Work out what I
211 \begin_layout Enumerate
212 copy over up to date Makefile guide from noweb-lyx document
215 \begin_layout Enumerate
216 Make chunk-name settings only apply to chunks with that name
219 \begin_layout Enumerate
220 indent of multi-line chunks may be mode dependant (i.e.
221 not in string literals)
224 \begin_layout Enumerate
225 support chunk-param usage =<
230 \begin_layout Enumerate
231 trim spaces from param
234 \begin_layout Chapter*
238 \begin_layout Standard
239 \begin_inset CommandInset label
245 Newfangle is licensed under the GPL 3
246 \begin_inset CommandInset citation
253 This doesn't mean that you can't use or distribute newfangle with sources
254 of an incompatible license, but it means you must make the source of newfangle
259 gpl3-copyright,language=
262 \begin_layout Standard
263 \begin_inset listings
267 \begin_layout Plain Layout
269 #newfangle - fully featured notangle replacement in awk
272 \begin_layout Plain Layout
277 \begin_layout Plain Layout
279 #Copyright (C) Sam Liddicott 2009
282 \begin_layout Plain Layout
287 \begin_layout Plain Layout
289 #This program is free software: you can redistribute it and/or modify
292 \begin_layout Plain Layout
294 #it under the terms of the GNU General Public License as published by
297 \begin_layout Plain Layout
299 #the Free Software Foundation, either version 3 of the License, or
302 \begin_layout Plain Layout
304 #(at your option) any later version.
307 \begin_layout Plain Layout
312 \begin_layout Plain Layout
314 #This program is distributed in the hope that it will be useful,
317 \begin_layout Plain Layout
319 #but WITHOUT ANY WARRANTY; without even the implied warranty of
322 \begin_layout Plain Layout
324 #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
328 \begin_layout Plain Layout
330 #GNU General Public License for more details.
333 \begin_layout Plain Layout
338 \begin_layout Plain Layout
340 #You should have received a copy of the GNU General Public License
343 \begin_layout Plain Layout
345 #along with this program.
346 If not, see <http://www.gnu.org/licenses/>.
354 \begin_layout Standard
355 \begin_inset CommandInset toc
356 LatexCommand tableofcontents
367 \begin_layout Chapter
371 \begin_layout Standard
372 Newfangle is a replacement for noweb, which consists of
373 \begin_inset Flex CharStyle:Code
376 \begin_layout Plain Layout
383 \begin_inset Flex CharStyle:Code
386 \begin_layout Plain Layout
393 \begin_inset Flex CharStyle:Code
396 \begin_layout Plain Layout
405 \begin_layout Standard
407 \begin_inset Flex CharStyle:Code
410 \begin_layout Plain Layout
417 \begin_inset Flex CharStyle:Code
420 \begin_layout Plain Layout
426 it can read multiple named files, or from stdin.
429 \begin_layout Section
433 \begin_layout Standard
434 The -r option causes newfangle to behave like noroots.
437 \begin_layout LyX-Code
438 newfangle -r filename.tex
441 \begin_layout Standard
442 will print out the newfangle roots of a tex file.
446 \begin_layout Standard
448 \begin_inset Flex CharStyle:Code
451 \begin_layout Plain Layout
457 command, the roots are not enclosed in
458 \begin_inset Flex CharStyle:Code
461 \begin_layout Plain Layout
467 , unless at least one of the roots is defined using the
468 \begin_inset Flex CharStyle:Code
471 \begin_layout Plain Layout
478 \begin_inset Flex CharStyle:Code
481 \begin_layout Plain Layout
490 \begin_layout Standard
491 Also, unlike noroots, it prints out all roots --- not just those that are
493 I find that a root not being used, doesn't make it particularly top level.
494 My convention is that top level roots to be extracted begin with
495 \begin_inset Flex CharStyle:Code
498 \begin_layout Plain Layout
504 and have the form of a filename.
507 \begin_layout Section
511 \begin_layout Standard
513 \begin_inset Flex CharStyle:Code
516 \begin_layout Plain Layout
523 \begin_inset Flex CharStyle:Code
526 \begin_layout Plain Layout
532 options are supported.
535 \begin_layout Standard
536 The standard way to extract a file would be:
539 \begin_layout LyX-Code
540 newfangle -R./Makefile.inc newfangle.tex > ./Makefile.inc
543 \begin_layout Standard
545 \begin_inset Flex CharStyle:Code
548 \begin_layout Plain Layout
555 \begin_inset Flex CharStyle:Code
558 \begin_layout Plain Layout
564 option does not break indenting; also the
565 \begin_inset Flex CharStyle:Code
568 \begin_layout Plain Layout
574 option does not interrupt (and break) multi-line C macros --- or indeed
575 any line ending with a backslash.
576 This does mean that sometimes the compiler might calculate the source line
577 wrongly when generating error messages in such cases, but there isn't any
578 other way around if multi-line macros include other chunks.
581 \begin_layout Section
582 Formatting source in LaTeX
585 \begin_layout Standard
586 The noweave replacement is a set of LaTeX macros dependant upon
590 , and which can be included with:
593 \begin_layout LyX-Code
596 usepackage{newfangle.sty}
599 \begin_layout Standard
600 The LaTeX macros are shown in section
601 \begin_inset CommandInset ref
603 reference "sec:Latex-Macros"
607 , and are part of a LyX module file
608 \begin_inset Flex CharStyle:Code
611 \begin_layout Plain Layout
617 , which automatically includes the macros in the document pre-amble when
618 the newfangle LyX module is used.
621 \begin_layout Standard
622 Because the noweave replacement is impemented in LaTeX, there is no processing
623 stage required before running the
624 \begin_inset Flex CharStyle:Code
627 \begin_layout Plain Layout
634 LaTeX may need running two or more times, so that the code chunk references
635 can be fully calculated.
638 \begin_layout Standard
640 \begin_inset Flex CharStyle:Code
643 \begin_layout Plain Layout
649 package is required as it is used for formatting the code chunk captions
652 \begin_layout Standard
654 \begin_inset Flex CharStyle:Code
657 \begin_layout Plain Layout
663 package is also required, as it is used for formatting the code chunks
667 \begin_layout Standard
669 \begin_inset Flex CharStyle:Code
672 \begin_layout Plain Layout
678 package is also required.
681 \begin_layout Chapter
682 Literate Programming with Newfangle
685 \begin_layout Standard
687 Should really follow on from a part-0 explanation of what literate programming
691 \begin_layout Chapter
692 Using Newfangle with LyX
695 \begin_layout Section
699 \begin_layout Subsection
700 Installing the LyX module
703 \begin_layout Standard
705 \begin_inset Flex CharStyle:Code
708 \begin_layout Plain Layout
714 to your LyX layouts directory, which for unix users will be
715 \begin_inset Flex CharStyle:Code
718 \begin_layout Plain Layout
727 \begin_layout Standard
728 You will need to reconfigure LyX by clicking Tools\SpecialChar \menuseparator
729 Reconfigure, and then
733 \begin_layout Subsection
734 \begin_inset CommandInset label
736 name "sub:Configuring-the-build"
740 Configuring the build script
743 \begin_layout Standard
744 Make sure you don't have a conversion defined for Lyx → Program
747 \begin_layout Standard
748 From the menu Tools\SpecialChar \menuseparator
749 Preferences, add a conversion from Latex(Plain) → Program
753 \begin_layout LyX-Code
754 set -x ; newfangle -Rlyx-build $$i |
757 \begin_layout LyX-Code
758 env LYX_b=$$b LYX_i=$$i LYX_o=$$o LYX_p=$$p LYX_r=$$r bash
761 \begin_layout Standard
762 (But don't cut-n-paste it from this document or you'll be pasting a multi-line
763 string which will break your lyx preferences file).
767 \begin_layout Standard
768 I hope that one day, LyX will set these into the environment when calling
772 \begin_layout Standard
773 You may also want to consider adding options to this conversion\SpecialChar \ldots{}
777 \begin_layout LyX-Code
778 parselog=/usr/share/lyx/scripts/listerrors
781 \begin_layout Standard
782 \SpecialChar \ldots{}
783 but if you do you will lose your stderr
787 \begin_layout Plain Layout
788 There is some bash plumbing to get a copy of stderr but this footnote is
797 \begin_layout Standard
798 Now, a shell script chunk called
799 \begin_inset Flex CharStyle:Code
802 \begin_layout Plain Layout
808 will be extracted and run whenever you choose the Document\SpecialChar \menuseparator
813 \begin_layout Standard
814 The lyx-build script for this document is in section
815 \begin_inset CommandInset ref
817 reference "lyx-build-script"
821 and on a unix system will extract
822 \begin_inset Flex CharStyle:Code
825 \begin_layout Plain Layout
832 \begin_inset Flex CharStyle:Code
835 \begin_layout Plain Layout
844 \begin_layout Subsection
845 Preparing your Lyx document
848 \begin_layout Standard
849 It is not necessary to base your literate document on any of the original
850 LyX literate classes; so select a regular class for your document type.
853 \begin_layout Standard
869 \begin_layout Standard
870 In the drop-down style listbox you should notice a new style defined, called
878 \begin_layout Standard
879 When you wish to insert a literate chunk, you enter it's plain name in the
880 Chunk style, instead of the older method that used
881 \begin_inset Flex CharStyle:Code
884 \begin_layout Plain Layout
891 Following the chunk name, you insert a listing with: Insert\SpecialChar \menuseparator
895 \begin_layout Standard
896 Inside the white listing box you can type (or paste using shift+ctrl+V)
898 There is not need to use ctrl+enter at the end of lines as with some older
899 LyX literate techniques --- just press enter as normal.
902 \begin_layout Subsubsection
903 Customising the listing appearance
906 \begin_layout Standard
907 In the final document, the code is formatted using the
912 The chunk style doesn't just define the chunk name, but can also define
913 any other chunk options supported by the lstlistings package
914 \begin_inset Flex CharStyle:Code
917 \begin_layout Plain Layout
926 In fact, what you type in the chunk style is raw latex.
927 If you want to set the chunk language without having to right-click the
929 \begin_inset Flex CharStyle:Code
932 \begin_layout Plain Layout
938 after the chunk name.
941 \begin_layout Standard
942 Of course you can do this by editing the listings box advanced properties
943 by right-clicking on the listings box, but that takes longer, and you can't
944 see at-a-glance what the advanced settings are while editing the document;
945 also advanced settings apply only to that box --- the chunk settings apply
946 through the rest of the document
950 \begin_layout Plain Layout
951 It ought to apply only to subsequent chunks of the same name.
958 \begin_inset Note Note
961 \begin_layout Plain Layout
962 So make sure they only apply to chunks of that name
970 \begin_layout Subsubsection
971 Global customisations
974 \begin_layout Standard
979 is used to set the code chunks, it's
980 \begin_inset Flex CharStyle:Code
983 \begin_layout Plain Layout
991 command can be used in the pre-amble to set some document wide settings.
994 \begin_layout Standard
995 If your source has many words with long sequences of capital letters, then
997 \begin_inset Flex CharStyle:Code
1000 \begin_layout Plain Layout
1001 columns=fullflexible
1006 may be a good idea, or the capital letters will get crowded.
1007 (I think lstlistings ought to use a slightly smaller font for captial letters
1008 so that they still fit).
1011 \begin_layout Standard
1013 \begin_inset Flex CharStyle:Code
1016 \begin_layout Plain Layout
1024 looks more normal for code, but has no bold (unless luximono is used, but
1025 it doesn't work for me); so I use
1026 \begin_inset Flex CharStyle:Code
1029 \begin_layout Plain Layout
1039 \begin_inset Flex CharStyle:Code
1042 \begin_layout Plain Layout
1051 \begin_inset Flex CharStyle:Code
1054 \begin_layout Plain Layout
1055 columns=fullflexible
1060 is used or the wrong letter spacing is used.
1063 \begin_layout Standard
1064 In my LeTeX pre-amble I usually specialise my code format with:
1068 document-preamble,language=tex
1071 \begin_layout Standard
1072 \begin_inset listings
1076 \begin_layout Plain Layout
1083 \begin_layout Plain Layout
1087 definecolor{darkgreen}{rgb}{0,0.5,0}
1090 \begin_layout Plain Layout
1094 lstset{numbers=left, stepnumber=5, numbersep=5pt, breaklines=false,
1097 \begin_layout Plain Layout
1106 \begin_layout Plain Layout
1113 \begin_layout Plain Layout
1117 tiny,language=C,columns=fullflexible,
1120 \begin_layout Plain Layout
1122 numberfirstline=true
1125 \begin_layout Plain Layout
1135 \begin_layout Chapter
1136 Newfangle with Makefiles
1139 \begin_layout Standard
1140 \begin_inset Note Note
1143 \begin_layout Plain Layout
1144 This chapter needs revising
1150 \begin_inset Note Greyedout
1153 \begin_layout Plain Layout
1154 This chapter needs revising
1159 Here we describe a Makefile.inc that you can include in your own Makefiles,
1160 or glue as a recursive make to other projects.
1163 \begin_layout Standard
1164 The Makefile.inc described here was put together for a Samba4 vfs module,
1165 but can be used in any Make project, including automake projects.
1168 \begin_layout Section
1169 A word about makefiles formats
1172 \begin_layout Standard
1173 Whitespace formatting is very important in a Makefile.
1174 The first character of each command line must be a TAB.
1177 \begin_layout LyX-Code
1178 target: pre-requisite
1179 \begin_inset Newline newline
1183 \begin_inset Newline newline
1189 \begin_layout Standard
1190 But a TAB is pretty hard to enter into most of the Lyx formats and insets
1192 An alternative is to use a semi-colon after the pre-requisite, and a backslash
1193 at the end of each line (except the last).
1194 Then any whitespace (or none) can prefix each action.
1197 \begin_layout LyX-Code
1198 target: pre-requisite ;
1201 \begin_inset Newline newline
1207 \begin_inset Newline newline
1213 \begin_layout Standard
1214 This is the style that we use and it works pretty well for GNU make at least.
1217 \begin_layout Standard
1218 We also adopt a convention that code chunks whose names beginning with ./
1219 should always be automatically extracted from the document.
1220 Code chunks whose names do not begin with ./ are for internal reference.
1221 (This doesn't prevent such chunks from being extracted directly).
1224 \begin_layout Section
1225 Boot-strapping the extraction
1228 \begin_layout Subsection
1232 \begin_layout Standard
1233 \begin_inset CommandInset label
1235 name "sub:Bootstrap-Using-a-Makefile"
1239 It seems convenient to have the makefile extract or update the C source
1240 files as part of it's operation.
1241 It also seems convenient to have the makefile itself extracted from this
1245 \begin_layout Standard
1246 It would also be convenient to have the code to extract the makefile from
1247 this document to also be part of this document, however we have to start
1248 somewhere and this unfortunately requires us to type at least a few words
1249 by hand to start things off.
1252 \begin_layout Standard
1253 Therefore we will have a minimal root fragment, which, when extracted, can
1254 cope with extracting the rest of the source.
1255 perhaps with this shell script, which could be called
1260 \begin_inset Note Note
1263 \begin_layout Plain Layout
1264 FIX THIS CHUNK AND TEST IT
1276 \begin_layout Standard
1277 \begin_inset listings
1281 \begin_layout Plain Layout
1286 \begin_layout Plain Layout
1290 \begin_layout Plain Layout
1292 MAKE_SRC="${1:-${NW_LYX:-../../noweb-lyx/noweb-lyx3.lyx}}"
1295 \begin_layout Plain Layout
1297 MAKE_SRC=`dirname "$MAKE_SRC"`/`basename "$MAKE_SRC" .lyx`
1300 \begin_layout Plain Layout
1302 NOWEB_SRC="${2:-${NOWEB_SRC:-$MAKE_SRC.lyx}}"
1305 \begin_layout Plain Layout
1307 lyx -e latex $MAKE_SRC
1310 \begin_layout Plain Layout
1314 \begin_layout Plain Layout
1316 newfangle -R./Makefile.inc ${MAKE_SRC}.tex
1321 \begin_layout Plain Layout
1323 | sed "/NEWFANGLE_SOURCE=/s/^/#/;T;aNOWEB_SOURCE=$NEWFANGLE_SRC"
1328 \begin_layout Plain Layout
1330 | cpif ./Makefile.inc
1333 \begin_layout Plain Layout
1337 \begin_layout Plain Layout
1339 make -f ./Makefile.inc newfangle_sources
1347 \begin_layout Standard
1348 The general Makefile can be invoked with
1352 and can also be included into any automake file to automatically re-generate
1356 \begin_layout Standard
1361 can be extracted with this command:
1364 \begin_layout LyX-Code
1365 lyx -e latex newfangle.lyx &&
1370 \begin_layout LyX-Code
1371 newfangle newfangle.lyx > ./autoboot
1374 \begin_layout Standard
1375 This looks simple enough, but as mentioned, newfangle has to be had from
1376 somewhere before it can be extracted.
1379 \begin_layout Subsection
1380 \begin_inset Note Note
1383 \begin_layout Plain Layout
1384 MERGE THIS WITH THE SECTIONS OF THIS DOCUMENT
1389 \SpecialChar \ldots{}
1393 \begin_layout Standard
1394 When the lyx-build chunk is executed, the current directory will be a temporary
1396 \begin_inset Flex CharStyle:Code
1399 \begin_layout Plain Layout
1405 will refer to the tex file in this temporary directory.
1406 This is unfortunate as our makefile wants to run from the project directory
1407 where the Lyx file is kept.
1410 \begin_layout Standard
1411 We can extract the project directory from $$r, and derive the probable Lyx
1412 filename from the noweb file that Lyx generated.
1419 \begin_layout Standard
1420 \begin_inset listings
1424 \begin_layout Plain Layout
1426 PROJECT_DIR="$LYX_r"
1429 \begin_layout Plain Layout
1431 LYX_SRC="$PROJECT_DIR/${LYX_i%.tex}.lyx"
1434 \begin_layout Plain Layout
1439 \begin_layout Plain Layout
1441 TEX_SRC="$TEX_DIR/$LYX_i"
1449 \begin_layout Standard
1450 And then we can define a lyx-build fragment similar to the autoboot fragment
1457 \begin_layout Standard
1458 \begin_inset listings
1462 \begin_layout Plain Layout
1467 \begin_layout Plain Layout
1471 chunkref{lyx-build-helper}>
1474 \begin_layout Plain Layout
1476 cd $PROJECT_DIR || exit 1
1479 \begin_layout Plain Layout
1483 \begin_layout Plain Layout
1485 #/usr/bin/newfangle -filter ./notanglefix-filter
1490 \begin_layout Plain Layout
1492 # -R./Makefile.inc "../../noweb-lyx/noweb-lyx3.lyx"
1497 \begin_layout Plain Layout
1499 # | sed '/NOWEB_SOURCE=/s/=.*/=samba4-dfs.lyx/'
1504 \begin_layout Plain Layout
1509 \begin_layout Plain Layout
1514 \begin_layout Plain Layout
1516 #make -f ./Makefile.inc newfangle_sources
1524 \begin_layout Section
1528 \begin_layout Subsection
1529 Including Makefile.inc
1532 \begin_layout Standard
1533 \begin_inset CommandInset label
1535 name "sub:Keeping-extracted-files"
1539 Makefile.inc will cope with extracting all the other source files from this
1540 document and keeping them up to date.
1544 \begin_layout Standard
1545 It may also be included by a Makefile or Makefile.am defined in a Lyx document
1546 to automatically deal with the extraction of source files and documents.
1549 \begin_layout Standard
1550 A makefile has two parts; variables must be defined before the targets that
1558 \begin_layout Standard
1559 \begin_inset listings
1563 \begin_layout Plain Layout
1567 chunkref{Makefile.inc-vars}>
1570 \begin_layout Plain Layout
1574 chunkref{Makefile.inc-targets}>
1582 \begin_layout Standard
1584 \begin_inset Flex CharStyle:Code
1587 \begin_layout Plain Layout
1593 to hold the name of this Lyx file.
1600 \begin_layout Standard
1601 \begin_inset listings
1605 \begin_layout Plain Layout
1610 \begin_layout Plain Layout
1612 LITERATE_SOURCE=$(LYX_SOURCE)
1620 \begin_layout Subsection
1621 Recursive use of Makefile.inc
1624 \begin_layout Standard
1625 The makefile glue described here is used when building Samba4 vfs modules.
1628 \begin_layout Standard
1629 If you are defining a module of an existing program you may find it easier
1630 to use a slight recursive make instead of including the makefile directly.
1631 This way there is less chance of definitions in Makefile.inc interfering
1632 with definitions in the main makefile, or with definitions in other Makefile.inc
1633 from other noweb modules.
1636 \begin_layout Standard
1637 The glue works by adding a .PHONY target to call the recursive make, and
1638 adding this target as an additional pre-requisite to the existing targets.
1641 \begin_layout Standard
1642 In this example, the existing build system already has a build target for
1644 \begin_inset Flex CharStyle:Code
1647 \begin_layout Plain Layout
1653 , so we just add another pre-requisite to that.
1655 \begin_inset Flex CharStyle:Code
1658 \begin_layout Plain Layout
1664 as a pre-requisite, the stamp file's modified time indicating when all
1665 sources were extracted.
1672 \begin_layout Standard
1673 \begin_inset listings
1677 \begin_layout Plain Layout
1679 $(example_srcdir)/example.o: $(example_srcdir)/example.tex.stamp
1687 \begin_layout Standard
1688 The target for this new pre-requisite is generated by a recursive make using
1689 Makefile.inc which will make sure that the source is up to date, before
1690 it is built by the main projects makefile.
1697 \begin_layout Standard
1698 \begin_inset listings
1702 \begin_layout Plain Layout
1704 $(example_srcdir)/example.tex.stamp: $(example_srcdir)/example.tex ;
1709 \begin_layout Plain Layout
1711 cd $(example_srcdir) &&
1716 \begin_layout Plain Layout
1718 $(MAKE) -f Makefile.inc newfangle_sources
1726 \begin_layout Standard
1727 We can do similar glue for the docs, clean and distclean targets.
1728 In this example our build system is using a double colon for these targets,
1729 so we use the same in our glue.
1736 \begin_layout Standard
1737 \begin_inset listings
1741 \begin_layout Plain Layout
1746 \begin_layout Plain Layout
1748 .PHONY: docs_example
1751 \begin_layout Plain Layout
1753 docs_example:: ; cd $(example_srcdir) &&
1758 \begin_layout Plain Layout
1760 $(MAKE) -f Makefile.inc docs
1763 \begin_layout Plain Layout
1767 \begin_layout Plain Layout
1769 clean:: clean_example
1772 \begin_layout Plain Layout
1774 .PHONEY: clean_example
1777 \begin_layout Plain Layout
1779 clean_example: ; cd $(example_srcdir) &&
1784 \begin_layout Plain Layout
1786 $(MAKE) -f Makefile.inc clean
1789 \begin_layout Plain Layout
1793 \begin_layout Plain Layout
1795 distclean:: distclean_example
1798 \begin_layout Plain Layout
1800 .PHONY: distclean_example
1803 \begin_layout Plain Layout
1805 distclean_example: ; cd $(example_srcdir) &&
1810 \begin_layout Plain Layout
1812 $(MAKE) -f Makefile.inc distclean
1820 \begin_layout Standard
1821 We could do similarly for install targets to install the generated docs.
1824 \begin_layout Subsection
1825 \begin_inset CommandInset label
1827 name "sub:Converting-from-Lyx"
1831 Converting from Lyx to LaTeX
1834 \begin_layout Standard
1835 The first stage will always be to convert the Lyx file to a LaTeX file;
1836 this must be so not only because newfangle needs to to run on a TeX file,
1837 but also because the Lyx command
1839 server-goto-file-line
1843 \begin_layout Plain Layout
1846 server-goto-file-line
1848 is used to position the Lyx cursor at the compiler errors.
1855 insists that the line number provided is a line in the TeX file, and always
1856 reverse maps this to derive the line in the Lyx docment.
1857 \begin_inset Note Note
1860 \begin_layout Plain Layout
1861 The tex file should probably be an automake extra dist sources or something,
1862 so that it gets produced and packaged by make dist
1870 \begin_layout Standard
1871 The command [[lyx -e literate noweb-lyx.lyx]] will produce [[noweb-lyx.nw]]
1872 a tex file, so we define the noweb target to be the same as the Lyx file
1873 but with the .nw extension.
1880 \begin_layout Standard
1881 \begin_inset listings
1885 \begin_layout Plain Layout
1887 TEX_SOURCE=$(LYX_SOURCE:.lyx=.tex)
1896 Makefile.inc-targets
1899 \begin_layout Standard
1900 \begin_inset listings
1904 \begin_layout Plain Layout
1906 $(TEX_SOURCE): $(LYX_SOURCE) ;
1911 \begin_layout Plain Layout
1916 \begin_layout Plain Layout
1918 clean_tex: ; rm -f -- $(TEX_SOURCE)
1926 \begin_layout Subsection
1927 Extracting Program Source
1930 \begin_layout Standard
1931 The program source is extracted using newfangle, which is designed to operate
1932 on a LaTeX document.
1940 \begin_layout Standard
1941 \begin_inset listings
1945 \begin_layout Plain Layout
1947 NEWFANGLE_SOURCE=$(TEX_SOURCE)
1955 \begin_layout Standard
1956 The Lyx document can result in any number of source documents, but not all
1957 of these will be changed each time the Lyx document is updated.
1958 We certainly don't want to update the timestamps of these files and cause
1959 the whole source tree to be recompiled just because the Lyx document was
1964 \begin_layout Standard
1965 To solve this problem we use a stamp file which is always updated each time
1966 the sources are extracted from the LaTeX document.
1967 If the stamp file is older than the LaTeX document, then we can make an
1968 attempt to re-extract the sources.
1975 \begin_layout Standard
1976 \begin_inset listings
1980 \begin_layout Plain Layout
1982 NEWFANGLE_SOURCE_STAMP=$(NEWFANGLE_SOURCE).stamp
1991 Makefile.inc-targets
1994 \begin_layout Standard
1995 \begin_inset listings
1999 \begin_layout Plain Layout
2001 $(NEWFANGLE_SOURCE_STAMP): $(NEWFANGLE_SOURCE)
2006 \begin_layout Plain Layout
2008 $(NEWFANGLE_SOURCES) ;
2013 \begin_layout Plain Layout
2015 echo > $(NEWFANGLE_SOURCE_STAMP)
2018 \begin_layout Plain Layout
2020 clean_stamp: ; rm -f $(NEWFANGLE_SOURCE_STAMP)
2023 \begin_layout Plain Layout
2033 \begin_layout Subsection
2034 Extracting C sources
2037 \begin_layout Standard
2039 \begin_inset Flex CharStyle:Code
2042 \begin_layout Plain Layout
2048 to hold the names of all the C source files defined in this document.
2049 We compute this only once, by means of := in assignent.
2050 The sed deletes the any <
2051 \begin_inset space \hspace*{}
2056 \begin_inset space \hspace*{}
2060 > which may surround the roots names (for noroots compatibility).
2064 \begin_layout Standard
2065 As we use chunk names beginning with ./ to denote top level fragments that
2066 should be extracted, we filter out all fragments that do not begin with
2074 \begin_layout Standard
2075 \begin_inset listings
2079 \begin_layout Plain Layout
2088 \begin_layout Plain Layout
2090 NEWFANGLE_SOURCES:=$(shell
2095 \begin_layout Plain Layout
2097 newfangle -r $(NEWFANGLE_SOURCE) |
2102 \begin_layout Plain Layout
2104 sed -e 's/^[<][<]//;s/[>][>]$$//;/^$(NEWFANGLE_PREFIX)/!d'
2109 \begin_layout Plain Layout
2111 -e 's/^$(NEWFANGLE_PREFIX)/
2118 \begin_layout Plain Layout
2129 Makefile.inc-targets
2132 \begin_layout Standard
2133 \begin_inset listings
2137 \begin_layout Plain Layout
2139 .PHONY: echo_newfangle_sources
2142 \begin_layout Plain Layout
2144 echo_newfangle_sources: ; @echo $(NEWFANGLE_SOURCES)
2152 \begin_layout Standard
2153 We define a convenient target called
2154 \begin_inset Flex CharStyle:Code
2157 \begin_layout Plain Layout
2163 to re-extract the source if the LaTeX file has been updated.
2167 Makefile.inc-targets
2170 \begin_layout Standard
2171 \begin_inset listings
2175 \begin_layout Plain Layout
2177 .PHONY: newfangle_sources
2180 \begin_layout Plain Layout
2182 newfangle_sources: $(NEWFANGLE_SOURCE_STAMP)
2190 \begin_layout Standard
2191 And also a convenient target to remove extracted sources.
2195 Makefile.inc-targets
2198 \begin_layout Standard
2199 \begin_inset listings
2203 \begin_layout Plain Layout
2205 .PHONY: clean_newfangle_sources
2208 \begin_layout Plain Layout
2210 clean_newfangle_sources: ;
2215 \begin_layout Plain Layout
2217 rm -f -- $(NEWFANGLE_SOURCE_STAMP) $(NEWFANGLE_SOURCES)
2225 \begin_layout Standard
2227 \begin_inset Flex CharStyle:Code
2230 \begin_layout Plain Layout
2236 macro takes 4 arguments: the filename (1), some extensions to match (2)
2237 and a some shell command to return if the filename matches the exentions
2245 \begin_layout Standard
2246 \begin_inset listings
2250 \begin_layout Plain Layout
2252 if_extension=$(if $(findstring $(suffix $(1)),$(2)),$(3),$(4))
2260 \begin_layout Standard
2261 For some source files like C files, we want to output the line number and
2262 filename of the original LaTeX document from which the source came.
2265 \begin_layout Standard
2266 To make this easier we define the file extensions for which we want to do
2274 \begin_layout Standard
2275 \begin_inset listings
2279 \begin_layout Plain Layout
2289 \begin_layout Standard
2290 We can then use the if_extensions macro to define a macro which expands
2292 \begin_inset Flex CharStyle:Code
2295 \begin_layout Plain Layout
2301 option if newfangle is being invoked in a C source file, so that C compile
2302 errors will refer to the line number in the Lyx document.
2310 \begin_layout Standard
2311 \begin_inset listings
2315 \begin_layout Plain Layout
2320 \begin_layout Plain Layout
2327 \begin_layout Plain Layout
2329 $(call if_extension,$(2),$(C_EXTENSIONS),$(nf_line))
2334 \begin_layout Plain Layout
2344 \begin_layout Standard
2345 We can use a similar trick to define an
2349 macro which takes just the filename as an argument and can return a pipeline
2350 stage calling the indent command.
2351 Indent can be turned off with
2352 \begin_inset Flex CharStyle:Code
2355 \begin_layout Plain Layout
2356 make newfangle_sources indent=
2368 \begin_layout Standard
2369 \begin_inset listings
2373 \begin_layout Plain Layout
2375 indent_options=-npro -kr -i8 -ts8 -sob -l80 -ss -ncs
2378 \begin_layout Plain Layout
2380 indent=$(call if_extension,$(1),$(C_EXTENSIONS),
2385 \begin_layout Plain Layout
2387 | indent $(indent_options))
2395 \begin_layout Standard
2396 We now define the pattern for extracting a file.
2397 The files are written using noweb's
2403 \begin_layout Plain Layout
2406 So you still need noweb installed in order to use cpif
2412 \begin_inset Note Note
2415 \begin_layout Plain Layout
2418 Write an awk version
2425 so that the file timestamp will not be touched if the contents haven't
2427 This avoids the need to rebuild the entire project because of a typographical
2428 change in the documentation, or if only a few C source files have changed.
2435 \begin_layout Standard
2436 \begin_inset listings
2440 \begin_layout Plain Layout
2442 newfangle_extract=@mkdir -p $(dir $(1)) &&
2447 \begin_layout Plain Layout
2449 $(call newfangle,$(2),$(1)) > "$(1).tmp" &&
2454 \begin_layout Plain Layout
2456 cat "$(1).tmp" $(indent) | cpif "$(1)"
2461 \begin_layout Plain Layout
2463 && rm -- "$(1).tmp" ||
2468 \begin_layout Plain Layout
2470 (echo error newfangling $(1) from $(2) ; exit 1)
2478 \begin_layout Standard
2479 We define a target which will extract or update all sources.
2480 To do this we first defined a makefile template that can do this for any
2481 source file in the LaTeX document.
2488 \begin_layout Standard
2489 \begin_inset listings
2493 \begin_layout Plain Layout
2495 define NEWFANGLE_template
2498 \begin_layout Plain Layout
2505 \begin_layout Plain Layout
2507 $$(call newfangle_extract,$(1),$(2))
2510 \begin_layout Plain Layout
2512 NEWFANGLE_TARGETS+=$(1)
2515 \begin_layout Plain Layout
2525 \begin_layout Standard
2526 We then enumerate the discovered
2527 \begin_inset Flex CharStyle:Code
2530 \begin_layout Plain Layout
2536 to generate a makefile rule for each one using the makefile template we
2541 Makefile.inc-targets
2544 \begin_layout Standard
2545 \begin_inset listings
2549 \begin_layout Plain Layout
2551 $(foreach source,$(NEWFANGLE_SOURCES),
2556 \begin_layout Plain Layout
2558 $(eval $(call NEWFANGLE_template,$(source),$(NEWFANGLE_SOURCE)))
2563 \begin_layout Plain Layout
2573 \begin_layout Standard
2574 These will all be built with NEWFANGLE_SOURCE_STAMP.
2577 \begin_layout Standard
2578 We also remove the generated sources on a
2586 Makefile.inc-targets
2589 \begin_layout Standard
2590 \begin_inset listings
2594 \begin_layout Plain Layout
2596 _distclean: clean_newfangle_sources
2604 \begin_layout Subsection
2605 Extracting Documentation
2608 \begin_layout Standard
2609 We then identify the intermediate stages of the documentation and their
2610 build and clean targets.
2613 \begin_layout Subsubsection
2617 \begin_layout Standard
2618 We produce a pdf file from the tex file.
2625 \begin_layout Standard
2626 \begin_inset listings
2630 \begin_layout Plain Layout
2632 NEWFANGLE_PDF=$(TEX_SOURCE:.tex=.pdf)
2640 \begin_layout Standard
2641 We run pdflatex twice to be sure that the contents and aux files are up
2643 We certainly are required to run pdflatex twice if these files do not exist!
2647 Makefile.inc-targets
2650 \begin_layout Standard
2651 \begin_inset listings
2655 \begin_layout Plain Layout
2657 $(NEWFANGLE_PDF): $(TEX_SOURCE); pdflatex $< && pdflatex $<
2660 \begin_layout Plain Layout
2662 clean_pdf: ; rm -f -- $(NEWFANGLE_PDF)
2667 \begin_layout Plain Layout
2669 $(TEX_SOURCE:.tex=.toc)
2674 \begin_layout Plain Layout
2676 $(TEX_SOURCE:.tex=.log)
2681 \begin_layout Plain Layout
2683 $(TEX_SOURCE:.tex=.aux)
2691 \begin_layout Subsubsection
2695 \begin_layout Standard
2696 Currently we only build pdf as a final format, but NEWFANGLE_DOCS may later
2697 hold other output formats.
2704 \begin_layout Standard
2705 \begin_inset listings
2709 \begin_layout Plain Layout
2711 NEWFANGLE_DOCS=$(NEWFANGLE_PDF)
2719 \begin_layout Standard
2720 We also define newfangle_docs as a convenient phony target<
2724 Makefile.inc-targets
2727 \begin_layout Standard
2728 \begin_inset listings
2732 \begin_layout Plain Layout
2734 .PHONY: newfangle_docs
2737 \begin_layout Plain Layout
2739 newfangle_docs: $(NEWFANGLE_DOCS)
2742 \begin_layout Plain Layout
2744 docs: newfangle_docs
2752 \begin_layout Standard
2753 And define a convenient clean_noweb_docs which we add to the regular clean
2758 Makefile.inc-targets
2761 \begin_layout Standard
2762 \begin_inset listings
2766 \begin_layout Plain Layout
2768 .PHONEY: clean_newfangle_docs
2771 \begin_layout Plain Layout
2773 clean_newfangle_docs: clean_tex clean_pdf
2776 \begin_layout Plain Layout
2778 clean: clean_newfangle_docs
2781 \begin_layout Plain Layout
2785 \begin_layout Plain Layout
2787 distclean_newfangle_docs: clean_tex clean_newfangle_docs
2790 \begin_layout Plain Layout
2792 distclean: clean distclean_newfangle_docs
2800 \begin_layout Subsection
2804 \begin_layout Standard
2805 If Makefile.inc is included into Makefile, then extracted files can be updated
2809 \begin_layout LyX-Code
2810 make newfangle_sources
2813 \begin_layout Standard
2817 \begin_layout LyX-Code
2818 make -f Makefile.inc newfangle_sources
2825 \begin_layout Chapter
2826 Newfangle awk source code
2829 \begin_layout Standard
2830 We use the copyright notice from chapter
2831 \begin_inset CommandInset ref
2833 reference "cha:License"
2841 ./newfangle,language=awk,morestring=[b]{/},morekeywords=else
2844 \begin_layout Standard
2845 \begin_inset listings
2849 \begin_layout Plain Layout
2854 \begin_layout Plain Layout
2858 chunkref{gpl3-copyright}>
2866 \begin_layout Standard
2867 We also use code from Arnold Robbins public domain getopt (1993 revision)
2869 \begin_inset CommandInset ref
2871 reference "cha:getopt"
2875 , and naturally want to attribute this appropriately.
2878 \begin_layout Standard
2879 \begin_inset listings
2883 \begin_layout Plain Layout
2887 \begin_layout Plain Layout
2889 # NOTE: Arnold Robbins public domain getopt for awk is also used:
2892 \begin_layout Plain Layout
2896 chunkref{getopt.awk-header}>
2899 \begin_layout Plain Layout
2903 \begin_layout Plain Layout
2907 chunkref{getopt.awk-getopt()}>
2910 \begin_layout Plain Layout
2919 \begin_layout Standard
2920 And include the following chunks
2927 \begin_layout Standard
2928 \begin_inset listings
2932 \begin_layout Plain Layout
2936 chunkref{helper-functions}>
2939 \begin_layout Plain Layout
2943 chunkref{mode-tracker}>
2946 \begin_layout Plain Layout
2950 chunkref{chunk-storage-functions}>
2953 \begin_layout Plain Layout
2957 chunkref{output_chunk_names()}>
2960 \begin_layout Plain Layout
2964 chunkref{output_chunks()}>
2967 \begin_layout Plain Layout
2971 chunkref{write_chunk()}>
2974 \begin_layout Plain Layout
2978 chunkref{expand_chunk_args()}>
2981 \begin_layout Plain Layout
2988 \begin_layout Plain Layout
2992 chunkref{recognize-chunk}>
2995 \begin_layout Plain Layout
3007 \begin_layout Section
3011 \begin_layout Standard
3012 The portable way to erase an array in awk is to split the empty string,
3017 awk-delete-array,params=ARRAY
3020 \begin_layout Standard
3021 \begin_inset listings
3025 \begin_layout Plain Layout
3027 split("", ${ARRAY});
3039 \begin_layout Section
3043 \begin_layout Standard
3044 Fatal errors are issued with the error function:
3051 \begin_layout Standard
3052 \begin_inset listings
3056 \begin_layout Plain Layout
3058 function error(message)
3061 \begin_layout Plain Layout
3066 \begin_layout Plain Layout
3068 print message > "/dev/stderr";
3071 \begin_layout Plain Layout
3076 \begin_layout Plain Layout
3086 \begin_layout Standard
3087 This is one of the helper functions.
3094 \begin_layout Standard
3095 \begin_inset listings
3099 \begin_layout Plain Layout
3111 \begin_layout Chapter
3115 \begin_layout Standard
3116 LaTeX arguments to lstlistings macros are a comma seperated list of key-value
3118 Values containing commas are enclosed in { braces }.
3121 \begin_layout Standard
3122 We need a function that can parse such an expression and assign the values
3130 \begin_layout Standard
3131 A sample expressions is:
3134 \begin_layout LyX-Code
3135 name=thomas, params={a, b}, something, something-else
3138 \begin_layout Standard
3139 but we see that this is just a simpler form of this expression:
3142 \begin_layout LyX-Code
3143 name=freddie, foo={bar=baz, quux={quirk, a=fleeg}}, etc
3146 \begin_layout Standard
3147 And that it would be a good idea to use a recursive parser into a multi-dimensio
3152 \begin_layout Plain Layout
3153 as AWK doesn't have nested-hash support
3161 \begin_layout Standard
3162 \begin_inset Tabular
3163 <lyxtabular version="3" rows="6" columns="2">
3165 <column alignment="left" valignment="top" width="0">
3166 <column alignment="left" valignment="top" width="0">
3168 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
3171 \begin_layout Plain Layout
3177 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
3180 \begin_layout Plain Layout
3188 <cell alignment="left" valignment="top" topline="true" leftline="true" usebox="none">
3191 \begin_layout Plain Layout
3197 <cell alignment="left" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
3200 \begin_layout Plain Layout
3208 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
3211 \begin_layout Plain Layout
3217 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
3220 \begin_layout Plain Layout
3228 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
3231 \begin_layout Plain Layout
3237 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
3240 \begin_layout Plain Layout
3248 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
3251 \begin_layout Plain Layout
3257 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
3260 \begin_layout Plain Layout
3268 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
3271 \begin_layout Plain Layout
3277 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
3280 \begin_layout Plain Layout
3294 \begin_layout Standard
3295 On reflection it seems that sometimes such nesting is not desirable, as
3296 the braces are also used to delimit values that contain commas --- we may
3300 \begin_layout LyX-Code
3301 name={williamson, freddie}
3304 \begin_layout Standard
3306 \begin_inset Flex CharStyle:Code
3309 \begin_layout Plain Layout
3316 \begin_inset Flex CharStyle:Code
3319 \begin_layout Plain Layout
3325 --- so I may change this behaviour.
3326 \begin_inset Note Note
3329 \begin_layout Plain Layout
3338 \begin_layout Standard
3340 \begin_inset Flex Chunkref
3343 \begin_layout Plain Layout
3349 will accept two paramters,
3350 \begin_inset Flex CharStyle:Code
3353 \begin_layout Plain Layout
3359 being the text to parse, and
3360 \begin_inset Flex CharStyle:Code
3363 \begin_layout Plain Layout
3369 being an array to receive the parsed values as described above.
3370 The optional parameter
3371 \begin_inset Flex CharStyle:Code
3374 \begin_layout Plain Layout
3380 is used during recursion to build up the multi-dimensional array path.
3387 \begin_layout Standard
3388 \begin_inset listings
3392 \begin_layout Plain Layout
3396 chunkref{get_chunk_args()}>
3408 \begin_layout Standard
3409 \begin_inset listings
3413 \begin_layout Plain Layout
3415 function get_chunk_args(text, values,
3418 \begin_layout Plain Layout
3420 # optional parameters
3423 \begin_layout Plain Layout
3425 path, # hierarchical precursors
3428 \begin_layout Plain Layout
3433 \begin_layout Plain Layout
3443 \begin_layout Standard
3444 The strategy is to parse the name, and then look for a value.
3445 If the value begins with a brace
3446 \begin_inset Flex CharStyle:Code
3449 \begin_layout Plain Layout
3455 , then we recurse and consume as much of the text as necessary, returning
3456 the remaining text when we encounter a leading close-brace
3457 \begin_inset Flex CharStyle:Code
3460 \begin_layout Plain Layout
3467 This being the strategy --- and executed in a loop --- we realise that
3468 we must first look for the closing brace (perhaps preceded by white space)
3469 in order to terminate the recursion, and returning remaining text.
3472 \begin_layout Standard
3473 \begin_inset listings
3477 \begin_layout Plain Layout
3482 \begin_layout Plain Layout
3484 while(length(text)) {
3487 \begin_layout Plain Layout
3489 if (match(text, "^ *}(.*)", a)) {
3492 \begin_layout Plain Layout
3497 \begin_layout Plain Layout
3502 \begin_layout Plain Layout
3506 chunkref{parse-chunk-args}>
3509 \begin_layout Plain Layout
3514 \begin_layout Plain Layout
3519 \begin_layout Plain Layout
3529 \begin_layout Standard
3530 \begin_inset Note Note
3533 \begin_layout Plain Layout
3534 Use BNF package here
3539 We can see that the text could be inspected with this regex:
3546 \begin_layout Standard
3547 \begin_inset listings
3551 \begin_layout Plain Layout
3553 if (! match(text, " *([^,=]*[^,= ]) *(([,=]) *(([^,}]*) *,* *(.*))|)$", a))
3557 \begin_layout Plain Layout
3562 \begin_layout Plain Layout
3572 \begin_layout Standard
3574 \begin_inset Flex CharStyle:Code
3577 \begin_layout Plain Layout
3583 will have the following values:
3586 \begin_layout Standard
3587 \begin_inset Tabular
3588 <lyxtabular version="3" rows="7" columns="2">
3590 <column alignment="center" valignment="top" width="0">
3591 <column alignment="left" valignment="top" width="0">
3593 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
3596 \begin_layout Plain Layout
3602 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
3605 \begin_layout Plain Layout
3613 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
3616 \begin_layout Plain Layout
3622 <cell alignment="left" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
3625 \begin_layout Plain Layout
3633 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
3636 \begin_layout Plain Layout
3642 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
3645 \begin_layout Plain Layout
3646 =freddie, foo={bar=baz, quux={quirk, a=fleeg}}, etc
3653 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
3656 \begin_layout Plain Layout
3662 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
3665 \begin_layout Plain Layout
3673 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
3676 \begin_layout Plain Layout
3682 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
3685 \begin_layout Plain Layout
3686 freddie, foo={bar=baz, quux={quirk, a=fleeg}}, etc
3693 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
3696 \begin_layout Plain Layout
3702 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
3705 \begin_layout Plain Layout
3713 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
3716 \begin_layout Plain Layout
3722 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
3725 \begin_layout Plain Layout
3726 , foo={bar=baz, quux={quirk, a=fleeg}}, etc
3739 \begin_layout Standard
3741 \begin_inset Flex CharStyle:Code
3744 \begin_layout Plain Layout
3751 \begin_inset Flex CharStyle:Code
3754 \begin_layout Plain Layout
3760 and signify whether the option named in
3761 \begin_inset Flex CharStyle:Code
3764 \begin_layout Plain Layout
3770 has a value or not (respectively).
3773 \begin_layout Standard
3774 If the option does have a value, then if the expression
3775 \begin_inset Flex CharStyle:Code
3778 \begin_layout Plain Layout
3785 \begin_inset Flex CharStyle:Code
3788 \begin_layout Plain Layout
3794 it will signify that we need to recurse:
3797 \begin_layout Standard
3798 \begin_inset listings
3802 \begin_layout Plain Layout
3807 \begin_layout Plain Layout
3812 \begin_layout Plain Layout
3814 if (substr(a[4],1,1) == "{") {
3817 \begin_layout Plain Layout
3819 text = get_chunk_args(substr(a[4],2), values, path name SUBSEP);
3822 \begin_layout Plain Layout
3827 \begin_layout Plain Layout
3829 values[path name]=a[5];
3832 \begin_layout Plain Layout
3837 \begin_layout Plain Layout
3842 \begin_layout Plain Layout
3847 \begin_layout Plain Layout
3849 values[path name]="";
3852 \begin_layout Plain Layout
3857 \begin_layout Plain Layout
3867 \begin_layout Standard
3868 We can test this function like this:
3875 \begin_layout Standard
3876 \begin_inset listings
3880 \begin_layout Plain Layout
3884 chunkref{get_chunk_args()}>
3887 \begin_layout Plain Layout
3892 \begin_layout Plain Layout
3897 \begin_layout Plain Layout
3901 \begin_layout Plain Layout
3903 print get_chunk_args("name=freddie, foo={bar=baz, quux={quirk, a=fleeg}},
3907 \begin_layout Plain Layout
3912 \begin_layout Plain Layout
3914 print "a[" b "] => " a[b];
3917 \begin_layout Plain Layout
3922 \begin_layout Plain Layout
3932 \begin_layout Standard
3933 which should give this output:
3937 gca-test.awk-results
3940 \begin_layout Standard
3941 \begin_inset listings
3945 \begin_layout Plain Layout
3947 a[foo.quux.quirk] =>
3950 \begin_layout Plain Layout
3952 a[foo.quux.a] => fleeg
3955 \begin_layout Plain Layout
3960 \begin_layout Plain Layout
3965 \begin_layout Plain Layout
3975 \begin_layout Chapter
3976 Expanding chunk arguments
3979 \begin_layout Standard
3980 \begin_inset CommandInset label
3982 name "cha:Chunk Arguments"
3987 \begin_inset Note Note
3990 \begin_layout Plain Layout
3991 Explain this in the documentation section too
3996 As an extension to many literate-programming styles, newfangle permits code
3997 chunks to take parameters and thus operate somewhat like C pre-processor
3998 macros, or like C++ templates.
4001 \begin_layout Standard
4002 Chunk parameters are declared with a chunk argument called
4003 \begin_inset Flex CharStyle:Code
4006 \begin_layout Plain Layout
4012 , which holds a semi-colon separated list of parameters, like this:
4015 \begin_layout LyX-Code
4016 achunk,language=C,params=name;address
4019 \begin_layout Standard
4020 When such a chunk is included the arguments are expressed thus, in square
4021 brackets as optional arguments separated by a comma
4022 \begin_inset Note Note
4025 \begin_layout Plain Layout
4026 We ought to support qouting in {} like ({Jones, John}, Jones@example.com)
4034 \begin_layout LyX-Code
4037 chunkref{achunk}(John Jones, jones@example.com)
4040 \begin_layout Standard
4041 Within the body a chunk, parameters are expressed as:
4042 \begin_inset Flex CharStyle:Code
4045 \begin_layout Plain Layout
4052 \begin_inset Flex CharStyle:Code
4055 \begin_layout Plain Layout
4062 There is a strong case that a LaTeX style notation should be used, like
4067 param{name}> as it would appear in the lstlisting.
4068 Such notation would make me go blind, but I do intend to adopt it.
4071 \begin_layout Standard
4072 We therefore need a function
4073 \begin_inset Flex CharStyle:Code
4076 \begin_layout Plain Layout
4082 which will take a block of text, a list of permitted parameters and the
4083 arguments which must substitute for the parameters.
4084 We also need to be able to parse a parameter list into an array of parameters.
4087 \begin_layout Section
4088 Parsing argument lists
4091 \begin_layout Standard
4092 An argument list may be as simple as in
4093 \begin_inset Flex CharStyle:Code
4096 \begin_layout Plain Layout
4099 chunkref{pull}(thing, otherthing)
4107 \begin_layout LyX-Code
4110 chunkref{pull}(things[x, y], get_other_things(a, "all"))
4113 \begin_layout Standard
4114 --- which for all it's commas and quotes and parenthesis represents only
4118 \begin_layout Standard
4119 How do we stop the comma in
4120 \begin_inset Flex CharStyle:Code
4123 \begin_layout Plain Layout
4129 from splitting it into two arguments
4130 \begin_inset Flex CharStyle:Code
4133 \begin_layout Plain Layout
4140 \begin_inset Flex CharStyle:Code
4143 \begin_layout Plain Layout
4149 --- neither of which make sense on their own?
4152 \begin_layout Standard
4153 One way it could be done is by refusing to split text between maching delimiters
4155 \begin_inset Flex CharStyle:Code
4158 \begin_layout Plain Layout
4165 \begin_inset Flex CharStyle:Code
4168 \begin_layout Plain Layout
4175 \begin_inset Flex CharStyle:Code
4178 \begin_layout Plain Layout
4185 \begin_inset Flex CharStyle:Code
4188 \begin_layout Plain Layout
4195 \begin_inset Flex CharStyle:Code
4198 \begin_layout Plain Layout
4205 \begin_inset Flex CharStyle:Code
4208 \begin_layout Plain Layout
4214 and most likely also
4215 \begin_inset Flex CharStyle:Code
4218 \begin_layout Plain Layout
4225 \begin_inset Flex CharStyle:Code
4228 \begin_layout Plain Layout
4235 \begin_inset Flex CharStyle:Code
4238 \begin_layout Plain Layout
4245 \begin_inset Flex CharStyle:Code
4248 \begin_layout Plain Layout
4255 Of course this also makes it impossible to pass such mis-matched code fragments
4256 as parameters, but I don't think users could cope with people passing such
4257 code unbalanced fragments as chunk parameters
4261 \begin_layout Plain Layout
4262 I know that I couldn't cope with users doing such things, and although the
4263 GPL3 license prevents me from actually forbidding anyone from trying, if
4264 they wan't it to work they'll have to write the code themselves and not
4265 expect any support from me.
4273 \begin_layout Standard
4274 Unfortunately, the full set of matching delimiters may vary from language
4276 In certain C++ template contexts,
4277 \begin_inset Flex CharStyle:Code
4280 \begin_layout Plain Layout
4287 \begin_inset Flex CharStyle:Code
4290 \begin_layout Plain Layout
4296 would count as delimiters, and yet in other contexts they would not.
4299 \begin_layout Standard
4300 This puts me in the unfortunate position of having to parse-somewhat all
4301 programming languages without knowing what they are! Eventually this will
4302 be managed in the chunk modes in chapter
4303 \begin_inset CommandInset ref
4305 reference "cha:modes"
4312 \begin_layout Standard
4313 Another way, inspired by LaTeX, is if the first character of the parameter
4314 is an opening-delimiter, to read up to the matching closing-delimiter wthout
4315 considering intervening commas; thus the above example could be expressed:
4318 \begin_layout LyX-Code
4321 chunkref{pull}({things[x, y]}, [get_other_things(a, "all")])
4324 \begin_layout Standard
4326 \begin_inset Flex CharStyle:Code
4329 \begin_layout Plain Layout
4336 \begin_inset Flex CharStyle:Code
4339 \begin_layout Plain Layout
4345 to wrap the first agument, and
4346 \begin_inset Flex CharStyle:Code
4349 \begin_layout Plain Layout
4356 \begin_inset Flex CharStyle:Code
4359 \begin_layout Plain Layout
4365 to wrap the second argument and protect the comma.
4368 \begin_layout Standard
4369 In the meantime, I'll work with the first method, and a fixed list of delimiters.
4372 \begin_layout Standard
4380 \begin_layout Standard
4381 \begin_inset listings
4385 \begin_layout Plain Layout
4387 function parse_chunk_args(text, values,
4390 \begin_layout Plain Layout
4392 # optional parameters
4395 \begin_layout Plain Layout
4397 path, # hierarchical precursors
4400 \begin_layout Plain Layout
4402 stack, # delimiters to be matched
4405 \begin_layout Plain Layout
4410 \begin_layout Plain Layout
4415 \begin_layout Plain Layout
4420 \begin_layout Plain Layout
4425 \begin_layout Plain Layout
4427 split(chunklet_parts[2], call_chunk_args, " *, *");
4430 \begin_layout Plain Layout
4440 \begin_layout Standard
4441 The strategy is to parse the name, and then look for a value.
4442 If the value begins with a brace
4443 \begin_inset Flex CharStyle:Code
4446 \begin_layout Plain Layout
4452 , then we recurse and consume as much of the text as necessary, returning
4453 the remaining text when we encounter a leading close-brace
4454 \begin_inset Flex CharStyle:Code
4457 \begin_layout Plain Layout
4464 This being the strategy --- and executed in a loop --- we realise that
4465 we must first look for the closing brace (perhaps preceded by white space)
4466 in order to terminate the recursion, and returning remaining text.
4469 \begin_layout Standard
4470 \begin_inset listings
4474 \begin_layout Plain Layout
4479 \begin_layout Plain Layout
4483 "", "delimiters" ]="
4490 \begin_layout Plain Layout
4494 "", "terminators"]="
4499 \begin_layout Plain Layout
4501 modes["{", "delimiters" ]="
4518 \begin_layout Plain Layout
4520 modes["{", "terminators"]="}";
4523 \begin_layout Plain Layout
4525 modes["[", "delimiters" ]="
4546 \begin_layout Plain Layout
4548 modes["[", "terminators"]="]";
4551 \begin_layout Plain Layout
4553 modes["(", "delimiters" ]="
4570 \begin_layout Plain Layout
4572 modes["(", "terminators"]=")";
4575 \begin_layout Plain Layout
4577 modes["'", "delimiters" ]="
4584 \begin_layout Plain Layout
4586 modes["'", "terminators"]="'";
4589 \begin_layout Plain Layout
4591 modes["/*", "terminators"]="*/";
4594 \begin_layout Plain Layout
4596 modes["//", "terminators"]="
4601 \begin_layout Plain Layout
4603 modes["", "delimiters" ]="
4620 \begin_layout Plain Layout
4625 \begin_layout Plain Layout
4629 \begin_layout Plain Layout
4631 delimiters=modes[mode, "delimiters"];
4634 \begin_layout Plain Layout
4638 \begin_layout Plain Layout
4640 while(length(text)) {
4643 \begin_layout Plain Layout
4645 if match(text, "(" delimiters ")", a) {
4648 \begin_layout Plain Layout
4650 if (a[1] == modes[mode, "terminator"]) return result a[1];
4653 \begin_layout Plain Layout
4658 \begin_layout Plain Layout
4660 #check if new_mode is defined
4663 \begin_layout Plain Layout
4665 if (! (new_mode, "terminators") in modes) {
4668 \begin_layout Plain Layout
4670 error("Delimiter %s set unknown mode in text: %s", new_mode, text);
4673 \begin_layout Plain Layout
4678 \begin_layout Plain Layout
4680 text = substr(text, RSTART));
4683 \begin_layout Plain Layout
4685 result = result substr(text, 1, RSTART -1) RECURSE(text,,new_mode);
4688 \begin_layout Plain Layout
4693 \begin_layout Plain Layout
4695 result = result text;
4698 \begin_layout Plain Layout
4703 \begin_layout Plain Layout
4708 \begin_layout Plain Layout
4713 \begin_layout Plain Layout
4723 \begin_layout Standard
4724 We can test this function like this:
4731 \begin_layout Standard
4732 \begin_inset listings
4736 \begin_layout Plain Layout
4740 chunkref{get_chunk_args()}>
4743 \begin_layout Plain Layout
4748 \begin_layout Plain Layout
4753 \begin_layout Plain Layout
4757 \begin_layout Plain Layout
4759 print parse_chunk_args("things[x, y], get_other_things(a,
4766 \begin_layout Plain Layout
4771 \begin_layout Plain Layout
4773 print "a[" b "] => " a[b];
4776 \begin_layout Plain Layout
4781 \begin_layout Plain Layout
4791 \begin_layout Standard
4792 which should give this output:
4796 pca-test.awk-results
4799 \begin_layout Standard
4800 \begin_inset listings
4804 \begin_layout Plain Layout
4806 a[foo.quux.quirk] =>
4809 \begin_layout Plain Layout
4811 a[foo.quux.a] => fleeg
4814 \begin_layout Plain Layout
4819 \begin_layout Plain Layout
4824 \begin_layout Plain Layout
4834 \begin_layout Section
4835 Expanding parameters
4838 \begin_layout Standard
4839 \begin_inset CommandInset label
4841 name "Here-we-split"
4845 Here we split the text on
4846 \begin_inset Flex CharStyle:Code
4849 \begin_layout Plain Layout
4855 which means that all parts except the first will begin with a parameter
4857 The split function will consume the literal
4858 \begin_inset Flex CharStyle:Code
4861 \begin_layout Plain Layout
4874 \begin_layout Standard
4875 \begin_inset listings
4879 \begin_layout Plain Layout
4881 function expand_chunk_args(text, params, args,
4884 \begin_layout Plain Layout
4886 p, text_array, next_text, v, t, l)
4889 \begin_layout Plain Layout
4894 \begin_layout Plain Layout
4896 if (split(text, text_array, "
4903 \begin_layout Plain Layout
4907 chunkref{substitute-chunk-args}>
4910 \begin_layout Plain Layout
4915 \begin_layout Plain Layout
4920 \begin_layout Plain Layout
4930 \begin_layout Standard
4931 First, we produce an associative array of substitution values indexed by
4936 substitute-chunk-args
4939 \begin_layout Standard
4940 \begin_inset listings
4944 \begin_layout Plain Layout
4949 \begin_layout Plain Layout
4951 v[params[p]]=args[p];
4954 \begin_layout Plain Layout
4964 \begin_layout Standard
4965 We accumulate substituted text in the variable
4966 \begin_inset Flex CharStyle:Code
4969 \begin_layout Plain Layout
4976 As the first part of the split function is the part before the delimiter
4978 \begin_inset Flex CharStyle:Code
4981 \begin_layout Plain Layout
4987 in our case --- this part will never contain a parameter reference, so
4988 we assign this directly to the result kept in
4989 \begin_inset Flex CharStyle:Code
4992 \begin_layout Plain Layout
4999 \begin_inset listings
5003 \begin_layout Plain Layout
5013 \begin_layout Standard
5014 We then iterate over the remaining values in the array
5018 \begin_layout Plain Layout
5019 I don't know why I think that it will enumerate the array in order, but
5026 \begin_inset Note Note
5029 \begin_layout Plain Layout
5030 So fix it or porve it
5035 , and substitute each reference for it's argument.
5038 \begin_layout Standard
5039 \begin_inset listings
5043 \begin_layout Plain Layout
5045 for(t in text_array) if (t>1) {
5048 \begin_layout Plain Layout
5052 chunkref{substitute-chunk-arg}>
5055 \begin_layout Plain Layout
5065 \begin_layout Standard
5067 \begin_inset Flex CharStyle:Code
5070 \begin_layout Plain Layout
5076 a valid parameter reference will consist of valid parameter name terminated
5078 \begin_inset Flex CharStyle:Code
5081 \begin_layout Plain Layout
5088 A valid character name begins with the underscore or a letter, and may
5089 contain letters, digits or underscores.
5092 \begin_layout Standard
5093 A valid looking reference that is not actually the name of a parameter will
5094 be and not substituted.
5095 This is good because there is nothing to substitute anyway, and it avoids
5096 clashes when writing code for languages where ${\SpecialChar \ldots{}
5097 } is a valid construct
5098 --- such constructs will not be interfered with unless the parameter name
5103 substitute-chunk-arg
5106 \begin_layout Standard
5107 \begin_inset listings
5111 \begin_layout Plain Layout
5113 if (match(text_array[t], "^([a-zA-Z_][a-zA-Z0-9_]*)}", l) &&
5116 \begin_layout Plain Layout
5121 \begin_layout Plain Layout
5126 \begin_layout Plain Layout
5128 text = text v[l[1]] substr(text_array[t], length(l[1])+2);
5131 \begin_layout Plain Layout
5136 \begin_layout Plain Layout
5138 text = text "${" text_array[t];
5141 \begin_layout Plain Layout
5151 \begin_layout Chapter
5155 \begin_layout Standard
5156 Newfangle recognizes noweb chunks, but as we also want better LaTeX integration
5157 we will recognize any of these:
5160 \begin_layout Itemize
5161 notangle chunks matching the pattern
5162 \begin_inset Flex CharStyle:Code
5165 \begin_layout Plain Layout
5167 \begin_inset space \hspace*{}
5172 \begin_inset space \hspace*{}
5184 \begin_layout Itemize
5185 a chunks beginning with
5186 \begin_inset Flex CharStyle:Code
5189 \begin_layout Plain Layout
5199 Chunk{\SpecialChar \ldots{}
5200 } on the previous line
5203 \begin_layout Itemize
5204 an older form I have used, beginning with
5205 \begin_inset Flex CharStyle:Code
5208 \begin_layout Plain Layout
5211 begin{Chunk}[options]
5216 --- also more suitable for plain LaTeX users
5220 \begin_layout Plain Layout
5221 Is there such a thing as plain LaTeX?
5229 \begin_layout Section
5233 \begin_layout Standard
5235 \begin_inset Flex CharStyle:Code
5238 \begin_layout Plain Layout
5244 is used to signify that we are processing a code chunk and not document.
5245 In such a state, input lines will be assigned to the current chunk; otherwise
5249 \begin_layout Subsection
5253 \begin_layout Standard
5254 Our current scheme is to recognize the new lstlisting chunks, but these
5255 may be preceded by a
5256 \begin_inset Flex CharStyle:Code
5259 \begin_layout Plain Layout
5267 command which in LyX is a more convenient way to pass the chunk name to
5269 \begin_inset Flex CharStyle:Code
5272 \begin_layout Plain Layout
5280 command, and a more visible way to specify other
5281 \begin_inset Flex CharStyle:Code
5284 \begin_layout Plain Layout
5293 \begin_layout Standard
5294 The arguments to the
5295 \begin_inset Flex CharStyle:Code
5298 \begin_layout Plain Layout
5306 command are a name, and then a comma-seperated list of key-value pairs
5308 \begin_inset Flex CharStyle:Code
5311 \begin_layout Plain Layout
5320 (In fact within the LaTeX
5321 \begin_inset Flex CharStyle:Code
5324 \begin_layout Plain Layout
5333 \begin_inset CommandInset ref
5335 reference "sub:The-chunk-command"
5340 \begin_inset Flex CharStyle:Code
5343 \begin_layout Plain Layout
5349 is prefixed to the argument which is then literally passed to
5350 \begin_inset Flex CharStyle:Code
5353 \begin_layout Plain Layout
5368 \begin_layout Standard
5369 \begin_inset listings
5373 \begin_layout Plain Layout
5382 \begin_layout Plain Layout
5392 Chunk{ *([^ ,}]*),?(.*)}", line)) {
5395 \begin_layout Plain Layout
5397 next_chunk_name = line[1];
5400 \begin_layout Plain Layout
5402 get_chunk_args(line[2], next_chunk_args);
5405 \begin_layout Plain Layout
5410 \begin_layout Plain Layout
5415 \begin_layout Plain Layout
5425 \begin_layout Standard
5426 We also make a basic attempt to parse the name out of the
5427 \begin_inset Flex CharStyle:Code
5430 \begin_layout Plain Layout
5434 \begin_inset space \hspace{}
5443 text, otherwise we fall back to the name found in the previous chunk command.
5444 This attempt is very basic and doesn't support commas or spaces or square
5445 brackets as part of the chunkname.
5447 \begin_inset Flex CharStyle:Code
5450 \begin_layout Plain Layout
5458 which is convenient for some users
5462 \begin_layout Plain Layout
5463 but not yet supported in the LaTeX macros
5469 \begin_inset Note Note
5472 \begin_layout Plain Layout
5481 \begin_layout Standard
5482 \begin_inset listings
5486 \begin_layout Plain Layout
5499 \begin_layout Plain Layout
5501 if (match($0, "}.*[[,] *name= *{? *([^], }]*)", line)) {
5504 \begin_layout Plain Layout
5509 \begin_layout Plain Layout
5514 \begin_layout Plain Layout
5516 new_chunk(next_chunk_name, next_chunk_args);
5519 \begin_layout Plain Layout
5524 \begin_layout Plain Layout
5529 \begin_layout Plain Layout
5534 \begin_layout Plain Layout
5544 \begin_layout Subsection
5548 \begin_layout Standard
5549 We recognize notangle style chunks too:
5556 \begin_layout Standard
5557 \begin_inset listings
5561 \begin_layout Plain Layout
5566 \begin_layout Plain Layout
5568 if (match($0, "^[<]<(.*)[>]>= *$", line)) {
5571 \begin_layout Plain Layout
5576 \begin_layout Plain Layout
5581 \begin_layout Plain Layout
5586 \begin_layout Plain Layout
5591 \begin_layout Plain Layout
5596 \begin_layout Plain Layout
5606 \begin_layout Section
5610 \begin_layout Standard
5611 Likewise, we need to recognize when a chunk ends.
5614 \begin_layout Subsection
5618 \begin_layout Standard
5620 \begin_inset Flex CharStyle:Code
5623 \begin_layout Plain Layout
5630 \begin_inset Flex CharStyle:Code
5633 \begin_layout Plain Layout
5639 is surrounded by square brackets so that when this document is processed,
5640 this chunk doesn't terminate early when the lstlistings package recognizes
5641 it's own end-string!
5642 \begin_inset Note Greyedout
5645 \begin_layout Plain Layout
5646 This doesn't make sense as the regex is anchored with ^, which this line
5647 does not begin with!
5653 \begin_inset Note Note
5656 \begin_layout Plain Layout
5669 \begin_layout Standard
5670 \begin_inset listings
5674 \begin_layout Plain Layout
5687 \begin_layout Plain Layout
5692 \begin_layout Plain Layout
5697 \begin_layout Plain Layout
5702 \begin_layout Plain Layout
5712 \begin_layout Subsection
5720 \begin_layout Standard
5721 \begin_inset listings
5725 \begin_layout Plain Layout
5730 \begin_layout Plain Layout
5735 \begin_layout Plain Layout
5740 \begin_layout Plain Layout
5750 \begin_layout Standard
5751 All other recognizers are only of effect if we are chunking; there's no
5752 point in looking at lines if they aren't part of a chunk, so we just ignore
5753 them as efficiently as we can.
5760 \begin_layout Standard
5761 \begin_inset listings
5765 \begin_layout Plain Layout
5767 ! chunking { next; }
5775 \begin_layout Section
5779 \begin_layout Standard
5780 Chunk contents are any lines read while
5781 \begin_inset Flex CharStyle:Code
5784 \begin_layout Plain Layout
5791 Some chunk contents are special in that they refer to other chunks, and
5792 will be replaced by the contents of these chunks when the file is generated.
5795 \begin_layout Standard
5796 \begin_inset CommandInset label
5798 name "sub:ORS-chunk-text"
5802 We add the output record separator
5803 \begin_inset Flex CharStyle:Code
5806 \begin_layout Plain Layout
5812 to the line now, because we will set
5813 \begin_inset Flex CharStyle:Code
5816 \begin_layout Plain Layout
5822 to the empty string when we generate the output
5826 \begin_layout Plain Layout
5827 So that we can print partial lines using
5828 \begin_inset Flex CharStyle:Code
5831 \begin_layout Plain Layout
5838 \begin_inset Flex CharStyle:Code
5841 \begin_layout Plain Layout
5859 \begin_layout Standard
5860 \begin_inset listings
5864 \begin_layout Plain Layout
5866 length(active_chunk) {
5869 \begin_layout Plain Layout
5873 chunkref{process-chunk}>
5876 \begin_layout Plain Layout
5886 \begin_layout Standard
5887 If a chunk just consisted of plain text, we could handle the chunk like
5892 process-chunk-simple
5895 \begin_layout Standard
5896 \begin_inset listings
5900 \begin_layout Plain Layout
5902 chunk_line(active_chunk, $0 ORS);
5910 \begin_layout Standard
5911 but in fact a chunk can include references to other chunks.
5912 Chunk includes are traditionally written as
5913 \begin_inset Flex CharStyle:Code
5916 \begin_layout Plain Layout
5922 , but we support other variations.
5925 \begin_layout Subsection
5926 \begin_inset CommandInset label
5928 name "sub:lstlistings-includes"
5935 \begin_layout Standard
5937 \begin_inset Flex CharStyle:Code
5940 \begin_layout Plain Layout
5943 lstset{escapeinside={=<}{>}}
5948 is set, then we can use
5949 \begin_inset Flex CharStyle:Code
5952 \begin_layout Plain Layout
5956 \begin_inset space \hspace{}
5967 \begin_inset Flex CharStyle:Code
5970 \begin_layout Plain Layout
5979 \begin_layout Enumerate
5980 it is a better mnemonic than
5981 \begin_inset Flex CharStyle:Code
5984 \begin_layout Plain Layout
5990 in that the = sign signifies equivalent or substitutability,
5993 \begin_layout Enumerate
5994 and because =< is not valid in C or in any language I can think of
5997 \begin_layout Enumerate
5998 and also because lstlistings doesn't like
5999 \begin_inset Flex CharStyle:Code
6002 \begin_layout Plain Layout
6008 as an end delimiter for the
6012 escape, so we must make do with a single
6013 \begin_inset Flex CharStyle:Code
6016 \begin_layout Plain Layout
6022 , which is better matched by
6023 \begin_inset Flex CharStyle:Code
6026 \begin_layout Plain Layout
6033 \begin_inset Flex CharStyle:Code
6036 \begin_layout Plain Layout
6045 \begin_layout Standard
6046 As each chunk line may contain more than one chunk include, we will split
6047 out chunk includes in an iterative fashion
6051 \begin_layout Plain Layout
6052 Contrary to our use of
6053 \begin_inset Flex CharStyle:Code
6056 \begin_layout Plain Layout
6062 when substituting parameters in chapter
6063 \begin_inset CommandInset ref
6065 reference "Here-we-split"
6077 \begin_layout Standard
6078 First, as long as the chunk contains a
6079 \begin_inset Flex CharStyle:Code
6082 \begin_layout Plain Layout
6090 command we take as much as we can up to the first
6091 \begin_inset Flex CharStyle:Code
6094 \begin_layout Plain Layout
6109 \begin_layout Standard
6110 \begin_inset listings
6114 \begin_layout Plain Layout
6119 \begin_layout Plain Layout
6124 \begin_layout Plain Layout
6129 \begin_layout Plain Layout
6147 )|)>|<<([a-zA-Z_][-a-zA-Z0-9_]*)>>)",
6150 \begin_layout Plain Layout
6157 \begin_layout Plain Layout
6162 \begin_layout Plain Layout
6164 chunklet = substr(chunk, 1, RSTART - 1);
6172 \begin_layout Standard
6173 We keep track of the indent count, by counting the number of literal characters
6175 We can then preserve this indent on each output line when multi-line chunks
6179 \begin_layout Standard
6180 We then process this first part literal text, and set the chunk which is
6181 still to be processed to be the text after the
6182 \begin_inset Flex CharStyle:Code
6185 \begin_layout Plain Layout
6193 command, which we will process next as we continue around the loop.
6196 \begin_layout Standard
6197 \begin_inset listings
6201 \begin_layout Plain Layout
6203 indent += length(chunklet);
6206 \begin_layout Plain Layout
6208 chunk_line(active_chunk, chunklet);
6211 \begin_layout Plain Layout
6213 chunk = substr(chunk, RSTART + RLENGTH);
6221 \begin_layout Standard
6222 We then consider the type of chunk command we have found, whether it is
6223 the newfangle style command beginning with
6224 \begin_inset Flex CharStyle:Code
6227 \begin_layout Plain Layout
6233 or the older notangle style beginning with
6234 \begin_inset Flex CharStyle:Code
6237 \begin_layout Plain Layout
6247 \begin_layout Standard
6248 Newfangle chunks may have parameters contained within square brackets.
6249 These will be matched in
6250 \begin_inset Flex CharStyle:Code
6253 \begin_layout Plain Layout
6259 and are considered at this stage of processing to be part of the name of
6260 the chunk to be included.
6263 \begin_layout Standard
6264 \begin_inset listings
6268 \begin_layout Plain Layout
6270 if (substr(line[1], 1, 1) == "=") {
6273 \begin_layout Plain Layout
6275 # chunk name up to }
6278 \begin_layout Plain Layout
6280 chunk_include(active_chunk, line[2] line[3], indent);
6283 \begin_layout Plain Layout
6285 } else if (substr(line[1], 1, 1) == "<") {
6288 \begin_layout Plain Layout
6290 chunk_include(active_chunk, line[4], indent);
6293 \begin_layout Plain Layout
6298 \begin_layout Plain Layout
6300 error("Unknown chunk fragment: " line[1]);
6303 \begin_layout Plain Layout
6313 \begin_layout Standard
6314 The loop will continue until there are no more chunkref statements in the
6315 text, at which point we process the final part of the chunk.
6318 \begin_layout Standard
6319 \begin_inset listings
6323 \begin_layout Plain Layout
6328 \begin_layout Plain Layout
6330 chunk_line(active_chunk, chunk);
6338 \begin_layout Standard
6339 \begin_inset CommandInset label
6345 We add the newline character as a chunklet on it's own, to make it easier
6346 to detect new lines and thus manage indentation when processing the output.
6349 \begin_layout Standard
6350 \begin_inset listings
6354 \begin_layout Plain Layout
6356 chunk_line(active_chunk, "
6366 \begin_layout Standard
6367 We will also permit a chunk-part number to follow in square brackets, so
6369 \begin_inset Flex CharStyle:Code
6372 \begin_layout Plain Layout
6375 chunkref{chunk-name[1]}>
6380 will refer to the first part only.
6381 This can make it easy to include a C function prototype in a header file,
6382 if the first part of the chunk is just the function prototype without the
6383 trailing semi-colon.
6384 The header file would include the prototype with the trailing semi-colon,
6388 \begin_layout LyX-Code
6391 chunkref{chunk-name[1]}>;
6394 \begin_layout Standard
6395 This is handled in section
6396 \begin_inset CommandInset ref
6398 reference "sub:Chunk-parts"
6405 \begin_layout Standard
6406 We should perhaps introduce a notion of language specific chunk options;
6407 so that perhaps we could specify:
6410 \begin_layout LyX-Code
6413 chunkref{chunk-name[function-declaration]}>;
6416 \begin_layout Standard
6417 which applies a transform
6418 \begin_inset Flex CharStyle:Code
6421 \begin_layout Plain Layout
6422 function-declaration
6427 to the chunk --- which in this case would extract a function prototype
6429 \begin_inset Note Note
6432 \begin_layout Plain Layout
6441 \begin_layout Chapter
6445 \begin_layout Standard
6446 At the start, first we set the default options.
6453 \begin_layout Standard
6454 \begin_inset listings
6458 \begin_layout Plain Layout
6463 \begin_layout Plain Layout
6468 \begin_layout Plain Layout
6473 \begin_layout Plain Layout
6478 \begin_layout Plain Layout
6488 \begin_layout Standard
6489 Then we use getopt the standard way, and null out ARGV afterwards in the
6497 \begin_layout Standard
6498 \begin_inset listings
6502 \begin_layout Plain Layout
6504 Optind = 1 # skip ARGV[0]
6507 \begin_layout Plain Layout
6509 while(getopt(ARGC, ARGV, "R:Ldhr")!=-1) {
6512 \begin_layout Plain Layout
6516 chunkref{handle-options}>
6519 \begin_layout Plain Layout
6524 \begin_layout Plain Layout
6526 for (i=1; i<Optind; i++) { ARGV[i]=""; }
6534 \begin_layout Standard
6535 This is how we handle our options:
6542 \begin_layout Standard
6543 \begin_inset listings
6547 \begin_layout Plain Layout
6549 if (Optopt == "R") root = Optarg;
6552 \begin_layout Plain Layout
6554 else if (Optopt == "r") root="";
6557 \begin_layout Plain Layout
6559 else if (Optopt == "L") linenos = 1;
6562 \begin_layout Plain Layout
6564 else if (Optopt == "d") debug = 1;
6567 \begin_layout Plain Layout
6569 else if (Optopt == "h") help();
6572 \begin_layout Plain Layout
6574 else if (Optopt == "?") help();
6582 \begin_layout Standard
6583 We do all of this at the beginning of the program
6590 \begin_layout Standard
6591 \begin_inset listings
6595 \begin_layout Plain Layout
6600 \begin_layout Plain Layout
6604 chunkref{constants}>
6607 \begin_layout Plain Layout
6611 chunkref{default-options}>
6614 \begin_layout Plain Layout
6618 \begin_layout Plain Layout
6622 chunkref{read-options}>
6625 \begin_layout Plain Layout
6635 \begin_layout Standard
6636 And have a simple help function
6643 \begin_layout Standard
6644 \begin_inset listings
6648 \begin_layout Plain Layout
6653 \begin_layout Plain Layout
6658 \begin_layout Plain Layout
6660 print " newfangle [-L] -R<rootname> [source.tex ...]"
6663 \begin_layout Plain Layout
6665 print " newfangle -r [source.tex ...]"
6668 \begin_layout Plain Layout
6670 print " If the filename, source.tex is not specified then stdin is used"
6673 \begin_layout Plain Layout
6678 \begin_layout Plain Layout
6680 print "-L causes the C statement: #line <lineno>
6687 \begin_layout Plain Layout
6689 print "-R causes the named root to be written to stdout"
6692 \begin_layout Plain Layout
6694 print "-r lists all roots in the file (even those used elsewhere)"
6697 \begin_layout Plain Layout
6702 \begin_layout Plain Layout
6712 \begin_layout Chapter
6713 Chunk Language Modes
6716 \begin_layout Standard
6717 \begin_inset CommandInset label
6724 \begin_inset Note Greyedout
6727 \begin_layout Plain Layout
6728 This feature is in-development and does not work yet
6734 \begin_inset Note Note
6737 \begin_layout Plain Layout
6746 \begin_layout Standard
6747 lstlistings and newfangle both recognize source languages, and perform some
6749 lstlistings can detect strings and comments within a language definition
6750 and perform suitable rendering, such as italics for comments, and visible-space
6754 \begin_layout Standard
6755 Newfangle similarly can recognize strings, and comments, etc, within a language,
6756 so that any chunks included with
6757 \begin_inset Flex CharStyle:Code
6760 \begin_layout Plain Layout
6768 can be suitably quoted.
6771 \begin_layout Standard
6772 For instance, consider this chunk with
6773 \begin_inset Flex CharStyle:Code
6776 \begin_layout Plain Layout
6786 example-perl,language=perl
6789 \begin_layout Standard
6790 \begin_inset listings
6794 \begin_layout Plain Layout
6804 \begin_layout Standard
6805 If it were included in a chunk with
6806 \begin_inset Flex CharStyle:Code
6809 \begin_layout Plain Layout
6819 example-sh,language=sh
6822 \begin_layout Standard
6823 \begin_inset listings
6827 \begin_layout Plain Layout
6831 chunkref{example-perl}>"
6839 \begin_layout Standard
6840 would need to generate output like this if it were to work:
6843 \begin_layout LyX-Code
6851 \begin_layout Standard
6852 See that the double quote " as part of the regex has been quoted with a
6853 slash to protect it from shell interpretation.
6856 \begin_layout Standard
6857 If that were then included in a chunk with
6858 \begin_inset Flex CharStyle:Code
6861 \begin_layout Plain Layout
6871 example-makefile,language=make
6874 \begin_layout Standard
6875 \begin_inset listings
6879 \begin_layout Plain Layout
6884 \begin_layout Plain Layout
6888 chunkref{example-sh}>
6896 \begin_layout Standard
6897 We would need the output to look like this --- note the $$:
6900 \begin_layout LyX-Code
6904 \begin_layout LyX-Code
6912 \begin_layout Standard
6913 In order to make this work, we need to define a mode-tracker for each supported
6914 language, that can detect the various quoting modes, and provide a transformati
6915 on that must be applied to any included text so that included text will
6916 be interpreted correctly after the additional interpolation that it will
6917 be subject to at run-time.
6920 \begin_layout Standard
6921 For example, the transformation for text to be inserted into sh double-quoted
6922 strings would be something like:
6925 \begin_layout LyX-Code
6949 \begin_layout Standard
6951 \begin_inset Flex CharStyle:Code
6954 \begin_layout Plain Layout
6965 \begin_layout Standard
6966 \begin_inset Note Note
6969 \begin_layout Plain Layout
6970 I don't think this example is true
6975 The mode tracker must also track nested mode-changes, as in this
6976 \begin_inset Flex CharStyle:Code
6979 \begin_layout Plain Layout
6988 \begin_layout LyX-Code
6989 echo "hello `id **`"
6992 \begin_layout Standard
6993 Any literal text inserted at the point marked ** would need to be escaped
6994 in all kinds of ways, including
6995 \begin_inset Flex CharStyle:Code
6998 \begin_layout Plain Layout
7005 First it would need escaping for the back-ticks `, and then for the double-quot
7009 \begin_layout Standard
7010 Escaping need not occur if the format and mode of the included chunk matches
7011 that of the including chunk, which would suggest that any back-ticks might
7012 need to be part of the included chunk and not including chunk
7013 \begin_inset Note Note
7016 \begin_layout Plain Layout
7017 or is it the other way around?
7025 \begin_layout Standard
7026 As each chunk is output a new mode tracker for that language is initialized
7027 in it's normal state.
7028 As text is output for that chunk the output mode is tracked.
7029 When a new chunk is included, a transformation appropriate to that mode
7030 is selected and pushed onto a stack of transformations.
7031 Any text to be output is first passed through this stack of transformations.
7034 \begin_layout Standard
7035 It remains to consider if the chunk-include function should return it's
7036 generated text so that the caller can apply any transformations (and formatting
7037 ), or if it should apply the stack of transformations itself.
7040 \begin_layout Standard
7041 Note that the transformed text should have the property of not being able
7042 to change the mode in the current chunk.
7045 \begin_layout Standard
7046 \begin_inset Note Note
7049 \begin_layout Plain Layout
7050 Note chunk parameters should probably also be transformed
7062 \begin_layout Standard
7063 \begin_inset listings
7067 \begin_layout Plain Layout
7069 function new_mode(language, mode) {
7072 \begin_layout Plain Layout
7074 mode["language"] = language;
7077 \begin_layout Plain Layout
7082 \begin_layout Plain Layout
7092 \begin_layout Standard
7093 Because awk functions cannot return an array, we must create the array first
7098 new-mode,params=language;mode
7101 \begin_layout Standard
7102 \begin_inset listings
7106 \begin_layout Plain Layout
7110 chunkref{awk-delete-array}(${mode})>
7113 \begin_layout Plain Layout
7115 new_mode(${language}, ${mode});
7123 \begin_layout Standard
7124 And for tracking modes, we dispatch to a mode-tracker action based on the
7132 \begin_layout Standard
7133 \begin_inset listings
7137 \begin_layout Plain Layout
7139 function track_mode(mode, text) {
7142 \begin_layout Plain Layout
7144 if (mode["language"] == "C") {
7147 \begin_layout Plain Layout
7151 chunkref{track-mode-C}>
7154 \begin_layout Plain Layout
7159 \begin_layout Plain Layout
7164 \begin_layout Plain Layout
7174 \begin_layout Standard
7175 For each mode, we look for a character that has the power to change the
7179 \begin_layout Standard
7184 \labelwidthstring 00.00.0000
7185 \begin_inset Quotes eld
7188 enters double-quote mode
7192 \labelwidthstring 00.00.0000
7193 ' enters single-quote mode
7197 \labelwidthstring 00.00.0000
7200 enters multi-line mode
7204 \labelwidthstring 00.00.0000
7205 # enters #define sub-mode, needs
7207 escaping end of line too
7211 \labelwidthstring 00.00.0000
7212 /* enters comment mode
7215 \begin_layout Standard
7216 In double-quote mode, escape
7219 \begin_inset Quotes eld
7225 \begin_layout Standard
7229 \begin_inset Quotes eld
7235 \begin_layout Standard
7236 \begin_inset Quotes eld
7242 \begin_layout Standard
7243 newline needs to close and re-open string or something
7246 \begin_layout Standard
7247 in single-quote mode escape
7250 \begin_inset Quotes eld
7260 \begin_layout Standard
7261 \begin_inset listings
7265 \begin_layout Plain Layout
7278 \begin_layout Standard
7279 \begin_inset listings
7283 \begin_layout Plain Layout
7287 chunkref{new_mode()}>
7295 \begin_layout Chapter
7296 Generating the output
7299 \begin_layout Standard
7300 We generate output by calling output_chunk, or listing the chunk names.
7307 \begin_layout Standard
7308 \begin_inset listings
7312 \begin_layout Plain Layout
7314 if (length(root)) output_chunk(root);
7317 \begin_layout Plain Layout
7319 else output_chunk_names();
7327 \begin_layout Standard
7328 We also have some other output debugging:
7335 \begin_layout Standard
7336 \begin_inset listings
7340 \begin_layout Plain Layout
7345 \begin_layout Plain Layout
7347 print "------ chunk names "
7350 \begin_layout Plain Layout
7352 output_chunk_names();
7355 \begin_layout Plain Layout
7357 print "====== chunks"
7360 \begin_layout Plain Layout
7365 \begin_layout Plain Layout
7367 print "++++++ debug"
7370 \begin_layout Plain Layout
7375 \begin_layout Plain Layout
7377 print a "=" chunks[a];
7380 \begin_layout Plain Layout
7385 \begin_layout Plain Layout
7395 \begin_layout Standard
7396 We do both of these at the end.
7398 \begin_inset Flex CharStyle:Code
7401 \begin_layout Plain Layout
7407 because each chunklet is not necessarily a complete line, and we already
7409 \begin_inset Flex CharStyle:Code
7412 \begin_layout Plain Layout
7418 to each input line in section
7419 \begin_inset CommandInset ref
7421 reference "sub:ORS-chunk-text"
7432 \begin_layout Standard
7433 \begin_inset listings
7437 \begin_layout Plain Layout
7442 \begin_layout Plain Layout
7446 chunkref{debug-output}>
7449 \begin_layout Plain Layout
7454 \begin_layout Plain Layout
7458 chunkref{generate-output}>
7461 \begin_layout Plain Layout
7471 \begin_layout Standard
7472 We write chunk names like this.
7473 If we seem to be running in notangle compatibility mode, then we enclose
7475 \begin_inset Flex CharStyle:Code
7478 \begin_layout Plain Layout
7484 the same way notangle does:
7488 output_chunk_names()
7491 \begin_layout Standard
7492 \begin_inset listings
7496 \begin_layout Plain Layout
7498 function output_chunk_names( c, prefix, suffix)
7501 \begin_layout Plain Layout
7506 \begin_layout Plain Layout
7508 if (notangle_mode) {
7511 \begin_layout Plain Layout
7516 \begin_layout Plain Layout
7521 \begin_layout Plain Layout
7526 \begin_layout Plain Layout
7528 for (c in chunk_names) {
7531 \begin_layout Plain Layout
7533 print prefix c suffix "
7538 \begin_layout Plain Layout
7543 \begin_layout Plain Layout
7553 \begin_layout Standard
7554 This function would write out all chunks
7561 \begin_layout Standard
7562 \begin_inset listings
7566 \begin_layout Plain Layout
7568 function output_chunks( a)
7571 \begin_layout Plain Layout
7576 \begin_layout Plain Layout
7578 for (a in chunk_names) {
7581 \begin_layout Plain Layout
7583 output_chunk(chunk_names[a]);
7586 \begin_layout Plain Layout
7591 \begin_layout Plain Layout
7596 \begin_layout Plain Layout
7600 \begin_layout Plain Layout
7602 function output_chunk(chunk) {
7605 \begin_layout Plain Layout
7610 \begin_layout Plain Layout
7612 lineno_needed = linenos;
7615 \begin_layout Plain Layout
7619 \begin_layout Plain Layout
7624 \begin_layout Plain Layout
7629 \begin_layout Plain Layout
7638 \begin_layout Section
7639 Assembling the chunks
7642 \begin_layout Standard
7643 \begin_inset Flex CharStyle:Code
7646 \begin_layout Plain Layout
7652 holds a string consisting of the names of all the chunks that resulted
7653 in this chunk being output.
7655 \begin_inset Note Note
7658 \begin_layout Plain Layout
7659 Make sure it includes the line numbers too...
7665 It should probably also contain the source line numbers at which each inclusion
7670 write_chunk(),emph={chunk_path}
7673 \begin_layout Standard
7674 \begin_inset listings
7678 \begin_layout Plain Layout
7680 function write_chunk(chunk_name, indent, tail,
7683 \begin_layout Plain Layout
7688 \begin_layout Plain Layout
7690 chunk_path, chunk_args,
7693 \begin_layout Plain Layout
7698 \begin_layout Plain Layout
7700 part, max_part, part_line, frag, max_frag, text,
7703 \begin_layout Plain Layout
7705 chunklet, only_part, call_chunk_args, mode)
7708 \begin_layout Plain Layout
7718 \begin_layout Subsection
7719 \begin_inset CommandInset label
7721 name "sub:Chunk-parts"
7728 \begin_layout Standard
7729 As mentioned in section
7730 \begin_inset CommandInset ref
7732 reference "sub:lstlistings-includes"
7736 , a chunk name may contain a part specifier in square brackets, limiting
7737 the parts that should be emitted.
7740 \begin_layout Standard
7741 \begin_inset listings
7745 \begin_layout Plain Layout
7747 if (match(chunk_name, "^(.*)
7755 ]$", chunk_name_parts)) {
7758 \begin_layout Plain Layout
7760 chunk_name = chunk_name_parts[1];
7763 \begin_layout Plain Layout
7765 only_part = chunk_name_parts[2];
7768 \begin_layout Plain Layout
7778 \begin_layout Standard
7779 We first create the mode tracker for this chunk.
7782 \begin_layout Standard
7785 chunkref{awk-delete-array}(mode)>
7788 \begin_layout Standard
7789 \begin_inset listings
7793 \begin_layout Plain Layout
7798 \begin_layout Plain Layout
7800 new_mode(chunks[chunk_name, "language"], mode);
7808 \begin_layout Standard
7811 chunkref{new-mode}(chunks[chunk_name, "language"], mode)>
7814 \begin_layout Standard
7816 \begin_inset Flex CharStyle:Code
7819 \begin_layout Plain Layout
7825 the names of the parameters that this chunk accepts, whose values were
7826 (optionally) passed in
7827 \begin_inset Flex CharStyle:Code
7830 \begin_layout Plain Layout
7839 \begin_layout Standard
7840 \begin_inset listings
7844 \begin_layout Plain Layout
7846 split(chunks[chunk_name, "params"], chunk_params, " *; *");
7854 \begin_layout Standard
7855 To assemble a chunk, we write out each part.
7862 \begin_layout Standard
7863 \begin_inset listings
7867 \begin_layout Plain Layout
7869 if (! (chunk_name in chunk_names)) {
7872 \begin_layout Plain Layout
7874 error(sprintf(_"The root module <<%s>> was not defined.
7881 \begin_layout Plain Layout
7883 chunk_name, chunk_path));
7886 \begin_layout Plain Layout
7891 \begin_layout Plain Layout
7895 \begin_layout Plain Layout
7897 max_part = chunks[chunk_name, "part"];
7900 \begin_layout Plain Layout
7902 for(part = 1; part <= max_part; part++) {
7905 \begin_layout Plain Layout
7907 if (! only_part || part == only_part) {
7910 \begin_layout Plain Layout
7914 chunkref{write-part}>
7917 \begin_layout Plain Layout
7922 \begin_layout Plain Layout
7927 \begin_layout Plain Layout
7937 \begin_layout Standard
7938 A part can either be a chunklet of lines, or an include of another chunk.
7941 \begin_layout Standard
7942 Chunks may also have parameters, specified in LaTeX style with braces after
7943 the chunk name --- looking like this in the document:
7944 \begin_inset Flex CharStyle:Code
7947 \begin_layout Plain Layout
7948 chunkname{param1, param2}
7954 Arguments are passed in square brackets:
7955 \begin_inset Flex CharStyle:Code
7958 \begin_layout Plain Layout
7961 chunkref{chunkname}[arg1, arg2]
7969 \begin_layout Standard
7970 Before we process each part, we check that the source position hasn't changed
7971 unexpectedly, so that we can know if we need to output a new file-line
7979 \begin_layout Standard
7980 \begin_inset listings
7984 \begin_layout Plain Layout
7988 chunkref{check-source-jump}>
7991 \begin_layout Plain Layout
7995 \begin_layout Plain Layout
7997 chunklet = chunks[chunk_name, "part", part];
8000 \begin_layout Plain Layout
8002 if (chunks[chunk_name, "part", part, "type"] == part_type_chunk) {
8005 \begin_layout Plain Layout
8009 chunkref{write-included-chunk}>
8012 \begin_layout Plain Layout
8014 } else if (chunklet SUBSEP "line" in chunks) {
8017 \begin_layout Plain Layout
8021 chunkref{write-chunklets}>
8024 \begin_layout Plain Layout
8029 \begin_layout Plain Layout
8031 # empty last chunklet
8034 \begin_layout Plain Layout
8044 \begin_layout Standard
8045 To write an included chunk, we must detect any optional chunk arguments
8047 Then we recurse calling
8048 \begin_inset Flex Chunkref
8051 \begin_layout Plain Layout
8061 write-included-chunk
8064 \begin_layout Standard
8065 \begin_inset listings
8069 \begin_layout Plain Layout
8071 if (match(chunklet, "^([^
8083 )$", chunklet_parts)) {
8086 \begin_layout Plain Layout
8088 chunklet = chunklet_parts[1];
8091 \begin_layout Plain Layout
8093 get_chunk_args(chunklet_parts[2], chunk_args);
8096 \begin_layout Plain Layout
8098 # TO BE parse_chunk_args SOON
8101 \begin_layout Plain Layout
8103 for (c in call_chunk_args) {
8106 \begin_layout Plain Layout
8108 call_chunk_args[c] = expand_chunk_args(call_chunk_args[c], chunk_params,
8112 \begin_layout Plain Layout
8117 \begin_layout Plain Layout
8122 \begin_layout Plain Layout
8124 split("", call_chunk_args);
8127 \begin_layout Plain Layout
8132 \begin_layout Plain Layout
8134 write_chunk(chunklet,
8137 \begin_layout Plain Layout
8139 chunks[chunk_name, "part", part, "indent"] indent,
8142 \begin_layout Plain Layout
8144 chunks[chunk_name, "part", part, "tail"],
8147 \begin_layout Plain Layout
8154 \begin_layout Plain Layout
8164 \begin_layout Standard
8165 Before we output a chunklet of lines, we first emit the file and line number
8166 if we have one, and if it is safe to do so.
8170 \begin_layout Standard
8171 Chunklets are generally broken up by includes, so the start of a chunklet
8172 is a good place to do this.
8173 Then we output each line of the chunklet.
8176 \begin_layout Standard
8177 When it is not safe, such as in the middle of a multi-line macro definition,
8179 \begin_inset Flex CharStyle:Code
8182 \begin_layout Plain Layout
8188 is set to true, and in such a case we note that we want to emit the line
8189 statement when it is next safe.
8196 \begin_layout Standard
8197 \begin_inset listings
8201 \begin_layout Plain Layout
8203 max_frag = chunks[chunklet, "line"];
8206 \begin_layout Plain Layout
8208 for(frag = 1; frag <= max_frag; frag++) {
8211 \begin_layout Plain Layout
8215 chunkref{write-file-line}>
8223 \begin_layout Standard
8224 We then extract the chunklet text and expand any arguments.
8227 \begin_layout Standard
8228 \begin_inset listings
8232 \begin_layout Plain Layout
8236 \begin_layout Plain Layout
8238 text = chunks[chunklet, frag];
8241 \begin_layout Plain Layout
8246 \begin_layout Plain Layout
8251 \begin_layout Plain Layout
8253 text = expand_chunk_args(text, chunk_params, chunk_args);
8261 \begin_layout Standard
8262 If the text is a single newline (which we keep separate - see
8263 \begin_inset CommandInset ref
8265 reference "lone-newline"
8269 ) then we increment the line number.
8270 In the case where this is the last line of a chunk and it is not a top-level
8271 chunk we replace the newline with an empty string --- because the chunk
8272 that included this chunk will have the newline at the end of the line that
8273 included this chunk.
8276 \begin_layout Standard
8278 \begin_inset Flex CharStyle:Code
8281 \begin_layout Plain Layout
8287 that we have started a new line, so that indentation can be managed with
8288 the following piece of text.
8291 \begin_layout Standard
8292 \begin_inset listings
8296 \begin_layout Plain Layout
8300 \begin_layout Plain Layout
8307 \begin_layout Plain Layout
8312 \begin_layout Plain Layout
8314 if (part == max_part && frag == max_frag && length(chunk_path)) {
8317 \begin_layout Plain Layout
8322 \begin_layout Plain Layout
8327 \begin_layout Plain Layout
8332 \begin_layout Plain Layout
8337 \begin_layout Plain Layout
8347 \begin_layout Standard
8348 If this text does not represent a newline, but we see that we are the first
8349 piece of text on a newline, then we prefix our text with the current indent.
8351 \begin_inset Flex CharStyle:Code
8354 \begin_layout Plain Layout
8360 is a global output-state variable, but the
8361 \begin_inset Flex CharStyle:Code
8364 \begin_layout Plain Layout
8374 \begin_layout Standard
8375 \begin_inset listings
8379 \begin_layout Plain Layout
8384 \begin_layout Plain Layout
8386 if (newline) text = indent text;
8389 \begin_layout Plain Layout
8394 \begin_layout Plain Layout
8399 \begin_layout Plain Layout
8408 \begin_layout Standard
8409 Tail will soon no longer be relevant once mode-detection is in place.
8412 \begin_layout Standard
8413 \begin_inset listings
8417 \begin_layout Plain Layout
8422 \begin_layout Plain Layout
8424 # track_mode(mode, text);
8427 \begin_layout Plain Layout
8437 \begin_layout Standard
8438 If a line ends in a backslash --- suggesting continuation --- then we supress
8439 outputting file-line as it would probably break the continued lines.
8443 \begin_layout Standard
8444 \begin_inset listings
8448 \begin_layout Plain Layout
8453 \begin_layout Plain Layout
8455 lineno_suppressed = substr(lastline, length(lastline)) == "
8462 \begin_layout Plain Layout
8467 \begin_layout Plain Layout
8477 \begin_layout Standard
8478 Of course there is no point in actually outputting the source filename and
8479 line number (file-line) if they don't say anything new! We only need to
8480 emit them if they aren't what is expected, or if we we not able to emit
8481 one when they had changed.
8488 \begin_layout Standard
8489 \begin_inset listings
8493 \begin_layout Plain Layout
8495 if (newline && lineno_needed && ! lineno_suppressed) {
8498 \begin_layout Plain Layout
8500 filename = a_filename;
8503 \begin_layout Plain Layout
8508 \begin_layout Plain Layout
8510 print "#line " lineno "
8519 \begin_layout Plain Layout
8524 \begin_layout Plain Layout
8534 \begin_layout Standard
8535 We check if a new file-line is needed by checking if the source line matches
8536 what we (or a compiler) would expect.
8544 \begin_layout Standard
8545 \begin_inset listings
8549 \begin_layout Plain Layout
8551 if (linenos && (chunk_name SUBSEP "part" SUBSEP part SUBSEP "FILENAME" in
8555 \begin_layout Plain Layout
8557 a_filename = chunks[chunk_name, "part", part, "FILENAME"];
8560 \begin_layout Plain Layout
8562 a_lineno = chunks[chunk_name, "part", part, "LINENO"];
8565 \begin_layout Plain Layout
8567 if (a_filename != filename || a_lineno != lineno) {
8570 \begin_layout Plain Layout
8575 \begin_layout Plain Layout
8580 \begin_layout Plain Layout
8590 \begin_layout Chapter
8594 \begin_layout Standard
8595 Awk has pretty limited data structures, so we will use two main hashes.
8596 Uninterrupted sequences of a chunk will be stored in
8597 \begin_inset Flex CharStyle:Code
8600 \begin_layout Plain Layout
8606 and the chunklets used in a chunk will be stored in
8607 \begin_inset Flex CharStyle:Code
8610 \begin_layout Plain Layout
8623 \begin_layout Standard
8624 \begin_inset listings
8628 \begin_layout Plain Layout
8638 \begin_layout Standard
8640 \begin_inset Flex CharStyle:Code
8643 \begin_layout Plain Layout
8649 mentioned are not chunk parameters for parameterized chunks, as mentioned
8651 \begin_inset CommandInset ref
8653 reference "cha:Chunk Arguments"
8657 , but the lstlistings style parameters used in the
8658 \begin_inset Flex CharStyle:Code
8661 \begin_layout Plain Layout
8673 \begin_layout Plain Layout
8675 \begin_inset Flex CharStyle:Code
8678 \begin_layout Plain Layout
8684 parameter is used to hold the parameters for parameterized chunks
8693 chunk-storage-functions
8696 \begin_layout Standard
8697 \begin_inset listings
8701 \begin_layout Plain Layout
8703 function new_chunk(chunk_name, params,
8706 \begin_layout Plain Layout
8711 \begin_layout Plain Layout
8716 \begin_layout Plain Layout
8721 \begin_layout Plain Layout
8723 # HACK WHILE WE CHANGE TO ( ) for PARAM CHUNKS
8726 \begin_layout Plain Layout
8736 )$", "", chunk_name);
8739 \begin_layout Plain Layout
8741 active_chunk = chunk_name;
8744 \begin_layout Plain Layout
8746 if (! (chunk_name in chunk_names)) {
8749 \begin_layout Plain Layout
8751 if (debug) print "New chunk " chunk_name;
8754 \begin_layout Plain Layout
8756 chunk_names[chunk_name];
8759 \begin_layout Plain Layout
8764 \begin_layout Plain Layout
8766 chunks[chunk_name, p] = params[p];
8769 \begin_layout Plain Layout
8774 \begin_layout Plain Layout
8779 \begin_layout Plain Layout
8781 prime_chunk(chunk_name);
8784 \begin_layout Plain Layout
8794 \begin_layout Standard
8795 \begin_inset listings
8799 \begin_layout Plain Layout
8803 \begin_layout Plain Layout
8805 function prime_chunk(chunk_name)
8808 \begin_layout Plain Layout
8813 \begin_layout Plain Layout
8815 chunks[chunk_name, "part", ++chunks[chunk_name, "part"] ] =
8820 \begin_layout Plain Layout
8822 chunk_name SUBSEP "chunklet" SUBSEP "" ++chunks[chunk_name, "chunklet"]
8826 \begin_layout Plain Layout
8828 chunks[chunk_name, "part", chunks[chunk_name, "part"], "FILENAME"] = FILENAME;
8831 \begin_layout Plain Layout
8833 chunks[chunk_name, "part", chunks[chunk_name, "part"], "LINENO"] = FNR
8837 \begin_layout Plain Layout
8842 \begin_layout Plain Layout
8846 \begin_layout Plain Layout
8848 function chunk_line(chunk_name, line){
8851 \begin_layout Plain Layout
8853 chunks[chunk_name, "chunklet", chunks[chunk_name, "chunklet"],
8856 \begin_layout Plain Layout
8858 ++chunks[chunk_name, "chunklet", chunks[chunk_name, "chunklet"],
8862 \begin_layout Plain Layout
8867 \begin_layout Plain Layout
8876 \begin_layout Standard
8877 Chunk include represents a
8881 statement, and stores the requirement to include another chunk.
8882 The parameter indent represents the quanity of literal text characters
8887 statement and therefore by how much additional lines of the included chunk
8891 \begin_layout Standard
8892 \begin_inset listings
8896 \begin_layout Plain Layout
8898 function chunk_include(chunk_name, chunk_ref, indent, tail)
8901 \begin_layout Plain Layout
8906 \begin_layout Plain Layout
8908 chunks[chunk_name, "part", ++chunks[chunk_name, "part"] ] = chunk_ref;
8911 \begin_layout Plain Layout
8913 chunks[chunk_name, "part", chunks[chunk_name, "part"], "type" ] = part_type_ch
8917 \begin_layout Plain Layout
8919 chunks[chunk_name, "part", chunks[chunk_name, "part"], "indent" ] = indent_str
8923 \begin_layout Plain Layout
8925 chunks[chunk_name, "part", chunks[chunk_name, "part"], "tail" ] = tail;
8928 \begin_layout Plain Layout
8930 prime_chunk(chunk_name);
8933 \begin_layout Plain Layout
8938 \begin_layout Plain Layout
8947 \begin_layout Standard
8948 The indent is calculated by indent_string, which may in future convert some
8949 spaces into tab characters.
8950 This function works by generating a printf padded format string, like
8951 \begin_inset Flex CharStyle:Code
8954 \begin_layout Plain Layout
8960 for an indent of 22, and then printing an empty string using that format.
8963 \begin_layout Standard
8964 \begin_inset listings
8968 \begin_layout Plain Layout
8970 function indent_string(indent) {
8973 \begin_layout Plain Layout
8975 return sprintf("%" indent "s", "");
8978 \begin_layout Plain Layout
8988 \begin_layout Chapter
8989 \begin_inset CommandInset label
8998 \begin_layout Standard
8999 I use Arnold Robbins public domain getopt (1993 revision).
9000 This is probably the same one that is covered in chapter 12 of
9001 \begin_inset Quotes eld
9004 Edition 3 of GAWK: Effective AWK Programming: A User's Guide for GNU Awk
9005 \begin_inset Quotes erd
9008 but as that is licensed under the GNU Free Documentation License, Version
9009 1.3, which conflicts with the GPL3, I can't use it from there (or it's accompany
9010 ing explanations), so I do my best to explain how it works here.
9013 \begin_layout Standard
9014 The getopt.awk header is:
9018 getopt.awk-header,language=awk,morestring=[b]{/},morekeywords=else
9021 \begin_layout Standard
9022 \begin_inset listings
9026 \begin_layout Plain Layout
9028 # getopt.awk --- do C library getopt(3) function in awk
9031 \begin_layout Plain Layout
9036 \begin_layout Plain Layout
9038 # Arnold Robbins, arnold@skeeve.com, Public Domain
9041 \begin_layout Plain Layout
9046 \begin_layout Plain Layout
9048 # Initial version: March, 1991
9051 \begin_layout Plain Layout
9053 # Revised: May, 1993
9061 \begin_layout Standard
9062 The provided explanation is:
9069 \begin_layout Standard
9070 \begin_inset listings
9074 \begin_layout Plain Layout
9076 # External variables:
9079 \begin_layout Plain Layout
9081 # Optind -- index in ARGV of first nonoption argument
9084 \begin_layout Plain Layout
9086 # Optarg -- string value of argument to current option
9089 \begin_layout Plain Layout
9091 # Opterr -- if nonzero, print our own diagnostic
9094 \begin_layout Plain Layout
9096 # Optopt -- current option letter
9099 \begin_layout Plain Layout
9103 \begin_layout Plain Layout
9108 \begin_layout Plain Layout
9110 # -1 at end of options
9113 \begin_layout Plain Layout
9115 # ? for unrecognized option
9118 \begin_layout Plain Layout
9120 # <c> a character representing the current option
9123 \begin_layout Plain Layout
9127 \begin_layout Plain Layout
9132 \begin_layout Plain Layout
9134 # _opti -- index in multi-flag option, e.g., -abc
9142 \begin_layout Standard
9143 The function follows.
9144 The final two parameters,
9145 \begin_inset Flex CharStyle:Code
9148 \begin_layout Plain Layout
9155 \begin_inset Flex CharStyle:Code
9158 \begin_layout Plain Layout
9164 are local variables and not parameters --- as indicated by the multiple
9165 spaces preceding them.
9166 Awk doesn't care, the multiple spaces are a convention to help us humans.
9173 \begin_layout Standard
9174 \begin_inset listings
9178 \begin_layout Plain Layout
9180 function getopt(argc, argv, options, thisopt, i)
9183 \begin_layout Plain Layout
9188 \begin_layout Plain Layout
9190 if (length(options) == 0) # no options given
9193 \begin_layout Plain Layout
9198 \begin_layout Plain Layout
9200 if (argv[Optind] == "--") { # all done
9203 \begin_layout Plain Layout
9208 \begin_layout Plain Layout
9213 \begin_layout Plain Layout
9218 \begin_layout Plain Layout
9220 } else if (argv[Optind] !~ /^-[^:
9235 \begin_layout Plain Layout
9240 \begin_layout Plain Layout
9245 \begin_layout Plain Layout
9250 \begin_layout Plain Layout
9255 \begin_layout Plain Layout
9260 \begin_layout Plain Layout
9262 thisopt = substr(argv[Optind], _opti, 1)
9265 \begin_layout Plain Layout
9270 \begin_layout Plain Layout
9272 i = index(options, thisopt)
9275 \begin_layout Plain Layout
9280 \begin_layout Plain Layout
9285 \begin_layout Plain Layout
9287 printf("%c -- invalid option
9292 \begin_layout Plain Layout
9294 thisopt) > "/dev/stderr"
9297 \begin_layout Plain Layout
9299 if (_opti >= length(argv[Optind])) {
9302 \begin_layout Plain Layout
9307 \begin_layout Plain Layout
9312 \begin_layout Plain Layout
9317 \begin_layout Plain Layout
9322 \begin_layout Plain Layout
9327 \begin_layout Plain Layout
9337 \begin_layout Standard
9338 At this point, the option has been found and we need to know if it takes
9342 \begin_layout Standard
9343 \begin_inset listings
9347 \begin_layout Plain Layout
9349 if (substr(options, i + 1, 1) == ":") {
9352 \begin_layout Plain Layout
9354 # get option argument
9357 \begin_layout Plain Layout
9359 if (length(substr(argv[Optind], _opti + 1)) > 0)
9362 \begin_layout Plain Layout
9364 Optarg = substr(argv[Optind], _opti + 1)
9367 \begin_layout Plain Layout
9372 \begin_layout Plain Layout
9374 Optarg = argv[++Optind]
9377 \begin_layout Plain Layout
9382 \begin_layout Plain Layout
9387 \begin_layout Plain Layout
9392 \begin_layout Plain Layout
9394 if (_opti == 0 || _opti >= length(argv[Optind])) {
9397 \begin_layout Plain Layout
9402 \begin_layout Plain Layout
9407 \begin_layout Plain Layout
9412 \begin_layout Plain Layout
9417 \begin_layout Plain Layout
9422 \begin_layout Plain Layout
9429 A test program is built in, too
9436 \begin_layout Standard
9437 \begin_inset listings
9441 \begin_layout Plain Layout
9446 \begin_layout Plain Layout
9448 Opterr = 1 # default is to diagnose
9451 \begin_layout Plain Layout
9453 Optind = 1 # skip ARGV[0]
9456 \begin_layout Plain Layout
9461 \begin_layout Plain Layout
9466 \begin_layout Plain Layout
9468 while ((_go_c = getopt(ARGC, ARGV, "ab:cd")) != -1)
9471 \begin_layout Plain Layout
9473 printf("c = <%c>, optarg = <%s>
9478 \begin_layout Plain Layout
9483 \begin_layout Plain Layout
9485 printf("non-option arguments:
9490 \begin_layout Plain Layout
9492 for (; Optind < ARGC; Optind++)
9495 \begin_layout Plain Layout
9504 \begin_layout Plain Layout
9506 Optind, ARGV[Optind])
9509 \begin_layout Plain Layout
9514 \begin_layout Plain Layout
9524 \begin_layout Standard
9525 The entire getopt.awk is made out of these chunks in order
9532 \begin_layout Standard
9533 \begin_inset listings
9537 \begin_layout Plain Layout
9541 chunkref{getopt.awk-header}>
9544 \begin_layout Plain Layout
9548 \begin_layout Plain Layout
9552 chunkref{getopt.awk-notes}>
9555 \begin_layout Plain Layout
9559 chunkref{getopt.awk-getopt()}>
9562 \begin_layout Plain Layout
9566 chunkref{getopt.awk-begin}>
9574 \begin_layout Standard
9575 Although we only want the header and function:
9582 \begin_layout Standard
9583 \begin_inset listings
9587 \begin_layout Plain Layout
9589 # try: locate getopt.awk for the full original file
9592 \begin_layout Plain Layout
9594 # as part of your standard awk installation
9597 \begin_layout Plain Layout
9601 chunkref{getopt.awk-header}>
9604 \begin_layout Plain Layout
9608 \begin_layout Plain Layout
9612 chunkref{getopt.awk-getopt()}>
9620 \begin_layout Chapter
9621 Newfangle LaTeX source code
9624 \begin_layout Section
9628 \begin_layout Standard
9629 Here we define a Lyx .module file that makes it convenient to use LyX for
9630 writing such literate programs.
9633 \begin_layout Standard
9635 \begin_inset Flex CharStyle:Code
9638 \begin_layout Plain Layout
9644 can be installed in your personal
9645 \begin_inset Flex CharStyle:Code
9648 \begin_layout Plain Layout
9655 You will need to Tools Reconfigure so that LyX notices it.
9656 It adds a new format Chunk, which should precede every listing and contain
9662 ./newfangle.module,language=
9665 \begin_layout Standard
9666 \begin_inset listings
9670 \begin_layout Plain Layout
9674 DeclareLyXModule{Newfangle Literate Listings}
9677 \begin_layout Plain Layout
9682 \begin_layout Plain Layout
9684 # Newfangle literate listings allow one to write
9687 \begin_layout Plain Layout
9689 # literate programs after the fashion of noweb, but without having
9692 \begin_layout Plain Layout
9694 # to use noweave to generate the documentation.
9695 Instead the listings
9698 \begin_layout Plain Layout
9700 # package is extended in conjunction with the noweb package to implement
9703 \begin_layout Plain Layout
9705 # to code formating directly as latex.
9708 \begin_layout Plain Layout
9710 # The newfangle awk script
9713 \begin_layout Plain Layout
9718 \begin_layout Plain Layout
9722 \begin_layout Plain Layout
9727 \begin_layout Plain Layout
9731 \begin_layout Plain Layout
9736 \begin_layout Plain Layout
9740 chunkref{./newfangle.sty}>
9743 \begin_layout Plain Layout
9748 \begin_layout Plain Layout
9752 \begin_layout Plain Layout
9756 chunkref{chunkstyle}>
9759 \begin_layout Plain Layout
9763 \begin_layout Plain Layout
9775 \begin_layout Subsection
9779 \begin_layout Standard
9784 style is to make it easier for LyX users to provide the name to
9785 \begin_inset Flex CharStyle:Code
9788 \begin_layout Plain Layout
9797 Normally this requires right-clicking on the listing, choosing settings,
9798 advanced, and then typing
9799 \begin_inset Flex CharStyle:Code
9802 \begin_layout Plain Layout
9809 This has the further disadvantage that the name (and other options) are
9810 not generally visible during document editing.
9813 \begin_layout Standard
9814 The chunk style is defined as a LaTeX command, so that all text on the same
9815 line is passed to the LaTeX command
9816 \begin_inset Flex CharStyle:Code
9819 \begin_layout Plain Layout
9826 This makes it easy to parse using
9827 \begin_inset Flex CharStyle:Code
9830 \begin_layout Plain Layout
9836 , and easy to pass these options on to the listings package.
9837 The first word in a chunk section should be the chunk name, and will have
9839 \begin_inset Flex CharStyle:Code
9842 \begin_layout Plain Layout
9849 Any other words are accepted arguments to
9850 \begin_inset Flex CharStyle:Code
9853 \begin_layout Plain Layout
9864 \begin_layout Standard
9865 We set PassThru to 1 because the user is actually entering raw latex.
9872 \begin_layout Standard
9873 \begin_inset listings
9877 \begin_layout Plain Layout
9882 \begin_layout Plain Layout
9887 \begin_layout Plain Layout
9892 \begin_layout Plain Layout
9894 Margin First_Dynamic
9897 \begin_layout Plain Layout
9899 LeftMargin Chunk:xxx
9902 \begin_layout Plain Layout
9907 \begin_layout Plain Layout
9912 \begin_layout Plain Layout
9914 LabelString "Chunk:"
9917 \begin_layout Plain Layout
9922 \begin_layout Plain Layout
9927 \begin_layout Plain Layout
9936 \begin_layout Standard
9937 To make the label very visible we choose a larger font coloured red.
9940 \begin_layout Standard
9941 \begin_inset listings
9945 \begin_layout Plain Layout
9950 \begin_layout Plain Layout
9955 \begin_layout Plain Layout
9960 \begin_layout Plain Layout
9965 \begin_layout Plain Layout
9970 \begin_layout Plain Layout
9975 \begin_layout Plain Layout
9980 \begin_layout Plain Layout
9990 \begin_layout Subsection
9994 \begin_layout Standard
9995 We also define the Chunkref style which can be used to express cross references
10003 \begin_layout Standard
10004 \begin_inset listings
10008 \begin_layout Plain Layout
10010 InsetLayout Chunkref
10013 \begin_layout Plain Layout
10018 \begin_layout Plain Layout
10023 \begin_layout Plain Layout
10028 \begin_layout Plain Layout
10033 \begin_layout Plain Layout
10038 \begin_layout Plain Layout
10043 \begin_layout Plain Layout
10048 \begin_layout Plain Layout
10053 \begin_layout Plain Layout
10063 \begin_layout Section
10064 \begin_inset CommandInset label
10066 name "sec:Latex-Macros"
10073 \begin_layout Standard
10087 As noweb defines it's own
10088 \begin_inset Flex CharStyle:Code
10091 \begin_layout Plain Layout
10099 environment, we re-define the one that LyX logical markup module expects
10103 \begin_layout Chunk
10104 ./newfangle.sty,language=tex,basicstyle=
10109 \begin_layout Standard
10110 \begin_inset listings
10114 \begin_layout Plain Layout
10118 usepackage{listings}%
10121 \begin_layout Plain Layout
10128 \begin_layout Plain Layout
10135 \begin_layout Plain Layout
10151 \begin_layout Standard
10153 \begin_inset Flex CharStyle:Code
10156 \begin_layout Plain Layout
10163 \begin_inset Flex CharStyle:Code
10166 \begin_layout Plain Layout
10174 which will need renaming to
10175 \begin_inset Flex CharStyle:Code
10178 \begin_layout Plain Layout
10186 when I can do this without clashing with
10187 \begin_inset Flex CharStyle:Code
10190 \begin_layout Plain Layout
10201 \begin_layout Standard
10202 \begin_inset listings
10206 \begin_layout Plain Layout
10210 lstnewenvironment{Chunk}{
10222 \begin_layout Standard
10223 We also define a suitable
10224 \begin_inset Flex CharStyle:Code
10227 \begin_layout Plain Layout
10235 of parameters that suit the literate programming style after the fashion
10243 \begin_layout Standard
10244 \begin_inset listings
10248 \begin_layout Plain Layout
10252 lstset{numbers=left, stepnumber=5, numbersep=5pt,
10255 \begin_layout Plain Layout
10257 breaklines=false,basicstyle=
10262 \begin_layout Plain Layout
10274 \begin_layout Standard
10275 We also define a notangle-like mechanism for
10279 to LaTeX from the listing, and by which we can refer to other listings.
10281 \begin_inset Flex CharStyle:Code
10284 \begin_layout Plain Layout
10285 =<\SpecialChar \ldots{}
10291 sequence to contain LaTeX code, and include another like this chunk:
10292 \begin_inset Flex CharStyle:Code
10295 \begin_layout Plain Layout
10298 chunkref{chunkname}>
10305 \begin_inset Flex CharStyle:Code
10308 \begin_layout Plain Layout
10309 =<\SpecialChar \ldots{}
10315 is already defined to contain LaTeX code for this document --- this is
10320 document after all --- the code fragment below effectively contains the
10322 \begin_inset Flex CharStyle:Code
10325 \begin_layout Plain Layout
10332 To avoid problems with document generation, I had to declare an lstlistings
10334 \begin_inset Flex CharStyle:Code
10337 \begin_layout Plain Layout
10343 for this listing only; which in LyX was done by right-clicking the listings
10345 \begin_inset Flex CharStyle:Code
10348 \begin_layout Plain Layout
10354 \SpecialChar \menuseparator
10356 \begin_inset Flex CharStyle:Code
10359 \begin_layout Plain Layout
10368 \begin_layout Standard
10369 \begin_inset Note Note
10372 \begin_layout Plain Layout
10373 =< isn't enjoyed literally here, in a listing when the escape sequence is
10374 already defined as shown...
10375 we need to somehow escape this representation...
10383 \begin_layout Standard
10384 \begin_inset listings
10385 lstparams "escapeinside={}"
10389 \begin_layout Plain Layout
10393 lstset{escapeinside={=<}{>}}%
10401 \begin_layout Standard
10402 Although our macros will contain the @ symbol, they will be included in
10404 \begin_inset Flex CharStyle:Code
10407 \begin_layout Plain Layout
10415 section by LyX; however we keep the commented out
10416 \begin_inset Flex CharStyle:Code
10419 \begin_layout Plain Layout
10428 The listings package likes to centre the titles, but noweb titles are specially
10429 formatted and must be left aligned.
10430 The simplest way to do this turned out to be by removing the definition
10432 \begin_inset Flex CharStyle:Code
10435 \begin_layout Plain Layout
10444 This may interact badly if other listings want a regular title or caption.
10445 We remember the old maketitle in case we need it.
10448 \begin_layout Standard
10449 \begin_inset listings
10453 \begin_layout Plain Layout
10460 \begin_layout Plain Layout
10462 %somehow re-defining maketitle gives us a left-aligned title
10465 \begin_layout Plain Layout
10467 %which is extactly what our specially formatted title needs!
10470 \begin_layout Plain Layout
10478 newfangle@lst@maketitle
10483 \begin_layout Plain Layout
10499 \begin_layout Subsection
10500 \begin_inset CommandInset label
10502 name "sub:The-chunk-command"
10509 \begin_layout Standard
10510 Our chunk command accepts one argument, and calls
10511 \begin_inset Flex CharStyle:Code
10514 \begin_layout Plain Layout
10524 \begin_inset Flex CharStyle:Code
10527 \begin_layout Plain Layout
10535 will note the name, this is erased when the next
10536 \begin_inset Flex CharStyle:Code
10539 \begin_layout Plain Layout
10547 starts, so we make a note of this in
10548 \begin_inset Flex CharStyle:Code
10551 \begin_layout Plain Layout
10559 and restore in in lstlistings Init hook.
10562 \begin_layout Standard
10563 \begin_inset listings
10567 \begin_layout Plain Layout
10576 \begin_layout Plain Layout
10582 newfanglecaption},name=#1}%
10585 \begin_layout Plain Layout
10598 \begin_layout Plain Layout
10603 \begin_layout Plain Layout
10619 \begin_layout Subsubsection
10623 \begin_layout Standard
10624 Newfangle permits parameterized chunks, and requires the paramters to be
10625 specified as listings options.
10626 The newfangle script uses this, and although we don't do anything with
10627 these in the LaTeX code right now, we need to stop the listings package
10631 \begin_layout Standard
10632 \begin_inset listings
10636 \begin_layout Plain Layout
10646 newfangle@chunk@params{#1}}%
10654 \begin_layout Subsection
10655 The noweb styled caption
10658 \begin_layout Standard
10659 We define a public macro
10660 \begin_inset Flex CharStyle:Code
10663 \begin_layout Plain Layout
10671 which can be set as a regular title.
10673 \begin_inset Flex CharStyle:Code
10676 \begin_layout Plain Layout
10685 \begin_inset Flex CharStyle:Code
10688 \begin_layout Plain Layout
10696 at the appriate time when the caption is emitted.
10699 \begin_layout Standard
10700 \begin_inset listings
10704 \begin_layout Plain Layout
10714 newfangle@caption}%
10722 \begin_layout Standard
10723 \begin_inset Float figure
10729 \begin_layout Plain Layout
10730 \begin_inset Box Boxed
10739 height_special "totalheight"
10742 \begin_layout Plain Layout
10744 \begin_inset space \qquad{}
10752 \begin_inset Formula $\equiv+$
10756 \begin_inset space \qquad{}
10760 \begin_inset space \qquad{}
10764 \begin_inset space \qquad{}
10768 \begin_inset Formula $\triangleleft$
10772 \begin_inset space \quad{}
10776 \begin_inset Formula $\triangleright$
10782 \begin_layout Plain Layout
10785 In this example, the current chunk is 22c, and therefore the third chunk
10789 \begin_layout Plain Layout
10800 \begin_layout Plain Layout
10803 The first chunk with this name (19b) occurs as the second chunk on page
10807 \begin_layout Plain Layout
10810 The previous chunk (22d) with the same name is the second chunk on page
10814 \begin_layout Plain Layout
10817 The next chunk (24d) is the fourth chunk on page 24.
10820 \begin_layout Plain Layout
10821 \begin_inset Caption
10823 \begin_layout Plain Layout
10839 The general noweb output format compactly identifies the current chunk,
10840 and references to the first chunk, and the previous and next chunks that
10841 have the same name.
10845 \begin_layout Standard
10846 This means that we need to keep a counter for each chunk-name, that we use
10847 to count chunks of the same name.
10851 \begin_layout Subsection
10855 \begin_layout Standard
10856 It would be natural to have a counter for each chunk name, but TeX would
10857 soon run out of counters
10861 \begin_layout Plain Layout
10862 \SpecialChar \ldots{}
10867 run out of counters and so I had to re-write the LaTeX macros to share
10868 a counter as described here
10873 , so we have one counter which we save at the end of a chunk and restore
10874 at the beginning of a chunk.
10877 \begin_layout Standard
10878 \begin_inset listings
10882 \begin_layout Plain Layout
10886 newcounter{newfangle@chunkcounter}%
10894 \begin_layout Standard
10895 We construct the name of this variable to store the counter to be the text
10897 \begin_inset Flex CharStyle:Code
10900 \begin_layout Plain Layout
10906 prefixed onto the chunks own name, and store it in
10907 \begin_inset Flex CharStyle:Code
10910 \begin_layout Plain Layout
10922 \begin_layout Standard
10923 We save the counter like this:
10926 \begin_layout Chunk
10930 \begin_layout Standard
10931 \begin_inset listings
10935 \begin_layout Plain Layout
10951 arabic{newfangle@chunkcounter}}%
10959 \begin_layout Standard
10960 and restore the counter like this:
10963 \begin_layout Chunk
10967 \begin_layout Standard
10968 \begin_inset listings
10972 \begin_layout Plain Layout
10976 setcounter{newfangle@chunkcounter}{
10990 \begin_layout Chunk
10994 \begin_layout Standard
10995 If there does not already exist a variable whose name is stored in
10996 \begin_inset Flex CharStyle:Code
10999 \begin_layout Plain Layout
11007 , then we know we are the first chunk with this name, and then define a
11012 \begin_layout Standard
11013 Although chunks of the same name share a common counter, they must still
11015 We use is the internal name of the listing, suffixed by the counter value.
11016 So the first chunk might be
11017 \begin_inset Flex CharStyle:Code
11020 \begin_layout Plain Layout
11026 and the second chunk be
11027 \begin_inset Flex CharStyle:Code
11030 \begin_layout Plain Layout
11039 \begin_layout Standard
11040 We also calculate the name of the previous chunk if we can (before we increment
11041 the chunk counter).
11042 If this is the first chunk of that name, then
11043 \begin_inset Flex CharStyle:Code
11046 \begin_layout Plain Layout
11055 \begin_inset Flex CharStyle:Code
11058 \begin_layout Plain Layout
11066 which the noweb package will interpret as not existing.
11069 \begin_layout Standard
11070 \begin_inset listings
11074 \begin_layout Plain Layout
11080 newfangle@caption{%
11083 \begin_layout Plain Layout
11089 chunkcount{lst-chunk-
11094 \begin_layout Plain Layout
11103 \begin_layout Plain Layout
11118 \begin_layout Plain Layout
11122 setcounter{newfangle@chunkcounter}{
11131 \begin_layout Plain Layout
11142 \begin_layout Plain Layout
11147 \begin_layout Plain Layout
11151 setcounter{newfangle@chunkcounter}{
11160 \begin_layout Plain Layout
11170 arabic{newfangle@chunkcounter}}%
11173 \begin_layout Plain Layout
11183 \begin_layout Standard
11184 After incrementing the chunk counter, we then define the name of this chunk,
11185 as well as the name of the first chunk.
11188 \begin_layout Standard
11189 \begin_inset listings
11193 \begin_layout Plain Layout
11197 addtocounter{newfangle@chunkcounter}{1}%
11200 \begin_layout Plain Layout
11216 arabic{newfangle@chunkcounter}}%
11219 \begin_layout Plain Layout
11229 arabic{newfangle@chunkcounter}}%
11232 \begin_layout Plain Layout
11248 \begin_layout Standard
11249 We now need to calculate the name of the next chunk.
11250 We do this by temporarily skipping the counter on by one; however there
11251 may not actually be another chunk with this name! We detect this by also
11252 defining a label for each chunk based on the chunkname.
11253 If there is a next chunkname then it will define a label with that name.
11254 As labels are persistent, we can at least tell the second time LaTeX is
11256 If we don't find such a defined label then we define
11257 \begin_inset Flex CharStyle:Code
11260 \begin_layout Plain Layout
11269 \begin_inset Flex CharStyle:Code
11272 \begin_layout Plain Layout
11283 \begin_layout Standard
11284 \begin_inset listings
11288 \begin_layout Plain Layout
11292 addtocounter{newfangle@chunkcounter}{1}%
11295 \begin_layout Plain Layout
11305 arabic{newfangle@chunkcounter}}%
11308 \begin_layout Plain Layout
11312 @ifundefined{r@label-
11328 \begin_layout Standard
11329 The noweb package requires that we define a
11330 \begin_inset Flex CharStyle:Code
11333 \begin_layout Plain Layout
11341 for every chunk, with a unique name, which is then used to print out it's
11345 \begin_layout Standard
11346 We also define a regular label for this chunk, as was mentioned above when
11348 \begin_inset Flex CharStyle:Code
11351 \begin_layout Plain Layout
11360 This requires LaTeX to be run at least twice after new chunk sections are
11361 added --- but noweb requried that anyway.
11364 \begin_layout Standard
11365 \begin_inset listings
11369 \begin_layout Plain Layout
11378 \begin_layout Plain Layout
11380 % define this label for every chunk instance, so we
11383 \begin_layout Plain Layout
11385 % can tell when we are the last chunk of this name
11388 \begin_layout Plain Layout
11402 \begin_layout Standard
11403 We also try and add the chunk to the list of listings, but I'm afraid we
11404 don't do very well.
11405 We want each chunk name listing once, with all of it's references.
11408 \begin_layout Standard
11409 \begin_inset listings
11413 \begin_layout Plain Layout
11417 addcontentsline{lol}{lstlisting}{
11433 \begin_layout Standard
11434 We then call the noweb output macros in the same way that noweave generates
11435 them, except that we don't need to call
11436 \begin_inset Flex CharStyle:Code
11439 \begin_layout Plain Layout
11442 nwstartdeflinemarkup
11448 \begin_inset Flex CharStyle:Code
11451 \begin_layout Plain Layout
11459 -- and if we do it messes up the output somewhat.
11462 \begin_layout Standard
11463 \begin_inset listings
11467 \begin_layout Plain Layout
11474 \begin_layout Plain Layout
11479 \begin_layout Plain Layout
11486 \begin_layout Plain Layout
11495 \begin_layout Plain Layout
11500 \begin_layout Plain Layout
11505 \begin_layout Plain Layout
11510 \begin_layout Plain Layout
11517 \begin_layout Plain Layout
11524 \begin_layout Plain Layout
11529 \begin_layout Plain Layout
11538 \begin_layout Plain Layout
11542 @ifundefined{newfangle@chunk@params}{}{%
11545 \begin_layout Plain Layout
11549 newfangle@chunk@params)%
11552 \begin_layout Plain Layout
11557 \begin_layout Plain Layout
11568 \begin_layout Plain Layout
11577 \begin_layout Plain Layout
11582 \begin_layout Plain Layout
11587 \begin_layout Plain Layout
11592 \begin_layout Plain Layout
11611 \begin_layout Plain Layout
11615 nwstartdeflinemarkup%
11618 \begin_layout Plain Layout
11629 \begin_layout Plain Layout
11633 nwenddeflinemarkup%
11636 \begin_layout Plain Layout
11646 \begin_layout Standard
11647 Originally this was developed as a
11648 \begin_inset Flex CharStyle:Code
11651 \begin_layout Plain Layout
11657 aspect, in the Init hook, but it was found easier to affect the title without
11659 \begin_inset Flex CharStyle:Code
11662 \begin_layout Plain Layout
11665 lst@AddToHookExe{PreSet}
11670 is still required to set the listings name to the name passed to the
11671 \begin_inset Flex CharStyle:Code
11674 \begin_layout Plain Layout
11685 \begin_layout Standard
11686 \begin_inset listings
11690 \begin_layout Plain Layout
11694 lst@BeginAspect{newfangle}
11697 \begin_layout Plain Layout
11701 lst@Key{newfangle}{true}[t]{
11703 lstKV@SetIf{#1}{true}}
11706 \begin_layout Plain Layout
11710 lst@AddToHookExe{PreSet}{
11721 \begin_layout Plain Layout
11725 lst@AddToHook{Init}{}%
11730 \begin_layout Plain Layout
11742 \begin_layout Subsection
11746 \begin_layout Standard
11749 chunkref command which makes it easy to generate visual references to different
11753 \begin_layout Standard
11754 \begin_inset Tabular
11755 <lyxtabular version="3" rows="4" columns="2">
11757 <column alignment="center" valignment="top" width="0">
11758 <column alignment="center" valignment="top" width="0">
11760 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
11763 \begin_layout Plain Layout
11769 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
11772 \begin_layout Plain Layout
11780 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
11783 \begin_layout Plain Layout
11791 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
11794 \begin_layout Plain Layout
11798 \begin_layout Plain Layout
11814 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
11817 \begin_layout Plain Layout
11820 chunkref[3]{preamble}
11825 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
11828 \begin_layout Plain Layout
11832 \begin_layout Plain Layout
11836 chunkref[3]{preamble}
11848 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
11851 \begin_layout Plain Layout
11854 chunkref{preamble}[arg1, arg2]
11859 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
11862 \begin_layout Plain Layout
11866 \begin_layout Plain Layout
11870 chunkref{preamble}[arg1, arg2]
11888 \begin_layout Standard
11889 Chunkref can also be used within a code chunk to include another code chunk.
11890 The third optional parameter to chunkref is a comma sepatarated list of
11891 arguments, which will replace defined parameters in the chunkref.
11892 \begin_inset Note Note
11895 \begin_layout Plain Layout
11896 Darn it, if I have: =<
11898 chunkref{new-mode}[{chunks[chunk_name, "language"]},{mode}]> the inner braces
11899 (inside [ ]) cause _ to signify subscript even though we have lst@ReplaceIn
11907 \begin_layout Standard
11908 \begin_inset listings
11912 \begin_layout Plain Layout
11921 \begin_layout Plain Layout
11930 \begin_layout Plain Layout
11941 \begin_layout Plain Layout
11948 \begin_layout Plain Layout
11959 \begin_layout Plain Layout
11964 \begin_layout Plain Layout
11973 \begin_layout Plain Layout
11979 chunkref@i{#1}{#2}}{
11981 chunkref@i{#1}{#2}()}%
11984 \begin_layout Plain Layout
11989 \begin_layout Plain Layout
11995 chunkref@i#1#2(#3){%
11998 \begin_layout Plain Layout
12007 \begin_layout Plain Layout
12016 \begin_layout Plain Layout
12025 \begin_layout Plain Layout
12034 \begin_layout Plain Layout
12045 \begin_layout Plain Layout
12054 \begin_layout Plain Layout
12061 \begin_layout Plain Layout
12072 \begin_layout Plain Layout
12079 \begin_layout Plain Layout
12090 \begin_layout Plain Layout
12101 \begin_layout Plain Layout
12110 \begin_layout Plain Layout
12117 \begin_layout Plain Layout
12122 \begin_layout Plain Layout
12131 \begin_layout Plain Layout
12142 \begin_layout Plain Layout
12149 \begin_layout Plain Layout
12156 \begin_layout Plain Layout
12163 \begin_layout Plain Layout
12174 \begin_layout Plain Layout
12181 \begin_layout Plain Layout
12185 chunkref@args #3,)%
12188 \begin_layout Plain Layout
12195 \begin_layout Plain Layout
12204 \begin_layout Plain Layout
12209 \begin_layout Plain Layout
12214 \begin_layout Plain Layout
12223 \begin_layout Plain Layout
12233 \begin_layout Subsection
12237 \begin_layout Standard
12238 \begin_inset listings
12242 \begin_layout Plain Layout
12247 \begin_layout Plain Layout
12259 \begin_layout Chapter
12260 Extracting newfangle
12263 \begin_layout Section
12264 Extracting from Lyx
12267 \begin_layout Standard
12268 To extract from LyX, you will need to configure LyX as explained in section
12270 \begin_inset CommandInset ref
12272 reference "sub:Configuring-the-build"
12279 \begin_layout Standard
12280 \begin_inset CommandInset label
12282 name "lyx-build-script"
12286 And this lyx-build scrap will extract newfangle for me.
12289 \begin_layout Chunk
12290 lyx-build,language=sh
12293 \begin_layout Standard
12294 \begin_inset listings
12298 \begin_layout Plain Layout
12303 \begin_layout Plain Layout
12308 \begin_layout Plain Layout
12312 \begin_layout Plain Layout
12316 chunkref{lyx-build-helper}>
12319 \begin_layout Plain Layout
12321 cd $PROJECT_DIR || exit 1
12324 \begin_layout Plain Layout
12328 \begin_layout Plain Layout
12330 /usr/local/bin/newfangle -R./newfangle $TEX_SRC > ./newfangle
12333 \begin_layout Plain Layout
12335 /usr/local/bin/newfangle -R./newfangle.module $TEX_SRC > ./newfangle.module
12343 \begin_layout Standard
12344 With a lyx-build-helper
12347 \begin_layout Chunk
12348 lyx-build-helper,language=sh
12351 \begin_layout Standard
12352 \begin_inset listings
12356 \begin_layout Plain Layout
12358 PROJECT_DIR="$LYX_r"
12361 \begin_layout Plain Layout
12363 LYX_SRC="$PROJECT_DIR/${LYX_i%.tex}.lyx"
12366 \begin_layout Plain Layout
12371 \begin_layout Plain Layout
12373 TEX_SRC="$TEX_DIR/$LYX_i"
12381 \begin_layout Section
12382 Extracting from the command line
12385 \begin_layout Standard
12386 First you will need the tex output, then you can extract:
12389 \begin_layout Chunk
12390 lyx-build-manual,language=sh
12393 \begin_layout Standard
12394 \begin_inset listings
12398 \begin_layout Plain Layout
12400 lyx -e latex newfangle.lyx
12403 \begin_layout Plain Layout
12405 newfangle -R./newfangle newfangle.tex > ./newfangle
12408 \begin_layout Plain Layout
12410 newfangle -R./newfangle.module newfangle.tex > ./newfangle.module
12422 \begin_layout Chapter
12426 \begin_layout Chunk
12427 tests-sub,params=THING;colour
12430 \begin_layout Standard
12431 \begin_inset listings
12435 \begin_layout Plain Layout
12437 I see a ${THING} of
12440 \begin_layout Plain Layout
12445 \begin_layout Plain Layout
12449 chunkref{tests-sub-sub}(${colour})>
12457 \begin_layout Chunk
12458 tests-sub-sub,params=colour
12461 \begin_layout Standard
12462 \begin_inset listings
12466 \begin_layout Plain Layout
12468 a funny shade of ${colour}
12476 \begin_layout Chunk
12480 \begin_layout Standard
12481 \begin_inset listings
12485 \begin_layout Plain Layout
12487 What do you see? "=<
12489 chunkref{tests-sub}(joe, red)>"
12492 \begin_layout Plain Layout
12502 \begin_layout Standard
12503 Should generate output:
12506 \begin_layout Chunk
12510 \begin_layout Standard
12511 \begin_inset listings
12515 \begin_layout Plain Layout
12517 What do you see? "I see a joe of
12520 \begin_layout Plain Layout
12525 \begin_layout Plain Layout
12527 looking closer a funny shade of red"
12530 \begin_layout Plain Layout
12535 \begin_layout Plain Layout