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 Standard
231 \begin_inset CommandInset toc
232 LatexCommand tableofcontents
239 \begin_layout Chapter
243 \begin_layout Standard
244 \begin_inset CommandInset label
250 Newfangle is licensed under the GPL 3
251 \begin_inset CommandInset citation
258 This doesn't mean that you can't use or distribute newfangle with sources
259 of an incompatible license, but it means you must make the source of newfangle
264 gpl3-copyright,language=
267 \begin_layout Standard
268 \begin_inset listings
272 \begin_layout Plain Layout
274 #newfangle - fully featured notangle replacement in awk
277 \begin_layout Plain Layout
282 \begin_layout Plain Layout
284 #Copyright (C) Sam Liddicott 2009
287 \begin_layout Plain Layout
292 \begin_layout Plain Layout
294 #This program is free software: you can redistribute it and/or modify
297 \begin_layout Plain Layout
299 #it under the terms of the GNU General Public License as published by
302 \begin_layout Plain Layout
304 #the Free Software Foundation, either version 3 of the License, or
307 \begin_layout Plain Layout
309 #(at your option) any later version.
312 \begin_layout Plain Layout
317 \begin_layout Plain Layout
319 #This program is distributed in the hope that it will be useful,
322 \begin_layout Plain Layout
324 #but WITHOUT ANY WARRANTY; without even the implied warranty of
327 \begin_layout Plain Layout
329 #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
333 \begin_layout Plain Layout
335 #GNU General Public License for more details.
338 \begin_layout Plain Layout
343 \begin_layout Plain Layout
345 #You should have received a copy of the GNU General Public License
348 \begin_layout Plain Layout
350 #along with this program.
351 If not, see <http://www.gnu.org/licenses/>.
363 \begin_layout Standard
364 Newfangle is a replacement for noweb, which consists of
365 \begin_inset Flex CharStyle:Code
368 \begin_layout Plain Layout
375 \begin_inset Flex CharStyle:Code
378 \begin_layout Plain Layout
385 \begin_inset Flex CharStyle:Code
388 \begin_layout Plain Layout
397 \begin_layout Standard
399 \begin_inset Flex CharStyle:Code
402 \begin_layout Plain Layout
409 \begin_inset Flex CharStyle:Code
412 \begin_layout Plain Layout
418 it can read multiple named files, or from stdin.
421 \begin_layout Chapter
425 \begin_layout Standard
426 The -r option causes newfangle to behave like noroots.
429 \begin_layout LyX-Code
430 newfangle -r filename.tex
433 \begin_layout Standard
434 will print out the newfangle roots of a tex file.
438 \begin_layout Standard
440 \begin_inset Flex CharStyle:Code
443 \begin_layout Plain Layout
449 command, the roots are not enclosed in
450 \begin_inset Flex CharStyle:Code
453 \begin_layout Plain Layout
459 , unless at least one of the roots is defined using the
460 \begin_inset Flex CharStyle:Code
463 \begin_layout Plain Layout
470 \begin_inset Flex CharStyle:Code
473 \begin_layout Plain Layout
482 \begin_layout Standard
483 Also, unlike noroots, it prints out all roots --- not just those that are
485 I find that a root not being used, doesn't make it particularly top level.
486 My convention is that top level roots to be extracted begin with
487 \begin_inset Flex CharStyle:Code
490 \begin_layout Plain Layout
496 and have the form of a filename.
499 \begin_layout Chapter
503 \begin_layout Standard
505 \begin_inset Flex CharStyle:Code
508 \begin_layout Plain Layout
515 \begin_inset Flex CharStyle:Code
518 \begin_layout Plain Layout
524 options are supported.
527 \begin_layout Standard
528 The standard way to extract a file would be:
531 \begin_layout LyX-Code
532 newfangle -R./Makefile.inc newfangle.tex > ./Makefile.inc
535 \begin_layout Standard
537 \begin_inset Flex CharStyle:Code
540 \begin_layout Plain Layout
547 \begin_inset Flex CharStyle:Code
550 \begin_layout Plain Layout
556 option does not break indenting; also the
557 \begin_inset Flex CharStyle:Code
560 \begin_layout Plain Layout
566 option does not interrupt (and break) multi-line C macros --- or indeed
567 any line ending with a backslash.
568 This does mean that sometimes the compiler might calculate the source line
569 wrongly when generating error messages in such cases, but there isn't any
570 other way around if multi-line macros include other chunks.
573 \begin_layout Chapter
577 \begin_layout Standard
578 The noweave replacement is a set of LaTeX macros dependant upon
582 , and which can be included with:
585 \begin_layout LyX-Code
588 usepackage{newfangle.sty}
591 \begin_layout Standard
592 The LaTeX macros are shown in section
593 \begin_inset CommandInset ref
595 reference "sec:Latex-Macros"
599 , and are part of a LyX module file
600 \begin_inset Flex CharStyle:Code
603 \begin_layout Plain Layout
609 , which automatically includes the macros in the document pre-amble when
610 the newfangle LyX module is used.
613 \begin_layout Standard
614 Because the noweave replacement is impemented in LaTeX, there is no processing
615 stage required before running the
616 \begin_inset Flex CharStyle:Code
619 \begin_layout Plain Layout
626 LaTeX may need running two or more times, so that the code chunk references
627 can be fully calculated.
630 \begin_layout Standard
632 \begin_inset Flex CharStyle:Code
635 \begin_layout Plain Layout
641 package is required as it is used for formatting the code chunk captions
644 \begin_layout Standard
646 \begin_inset Flex CharStyle:Code
649 \begin_layout Plain Layout
655 package is also required, as it is used for formatting the code chunks
659 \begin_layout Standard
661 \begin_inset Flex CharStyle:Code
664 \begin_layout Plain Layout
670 package is also required.
673 \begin_layout Chapter
674 Literate Programming with Newfangle
677 \begin_layout Standard
679 Should really follow on from a part-0 explanation of what literate programming
683 \begin_layout Chapter
684 Using Newfangle with LyX
687 \begin_layout Section
691 \begin_layout Subsection
692 Installing the LyX module
695 \begin_layout Standard
697 \begin_inset Flex CharStyle:Code
700 \begin_layout Plain Layout
706 to your LyX layouts directory, which for unix users will be
707 \begin_inset Flex CharStyle:Code
710 \begin_layout Plain Layout
719 \begin_layout Standard
720 You will need to reconfigure LyX by clicking Tools\SpecialChar \menuseparator
721 Reconfigure, and then
725 \begin_layout Subsection
726 \begin_inset CommandInset label
728 name "sub:Configuring-the-build"
732 Configuring the build script
735 \begin_layout Standard
736 Make sure you don't have a conversion defined for Lyx → Program
739 \begin_layout Standard
740 From the menu Tools\SpecialChar \menuseparator
741 Preferences, add a conversion from Latex(Plain) → Program
745 \begin_layout LyX-Code
746 set -x ; newfangle -Rlyx-build $$i |
749 \begin_layout LyX-Code
750 env LYX_b=$$b LYX_i=$$i LYX_o=$$o LYX_p=$$p LYX_r=$$r bash
753 \begin_layout Standard
754 (But don't cut-n-paste it from this document or you'll be pasting a multi-line
755 string which will break your lyx preferences file).
759 \begin_layout Standard
760 I hope that one day, LyX will set these into the environment when calling
764 \begin_layout Standard
765 You may also want to consider adding options to this conversion\SpecialChar \ldots{}
769 \begin_layout LyX-Code
770 parselog=/usr/share/lyx/scripts/listerrors
773 \begin_layout Standard
774 \SpecialChar \ldots{}
775 but if you do you will lose your stderr
779 \begin_layout Plain Layout
780 There is some bash plumbing to get a copy of stderr but this footnote is
789 \begin_layout Standard
790 Now, a shell script chunk called
791 \begin_inset Flex CharStyle:Code
794 \begin_layout Plain Layout
800 will be extracted and run whenever you choose the Document\SpecialChar \menuseparator
805 \begin_layout Standard
806 The lyx-build script for this document is in section
807 \begin_inset CommandInset ref
809 reference "lyx-build-script"
813 and on a unix system will extract
814 \begin_inset Flex CharStyle:Code
817 \begin_layout Plain Layout
824 \begin_inset Flex CharStyle:Code
827 \begin_layout Plain Layout
836 \begin_layout Subsection
837 Preparing your Lyx document
840 \begin_layout Standard
841 It is not necessary to base your literate document on any of the original
842 LyX literate classes; so select a regular class for your document type.
845 \begin_layout Standard
861 \begin_layout Standard
862 In the drop-down style listbox you should notice a new style defined, called
870 \begin_layout Standard
871 When you wish to insert a literate chunk, you enter it's plain name in the
872 Chunk style, instead of the older method that used
873 \begin_inset Flex CharStyle:Code
876 \begin_layout Plain Layout
883 Following the chunk name, you insert a listing with: Insert\SpecialChar \menuseparator
887 \begin_layout Standard
888 Inside the white listing box you can type (or paste using shift+ctrl+V)
890 There is not need to use ctrl+enter at the end of lines as with some older
891 LyX literate techniques --- just press enter as normal.
894 \begin_layout Subsubsection
895 Customising the listing appearance
898 \begin_layout Standard
899 In the final document, the code is formatted using the
904 The chunk style doesn't just define the chunk name, but can also define
905 any other chunk options supported by the lstlistings package
906 \begin_inset Flex CharStyle:Code
909 \begin_layout Plain Layout
918 In fact, what you type in the chunk style is raw latex.
919 If you want to set the chunk language without having to right-click the
921 \begin_inset Flex CharStyle:Code
924 \begin_layout Plain Layout
930 after the chunk name.
933 \begin_layout Standard
934 Of course you can do this by editing the listings box advanced properties
935 by right-clicking on the listings box, but that takes longer, and you can't
936 see at-a-glance what the advanced settings are while editing the document;
937 also advanced settings apply only to that box --- the chunk settings apply
938 through the rest of the document
942 \begin_layout Plain Layout
943 It ought to apply only to subsequent chunks of the same name.
950 \begin_inset Note Note
953 \begin_layout Plain Layout
954 So make sure they only apply to chunks of that name
962 \begin_layout Subsubsection
963 Global customisations
966 \begin_layout Standard
971 is used to set the code chunks, it's
972 \begin_inset Flex CharStyle:Code
975 \begin_layout Plain Layout
983 command can be used in the pre-amble to set some document wide settings.
986 \begin_layout Standard
987 If your source has many words with long sequences of capital letters, then
989 \begin_inset Flex CharStyle:Code
992 \begin_layout Plain Layout
998 may be a good idea, or the capital letters will get crowded.
999 (I think lstlistings ought to use a slightly smaller font for captial letters
1000 so that they still fit).
1003 \begin_layout Standard
1005 \begin_inset Flex CharStyle:Code
1008 \begin_layout Plain Layout
1016 looks more normal for code, but has no bold (unless luximono is used, but
1017 it doesn't work for me); so I use
1018 \begin_inset Flex CharStyle:Code
1021 \begin_layout Plain Layout
1031 \begin_inset Flex CharStyle:Code
1034 \begin_layout Plain Layout
1043 \begin_inset Flex CharStyle:Code
1046 \begin_layout Plain Layout
1047 columns=fullflexible
1052 is used or the wrong letter spacing is used.
1055 \begin_layout Standard
1056 In my LeTeX pre-amble I usually specialise my code format with:
1060 document-preamble,language=tex
1063 \begin_layout Standard
1064 \begin_inset listings
1068 \begin_layout Plain Layout
1075 \begin_layout Plain Layout
1079 definecolor{darkgreen}{rgb}{0,0.5,0}
1082 \begin_layout Plain Layout
1086 lstset{numbers=left, stepnumber=5, numbersep=5pt, breaklines=false,
1089 \begin_layout Plain Layout
1098 \begin_layout Plain Layout
1105 \begin_layout Plain Layout
1109 tiny,language=C,columns=fullflexible,
1112 \begin_layout Plain Layout
1114 numberfirstline=true
1117 \begin_layout Plain Layout
1127 \begin_layout Chapter
1128 Newfangle with Makefiles
1131 \begin_layout Standard
1132 \begin_inset Note Note
1135 \begin_layout Plain Layout
1136 This chapter needs revising
1142 \begin_inset Note Greyedout
1145 \begin_layout Plain Layout
1146 This chapter needs revising
1151 Here we describe a Makefile.inc that you can include in your own Makefiles,
1152 or glue as a recursive make to other projects.
1155 \begin_layout Standard
1156 The Makefile.inc described here was put together for a Samba4 vfs module,
1157 but can be used in any Make project, including automake projects.
1160 \begin_layout Section
1161 A word about makefiles formats
1164 \begin_layout Standard
1165 Whitespace formatting is very important in a Makefile.
1166 The first character of each command line must be a TAB.
1169 \begin_layout LyX-Code
1170 target: pre-requisite
1171 \begin_inset Newline newline
1175 \begin_inset Newline newline
1181 \begin_layout Standard
1182 But a TAB is pretty hard to enter into most of the Lyx formats and insets
1184 An alternative is to use a semi-colon after the pre-requisite, and a backslash
1185 at the end of each line (except the last).
1186 Then any whitespace (or none) can prefix each action.
1189 \begin_layout LyX-Code
1190 target: pre-requisite ;
1193 \begin_inset Newline newline
1199 \begin_inset Newline newline
1205 \begin_layout Standard
1206 This is the style that we use and it works pretty well for GNU make at least.
1209 \begin_layout Standard
1210 We also adopt a convention that code chunks whose names beginning with ./
1211 should always be automatically extracted from the document.
1212 Code chunks whose names do not begin with ./ are for internal reference.
1213 (This doesn't prevent such chunks from being extracted directly).
1216 \begin_layout Section
1217 Boot-strapping the extraction
1220 \begin_layout Subsection
1224 \begin_layout Standard
1225 \begin_inset CommandInset label
1227 name "sub:Bootstrap-Using-a-Makefile"
1231 It seems convenient to have the makefile extract or update the C source
1232 files as part of it's operation.
1233 It also seems convenient to have the makefile itself extracted from this
1237 \begin_layout Standard
1238 It would also be convenient to have the code to extract the makefile from
1239 this document to also be part of this document, however we have to start
1240 somewhere and this unfortunately requires us to type at least a few words
1241 by hand to start things off.
1244 \begin_layout Standard
1245 Therefore we will have a minimal root fragment, which, when extracted, can
1246 cope with extracting the rest of the source.
1247 perhaps with this shell script, which could be called
1252 \begin_inset Note Note
1255 \begin_layout Plain Layout
1256 FIX THIS CHUNK AND TEST IT
1268 \begin_layout Standard
1269 \begin_inset listings
1273 \begin_layout Plain Layout
1278 \begin_layout Plain Layout
1282 \begin_layout Plain Layout
1284 MAKE_SRC="${1:-${NW_LYX:-../../noweb-lyx/noweb-lyx3.lyx}}"
1287 \begin_layout Plain Layout
1289 MAKE_SRC=`dirname "$MAKE_SRC"`/`basename "$MAKE_SRC" .lyx`
1292 \begin_layout Plain Layout
1294 NOWEB_SRC="${2:-${NOWEB_SRC:-$MAKE_SRC.lyx}}"
1297 \begin_layout Plain Layout
1299 lyx -e latex $MAKE_SRC
1302 \begin_layout Plain Layout
1306 \begin_layout Plain Layout
1308 newfangle -R./Makefile.inc ${MAKE_SRC}.tex
1313 \begin_layout Plain Layout
1315 | sed "/NEWFANGLE_SOURCE=/s/^/#/;T;aNOWEB_SOURCE=$NEWFANGLE_SRC"
1320 \begin_layout Plain Layout
1322 | cpif ./Makefile.inc
1325 \begin_layout Plain Layout
1329 \begin_layout Plain Layout
1331 make -f ./Makefile.inc newfangle_sources
1339 \begin_layout Standard
1340 The general Makefile can be invoked with
1344 and can also be included into any automake file to automatically re-generate
1348 \begin_layout Standard
1353 can be extracted with this command:
1356 \begin_layout LyX-Code
1357 lyx -e latex newfangle.lyx &&
1362 \begin_layout LyX-Code
1363 newfangle newfangle.lyx > ./autoboot
1366 \begin_layout Standard
1367 This looks simple enough, but as mentioned, newfangle has to be had from
1368 somewhere before it can be extracted.
1371 \begin_layout Subsection
1372 \begin_inset Note Note
1375 \begin_layout Plain Layout
1376 MERGE THIS WITH THE SECTIONS OF THIS DOCUMENT
1381 \SpecialChar \ldots{}
1385 \begin_layout Standard
1386 When the lyx-build chunk is executed, the current directory will be a temporary
1388 \begin_inset Flex CharStyle:Code
1391 \begin_layout Plain Layout
1397 will refer to the tex file in this temporary directory.
1398 This is unfortunate as our makefile wants to run from the project directory
1399 where the Lyx file is kept.
1402 \begin_layout Standard
1403 We can extract the project directory from $$r, and derive the probable Lyx
1404 filename from the noweb file that Lyx generated.
1411 \begin_layout Standard
1412 \begin_inset listings
1416 \begin_layout Plain Layout
1418 PROJECT_DIR="$LYX_r"
1421 \begin_layout Plain Layout
1423 LYX_SRC="$PROJECT_DIR/${LYX_i%.tex}.lyx"
1426 \begin_layout Plain Layout
1431 \begin_layout Plain Layout
1433 TEX_SRC="$TEX_DIR/$LYX_i"
1441 \begin_layout Standard
1442 And then we can define a lyx-build fragment similar to the autoboot fragment
1449 \begin_layout Standard
1450 \begin_inset listings
1454 \begin_layout Plain Layout
1459 \begin_layout Plain Layout
1463 chunkref{lyx-build-helper}>
1466 \begin_layout Plain Layout
1468 cd $PROJECT_DIR || exit 1
1471 \begin_layout Plain Layout
1475 \begin_layout Plain Layout
1477 #/usr/bin/newfangle -filter ./notanglefix-filter
1482 \begin_layout Plain Layout
1484 # -R./Makefile.inc "../../noweb-lyx/noweb-lyx3.lyx"
1489 \begin_layout Plain Layout
1491 # | sed '/NOWEB_SOURCE=/s/=.*/=samba4-dfs.lyx/'
1496 \begin_layout Plain Layout
1501 \begin_layout Plain Layout
1506 \begin_layout Plain Layout
1508 #make -f ./Makefile.inc newfangle_sources
1516 \begin_layout Section
1520 \begin_layout Subsection
1521 Including Makefile.inc
1524 \begin_layout Standard
1525 \begin_inset CommandInset label
1527 name "sub:Keeping-extracted-files"
1531 Makefile.inc will cope with extracting all the other source files from this
1532 document and keeping them up to date.
1536 \begin_layout Standard
1537 It may also be included by a Makefile or Makefile.am defined in a Lyx document
1538 to automatically deal with the extraction of source files and documents.
1541 \begin_layout Standard
1542 A makefile has two parts; variables must be defined before the targets that
1550 \begin_layout Standard
1551 \begin_inset listings
1555 \begin_layout Plain Layout
1559 chunkref{Makefile.inc-vars}>
1562 \begin_layout Plain Layout
1566 chunkref{Makefile.inc-targets}>
1574 \begin_layout Standard
1576 \begin_inset Flex CharStyle:Code
1579 \begin_layout Plain Layout
1585 to hold the name of this Lyx file.
1592 \begin_layout Standard
1593 \begin_inset listings
1597 \begin_layout Plain Layout
1599 LYX_SOURCE=../../noweb-lyx/newfangle.lyx
1602 \begin_layout Plain Layout
1604 LITERATE_SOURCE=$(LYX_SOURCE)
1612 \begin_layout Subsection
1613 Recursive use of Makefile.inc
1616 \begin_layout Standard
1617 The makefile glue described here is used when building Samba4 vfs modules.
1620 \begin_layout Standard
1621 If you are defining a module of an existing program you may find it easier
1622 to use a slight recursive make instead of including the makefile directly.
1623 This way there is less chance of definitions in Makefile.inc interfering
1624 with definitions in the main makefile, or with definitions in other Makefile.inc
1625 from other noweb modules.
1628 \begin_layout Standard
1629 The glue works by adding a .PHONY target to call the recursive make, and
1630 adding this target as an additional pre-requisite to the existing targets.
1633 \begin_layout Standard
1634 In this example, the existing build system already has a build target for
1636 \begin_inset Flex CharStyle:Code
1639 \begin_layout Plain Layout
1645 , so we just add another pre-requisite to that.
1647 \begin_inset Flex CharStyle:Code
1650 \begin_layout Plain Layout
1656 as a pre-requisite, the stamp file's modified time indicating when all
1657 sources were extracted.
1664 \begin_layout Standard
1665 \begin_inset listings
1669 \begin_layout Plain Layout
1671 $(example_srcdir)/example.o: $(example_srcdir)/example.tex.stamp
1679 \begin_layout Standard
1680 The target for this new pre-requisite is generated by a recursive make using
1681 Makefile.inc which will make sure that the source is up to date, before
1682 it is built by the main projects makefile.
1689 \begin_layout Standard
1690 \begin_inset listings
1694 \begin_layout Plain Layout
1696 $(example_srcdir)/example.tex.stamp: $(example_srcdir)/example.tex ;
1701 \begin_layout Plain Layout
1703 cd $(example_srcdir) &&
1708 \begin_layout Plain Layout
1710 $(MAKE) -f Makefile.inc newfangle_sources
1718 \begin_layout Standard
1719 We can do similar glue for the docs, clean and distclean targets.
1720 In this example our build system is using a double colon for these targets,
1721 so we use the same in our glue.
1728 \begin_layout Standard
1729 \begin_inset listings
1733 \begin_layout Plain Layout
1738 \begin_layout Plain Layout
1740 .PHONY: docs_example
1743 \begin_layout Plain Layout
1745 docs_example:: ; cd $(example_srcdir) &&
1750 \begin_layout Plain Layout
1752 $(MAKE) -f Makefile.inc docs
1755 \begin_layout Plain Layout
1759 \begin_layout Plain Layout
1761 clean:: clean_example
1764 \begin_layout Plain Layout
1766 .PHONEY: clean_example
1769 \begin_layout Plain Layout
1771 clean_example: ; cd $(example_srcdir) &&
1776 \begin_layout Plain Layout
1778 $(MAKE) -f Makefile.inc clean
1781 \begin_layout Plain Layout
1785 \begin_layout Plain Layout
1787 distclean:: distclean_example
1790 \begin_layout Plain Layout
1792 .PHONY: distclean_example
1795 \begin_layout Plain Layout
1797 distclean_example: ; cd $(example_srcdir) &&
1802 \begin_layout Plain Layout
1804 $(MAKE) -f Makefile.inc distclean
1812 \begin_layout Standard
1813 We could do similarly for install targets to install the generated docs.
1816 \begin_layout Subsection
1817 \begin_inset CommandInset label
1819 name "sub:Converting-from-Lyx"
1823 Converting from Lyx to LaTeX
1826 \begin_layout Standard
1827 The first stage will always be to convert the Lyx file to a LaTeX file;
1828 this must be so not only because newfangle needs to to run on a TeX file,
1829 but also because the Lyx command
1831 server-goto-file-line
1835 \begin_layout Plain Layout
1838 server-goto-file-line
1840 is used to position the Lyx cursor at the compiler errors.
1847 insists that the line number provided is a line in the TeX file, and always
1848 reverse maps this to derive the line in the Lyx docment.
1849 \begin_inset Note Note
1852 \begin_layout Plain Layout
1853 The tex file should probably be an automake extra dist sources or something,
1854 so that it gets produced and packaged by make dist
1862 \begin_layout Standard
1863 The command [[lyx -e literate noweb-lyx.lyx]] will produce [[noweb-lyx.nw]]
1864 a tex file, so we define the noweb target to be the same as the Lyx file
1865 but with the .nw extension.
1872 \begin_layout Standard
1873 \begin_inset listings
1877 \begin_layout Plain Layout
1879 TEX_SOURCE=$(LYX_SOURCE:.lyx=.tex)
1888 Makefile.inc-targets
1891 \begin_layout Standard
1892 \begin_inset listings
1896 \begin_layout Plain Layout
1898 $(TEX_SOURCE): $(LYX_SOURCE) ;
1903 \begin_layout Plain Layout
1908 \begin_layout Plain Layout
1910 clean_tex: ; rm -f -- $(TEX_SOURCE)
1918 \begin_layout Subsection
1919 Extracting Program Source
1922 \begin_layout Standard
1923 The program source is extracted using newfangle, which is designed to operate
1924 on a LaTeX document.
1932 \begin_layout Standard
1933 \begin_inset listings
1937 \begin_layout Plain Layout
1939 NEWFANGLE_SOURCE=$(TEX_SOURCE)
1947 \begin_layout Standard
1948 The Lyx document can result in any number of source documents, but not all
1949 of these will be changed each time the Lyx document is updated.
1950 We certainly don't want to update the timestamps of these files and cause
1951 the whole source tree to be recompiled just because the Lyx document was
1956 \begin_layout Standard
1957 To solve this problem we use a stamp file which is always updated each time
1958 the sources are extracted from the LaTeX document.
1959 If the stamp file is older than the LaTeX document, then we can make an
1960 attempt to re-extract the sources.
1967 \begin_layout Standard
1968 \begin_inset listings
1972 \begin_layout Plain Layout
1974 NEWFANGLE_SOURCE_STAMP=$(NEWFANGLE_SOURCE).stamp
1983 Makefile.inc-targets
1986 \begin_layout Standard
1987 \begin_inset listings
1991 \begin_layout Plain Layout
1993 $(NEWFANGLE_SOURCE_STAMP): $(NEWFANGLE_SOURCE)
1998 \begin_layout Plain Layout
2000 $(NEWFANGLE_SOURCES) ;
2005 \begin_layout Plain Layout
2007 touch $(NEWFANGLE_SOURCE_STAMP)
2010 \begin_layout Plain Layout
2012 clean_stamp: ; rm -f $(NEWFANGLE_SOURCE_STAMP)
2015 \begin_layout Plain Layout
2025 \begin_layout Subsection
2026 Extracting C sources
2029 \begin_layout Standard
2031 \begin_inset Flex CharStyle:Code
2034 \begin_layout Plain Layout
2040 to hold the names of all the C source files defined in this document.
2041 We compute this only once, by means of := in assignent.
2042 The sed deletes the any <
2043 \begin_inset space \hspace*{}
2048 \begin_inset space \hspace*{}
2052 > which may surround the roots names (for noroots compatibility).
2056 \begin_layout Standard
2057 As we use chunk names beginning with ./ to denote top level fragments that
2058 should be extracted, we filter out all fragments that do not begin with
2066 \begin_layout Standard
2067 \begin_inset listings
2071 \begin_layout Plain Layout
2080 \begin_layout Plain Layout
2082 NEWFANGLE_SOURCES:=$(shell
2087 \begin_layout Plain Layout
2089 newfangle -r $(NEWFANGLE_SOURCE) |
2094 \begin_layout Plain Layout
2096 sed -e 's/^[<][<]//;s/[>][>]$$//;/^$(NEWFANGLE_PREFIX)/!d'
2101 \begin_layout Plain Layout
2103 -e 's/^$(NEWFANGLE_PREFIX)/
2110 \begin_layout Plain Layout
2121 Makefile.inc-targets
2124 \begin_layout Standard
2125 \begin_inset listings
2129 \begin_layout Plain Layout
2131 .PHONY: echo_newfangle_sources
2134 \begin_layout Plain Layout
2136 echo_newfangle_sources: ; @echo $(NEWFANGLE_SOURCES)
2144 \begin_layout Standard
2145 We define a convenient target called
2146 \begin_inset Flex CharStyle:Code
2149 \begin_layout Plain Layout
2155 to re-extract the source if the LaTeX file has been updated.
2159 Makefile.inc-targets
2162 \begin_layout Standard
2163 \begin_inset listings
2167 \begin_layout Plain Layout
2169 .PHONY: newfangle_sources
2172 \begin_layout Plain Layout
2174 newfangle_sources: $(NEWFANGLE_SOURCE_STAMP)
2182 \begin_layout Standard
2183 And also a convenient target to remove extracted sources.
2187 Makefile.inc-targets
2190 \begin_layout Standard
2191 \begin_inset listings
2195 \begin_layout Plain Layout
2197 .PHONY: clean_newfangle_sources
2200 \begin_layout Plain Layout
2202 clean_newfangle_sources: ;
2207 \begin_layout Plain Layout
2209 rm -f -- $(NEWFANGLE_SOURCE_STAMP) $(NEWFANGLE_SOURCES)
2217 \begin_layout Standard
2219 \begin_inset Flex CharStyle:Code
2222 \begin_layout Plain Layout
2228 macro takes 4 arguments: the filename (1), some extensions to match (2)
2229 and a some shell command to return if the filename matches the exentions
2237 \begin_layout Standard
2238 \begin_inset listings
2242 \begin_layout Plain Layout
2244 if_extension=$(if $(findstring $(suffix $(1)),$(2)),$(3),$(4))
2252 \begin_layout Standard
2253 For some source files like C files, we want to output the line number and
2254 filename of the original LaTeX document from which the source came.
2257 \begin_layout Standard
2258 To make this easier we define the file extensions for which we want to do
2266 \begin_layout Standard
2267 \begin_inset listings
2271 \begin_layout Plain Layout
2281 \begin_layout Standard
2282 We can then use the if_extensions macro to define a macro which expands
2284 \begin_inset Flex CharStyle:Code
2287 \begin_layout Plain Layout
2293 option if newfangle is being invoked in a C source file, so that C compile
2294 errors will refer to the line number in the Lyx document.
2302 \begin_layout Standard
2303 \begin_inset listings
2307 \begin_layout Plain Layout
2312 \begin_layout Plain Layout
2319 \begin_layout Plain Layout
2321 $(call if_extension,$(2),$(C_EXTENSIONS),$(nf_line))
2326 \begin_layout Plain Layout
2336 \begin_layout Standard
2337 We can use a similar trick to define an
2341 macro which takes just the filename as an argument and can return a pipeline
2342 stage calling the indent command.
2343 Indent can be turned off with
2344 \begin_inset Flex CharStyle:Code
2347 \begin_layout Plain Layout
2348 make newfangle_sources indent=
2360 \begin_layout Standard
2361 \begin_inset listings
2365 \begin_layout Plain Layout
2367 indent_options=-npro -kr -i8 -ts8 -sob -l80 -ss -ncs
2370 \begin_layout Plain Layout
2372 indent=$(call if_extension,$(1),$(C_EXTENSIONS),
2377 \begin_layout Plain Layout
2379 | indent $(indent_options))
2387 \begin_layout Standard
2388 We now define the pattern for extracting a file.
2389 The files are written using noweb's
2395 \begin_layout Plain Layout
2398 So you still need noweb installed in order to use cpif
2404 \begin_inset Note Note
2407 \begin_layout Plain Layout
2410 Write an awk version
2417 so that the file timestamp will not be touched if the contents haven't
2419 This avoids the need to rebuild the entire project because of a typographical
2420 change in the documentation, or if only a few C source files have changed.
2427 \begin_layout Standard
2428 \begin_inset listings
2432 \begin_layout Plain Layout
2434 newfangle_extract=@mkdir -p $(dir $(1)) &&
2439 \begin_layout Plain Layout
2441 $(call newfangle,$(2),$(1)) > "$(1).tmp" &&
2446 \begin_layout Plain Layout
2448 cat "$(1).tmp" $(indent) | cpif "$(1)"
2453 \begin_layout Plain Layout
2455 && rm -- "$(1).tmp" ||
2460 \begin_layout Plain Layout
2462 (echo error newfangling $(1) from $(2) ; exit 1)
2470 \begin_layout Standard
2471 We define a target which will extract or update all sources.
2472 To do this we first defined a makefile template that can do this for any
2473 source file in the LaTeX document.
2480 \begin_layout Standard
2481 \begin_inset listings
2485 \begin_layout Plain Layout
2487 define NEWFANGLE_template
2490 \begin_layout Plain Layout
2497 \begin_layout Plain Layout
2499 $$(call newfangle_extract,$(1),$(2))
2502 \begin_layout Plain Layout
2504 NEWFANGLE_TARGETS+=$(1)
2507 \begin_layout Plain Layout
2517 \begin_layout Standard
2518 We then enumerate the discovered
2519 \begin_inset Flex CharStyle:Code
2522 \begin_layout Plain Layout
2528 to generate a makefile rule for each one using the makefile template we
2533 Makefile.inc-targets
2536 \begin_layout Standard
2537 \begin_inset listings
2541 \begin_layout Plain Layout
2543 $(foreach source,$(NEWFANGLE_SOURCES),
2548 \begin_layout Plain Layout
2550 $(eval $(call NEWFANGLE_template,$(source),$(NEWFANGLE_SOURCE)))
2555 \begin_layout Plain Layout
2565 \begin_layout Standard
2566 These will all be built with NEWFANGLE_SOURCE_STAMP.
2569 \begin_layout Standard
2570 We also remove the generated sources on a
2578 Makefile.inc-targets
2581 \begin_layout Standard
2582 \begin_inset listings
2586 \begin_layout Plain Layout
2588 _distclean: clean_newfangle_sources
2596 \begin_layout Subsection
2597 Extracting Documentation
2600 \begin_layout Standard
2601 We then identify the intermediate stages of the documentation and their
2602 build and clean targets.
2605 \begin_layout Subsubsection
2609 \begin_layout Standard
2610 We produce a pdf file from the tex file.
2617 \begin_layout Standard
2618 \begin_inset listings
2622 \begin_layout Plain Layout
2624 NEWFANGLE_PDF=$(TEX_SOURCE:.tex=.pdf)
2632 \begin_layout Standard
2633 We run pdflatex twice to be sure that the contents and aux files are up
2635 We certainly are required to run pdflatex twice if these files do not exist!
2639 Makefile.inc-targets
2642 \begin_layout Standard
2643 \begin_inset listings
2647 \begin_layout Plain Layout
2649 $(NEWFANGLE_PDF): $(TEX_SOURCE); pdflatex $< && pdflatex $<
2652 \begin_layout Plain Layout
2654 clean_pdf: ; rm -f -- $(NEWFANGLE_PDF)
2659 \begin_layout Plain Layout
2661 $(TEX_SOURCE:.tex=.toc)
2666 \begin_layout Plain Layout
2668 $(TEX_SOURCE:.tex=.log)
2673 \begin_layout Plain Layout
2675 $(TEX_SOURCE:.tex=.aux)
2683 \begin_layout Subsubsection
2687 \begin_layout Standard
2688 Currently we only build pdf as a final format, but NEWFANGLE_DOCS may later
2689 hold other output formats.
2696 \begin_layout Standard
2697 \begin_inset listings
2701 \begin_layout Plain Layout
2703 NEWFANGLE_DOCS=$(NEWFANGLE_PDF)
2711 \begin_layout Standard
2712 We also define noweb_docs as a convenient phony target<
2716 Makefile.inc-targets
2719 \begin_layout Standard
2720 \begin_inset listings
2724 \begin_layout Plain Layout
2726 .PHONY: newfangle_docs
2729 \begin_layout Plain Layout
2731 newfangle_docs: $(NOWEB_DOCS)
2734 \begin_layout Plain Layout
2736 docs: newfangle_docs
2744 \begin_layout Standard
2745 And define a convenient clean_noweb_docs which we add to the regular clean
2750 Makefile.inc-targets
2753 \begin_layout Standard
2754 \begin_inset listings
2758 \begin_layout Plain Layout
2760 .PHONEY: clean_newfangle_docs
2763 \begin_layout Plain Layout
2765 clean_newfangle_docs: clean_tex clean_pdf
2768 \begin_layout Plain Layout
2770 clean: clean_newfangle_docs
2773 \begin_layout Plain Layout
2777 \begin_layout Plain Layout
2779 distclean_newfangle_docs: clean_tex clean_newfangle_docs
2782 \begin_layout Plain Layout
2784 distclean: clean distclean_newfangle_docs
2792 \begin_layout Subsection
2796 \begin_layout Standard
2797 If Makefile.inc is included into Makefile, then extracted files can be updated
2801 \begin_layout LyX-Code
2802 make newfangle_sources
2805 \begin_layout Standard
2809 \begin_layout LyX-Code
2810 make -f Makefile.inc newfangle_sources
2817 \begin_layout Chapter
2818 Newfangle awk source code
2821 \begin_layout Standard
2822 We use the copyright notice from chapter
2823 \begin_inset CommandInset ref
2825 reference "cha:License"
2833 ./newfangle,language=awk,morestring=[b]{/},morekeywords=else
2836 \begin_layout Standard
2837 \begin_inset listings
2841 \begin_layout Plain Layout
2846 \begin_layout Plain Layout
2850 chunkref{gpl3-copyright}>
2858 \begin_layout Standard
2859 We also use code from Arnold Robbins public domain getopt (1993 revision)
2861 \begin_inset CommandInset ref
2863 reference "cha:getopt"
2867 , and naturally want to attribute this appropriately.
2870 \begin_layout Standard
2871 \begin_inset listings
2875 \begin_layout Plain Layout
2879 \begin_layout Plain Layout
2881 # NOTE: Arnold Robbins public domain getopt for awk is also used:
2884 \begin_layout Plain Layout
2888 chunkref{getopt.awk-header}>
2891 \begin_layout Plain Layout
2895 \begin_layout Plain Layout
2899 chunkref{getopt.awk-getopt()}>
2902 \begin_layout Plain Layout
2911 \begin_layout Standard
2912 And include the following chunks
2919 \begin_layout Standard
2920 \begin_inset listings
2924 \begin_layout Plain Layout
2928 chunkref{helper-functions}>
2931 \begin_layout Plain Layout
2935 chunkref{mode-tracker}>
2938 \begin_layout Plain Layout
2942 chunkref{chunk-storage-functions}>
2945 \begin_layout Plain Layout
2949 chunkref{output_chunk_names()}>
2952 \begin_layout Plain Layout
2956 chunkref{output_chunks()}>
2959 \begin_layout Plain Layout
2963 chunkref{write_chunk()}>
2966 \begin_layout Plain Layout
2970 chunkref{expand_chunk_args()}>
2973 \begin_layout Plain Layout
2980 \begin_layout Plain Layout
2984 chunkref{recognize-chunk}>
2987 \begin_layout Plain Layout
2999 \begin_layout Section
3003 \begin_layout Standard
3004 The portable way to erase an array in awk is to split the empty string,
3009 awk-delete-array,params=ARRAY
3012 \begin_layout Standard
3013 \begin_inset listings
3017 \begin_layout Plain Layout
3019 split("", ${ARRAY});
3031 \begin_layout Section
3035 \begin_layout Standard
3036 Fatal errors are issued with the error function:
3043 \begin_layout Standard
3044 \begin_inset listings
3048 \begin_layout Plain Layout
3050 function error(message)
3053 \begin_layout Plain Layout
3058 \begin_layout Plain Layout
3060 print message > "/dev/stderr";
3063 \begin_layout Plain Layout
3068 \begin_layout Plain Layout
3078 \begin_layout Standard
3079 This is one of the helper functions.
3086 \begin_layout Standard
3087 \begin_inset listings
3091 \begin_layout Plain Layout
3103 \begin_layout Chapter
3107 \begin_layout Standard
3108 LaTeX arguments to lstlistings macros are a comma seperated list of key-value
3110 Values containing commas are enclosed in { braces }.
3113 \begin_layout Standard
3114 We need a function that can parse such an expression and assign the values
3122 \begin_layout Standard
3123 A sample expressions is:
3126 \begin_layout LyX-Code
3127 name=thomas, params={a, b}, something, something-else
3130 \begin_layout Standard
3131 but we see that this is just a simpler form of this expression:
3134 \begin_layout LyX-Code
3135 name=freddie, foo={bar=baz, quux={quirk, a=fleeg}}, etc
3138 \begin_layout Standard
3139 And that it would be a good idea to use a recursive parser into a multi-dimensio
3144 \begin_layout Plain Layout
3145 as AWK doesn't have nested-hash support
3153 \begin_layout Standard
3154 \begin_inset Tabular
3155 <lyxtabular version="3" rows="6" columns="2">
3157 <column alignment="left" valignment="top" width="0">
3158 <column alignment="left" valignment="top" width="0">
3160 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
3163 \begin_layout Plain Layout
3169 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
3172 \begin_layout Plain Layout
3180 <cell alignment="left" valignment="top" topline="true" leftline="true" usebox="none">
3183 \begin_layout Plain Layout
3189 <cell alignment="left" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
3192 \begin_layout Plain Layout
3200 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
3203 \begin_layout Plain Layout
3209 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
3212 \begin_layout Plain Layout
3220 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
3223 \begin_layout Plain Layout
3229 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
3232 \begin_layout Plain Layout
3240 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
3243 \begin_layout Plain Layout
3249 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
3252 \begin_layout Plain Layout
3260 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
3263 \begin_layout Plain Layout
3269 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
3272 \begin_layout Plain Layout
3286 \begin_layout Standard
3287 On reflection it seems that sometimes such nesting is not desirable, as
3288 the braces are also used to delimit values that contain commas --- we may
3292 \begin_layout LyX-Code
3293 name={williamson, freddie}
3296 \begin_layout Standard
3298 \begin_inset Flex CharStyle:Code
3301 \begin_layout Plain Layout
3308 \begin_inset Flex CharStyle:Code
3311 \begin_layout Plain Layout
3317 --- so I may change this behaviour.
3318 \begin_inset Note Note
3321 \begin_layout Plain Layout
3330 \begin_layout Standard
3332 \begin_inset Flex Chunkref
3335 \begin_layout Plain Layout
3341 will accept two paramters,
3342 \begin_inset Flex CharStyle:Code
3345 \begin_layout Plain Layout
3351 being the text to parse, and
3352 \begin_inset Flex CharStyle:Code
3355 \begin_layout Plain Layout
3361 being an array to receive the parsed values as described above.
3362 The optional parameter
3363 \begin_inset Flex CharStyle:Code
3366 \begin_layout Plain Layout
3372 is used during recursion to build up the multi-dimensional array path.
3379 \begin_layout Standard
3380 \begin_inset listings
3384 \begin_layout Plain Layout
3388 chunkref{get_chunk_args()}>
3400 \begin_layout Standard
3401 \begin_inset listings
3405 \begin_layout Plain Layout
3407 function get_chunk_args(text, values,
3410 \begin_layout Plain Layout
3412 # optional parameters
3415 \begin_layout Plain Layout
3417 path, # hierarchical precursors
3420 \begin_layout Plain Layout
3425 \begin_layout Plain Layout
3435 \begin_layout Standard
3436 The strategy is to parse the name, and then look for a value.
3437 If the value begins with a brace
3438 \begin_inset Flex CharStyle:Code
3441 \begin_layout Plain Layout
3447 , then we recurse and consume as much of the text as necessary, returning
3448 the remaining text when we encounter a leading close-brace
3449 \begin_inset Flex CharStyle:Code
3452 \begin_layout Plain Layout
3459 This being the strategy --- and executed in a loop --- we realise that
3460 we must first look for the closing brace (perhaps preceded by white space)
3461 in order to terminate the recursion, and returning remaining text.
3464 \begin_layout Standard
3465 \begin_inset listings
3469 \begin_layout Plain Layout
3474 \begin_layout Plain Layout
3476 while(length(text)) {
3479 \begin_layout Plain Layout
3481 if (match(text, "^ *}(.*)", a)) {
3484 \begin_layout Plain Layout
3489 \begin_layout Plain Layout
3494 \begin_layout Plain Layout
3498 chunkref{parse-chunk-args}>
3501 \begin_layout Plain Layout
3506 \begin_layout Plain Layout
3511 \begin_layout Plain Layout
3521 \begin_layout Standard
3522 \begin_inset Note Note
3525 \begin_layout Plain Layout
3526 Use BNF package here
3531 We can see that the text could be inspected with this regex:
3538 \begin_layout Standard
3539 \begin_inset listings
3543 \begin_layout Plain Layout
3545 if (! match(text, " *([^,=]*[^,= ]) *(([,=]) *(([^,}]*) *,* *(.*))|)$", a))
3549 \begin_layout Plain Layout
3554 \begin_layout Plain Layout
3564 \begin_layout Standard
3566 \begin_inset Flex CharStyle:Code
3569 \begin_layout Plain Layout
3575 will have the following values:
3578 \begin_layout Standard
3579 \begin_inset Tabular
3580 <lyxtabular version="3" rows="7" columns="2">
3582 <column alignment="center" valignment="top" width="0">
3583 <column alignment="left" valignment="top" width="0">
3585 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
3588 \begin_layout Plain Layout
3594 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
3597 \begin_layout Plain Layout
3605 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
3608 \begin_layout Plain Layout
3614 <cell alignment="left" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
3617 \begin_layout Plain Layout
3625 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
3628 \begin_layout Plain Layout
3634 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
3637 \begin_layout Plain Layout
3638 =freddie, foo={bar=baz, quux={quirk, a=fleeg}}, etc
3645 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
3648 \begin_layout Plain Layout
3654 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
3657 \begin_layout Plain Layout
3665 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
3668 \begin_layout Plain Layout
3674 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
3677 \begin_layout Plain Layout
3678 freddie, foo={bar=baz, quux={quirk, a=fleeg}}, etc
3685 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
3688 \begin_layout Plain Layout
3694 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
3697 \begin_layout Plain Layout
3705 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
3708 \begin_layout Plain Layout
3714 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
3717 \begin_layout Plain Layout
3718 , foo={bar=baz, quux={quirk, a=fleeg}}, etc
3731 \begin_layout Standard
3733 \begin_inset Flex CharStyle:Code
3736 \begin_layout Plain Layout
3743 \begin_inset Flex CharStyle:Code
3746 \begin_layout Plain Layout
3752 and signify whether the option named in
3753 \begin_inset Flex CharStyle:Code
3756 \begin_layout Plain Layout
3762 has a value or not (respectively).
3765 \begin_layout Standard
3766 If the option does have a value, then if the expression
3767 \begin_inset Flex CharStyle:Code
3770 \begin_layout Plain Layout
3777 \begin_inset Flex CharStyle:Code
3780 \begin_layout Plain Layout
3786 it will signify that we need to recurse:
3789 \begin_layout Standard
3790 \begin_inset listings
3794 \begin_layout Plain Layout
3799 \begin_layout Plain Layout
3804 \begin_layout Plain Layout
3806 if (substr(a[4],1,1) == "{") {
3809 \begin_layout Plain Layout
3811 text = get_chunk_args(substr(a[4],2), values, path name SUBSEP);
3814 \begin_layout Plain Layout
3819 \begin_layout Plain Layout
3821 values[path name]=a[5];
3824 \begin_layout Plain Layout
3829 \begin_layout Plain Layout
3834 \begin_layout Plain Layout
3839 \begin_layout Plain Layout
3841 values[path name]="";
3844 \begin_layout Plain Layout
3849 \begin_layout Plain Layout
3859 \begin_layout Standard
3860 We can test this function like this:
3867 \begin_layout Standard
3868 \begin_inset listings
3872 \begin_layout Plain Layout
3876 chunkref{get_chunk_args()}>
3879 \begin_layout Plain Layout
3884 \begin_layout Plain Layout
3889 \begin_layout Plain Layout
3893 \begin_layout Plain Layout
3895 print get_chunk_args("name=freddie, foo={bar=baz, quux={quirk, a=fleeg}},
3899 \begin_layout Plain Layout
3904 \begin_layout Plain Layout
3906 print "a[" b "] => " a[b];
3909 \begin_layout Plain Layout
3914 \begin_layout Plain Layout
3924 \begin_layout Standard
3925 which should give this output:
3929 gca-test.awk-results
3932 \begin_layout Standard
3933 \begin_inset listings
3937 \begin_layout Plain Layout
3939 a[foo.quux.quirk] =>
3942 \begin_layout Plain Layout
3944 a[foo.quux.a] => fleeg
3947 \begin_layout Plain Layout
3952 \begin_layout Plain Layout
3957 \begin_layout Plain Layout
3967 \begin_layout Chapter
3968 Expanding chunk arguments
3971 \begin_layout Standard
3972 \begin_inset CommandInset label
3974 name "cha:Chunk Arguments"
3979 \begin_inset Note Note
3982 \begin_layout Plain Layout
3983 Explain this in the documentation section too
3988 As an extension to many literate-programming styles, newfangle permits code
3989 chunks to take parameters and thus operate somewhat like C pre-processor
3990 macros, or like C++ templates.
3993 \begin_layout Standard
3994 Chunk parameters are declared with a chunk argument called
3995 \begin_inset Flex CharStyle:Code
3998 \begin_layout Plain Layout
4004 , which holds a semi-colon separated list of parameters, like this:
4007 \begin_layout LyX-Code
4008 achunk,language=C,params=name;address
4011 \begin_layout Standard
4012 When such a chunk is included the arguments are expressed thus, in square
4013 brackets as optional arguments separated by a comma
4014 \begin_inset Note Note
4017 \begin_layout Plain Layout
4018 We ought to support qouting in {} like ({Jones, John}, Jones@example.com)
4026 \begin_layout LyX-Code
4029 chunkref{achunk}(John Jones, jones@example.com)
4032 \begin_layout Standard
4033 Within the body a chunk, parameters are expressed as:
4034 \begin_inset Flex CharStyle:Code
4037 \begin_layout Plain Layout
4044 \begin_inset Flex CharStyle:Code
4047 \begin_layout Plain Layout
4054 There is a strong case that a LaTeX style notation should be used, like
4059 param{name}> as it would appear in the lstlisting.
4060 Such notation would make me go blind, but I do intend to adopt it.
4063 \begin_layout Standard
4064 We therefore need a function
4065 \begin_inset Flex CharStyle:Code
4068 \begin_layout Plain Layout
4074 which will take a block of text, a list of permitted parameters and the
4075 arguments which must substitute for the parameters.
4079 \begin_layout Standard
4080 \begin_inset CommandInset label
4082 name "Here-we-split"
4086 Here we split the text on
4087 \begin_inset Flex CharStyle:Code
4090 \begin_layout Plain Layout
4096 which means that all parts except the first will begin with a parameter
4098 The split function will consume the literal
4099 \begin_inset Flex CharStyle:Code
4102 \begin_layout Plain Layout
4115 \begin_layout Standard
4116 \begin_inset listings
4120 \begin_layout Plain Layout
4122 function expand_chunk_args(text, params, args,
4125 \begin_layout Plain Layout
4127 p, text_array, next_text, v, t, l)
4130 \begin_layout Plain Layout
4135 \begin_layout Plain Layout
4137 if (split(text, text_array, "
4144 \begin_layout Plain Layout
4148 chunkref{substitute-chunk-args}>
4151 \begin_layout Plain Layout
4156 \begin_layout Plain Layout
4161 \begin_layout Plain Layout
4171 \begin_layout Standard
4172 First, we produce an associative array of substitution values indexed by
4177 substitute-chunk-args
4180 \begin_layout Standard
4181 \begin_inset listings
4185 \begin_layout Plain Layout
4190 \begin_layout Plain Layout
4192 v[params[p]]=args[p];
4195 \begin_layout Plain Layout
4205 \begin_layout Standard
4206 We accumulate substituted text in the variable
4207 \begin_inset Flex CharStyle:Code
4210 \begin_layout Plain Layout
4217 As the first part of the split function is the part before the delimiter
4219 \begin_inset Flex CharStyle:Code
4222 \begin_layout Plain Layout
4228 in our case --- this part will never contain a parameter reference, so
4229 we assign this directly to the result kept in
4230 \begin_inset Flex CharStyle:Code
4233 \begin_layout Plain Layout
4240 \begin_inset listings
4244 \begin_layout Plain Layout
4254 \begin_layout Standard
4255 We then iterate over the remaining values in the array
4259 \begin_layout Plain Layout
4260 I don't know why I think that it will enumerate the array in order, but
4267 \begin_inset Note Note
4270 \begin_layout Plain Layout
4271 So fix it or porve it
4276 , and substitute each reference for it's argument.
4279 \begin_layout Standard
4280 \begin_inset listings
4284 \begin_layout Plain Layout
4286 for(t in text_array) if (t>1) {
4289 \begin_layout Plain Layout
4293 chunkref{substitute-chunk-arg}>
4296 \begin_layout Plain Layout
4306 \begin_layout Standard
4308 \begin_inset Flex CharStyle:Code
4311 \begin_layout Plain Layout
4317 a valid parameter reference will consist of valid parameter name terminated
4319 \begin_inset Flex CharStyle:Code
4322 \begin_layout Plain Layout
4329 A valid character name begins with the underscore or a letter, and may
4330 contain letters, digits or underscores.
4333 \begin_layout Standard
4334 A valid looking reference that is not actually the name of a parameter will
4335 be and not substituted.
4336 This is good because there is nothing to substitute anyway, and it avoids
4337 clashes when writing code for languages where ${\SpecialChar \ldots{}
4338 } is a valid construct
4339 --- such constructs will not be interfered with unless the parameter name
4344 substitute-chunk-arg
4347 \begin_layout Standard
4348 \begin_inset listings
4352 \begin_layout Plain Layout
4354 if (match(text_array[t], "^([a-zA-Z_][a-zA-Z0-9_]*)}", l) &&
4357 \begin_layout Plain Layout
4362 \begin_layout Plain Layout
4367 \begin_layout Plain Layout
4369 text = text v[l[1]] substr(text_array[t], length(l[1])+2);
4372 \begin_layout Plain Layout
4377 \begin_layout Plain Layout
4379 text = text "${" text_array[t];
4382 \begin_layout Plain Layout
4392 \begin_layout Chapter
4396 \begin_layout Standard
4397 Newfangle recognizes noweb chunks, but as we also want better LaTeX integration
4398 we will recognize any of these:
4401 \begin_layout Itemize
4402 notangle chunks matching the pattern
4403 \begin_inset Flex CharStyle:Code
4406 \begin_layout Plain Layout
4408 \begin_inset space \hspace*{}
4413 \begin_inset space \hspace*{}
4425 \begin_layout Itemize
4426 a chunks beginning with
4427 \begin_inset Flex CharStyle:Code
4430 \begin_layout Plain Layout
4440 Chunk{\SpecialChar \ldots{}
4441 } on the previous line
4444 \begin_layout Itemize
4445 an older form I have used, beginning with
4446 \begin_inset Flex CharStyle:Code
4449 \begin_layout Plain Layout
4452 begin{Chunk}[options]
4457 --- also more suitable for plain LaTeX users
4461 \begin_layout Plain Layout
4462 Is there such a thing as plain LaTeX?
4470 \begin_layout Section
4474 \begin_layout Standard
4476 \begin_inset Flex CharStyle:Code
4479 \begin_layout Plain Layout
4485 is used to signify that we are processing a code chunk and not document.
4486 In such a state, input lines will be assigned to the current chunk; otherwise
4490 \begin_layout Subsection
4494 \begin_layout Standard
4495 Our current scheme is to recognize the new lstlisting chunks, but these
4496 may be preceded by a
4497 \begin_inset Flex CharStyle:Code
4500 \begin_layout Plain Layout
4508 command which in LyX is a more convenient way to pass the chunk name to
4510 \begin_inset Flex CharStyle:Code
4513 \begin_layout Plain Layout
4521 command, and a more visible way to specify other
4522 \begin_inset Flex CharStyle:Code
4525 \begin_layout Plain Layout
4534 \begin_layout Standard
4535 The arguments to the
4536 \begin_inset Flex CharStyle:Code
4539 \begin_layout Plain Layout
4547 command are a name, and then a comma-seperated list of key-value pairs
4549 \begin_inset Flex CharStyle:Code
4552 \begin_layout Plain Layout
4561 (In fact within the LaTeX
4562 \begin_inset Flex CharStyle:Code
4565 \begin_layout Plain Layout
4574 \begin_inset CommandInset ref
4576 reference "sub:The-chunk-command"
4581 \begin_inset Flex CharStyle:Code
4584 \begin_layout Plain Layout
4590 is prefixed to the argument which is then literally passed to
4591 \begin_inset Flex CharStyle:Code
4594 \begin_layout Plain Layout
4609 \begin_layout Standard
4610 \begin_inset listings
4614 \begin_layout Plain Layout
4623 \begin_layout Plain Layout
4633 Chunk{ *([^ ,}]*),?(.*)}", line)) {
4636 \begin_layout Plain Layout
4638 next_chunk_name = line[1];
4641 \begin_layout Plain Layout
4643 get_chunk_args(line[2], next_chunk_args);
4646 \begin_layout Plain Layout
4651 \begin_layout Plain Layout
4656 \begin_layout Plain Layout
4666 \begin_layout Standard
4667 We also make a basic attempt to parse the name out of the
4668 \begin_inset Flex CharStyle:Code
4671 \begin_layout Plain Layout
4675 \begin_inset space \hspace{}
4684 text, otherwise we fall back to the name found in the previous chunk command.
4685 This attempt is very basic and doesn't support commas or spaces or square
4686 brackets as part of the chunkname.
4688 \begin_inset Flex CharStyle:Code
4691 \begin_layout Plain Layout
4699 which is convenient for some users
4703 \begin_layout Plain Layout
4704 but not yet supported in the LaTeX macros
4710 \begin_inset Note Note
4713 \begin_layout Plain Layout
4722 \begin_layout Standard
4723 \begin_inset listings
4727 \begin_layout Plain Layout
4740 \begin_layout Plain Layout
4742 if (match($0, "}.*[[,] *name= *{? *([^], }]*)", line)) {
4745 \begin_layout Plain Layout
4750 \begin_layout Plain Layout
4755 \begin_layout Plain Layout
4757 new_chunk(next_chunk_name, next_chunk_args);
4760 \begin_layout Plain Layout
4765 \begin_layout Plain Layout
4770 \begin_layout Plain Layout
4775 \begin_layout Plain Layout
4785 \begin_layout Subsection
4789 \begin_layout Standard
4790 We recognize notangle style chunks too:
4797 \begin_layout Standard
4798 \begin_inset listings
4802 \begin_layout Plain Layout
4807 \begin_layout Plain Layout
4809 if (match($0, "^[<]<(.*)[>]>= *$", line)) {
4812 \begin_layout Plain Layout
4817 \begin_layout Plain Layout
4822 \begin_layout Plain Layout
4827 \begin_layout Plain Layout
4832 \begin_layout Plain Layout
4837 \begin_layout Plain Layout
4847 \begin_layout Section
4851 \begin_layout Standard
4852 Likewise, we need to recognize when a chunk ends.
4855 \begin_layout Subsection
4859 \begin_layout Standard
4861 \begin_inset Flex CharStyle:Code
4864 \begin_layout Plain Layout
4871 \begin_inset Flex CharStyle:Code
4874 \begin_layout Plain Layout
4880 is surrounded by square brackets so that when this document is processed,
4881 this chunk doesn't terminate early when the lstlistings package recognizes
4882 it's own end-string!
4883 \begin_inset Note Greyedout
4886 \begin_layout Plain Layout
4887 This doesn't make sense as the regex is anchored with ^, which this line
4888 does not begin with!
4894 \begin_inset Note Note
4897 \begin_layout Plain Layout
4910 \begin_layout Standard
4911 \begin_inset listings
4915 \begin_layout Plain Layout
4928 \begin_layout Plain Layout
4933 \begin_layout Plain Layout
4938 \begin_layout Plain Layout
4943 \begin_layout Plain Layout
4953 \begin_layout Subsection
4961 \begin_layout Standard
4962 \begin_inset listings
4966 \begin_layout Plain Layout
4971 \begin_layout Plain Layout
4976 \begin_layout Plain Layout
4981 \begin_layout Plain Layout
4991 \begin_layout Standard
4992 All other recognizers are only of effect if we are chunking; there's no
4993 point in looking at lines if they aren't part of a chunk, so we just ignore
4994 them as efficiently as we can.
5001 \begin_layout Standard
5002 \begin_inset listings
5006 \begin_layout Plain Layout
5008 ! chunking { next; }
5016 \begin_layout Section
5020 \begin_layout Standard
5021 Chunk contents are any lines read while
5022 \begin_inset Flex CharStyle:Code
5025 \begin_layout Plain Layout
5032 Some chunk contents are special in that they refer to other chunks, and
5033 will be replaced by the contents of these chunks when the file is generated.
5036 \begin_layout Standard
5037 \begin_inset CommandInset label
5039 name "sub:ORS-chunk-text"
5043 We add the output record separator
5044 \begin_inset Flex CharStyle:Code
5047 \begin_layout Plain Layout
5053 to the line now, because we will set
5054 \begin_inset Flex CharStyle:Code
5057 \begin_layout Plain Layout
5063 to the empty string when we generate the output
5067 \begin_layout Plain Layout
5068 So that we can print partial lines using
5069 \begin_inset Flex CharStyle:Code
5072 \begin_layout Plain Layout
5079 \begin_inset Flex CharStyle:Code
5082 \begin_layout Plain Layout
5100 \begin_layout Standard
5101 \begin_inset listings
5105 \begin_layout Plain Layout
5107 length(active_chunk) {
5110 \begin_layout Plain Layout
5114 chunkref{process-chunk}>
5117 \begin_layout Plain Layout
5127 \begin_layout Standard
5128 If a chunk just consisted of plain text, we could handle the chunk like
5133 process-chunk-simple
5136 \begin_layout Standard
5137 \begin_inset listings
5141 \begin_layout Plain Layout
5143 chunk_line(active_chunk, $0 ORS);
5151 \begin_layout Standard
5152 but in fact a chunk can include references to other chunks.
5153 Chunk includes are traditionally written as
5154 \begin_inset Flex CharStyle:Code
5157 \begin_layout Plain Layout
5163 , but we support other variations.
5166 \begin_layout Subsection
5167 \begin_inset CommandInset label
5169 name "sub:lstlistings-includes"
5176 \begin_layout Standard
5178 \begin_inset Flex CharStyle:Code
5181 \begin_layout Plain Layout
5184 lstset{escapeinside={=<}{>}}
5189 is set, then we can use
5190 \begin_inset Flex CharStyle:Code
5193 \begin_layout Plain Layout
5197 \begin_inset space \hspace{}
5208 \begin_inset Flex CharStyle:Code
5211 \begin_layout Plain Layout
5220 \begin_layout Enumerate
5221 it is a better mnemonic than
5222 \begin_inset Flex CharStyle:Code
5225 \begin_layout Plain Layout
5231 in that the = sign signifies equivalent or substitutability,
5234 \begin_layout Enumerate
5235 and because =< is not valid in C or in any language I can think of
5238 \begin_layout Enumerate
5239 and also because lstlistings doesn't like
5240 \begin_inset Flex CharStyle:Code
5243 \begin_layout Plain Layout
5249 as an end delimiter for the
5253 escape, so we must make do with a single
5254 \begin_inset Flex CharStyle:Code
5257 \begin_layout Plain Layout
5263 , which is better matched by
5264 \begin_inset Flex CharStyle:Code
5267 \begin_layout Plain Layout
5274 \begin_inset Flex CharStyle:Code
5277 \begin_layout Plain Layout
5286 \begin_layout Standard
5287 As each chunk line may contain more than one chunk include, we will split
5288 out chunk includes in an iterative fashion
5292 \begin_layout Plain Layout
5293 Contrary to our use of
5294 \begin_inset Flex CharStyle:Code
5297 \begin_layout Plain Layout
5303 when substituting parameters in chapter
5304 \begin_inset CommandInset ref
5306 reference "Here-we-split"
5318 \begin_layout Standard
5319 First, as long as the chunk contains a
5320 \begin_inset Flex CharStyle:Code
5323 \begin_layout Plain Layout
5331 command we take as much as we can up to the first
5332 \begin_inset Flex CharStyle:Code
5335 \begin_layout Plain Layout
5350 \begin_layout Standard
5351 \begin_inset listings
5355 \begin_layout Plain Layout
5360 \begin_layout Plain Layout
5365 \begin_layout Plain Layout
5370 \begin_layout Plain Layout
5388 )|)>|<<([a-zA-Z_][-a-zA-Z0-9_]*)>>)",
5391 \begin_layout Plain Layout
5398 \begin_layout Plain Layout
5403 \begin_layout Plain Layout
5405 chunklet = substr(chunk, 1, RSTART - 1);
5413 \begin_layout Standard
5414 We keep track of the indent count, by counting the number of literal characters
5416 We can then preserve this indent on each output line when multi-line chunks
5420 \begin_layout Standard
5421 We then process this first part literal text, and set the chunk which is
5422 still to be processed to be the text after the
5423 \begin_inset Flex CharStyle:Code
5426 \begin_layout Plain Layout
5434 command, which we will process next as we continue around the loop.
5437 \begin_layout Standard
5438 \begin_inset listings
5442 \begin_layout Plain Layout
5444 indent += length(chunklet);
5447 \begin_layout Plain Layout
5449 chunk_line(active_chunk, chunklet);
5452 \begin_layout Plain Layout
5454 chunk = substr(chunk, RSTART + RLENGTH);
5462 \begin_layout Standard
5463 We then consider the type of chunk command we have found, whether it is
5464 the newfangle style command beginning with
5465 \begin_inset Flex CharStyle:Code
5468 \begin_layout Plain Layout
5474 or the older notangle style beginning with
5475 \begin_inset Flex CharStyle:Code
5478 \begin_layout Plain Layout
5488 \begin_layout Standard
5489 Newfangle chunks may have parameters contained within square brackets.
5490 These will be matched in
5491 \begin_inset Flex CharStyle:Code
5494 \begin_layout Plain Layout
5500 and are considered at this stage of processing to be part of the name of
5501 the chunk to be included.
5504 \begin_layout Standard
5505 \begin_inset listings
5509 \begin_layout Plain Layout
5511 if (substr(line[1], 1, 1) == "=") {
5514 \begin_layout Plain Layout
5516 # chunk name up to }
5519 \begin_layout Plain Layout
5521 chunk_include(active_chunk, line[2] line[3], indent);
5524 \begin_layout Plain Layout
5526 } else if (substr(line[1], 1, 1) == "<") {
5529 \begin_layout Plain Layout
5531 chunk_include(active_chunk, line[4], indent);
5534 \begin_layout Plain Layout
5539 \begin_layout Plain Layout
5541 error("Unknown chunk fragment: " line[1]);
5544 \begin_layout Plain Layout
5554 \begin_layout Standard
5555 The loop will continue until there are no more chunkref statements in the
5556 text, at which point we process the final part of the chunk.
5559 \begin_layout Standard
5560 \begin_inset listings
5564 \begin_layout Plain Layout
5569 \begin_layout Plain Layout
5571 chunk_line(active_chunk, chunk);
5579 \begin_layout Standard
5580 \begin_inset CommandInset label
5586 We add the newline character as a chunklet on it's own, to make it easier
5587 to detect new lines and thus manage indentation when processing the output.
5590 \begin_layout Standard
5591 \begin_inset listings
5595 \begin_layout Plain Layout
5597 chunk_line(active_chunk, "
5607 \begin_layout Standard
5608 We will also permit a chunk-part number to follow in square brackets, so
5610 \begin_inset Flex CharStyle:Code
5613 \begin_layout Plain Layout
5616 chunkref{chunk-name[1]}>
5621 will refer to the first part only.
5622 This can make it easy to include a C function prototype in a header file,
5623 if the first part of the chunk is just the function prototype without the
5624 trailing semi-colon.
5625 The header file would include the prototype with the trailing semi-colon,
5629 \begin_layout LyX-Code
5632 chunkref{chunk-name[1]}>;
5635 \begin_layout Standard
5636 This is handled in section
5637 \begin_inset CommandInset ref
5639 reference "sub:Chunk-parts"
5646 \begin_layout Standard
5647 We should perhaps introduce a notion of language specific chunk options;
5648 so that perhaps we could specify:
5651 \begin_layout LyX-Code
5654 chunkref{chunk-name[function-declaration]}>;
5657 \begin_layout Standard
5658 which applies a transform
5659 \begin_inset Flex CharStyle:Code
5662 \begin_layout Plain Layout
5663 function-declaration
5668 to the chunk --- which in this case would extract a function prototype
5670 \begin_inset Note Note
5673 \begin_layout Plain Layout
5682 \begin_layout Chapter
5686 \begin_layout Standard
5687 At the start, first we set the default options.
5694 \begin_layout Standard
5695 \begin_inset listings
5699 \begin_layout Plain Layout
5704 \begin_layout Plain Layout
5709 \begin_layout Plain Layout
5714 \begin_layout Plain Layout
5719 \begin_layout Plain Layout
5729 \begin_layout Standard
5730 Then we use getopt the standard way, and null out ARGV afterwards in the
5738 \begin_layout Standard
5739 \begin_inset listings
5743 \begin_layout Plain Layout
5745 Optind = 1 # skip ARGV[0]
5748 \begin_layout Plain Layout
5750 while(getopt(ARGC, ARGV, "R:Ldhr")!=-1) {
5753 \begin_layout Plain Layout
5757 chunkref{handle-options}>
5760 \begin_layout Plain Layout
5765 \begin_layout Plain Layout
5767 for (i=1; i<Optind; i++) { ARGV[i]=""; }
5775 \begin_layout Standard
5776 This is how we handle our options:
5783 \begin_layout Standard
5784 \begin_inset listings
5788 \begin_layout Plain Layout
5790 if (Optopt == "R") root = Optarg;
5793 \begin_layout Plain Layout
5795 else if (Optopt == "r") root="";
5798 \begin_layout Plain Layout
5800 else if (Optopt == "L") linenos = 1;
5803 \begin_layout Plain Layout
5805 else if (Optopt == "d") debug = 1;
5808 \begin_layout Plain Layout
5810 else if (Optopt == "h") help();
5813 \begin_layout Plain Layout
5815 else if (Optopt == "?") help();
5823 \begin_layout Standard
5824 We do all of this at the beginning of the program
5831 \begin_layout Standard
5832 \begin_inset listings
5836 \begin_layout Plain Layout
5841 \begin_layout Plain Layout
5845 chunkref{constants}>
5848 \begin_layout Plain Layout
5852 chunkref{default-options}>
5855 \begin_layout Plain Layout
5859 \begin_layout Plain Layout
5863 chunkref{read-options}>
5866 \begin_layout Plain Layout
5876 \begin_layout Standard
5877 And have a simple help function
5884 \begin_layout Standard
5885 \begin_inset listings
5889 \begin_layout Plain Layout
5894 \begin_layout Plain Layout
5899 \begin_layout Plain Layout
5901 print " newfangle [-L] -R<rootname> [source.tex ...]"
5904 \begin_layout Plain Layout
5906 print " newfangle -r [source.tex ...]"
5909 \begin_layout Plain Layout
5911 print " If the filename, source.tex is not specified then stdin is used"
5914 \begin_layout Plain Layout
5919 \begin_layout Plain Layout
5921 print "-L causes the C statement: #line <lineno>
5928 \begin_layout Plain Layout
5930 print "-R causes the named root to be written to stdout"
5933 \begin_layout Plain Layout
5935 print "-r lists all roots in the file (even those used elsewhere)"
5938 \begin_layout Plain Layout
5943 \begin_layout Plain Layout
5953 \begin_layout Chapter
5954 Chunk Language Modes
5957 \begin_layout Standard
5958 \begin_inset Note Greyedout
5961 \begin_layout Plain Layout
5962 This feature is in-development and does not work yet
5968 \begin_inset Note Note
5971 \begin_layout Plain Layout
5980 \begin_layout Standard
5981 lstlistings and newfangle both recognize source languages, and perform some
5983 lstlistings can detect strings and comments within a language definition
5984 and perform suitable rendering, such as italics for comments, and visible-space
5988 \begin_layout Standard
5989 Newfangle similarly can recognize strings, and comments, etc, within a language,
5990 so that any chunks included with
5991 \begin_inset Flex CharStyle:Code
5994 \begin_layout Plain Layout
6002 can be suitably quoted.
6005 \begin_layout Standard
6006 For instance, consider this chunk with
6007 \begin_inset Flex CharStyle:Code
6010 \begin_layout Plain Layout
6020 example-perl,language=perl
6023 \begin_layout Standard
6024 \begin_inset listings
6028 \begin_layout Plain Layout
6038 \begin_layout Standard
6039 If it were included in a chunk with
6040 \begin_inset Flex CharStyle:Code
6043 \begin_layout Plain Layout
6053 example-sh,language=sh
6056 \begin_layout Standard
6057 \begin_inset listings
6061 \begin_layout Plain Layout
6065 chunkref{example-perl}>"
6073 \begin_layout Standard
6074 would need to generate output like this if it were to work:
6077 \begin_layout LyX-Code
6085 \begin_layout Standard
6086 See that the double quote " as part of the regex has been quoted with a
6087 slash to protect it from shell interpretation.
6090 \begin_layout Standard
6091 If that were then included in a chunk with
6092 \begin_inset Flex CharStyle:Code
6095 \begin_layout Plain Layout
6105 example-makefile,language=make
6108 \begin_layout Standard
6109 \begin_inset listings
6113 \begin_layout Plain Layout
6118 \begin_layout Plain Layout
6122 chunkref{example-sh}>
6130 \begin_layout Standard
6131 We would need the output to look like this --- note the $$:
6134 \begin_layout LyX-Code
6138 \begin_layout LyX-Code
6146 \begin_layout Standard
6147 In order to make this work, we need to define a mode-tracker for each supported
6148 language, that can detect the various quoting modes, and provide a transformati
6149 on that must be applied to any included text so that included text will
6150 be interpreted correctly after the additional interpolation that it will
6151 be subject to at run-time.
6154 \begin_layout Standard
6155 For example, the transformation for text to be inserted into sh double-quoted
6156 strings would be something like:
6159 \begin_layout LyX-Code
6183 \begin_layout Standard
6185 \begin_inset Flex CharStyle:Code
6188 \begin_layout Plain Layout
6199 \begin_layout Standard
6200 \begin_inset Note Note
6203 \begin_layout Plain Layout
6204 I don't think this example is true
6209 The mode tracker must also track nested mode-changes, as in this
6210 \begin_inset Flex CharStyle:Code
6213 \begin_layout Plain Layout
6222 \begin_layout LyX-Code
6223 echo "hello `id **`"
6226 \begin_layout Standard
6227 Any literal text inserted at the point marked ** would need to be escaped
6228 in all kinds of ways, including
6229 \begin_inset Flex CharStyle:Code
6232 \begin_layout Plain Layout
6239 First it would need escaping for the back-ticks `, and then for the double-quot
6243 \begin_layout Standard
6244 Escaping need not occur if the format and mode of the included chunk matches
6245 that of the including chunk, which would suggest that any back-ticks might
6246 need to be part of the included chunk and not including chunk
6247 \begin_inset Note Note
6250 \begin_layout Plain Layout
6251 or is it the other way around?
6259 \begin_layout Standard
6260 As each chunk is output a new mode tracker for that language is initialized
6261 in it's normal state.
6262 As text is output for that chunk the output mode is tracked.
6263 When a new chunk is included, a transformation appropriate to that mode
6264 is selected and pushed onto a stack of transformations.
6265 Any text to be output is first passed through this stack of transformations.
6268 \begin_layout Standard
6269 It remains to consider if the chunk-include function should return it's
6270 generated text so that the caller can apply any transformations (and formatting
6271 ), or if it should apply the stack of transformations itself.
6274 \begin_layout Standard
6275 Note that the transformed text should have the property of not being able
6276 to change the mode in the current chunk.
6279 \begin_layout Standard
6280 \begin_inset Note Note
6283 \begin_layout Plain Layout
6284 Note chunk parameters should probably also be transformed
6296 \begin_layout Standard
6297 \begin_inset listings
6301 \begin_layout Plain Layout
6303 function new_mode(language, mode) {
6306 \begin_layout Plain Layout
6308 mode["language"] = language;
6311 \begin_layout Plain Layout
6316 \begin_layout Plain Layout
6326 \begin_layout Standard
6327 Because awk functions cannot return an array, we must create the array first
6332 new-mode,params=language;mode
6335 \begin_layout Standard
6336 \begin_inset listings
6340 \begin_layout Plain Layout
6344 chunkref{awk-delete-array}(${mode})>
6347 \begin_layout Plain Layout
6349 new_mode(${language}, ${mode});
6357 \begin_layout Standard
6358 And for tracking modes, we dispatch to a mode-tracker action based on the
6366 \begin_layout Standard
6367 \begin_inset listings
6371 \begin_layout Plain Layout
6373 function track_mode(mode, text) {
6376 \begin_layout Plain Layout
6378 if (mode["language"] == "C") {
6381 \begin_layout Plain Layout
6385 chunkref{track-mode-C}>
6388 \begin_layout Plain Layout
6393 \begin_layout Plain Layout
6398 \begin_layout Plain Layout
6408 \begin_layout Standard
6409 For each mode, we look for a character that has the power to change the
6413 \begin_layout Standard
6418 \labelwidthstring 00.00.0000
6419 \begin_inset Quotes eld
6422 enters double-quote mode
6426 \labelwidthstring 00.00.0000
6427 ' enters single-quote mode
6431 \labelwidthstring 00.00.0000
6434 enters multi-line mode
6438 \labelwidthstring 00.00.0000
6439 # enters #define sub-mode, needs
6441 escaping end of line too
6445 \labelwidthstring 00.00.0000
6446 /* enters comment mode
6449 \begin_layout Standard
6450 In double-quote mode, escape
6453 \begin_inset Quotes eld
6459 \begin_layout Standard
6463 \begin_inset Quotes eld
6469 \begin_layout Standard
6470 \begin_inset Quotes eld
6476 \begin_layout Standard
6477 newline needs to close and re-open string or something
6480 \begin_layout Standard
6481 in single-quote mode escape
6484 \begin_inset Quotes eld
6494 \begin_layout Standard
6495 \begin_inset listings
6499 \begin_layout Plain Layout
6512 \begin_layout Standard
6513 \begin_inset listings
6517 \begin_layout Plain Layout
6521 chunkref{new_mode()}>
6529 \begin_layout Chapter
6530 Generating the output
6533 \begin_layout Standard
6534 We generate output by calling output_chunk, or listing the chunk names.
6541 \begin_layout Standard
6542 \begin_inset listings
6546 \begin_layout Plain Layout
6548 if (length(root)) output_chunk(root);
6551 \begin_layout Plain Layout
6553 else output_chunk_names();
6561 \begin_layout Standard
6562 We also have some other output debugging:
6569 \begin_layout Standard
6570 \begin_inset listings
6574 \begin_layout Plain Layout
6579 \begin_layout Plain Layout
6581 print "------ chunk names "
6584 \begin_layout Plain Layout
6586 output_chunk_names();
6589 \begin_layout Plain Layout
6591 print "====== chunks"
6594 \begin_layout Plain Layout
6599 \begin_layout Plain Layout
6601 print "++++++ debug"
6604 \begin_layout Plain Layout
6609 \begin_layout Plain Layout
6611 print a "=" chunks[a];
6614 \begin_layout Plain Layout
6619 \begin_layout Plain Layout
6629 \begin_layout Standard
6630 We do both of these at the end.
6632 \begin_inset Flex CharStyle:Code
6635 \begin_layout Plain Layout
6641 because each chunklet is not necessarily a complete line, and we already
6643 \begin_inset Flex CharStyle:Code
6646 \begin_layout Plain Layout
6652 to each input line in section
6653 \begin_inset CommandInset ref
6655 reference "sub:ORS-chunk-text"
6666 \begin_layout Standard
6667 \begin_inset listings
6671 \begin_layout Plain Layout
6676 \begin_layout Plain Layout
6680 chunkref{debug-output}>
6683 \begin_layout Plain Layout
6688 \begin_layout Plain Layout
6692 chunkref{generate-output}>
6695 \begin_layout Plain Layout
6705 \begin_layout Standard
6706 We write chunk names like this.
6707 If we seem to be running in notangle compatibility mode, then we enclose
6709 \begin_inset Flex CharStyle:Code
6712 \begin_layout Plain Layout
6718 the same way notangle does:
6722 output_chunk_names()
6725 \begin_layout Standard
6726 \begin_inset listings
6730 \begin_layout Plain Layout
6732 function output_chunk_names( c, prefix, suffix)
6735 \begin_layout Plain Layout
6740 \begin_layout Plain Layout
6742 if (notangle_mode) {
6745 \begin_layout Plain Layout
6750 \begin_layout Plain Layout
6755 \begin_layout Plain Layout
6760 \begin_layout Plain Layout
6762 for (c in chunk_names) {
6765 \begin_layout Plain Layout
6767 print prefix c suffix;
6770 \begin_layout Plain Layout
6775 \begin_layout Plain Layout
6785 \begin_layout Standard
6786 This function would write out all chunks
6793 \begin_layout Standard
6794 \begin_inset listings
6798 \begin_layout Plain Layout
6800 function output_chunks( a)
6803 \begin_layout Plain Layout
6808 \begin_layout Plain Layout
6810 for (a in chunk_names) {
6813 \begin_layout Plain Layout
6815 output_chunk(chunk_names[a]);
6818 \begin_layout Plain Layout
6823 \begin_layout Plain Layout
6828 \begin_layout Plain Layout
6832 \begin_layout Plain Layout
6834 function output_chunk(chunk) {
6837 \begin_layout Plain Layout
6842 \begin_layout Plain Layout
6844 lineno_needed = linenos;
6847 \begin_layout Plain Layout
6851 \begin_layout Plain Layout
6856 \begin_layout Plain Layout
6861 \begin_layout Plain Layout
6870 \begin_layout Section
6871 Assembling the chunks
6874 \begin_layout Standard
6875 \begin_inset Flex CharStyle:Code
6878 \begin_layout Plain Layout
6884 holds a string consisting of the names of all the chunks that resulted
6885 in this chunk being output.
6887 \begin_inset Note Note
6890 \begin_layout Plain Layout
6891 Make sure it includes the line numbers too...
6897 It should probably also contain the source line numbers at which each inclusion
6902 write_chunk(),emph={chunk_path}
6905 \begin_layout Standard
6906 \begin_inset listings
6910 \begin_layout Plain Layout
6912 function write_chunk(chunk_name, indent, tail,
6915 \begin_layout Plain Layout
6920 \begin_layout Plain Layout
6922 chunk_path, chunk_args,
6925 \begin_layout Plain Layout
6930 \begin_layout Plain Layout
6932 part, max_part, part_line, frag, max_frag, text,
6935 \begin_layout Plain Layout
6937 chunklet, only_part, call_chunk_args, mode)
6940 \begin_layout Plain Layout
6950 \begin_layout Subsection
6951 \begin_inset CommandInset label
6953 name "sub:Chunk-parts"
6960 \begin_layout Standard
6961 As mentioned in section
6962 \begin_inset CommandInset ref
6964 reference "sub:lstlistings-includes"
6968 , a chunk name may contain a part specifier in square brackets, limiting
6969 the parts that should be emitted.
6972 \begin_layout Standard
6973 \begin_inset listings
6977 \begin_layout Plain Layout
6979 if (match(chunk_name, "^(.*)
6987 ]$", chunk_name_parts)) {
6990 \begin_layout Plain Layout
6992 chunk_name = chunk_name_parts[1];
6995 \begin_layout Plain Layout
6997 only_part = chunk_name_parts[2];
7000 \begin_layout Plain Layout
7010 \begin_layout Standard
7011 We first create the mode tracker for this chunk.
7014 \begin_layout Standard
7015 \begin_inset listings
7019 \begin_layout Plain Layout
7023 chunkref{awk-delete-array}(mode)>
7026 \begin_layout Plain Layout
7028 new_mode(chunks[chunk_name, "language"], mode);
7036 \begin_layout Standard
7038 \begin_inset Flex CharStyle:Code
7041 \begin_layout Plain Layout
7047 the names of the parameters that this chunk accepts, whose values were
7048 (optionally) passed in
7049 \begin_inset Flex CharStyle:Code
7052 \begin_layout Plain Layout
7061 \begin_layout Standard
7062 \begin_inset listings
7066 \begin_layout Plain Layout
7068 split(chunks[chunk_name, "params"], chunk_params, " *; *");
7076 \begin_layout Standard
7077 To assemble a chunk, we write out each part.
7084 \begin_layout Standard
7085 \begin_inset listings
7089 \begin_layout Plain Layout
7091 if (! (chunk_name in chunk_names)) {
7094 \begin_layout Plain Layout
7096 error(sprintf(_"The root module <<%s>> was not defined.
7103 \begin_layout Plain Layout
7105 chunk_name, chunk_path));
7108 \begin_layout Plain Layout
7113 \begin_layout Plain Layout
7117 \begin_layout Plain Layout
7119 max_part = chunks[chunk_name, "part"];
7122 \begin_layout Plain Layout
7124 for(part = 1; part <= max_part; part++) {
7127 \begin_layout Plain Layout
7129 if (! only_part || part == only_part) {
7132 \begin_layout Plain Layout
7136 chunkref{write-part}>
7139 \begin_layout Plain Layout
7144 \begin_layout Plain Layout
7149 \begin_layout Plain Layout
7159 \begin_layout Standard
7160 A part can either be a chunklet of lines, or an include of another chunk.
7163 \begin_layout Standard
7164 Chunks may also have parameters, specified in LaTeX style with braces after
7165 the chunk name --- looking like this in the document:
7166 \begin_inset Flex CharStyle:Code
7169 \begin_layout Plain Layout
7170 chunkname{param1, param2}
7176 Arguments are passed in square brackets:
7177 \begin_inset Flex CharStyle:Code
7180 \begin_layout Plain Layout
7183 chunkref{chunkname}[arg1, arg2]
7191 \begin_layout Standard
7192 Before we process each part, we check that the source position hasn't changed
7193 unexpectedly, so that we can know if we need to output a new file-line
7201 \begin_layout Standard
7202 \begin_inset listings
7206 \begin_layout Plain Layout
7210 chunkref{check-source-jump}>
7213 \begin_layout Plain Layout
7217 \begin_layout Plain Layout
7219 chunklet = chunks[chunk_name, "part", part];
7222 \begin_layout Plain Layout
7224 if (chunks[chunk_name, "part", part, "type"] == part_type_chunk) {
7227 \begin_layout Plain Layout
7231 chunkref{write-included-chunk}>
7234 \begin_layout Plain Layout
7236 } else if (chunklet SUBSEP "line" in chunks) {
7239 \begin_layout Plain Layout
7243 chunkref{write-chunklets}>
7246 \begin_layout Plain Layout
7251 \begin_layout Plain Layout
7253 # empty last chunklet
7256 \begin_layout Plain Layout
7266 \begin_layout Standard
7267 To write an included chunk, we must detect any optional chunk arguments
7269 Then we recurse calling
7270 \begin_inset Flex Chunkref
7273 \begin_layout Plain Layout
7283 write-included-chunk
7286 \begin_layout Standard
7287 \begin_inset listings
7291 \begin_layout Plain Layout
7293 if (match(chunklet, "^([^
7305 )$", chunklet_parts)) {
7308 \begin_layout Plain Layout
7310 chunklet = chunklet_parts[1];
7313 \begin_layout Plain Layout
7315 split(chunklet_parts[2], call_chunk_args, " *, *");
7318 \begin_layout Plain Layout
7320 for (c in call_chunk_args) {
7323 \begin_layout Plain Layout
7325 call_chunk_args[c] = expand_chunk_args(call_chunk_args[c], chunk_params,
7329 \begin_layout Plain Layout
7334 \begin_layout Plain Layout
7339 \begin_layout Plain Layout
7343 chunkref{awk-delete-array}(call_chunk_args)>
7346 \begin_layout Plain Layout
7351 \begin_layout Plain Layout
7353 write_chunk(chunklet,
7356 \begin_layout Plain Layout
7358 chunks[chunk_name, "part", part, "indent"] indent,
7361 \begin_layout Plain Layout
7363 chunks[chunk_name, "part", part, "tail"],
7366 \begin_layout Plain Layout
7373 \begin_layout Plain Layout
7383 \begin_layout Standard
7384 Before we output a chunklet of lines, we first emit the file and line number
7385 if we have one, and if it is safe to do so.
7389 \begin_layout Standard
7390 Chunklets are generally broken up by includes, so the start of a chunklet
7391 is a good place to do this.
7392 Then we output each line of the chunklet.
7395 \begin_layout Standard
7396 When it is not safe, such as in the middle of a multi-line macro definition,
7398 \begin_inset Flex CharStyle:Code
7401 \begin_layout Plain Layout
7407 is set to true, and in such a case we note that we want to emit the line
7408 statement when it is next safe.
7415 \begin_layout Standard
7416 \begin_inset listings
7420 \begin_layout Plain Layout
7422 max_frag = chunks[chunklet, "line"];
7425 \begin_layout Plain Layout
7427 for(frag = 1; frag <= max_frag; frag++) {
7430 \begin_layout Plain Layout
7434 chunkref{write-file-line}>
7442 \begin_layout Standard
7443 We then extract the chunklet text and expand any arguments.
7446 \begin_layout Standard
7447 \begin_inset listings
7451 \begin_layout Plain Layout
7455 \begin_layout Plain Layout
7457 text = chunks[chunklet, frag];
7460 \begin_layout Plain Layout
7465 \begin_layout Plain Layout
7470 \begin_layout Plain Layout
7472 text = expand_chunk_args(text, chunk_params, chunk_args);
7480 \begin_layout Standard
7481 If the text is a single newline (which we keep separate - see
7482 \begin_inset CommandInset ref
7484 reference "lone-newline"
7488 ) then we increment the line number.
7489 In the case where this is the last line of a chunk and it is not a top-level
7490 chunk we replace the newline with an empty string --- because the chunk
7491 that included this chunk will have the newline at the end of the line that
7492 included this chunk.
7495 \begin_layout Standard
7497 \begin_inset Flex CharStyle:Code
7500 \begin_layout Plain Layout
7506 that we have started a new line, so that indentation can be managed with
7507 the following piece of text.
7510 \begin_layout Standard
7511 \begin_inset listings
7515 \begin_layout Plain Layout
7519 \begin_layout Plain Layout
7526 \begin_layout Plain Layout
7531 \begin_layout Plain Layout
7533 if (part == max_part && frag == max_frag && length(chunk_path)) {
7536 \begin_layout Plain Layout
7541 \begin_layout Plain Layout
7546 \begin_layout Plain Layout
7551 \begin_layout Plain Layout
7556 \begin_layout Plain Layout
7566 \begin_layout Standard
7567 If this text does not represent a newline, but we see that we are the first
7568 piece of text on a newline, then we prefix our text with the current indent.
7570 \begin_inset Flex CharStyle:Code
7573 \begin_layout Plain Layout
7579 is a global output-state variable, but the
7580 \begin_inset Flex CharStyle:Code
7583 \begin_layout Plain Layout
7593 \begin_layout Standard
7594 \begin_inset listings
7598 \begin_layout Plain Layout
7603 \begin_layout Plain Layout
7605 if (newline) text = indent text;
7608 \begin_layout Plain Layout
7613 \begin_layout Plain Layout
7618 \begin_layout Plain Layout
7627 \begin_layout Standard
7628 Tail will soon no longer be relevant once mode-detection is in place.
7631 \begin_layout Standard
7632 \begin_inset listings
7636 \begin_layout Plain Layout
7641 \begin_layout Plain Layout
7643 # track_mode(mode, text);
7646 \begin_layout Plain Layout
7656 \begin_layout Standard
7657 If a line ends in a backslash --- suggesting continuation --- then we supress
7658 outputting file-line as it would probably break the continued lines.
7662 \begin_layout Standard
7663 \begin_inset listings
7667 \begin_layout Plain Layout
7672 \begin_layout Plain Layout
7674 lineno_suppressed = substr(lastline, length(lastline)) == "
7681 \begin_layout Plain Layout
7686 \begin_layout Plain Layout
7696 \begin_layout Standard
7697 Of course there is no point in actually outputting the source filename and
7698 line number (file-line) if they don't say anything new! We only need to
7699 emit them if they aren't what is expected, or if we we not able to emit
7700 one when they had changed.
7707 \begin_layout Standard
7708 \begin_inset listings
7712 \begin_layout Plain Layout
7714 if (newline && lineno_needed && ! lineno_suppressed) {
7717 \begin_layout Plain Layout
7719 filename = a_filename;
7722 \begin_layout Plain Layout
7727 \begin_layout Plain Layout
7729 print "#line " lineno "
7738 \begin_layout Plain Layout
7743 \begin_layout Plain Layout
7753 \begin_layout Standard
7754 We check if a new file-line is needed by checking if the source line matches
7755 what we (or a compiler) would expect.
7763 \begin_layout Standard
7764 \begin_inset listings
7768 \begin_layout Plain Layout
7770 if (linenos && (chunk_name SUBSEP "part" SUBSEP part SUBSEP "FILENAME" in
7774 \begin_layout Plain Layout
7776 a_filename = chunks[chunk_name, "part", part, "FILENAME"];
7779 \begin_layout Plain Layout
7781 a_lineno = chunks[chunk_name, "part", part, "LINENO"];
7784 \begin_layout Plain Layout
7786 if (a_filename != filename || a_lineno != lineno) {
7789 \begin_layout Plain Layout
7794 \begin_layout Plain Layout
7799 \begin_layout Plain Layout
7809 \begin_layout Chapter
7813 \begin_layout Standard
7814 Awk has pretty limited data structures, so we will use two main hashes.
7815 Uninterrupted sequences of a chunk will be stored in
7816 \begin_inset Flex CharStyle:Code
7819 \begin_layout Plain Layout
7825 and the chunklets used in a chunk will be stored in
7826 \begin_inset Flex CharStyle:Code
7829 \begin_layout Plain Layout
7842 \begin_layout Standard
7843 \begin_inset listings
7847 \begin_layout Plain Layout
7857 \begin_layout Standard
7859 \begin_inset Flex CharStyle:Code
7862 \begin_layout Plain Layout
7868 mentioned are not chunk parameters for parameterized chunks, as mentioned
7870 \begin_inset CommandInset ref
7872 reference "cha:Chunk Arguments"
7876 , but the lstlistings style parameters used in the
7877 \begin_inset Flex CharStyle:Code
7880 \begin_layout Plain Layout
7892 \begin_layout Plain Layout
7894 \begin_inset Flex CharStyle:Code
7897 \begin_layout Plain Layout
7903 parameter is used to hold the parameters for parameterized chunks
7912 chunk-storage-functions
7915 \begin_layout Standard
7916 \begin_inset listings
7920 \begin_layout Plain Layout
7922 function new_chunk(chunk_name, params,
7925 \begin_layout Plain Layout
7930 \begin_layout Plain Layout
7935 \begin_layout Plain Layout
7940 \begin_layout Plain Layout
7942 # HACK WHILE WE CHANGE TO ( ) for PARAM CHUNKS
7945 \begin_layout Plain Layout
7955 )$", "", chunk_name);
7958 \begin_layout Plain Layout
7960 active_chunk = chunk_name;
7963 \begin_layout Plain Layout
7965 if (! (chunk_name in chunk_names)) {
7968 \begin_layout Plain Layout
7970 if (debug) print "New chunk " chunk_name;
7973 \begin_layout Plain Layout
7975 chunk_names[chunk_name];
7978 \begin_layout Plain Layout
7983 \begin_layout Plain Layout
7985 chunks[chunk_name, p] = params[p];
7988 \begin_layout Plain Layout
7993 \begin_layout Plain Layout
7998 \begin_layout Plain Layout
8000 prime_chunk(chunk_name);
8003 \begin_layout Plain Layout
8013 \begin_layout Standard
8014 \begin_inset listings
8018 \begin_layout Plain Layout
8022 \begin_layout Plain Layout
8024 function prime_chunk(chunk_name)
8027 \begin_layout Plain Layout
8032 \begin_layout Plain Layout
8034 chunks[chunk_name, "part", ++chunks[chunk_name, "part"] ] =
8039 \begin_layout Plain Layout
8041 chunk_name SUBSEP "chunklet" SUBSEP "" ++chunks[chunk_name, "chunklet"]
8045 \begin_layout Plain Layout
8047 chunks[chunk_name, "part", chunks[chunk_name, "part"], "FILENAME"] = FILENAME;
8050 \begin_layout Plain Layout
8052 chunks[chunk_name, "part", chunks[chunk_name, "part"], "LINENO"] = FNR
8056 \begin_layout Plain Layout
8061 \begin_layout Plain Layout
8065 \begin_layout Plain Layout
8067 function chunk_line(chunk_name, line){
8070 \begin_layout Plain Layout
8072 chunks[chunk_name, "chunklet", chunks[chunk_name, "chunklet"],
8075 \begin_layout Plain Layout
8077 ++chunks[chunk_name, "chunklet", chunks[chunk_name, "chunklet"],
8081 \begin_layout Plain Layout
8086 \begin_layout Plain Layout
8095 \begin_layout Standard
8096 Chunk include represents a
8100 statement, and stores the requirement to include another chunk.
8101 The parameter indent represents the quanity of literal text characters
8106 statement and therefore by how much additional lines of the included chunk
8110 \begin_layout Standard
8111 \begin_inset listings
8115 \begin_layout Plain Layout
8117 function chunk_include(chunk_name, chunk_ref, indent, tail)
8120 \begin_layout Plain Layout
8125 \begin_layout Plain Layout
8127 chunks[chunk_name, "part", ++chunks[chunk_name, "part"] ] = chunk_ref;
8130 \begin_layout Plain Layout
8132 chunks[chunk_name, "part", chunks[chunk_name, "part"], "type" ] = part_type_ch
8136 \begin_layout Plain Layout
8138 chunks[chunk_name, "part", chunks[chunk_name, "part"], "indent" ] = indent_str
8142 \begin_layout Plain Layout
8144 chunks[chunk_name, "part", chunks[chunk_name, "part"], "tail" ] = tail;
8147 \begin_layout Plain Layout
8149 prime_chunk(chunk_name);
8152 \begin_layout Plain Layout
8157 \begin_layout Plain Layout
8166 \begin_layout Standard
8167 The indent is calculated by indent_string, which may in future convert some
8168 spaces into tab characters.
8169 This function works by generating a printf padded format string, like
8170 \begin_inset Flex CharStyle:Code
8173 \begin_layout Plain Layout
8179 for an indent of 22, and then printing an empty string using that format.
8182 \begin_layout Standard
8183 \begin_inset listings
8187 \begin_layout Plain Layout
8189 function indent_string(indent) {
8192 \begin_layout Plain Layout
8194 return sprintf("%" indent "s", "");
8197 \begin_layout Plain Layout
8207 \begin_layout Chapter
8208 \begin_inset CommandInset label
8217 \begin_layout Standard
8218 I use Arnold Robbins public domain getopt (1993 revision).
8219 This is probably the same one that is covered in chapter 12 of
8220 \begin_inset Quotes eld
8223 Edition 3 of GAWK: Effective AWK Programming: A User's Guide for GNU Awk
8224 \begin_inset Quotes erd
8227 but as that is licensed under the GNU Free Documentation License, Version
8228 1.3, which conflicts with the GPL3, I can't use it from there (or it's accompany
8229 ing explanations), so I do my best to explain how it works here.
8232 \begin_layout Standard
8233 The getopt.awk header is:
8237 getopt.awk-header,language=awk,morestring=[b]{/},morekeywords=else
8240 \begin_layout Standard
8241 \begin_inset listings
8245 \begin_layout Plain Layout
8247 # getopt.awk --- do C library getopt(3) function in awk
8250 \begin_layout Plain Layout
8255 \begin_layout Plain Layout
8257 # Arnold Robbins, arnold@skeeve.com, Public Domain
8260 \begin_layout Plain Layout
8265 \begin_layout Plain Layout
8267 # Initial version: March, 1991
8270 \begin_layout Plain Layout
8272 # Revised: May, 1993
8280 \begin_layout Standard
8281 The provided explanation is:
8288 \begin_layout Standard
8289 \begin_inset listings
8293 \begin_layout Plain Layout
8295 # External variables:
8298 \begin_layout Plain Layout
8300 # Optind -- index in ARGV of first nonoption argument
8303 \begin_layout Plain Layout
8305 # Optarg -- string value of argument to current option
8308 \begin_layout Plain Layout
8310 # Opterr -- if nonzero, print our own diagnostic
8313 \begin_layout Plain Layout
8315 # Optopt -- current option letter
8318 \begin_layout Plain Layout
8322 \begin_layout Plain Layout
8327 \begin_layout Plain Layout
8329 # -1 at end of options
8332 \begin_layout Plain Layout
8334 # ? for unrecognized option
8337 \begin_layout Plain Layout
8339 # <c> a character representing the current option
8342 \begin_layout Plain Layout
8346 \begin_layout Plain Layout
8351 \begin_layout Plain Layout
8353 # _opti -- index in multi-flag option, e.g., -abc
8361 \begin_layout Standard
8362 The function follows.
8363 The final two parameters,
8364 \begin_inset Flex CharStyle:Code
8367 \begin_layout Plain Layout
8374 \begin_inset Flex CharStyle:Code
8377 \begin_layout Plain Layout
8383 are local variables and not parameters --- as indicated by the multiple
8384 spaces preceding them.
8385 Awk doesn't care, the multiple spaces are a convention to help us humans.
8392 \begin_layout Standard
8393 \begin_inset listings
8397 \begin_layout Plain Layout
8399 function getopt(argc, argv, options, thisopt, i)
8402 \begin_layout Plain Layout
8407 \begin_layout Plain Layout
8409 if (length(options) == 0) # no options given
8412 \begin_layout Plain Layout
8417 \begin_layout Plain Layout
8419 if (argv[Optind] == "--") { # all done
8422 \begin_layout Plain Layout
8427 \begin_layout Plain Layout
8432 \begin_layout Plain Layout
8437 \begin_layout Plain Layout
8439 } else if (argv[Optind] !~ /^-[^:
8454 \begin_layout Plain Layout
8459 \begin_layout Plain Layout
8464 \begin_layout Plain Layout
8469 \begin_layout Plain Layout
8474 \begin_layout Plain Layout
8479 \begin_layout Plain Layout
8481 thisopt = substr(argv[Optind], _opti, 1)
8484 \begin_layout Plain Layout
8489 \begin_layout Plain Layout
8491 i = index(options, thisopt)
8494 \begin_layout Plain Layout
8499 \begin_layout Plain Layout
8504 \begin_layout Plain Layout
8506 printf("%c -- invalid option
8511 \begin_layout Plain Layout
8513 thisopt) > "/dev/stderr"
8516 \begin_layout Plain Layout
8518 if (_opti >= length(argv[Optind])) {
8521 \begin_layout Plain Layout
8526 \begin_layout Plain Layout
8531 \begin_layout Plain Layout
8536 \begin_layout Plain Layout
8541 \begin_layout Plain Layout
8546 \begin_layout Plain Layout
8556 \begin_layout Standard
8557 At this point, the option has been found and we need to know if it takes
8561 \begin_layout Standard
8562 \begin_inset listings
8566 \begin_layout Plain Layout
8568 if (substr(options, i + 1, 1) == ":") {
8571 \begin_layout Plain Layout
8573 # get option argument
8576 \begin_layout Plain Layout
8578 if (length(substr(argv[Optind], _opti + 1)) > 0)
8581 \begin_layout Plain Layout
8583 Optarg = substr(argv[Optind], _opti + 1)
8586 \begin_layout Plain Layout
8591 \begin_layout Plain Layout
8593 Optarg = argv[++Optind]
8596 \begin_layout Plain Layout
8601 \begin_layout Plain Layout
8606 \begin_layout Plain Layout
8611 \begin_layout Plain Layout
8613 if (_opti == 0 || _opti >= length(argv[Optind])) {
8616 \begin_layout Plain Layout
8621 \begin_layout Plain Layout
8626 \begin_layout Plain Layout
8631 \begin_layout Plain Layout
8636 \begin_layout Plain Layout
8641 \begin_layout Plain Layout
8648 A test program is built in, too
8655 \begin_layout Standard
8656 \begin_inset listings
8660 \begin_layout Plain Layout
8665 \begin_layout Plain Layout
8667 Opterr = 1 # default is to diagnose
8670 \begin_layout Plain Layout
8672 Optind = 1 # skip ARGV[0]
8675 \begin_layout Plain Layout
8680 \begin_layout Plain Layout
8685 \begin_layout Plain Layout
8687 while ((_go_c = getopt(ARGC, ARGV, "ab:cd")) != -1)
8690 \begin_layout Plain Layout
8692 printf("c = <%c>, optarg = <%s>
8697 \begin_layout Plain Layout
8702 \begin_layout Plain Layout
8704 printf("non-option arguments:
8709 \begin_layout Plain Layout
8711 for (; Optind < ARGC; Optind++)
8714 \begin_layout Plain Layout
8723 \begin_layout Plain Layout
8725 Optind, ARGV[Optind])
8728 \begin_layout Plain Layout
8733 \begin_layout Plain Layout
8743 \begin_layout Standard
8744 The entire getopt.awk is made out of these chunks in order
8751 \begin_layout Standard
8752 \begin_inset listings
8756 \begin_layout Plain Layout
8760 chunkref{getopt.awk-header}>
8763 \begin_layout Plain Layout
8767 \begin_layout Plain Layout
8771 chunkref{getopt.awk-notes}>
8774 \begin_layout Plain Layout
8778 chunkref{getopt.awk-getopt()}>
8781 \begin_layout Plain Layout
8785 chunkref{getopt.awk-begin}>
8793 \begin_layout Standard
8794 Although we only want the header and function:
8801 \begin_layout Standard
8802 \begin_inset listings
8806 \begin_layout Plain Layout
8808 # try: locate getopt.awk for the full original file
8811 \begin_layout Plain Layout
8813 # as part of your standard awk installation
8816 \begin_layout Plain Layout
8820 chunkref{getopt.awk-header}>
8823 \begin_layout Plain Layout
8827 \begin_layout Plain Layout
8831 chunkref{getopt.awk-getopt()}>
8839 \begin_layout Chapter
8840 Newfangle LaTeX source code
8843 \begin_layout Section
8847 \begin_layout Standard
8848 Here we define a Lyx .module file that makes it convenient to use LyX for
8849 writing such literate programs.
8852 \begin_layout Standard
8854 \begin_inset Flex CharStyle:Code
8857 \begin_layout Plain Layout
8863 can be installed in your personal
8864 \begin_inset Flex CharStyle:Code
8867 \begin_layout Plain Layout
8874 You will need to Tools Reconfigure so that LyX notices it.
8875 It adds a new format Chunk, which should precede every listing and contain
8881 ./newfangle.module,language=
8884 \begin_layout Standard
8885 \begin_inset listings
8889 \begin_layout Plain Layout
8893 DeclareLyXModule{Newfangle Literate Listings}
8896 \begin_layout Plain Layout
8901 \begin_layout Plain Layout
8903 # Newfangle literate listings allow one to write
8906 \begin_layout Plain Layout
8908 # literate programs after the fashion of noweb, but without having
8911 \begin_layout Plain Layout
8913 # to use noweave to generate the documentation.
8914 Instead the listings
8917 \begin_layout Plain Layout
8919 # package is extended in conjunction with the noweb package to implement
8922 \begin_layout Plain Layout
8924 # to code formating directly as latex.
8927 \begin_layout Plain Layout
8929 # The newfangle awk script
8932 \begin_layout Plain Layout
8937 \begin_layout Plain Layout
8941 \begin_layout Plain Layout
8946 \begin_layout Plain Layout
8950 \begin_layout Plain Layout
8955 \begin_layout Plain Layout
8959 chunkref{./newfangle.sty}>
8962 \begin_layout Plain Layout
8967 \begin_layout Plain Layout
8971 \begin_layout Plain Layout
8975 chunkref{chunkstyle}>
8978 \begin_layout Plain Layout
8982 \begin_layout Plain Layout
8994 \begin_layout Subsection
8998 \begin_layout Standard
9003 style is to make it easier for LyX users to provide the name to
9004 \begin_inset Flex CharStyle:Code
9007 \begin_layout Plain Layout
9016 Normally this requires right-clicking on the listing, choosing settings,
9017 advanced, and then typing
9018 \begin_inset Flex CharStyle:Code
9021 \begin_layout Plain Layout
9028 This has the further disadvantage that the name (and other options) are
9029 not generally visible during document editing.
9032 \begin_layout Standard
9033 The chunk style is defined as a LaTeX command, so that all text on the same
9034 line is passed to the LaTeX command
9035 \begin_inset Flex CharStyle:Code
9038 \begin_layout Plain Layout
9045 This makes it easy to parse using
9046 \begin_inset Flex CharStyle:Code
9049 \begin_layout Plain Layout
9055 , and easy to pass these options on to the listings package.
9056 The first word in a chunk section should be the chunk name, and will have
9058 \begin_inset Flex CharStyle:Code
9061 \begin_layout Plain Layout
9068 Any other words are accepted arguments to
9069 \begin_inset Flex CharStyle:Code
9072 \begin_layout Plain Layout
9083 \begin_layout Standard
9084 We set PassThru to 1 because the user is actually entering raw latex.
9091 \begin_layout Standard
9092 \begin_inset listings
9096 \begin_layout Plain Layout
9101 \begin_layout Plain Layout
9106 \begin_layout Plain Layout
9111 \begin_layout Plain Layout
9113 Margin First_Dynamic
9116 \begin_layout Plain Layout
9118 LeftMargin Chunk:xxx
9121 \begin_layout Plain Layout
9126 \begin_layout Plain Layout
9131 \begin_layout Plain Layout
9133 LabelString "Chunk:"
9136 \begin_layout Plain Layout
9141 \begin_layout Plain Layout
9146 \begin_layout Plain Layout
9155 \begin_layout Standard
9156 To make the label very visible we choose a larger font coloured red.
9159 \begin_layout Standard
9160 \begin_inset listings
9164 \begin_layout Plain Layout
9169 \begin_layout Plain Layout
9174 \begin_layout Plain Layout
9179 \begin_layout Plain Layout
9184 \begin_layout Plain Layout
9189 \begin_layout Plain Layout
9194 \begin_layout Plain Layout
9199 \begin_layout Plain Layout
9209 \begin_layout Subsection
9213 \begin_layout Standard
9214 We also define the Chunkref style which can be used to express cross references
9222 \begin_layout Standard
9223 \begin_inset listings
9227 \begin_layout Plain Layout
9229 InsetLayout Chunkref
9232 \begin_layout Plain Layout
9237 \begin_layout Plain Layout
9242 \begin_layout Plain Layout
9247 \begin_layout Plain Layout
9252 \begin_layout Plain Layout
9257 \begin_layout Plain Layout
9262 \begin_layout Plain Layout
9267 \begin_layout Plain Layout
9272 \begin_layout Plain Layout
9282 \begin_layout Section
9283 \begin_inset CommandInset label
9285 name "sec:Latex-Macros"
9292 \begin_layout Standard
9306 As noweb defines it's own
9307 \begin_inset Flex CharStyle:Code
9310 \begin_layout Plain Layout
9318 environment, we re-define the one that LyX logical markup module expects
9323 ./newfangle.sty,language=tex,basicstyle=
9328 \begin_layout Standard
9329 \begin_inset listings
9333 \begin_layout Plain Layout
9337 usepackage{listings}%
9340 \begin_layout Plain Layout
9347 \begin_layout Plain Layout
9354 \begin_layout Plain Layout
9370 \begin_layout Standard
9372 \begin_inset Flex CharStyle:Code
9375 \begin_layout Plain Layout
9382 \begin_inset Flex CharStyle:Code
9385 \begin_layout Plain Layout
9393 which will need renaming to
9394 \begin_inset Flex CharStyle:Code
9397 \begin_layout Plain Layout
9405 when I can do this without clashing with
9406 \begin_inset Flex CharStyle:Code
9409 \begin_layout Plain Layout
9420 \begin_layout Standard
9421 \begin_inset listings
9425 \begin_layout Plain Layout
9429 lstnewenvironment{Chunk}{
9441 \begin_layout Standard
9442 We also define a suitable
9443 \begin_inset Flex CharStyle:Code
9446 \begin_layout Plain Layout
9454 of parameters that suit the literate programming style after the fashion
9462 \begin_layout Standard
9463 \begin_inset listings
9467 \begin_layout Plain Layout
9471 lstset{numbers=left, stepnumber=5, numbersep=5pt,
9474 \begin_layout Plain Layout
9476 breaklines=false,basicstyle=
9481 \begin_layout Plain Layout
9493 \begin_layout Standard
9494 We also define a notangle-like mechanism for
9498 to LaTeX from the listing, and by which we can refer to other listings.
9500 \begin_inset Flex CharStyle:Code
9503 \begin_layout Plain Layout
9504 =<\SpecialChar \ldots{}
9510 sequence to contain LaTeX code, and include another like this chunk:
9511 \begin_inset Flex CharStyle:Code
9514 \begin_layout Plain Layout
9517 chunkref{chunkname}>
9524 \begin_inset Flex CharStyle:Code
9527 \begin_layout Plain Layout
9528 =<\SpecialChar \ldots{}
9534 is already defined to contain LaTeX code for this document --- this is
9539 document after all --- the code fragment below effectively contains the
9541 \begin_inset Flex CharStyle:Code
9544 \begin_layout Plain Layout
9551 To avoid problems with document generation, I had to declare an lstlistings
9553 \begin_inset Flex CharStyle:Code
9556 \begin_layout Plain Layout
9562 for this listing only; which in LyX was done by right-clicking the listings
9564 \begin_inset Flex CharStyle:Code
9567 \begin_layout Plain Layout
9573 \SpecialChar \menuseparator
9575 \begin_inset Flex CharStyle:Code
9578 \begin_layout Plain Layout
9587 \begin_layout Standard
9588 \begin_inset Note Note
9591 \begin_layout Plain Layout
9592 =< isn't enjoyed literally here, in a listing when the escape sequence is
9593 already defined as shown...
9594 we need to somehow escape this representation...
9602 \begin_layout Standard
9603 \begin_inset listings
9604 lstparams "escapeinside={}"
9608 \begin_layout Plain Layout
9612 lstset{escapeinside={=<}{>}}%
9620 \begin_layout Standard
9621 Although our macros will contain the @ symbol, they will be included in
9623 \begin_inset Flex CharStyle:Code
9626 \begin_layout Plain Layout
9634 section by LyX; however we keep the commented out
9635 \begin_inset Flex CharStyle:Code
9638 \begin_layout Plain Layout
9647 The listings package likes to centre the titles, but noweb titles are specially
9648 formatted and must be left aligned.
9649 The simplest way to do this turned out to be by removing the definition
9651 \begin_inset Flex CharStyle:Code
9654 \begin_layout Plain Layout
9663 This may interact badly if other listings want a regular title or caption.
9664 We remember the old maketitle in case we need it.
9667 \begin_layout Standard
9668 \begin_inset listings
9672 \begin_layout Plain Layout
9679 \begin_layout Plain Layout
9681 %somehow re-defining maketitle gives us a left-aligned title
9684 \begin_layout Plain Layout
9686 %which is extactly what our specially formatted title needs!
9689 \begin_layout Plain Layout
9697 newfangle@lst@maketitle
9702 \begin_layout Plain Layout
9718 \begin_layout Subsection
9719 \begin_inset CommandInset label
9721 name "sub:The-chunk-command"
9728 \begin_layout Standard
9729 Our chunk command accepts one argument, and calls
9730 \begin_inset Flex CharStyle:Code
9733 \begin_layout Plain Layout
9743 \begin_inset Flex CharStyle:Code
9746 \begin_layout Plain Layout
9754 will note the name, this is erased when the next
9755 \begin_inset Flex CharStyle:Code
9758 \begin_layout Plain Layout
9766 starts, so we make a note of this in
9767 \begin_inset Flex CharStyle:Code
9770 \begin_layout Plain Layout
9778 and restore in in lstlistings Init hook.
9781 \begin_layout Standard
9782 \begin_inset listings
9786 \begin_layout Plain Layout
9795 \begin_layout Plain Layout
9801 newfanglecaption},name=#1}%
9804 \begin_layout Plain Layout
9817 \begin_layout Plain Layout
9822 \begin_layout Plain Layout
9838 \begin_layout Subsubsection
9842 \begin_layout Standard
9843 Newfangle permits parameterized chunks, and requires the paramters to be
9844 specified as listings options.
9845 The newfangle script uses this, and although we don't do anything with
9846 these in the LaTeX code right now, we need to stop the listings package
9850 \begin_layout Standard
9851 \begin_inset listings
9855 \begin_layout Plain Layout
9865 newfangle@chunk@params{#1}}%
9873 \begin_layout Subsection
9874 The noweb styled caption
9877 \begin_layout Standard
9878 We define a public macro
9879 \begin_inset Flex CharStyle:Code
9882 \begin_layout Plain Layout
9890 which can be set as a regular title.
9892 \begin_inset Flex CharStyle:Code
9895 \begin_layout Plain Layout
9904 \begin_inset Flex CharStyle:Code
9907 \begin_layout Plain Layout
9915 at the appriate time when the caption is emitted.
9918 \begin_layout Standard
9919 \begin_inset listings
9923 \begin_layout Plain Layout
9941 \begin_layout Standard
9942 \begin_inset Float figure
9948 \begin_layout Plain Layout
9949 \begin_inset Box Boxed
9958 height_special "totalheight"
9961 \begin_layout Plain Layout
9963 \begin_inset space \qquad{}
9971 \begin_inset Formula $\equiv+$
9975 \begin_inset space \qquad{}
9979 \begin_inset space \qquad{}
9983 \begin_inset space \qquad{}
9987 \begin_inset Formula $\triangleleft$
9991 \begin_inset space \quad{}
9995 \begin_inset Formula $\triangleright$
10001 \begin_layout Plain Layout
10004 In this example, the current chunk is 22c, and therefore the third chunk
10008 \begin_layout Plain Layout
10019 \begin_layout Plain Layout
10022 The first chunk with this name (19b) occurs as the second chunk on page
10026 \begin_layout Plain Layout
10029 The previous chunk (22d) with the same name is the second chunk on page
10033 \begin_layout Plain Layout
10036 The next chunk (24d) is the fourth chunk on page 24.
10039 \begin_layout Plain Layout
10040 \begin_inset Caption
10042 \begin_layout Plain Layout
10058 The general noweb output format compactly identifies the current chunk,
10059 and references to the first chunk, and the previous and next chunks that
10060 have the same name.
10064 \begin_layout Standard
10065 This means that we need to keep a counter for each chunk-name, that we use
10066 to count chunks of the same name.
10070 \begin_layout Subsection
10074 \begin_layout Standard
10075 It would be natural to have a counter for each chunk name, but TeX would
10076 soon run out of counters
10080 \begin_layout Plain Layout
10081 \SpecialChar \ldots{}
10086 run out of counters and so I had to re-write the LaTeX macros to share
10087 a counter as described here
10092 , so we have one counter which we save at the end of a chunk and restore
10093 at the beginning of a chunk.
10096 \begin_layout Standard
10097 \begin_inset listings
10101 \begin_layout Plain Layout
10105 newcounter{newfangle@chunkcounter}%
10113 \begin_layout Standard
10114 We construct the name of this variable to store the counter to be the text
10116 \begin_inset Flex CharStyle:Code
10119 \begin_layout Plain Layout
10125 prefixed onto the chunks own name, and store it in
10126 \begin_inset Flex CharStyle:Code
10129 \begin_layout Plain Layout
10141 \begin_layout Standard
10142 We save the counter like this:
10145 \begin_layout Chunk
10149 \begin_layout Standard
10150 \begin_inset listings
10154 \begin_layout Plain Layout
10170 arabic{newfangle@chunkcounter}}%
10178 \begin_layout Standard
10179 and restore the counter like this:
10182 \begin_layout Chunk
10186 \begin_layout Standard
10187 \begin_inset listings
10191 \begin_layout Plain Layout
10195 setcounter{newfangle@chunkcounter}{
10209 \begin_layout Chunk
10213 \begin_layout Standard
10214 If there does not already exist a variable whose name is stored in
10215 \begin_inset Flex CharStyle:Code
10218 \begin_layout Plain Layout
10226 , then we know we are the first chunk with this name, and then define a
10231 \begin_layout Standard
10232 Although chunks of the same name share a common counter, they must still
10234 We use is the internal name of the listing, suffixed by the counter value.
10235 So the first chunk might be
10236 \begin_inset Flex CharStyle:Code
10239 \begin_layout Plain Layout
10245 and the second chunk be
10246 \begin_inset Flex CharStyle:Code
10249 \begin_layout Plain Layout
10258 \begin_layout Standard
10259 We also calculate the name of the previous chunk if we can (before we increment
10260 the chunk counter).
10261 If this is the first chunk of that name, then
10262 \begin_inset Flex CharStyle:Code
10265 \begin_layout Plain Layout
10274 \begin_inset Flex CharStyle:Code
10277 \begin_layout Plain Layout
10285 which the noweb package will interpret as not existing.
10288 \begin_layout Standard
10289 \begin_inset listings
10293 \begin_layout Plain Layout
10299 newfangle@caption{%
10302 \begin_layout Plain Layout
10308 chunkcount{lst-chunk-
10313 \begin_layout Plain Layout
10322 \begin_layout Plain Layout
10337 \begin_layout Plain Layout
10341 setcounter{newfangle@chunkcounter}{
10350 \begin_layout Plain Layout
10361 \begin_layout Plain Layout
10366 \begin_layout Plain Layout
10370 setcounter{newfangle@chunkcounter}{
10379 \begin_layout Plain Layout
10389 arabic{newfangle@chunkcounter}}%
10392 \begin_layout Plain Layout
10402 \begin_layout Standard
10403 After incrementing the chunk counter, we then define the name of this chunk,
10404 as well as the name of the first chunk.
10407 \begin_layout Standard
10408 \begin_inset listings
10412 \begin_layout Plain Layout
10416 addtocounter{newfangle@chunkcounter}{1}%
10419 \begin_layout Plain Layout
10435 arabic{newfangle@chunkcounter}}%
10438 \begin_layout Plain Layout
10448 arabic{newfangle@chunkcounter}}%
10451 \begin_layout Plain Layout
10467 \begin_layout Standard
10468 We now need to calculate the name of the next chunk.
10469 We do this by temporarily skipping the counter on by one; however there
10470 may not actually be another chunk with this name! We detect this by also
10471 defining a label for each chunk based on the chunkname.
10472 If there is a next chunkname then it will define a label with that name.
10473 As labels are persistent, we can at least tell the second time LaTeX is
10475 If we don't find such a defined label then we define
10476 \begin_inset Flex CharStyle:Code
10479 \begin_layout Plain Layout
10488 \begin_inset Flex CharStyle:Code
10491 \begin_layout Plain Layout
10502 \begin_layout Standard
10503 \begin_inset listings
10507 \begin_layout Plain Layout
10511 addtocounter{newfangle@chunkcounter}{1}%
10514 \begin_layout Plain Layout
10524 arabic{newfangle@chunkcounter}}%
10527 \begin_layout Plain Layout
10531 @ifundefined{r@label-
10547 \begin_layout Standard
10548 The noweb package requires that we define a
10549 \begin_inset Flex CharStyle:Code
10552 \begin_layout Plain Layout
10560 for every chunk, with a unique name, which is then used to print out it's
10564 \begin_layout Standard
10565 We also define a regular label for this chunk, as was mentioned above when
10567 \begin_inset Flex CharStyle:Code
10570 \begin_layout Plain Layout
10579 This requires LaTeX to be run at least twice after new chunk sections are
10580 added --- but noweb requried that anyway.
10583 \begin_layout Standard
10584 \begin_inset listings
10588 \begin_layout Plain Layout
10597 \begin_layout Plain Layout
10599 % define this label for every chunk instance, so we
10602 \begin_layout Plain Layout
10604 % can tell when we are the last chunk of this name
10607 \begin_layout Plain Layout
10621 \begin_layout Standard
10622 We also try and add the chunk to the list of listings, but I'm afraid we
10623 don't do very well.
10624 We want each chunk name listing once, with all of it's references.
10627 \begin_layout Standard
10628 \begin_inset listings
10632 \begin_layout Plain Layout
10636 addcontentsline{lol}{lstlisting}{
10652 \begin_layout Standard
10653 We then call the noweb output macros in the same way that noweave generates
10654 them, except that we don't need to call
10655 \begin_inset Flex CharStyle:Code
10658 \begin_layout Plain Layout
10661 nwstartdeflinemarkup
10667 \begin_inset Flex CharStyle:Code
10670 \begin_layout Plain Layout
10678 -- and if we do it messes up the output somewhat.
10681 \begin_layout Standard
10682 \begin_inset listings
10686 \begin_layout Plain Layout
10693 \begin_layout Plain Layout
10698 \begin_layout Plain Layout
10705 \begin_layout Plain Layout
10714 \begin_layout Plain Layout
10719 \begin_layout Plain Layout
10724 \begin_layout Plain Layout
10729 \begin_layout Plain Layout
10736 \begin_layout Plain Layout
10743 \begin_layout Plain Layout
10748 \begin_layout Plain Layout
10757 \begin_layout Plain Layout
10761 @ifundefined{newfangle@chunk@params}{}{%
10764 \begin_layout Plain Layout
10768 newfangle@chunk@params)%
10771 \begin_layout Plain Layout
10776 \begin_layout Plain Layout
10787 \begin_layout Plain Layout
10796 \begin_layout Plain Layout
10801 \begin_layout Plain Layout
10806 \begin_layout Plain Layout
10811 \begin_layout Plain Layout
10830 \begin_layout Plain Layout
10834 nwstartdeflinemarkup%
10837 \begin_layout Plain Layout
10848 \begin_layout Plain Layout
10852 nwenddeflinemarkup%
10855 \begin_layout Plain Layout
10865 \begin_layout Standard
10866 Originally this was developed as a
10867 \begin_inset Flex CharStyle:Code
10870 \begin_layout Plain Layout
10876 aspect, in the Init hook, but it was found easier to affect the title without
10878 \begin_inset Flex CharStyle:Code
10881 \begin_layout Plain Layout
10884 lst@AddToHookExe{PreSet}
10889 is still required to set the listings name to the name passed to the
10890 \begin_inset Flex CharStyle:Code
10893 \begin_layout Plain Layout
10904 \begin_layout Standard
10905 \begin_inset listings
10909 \begin_layout Plain Layout
10913 lst@BeginAspect{newfangle}
10916 \begin_layout Plain Layout
10920 lst@Key{newfangle}{true}[t]{
10922 lstKV@SetIf{#1}{true}}
10925 \begin_layout Plain Layout
10929 lst@AddToHookExe{PreSet}{
10940 \begin_layout Plain Layout
10944 lst@AddToHook{Init}{}%
10949 \begin_layout Plain Layout
10961 \begin_layout Subsection
10965 \begin_layout Standard
10968 chunkref command which makes it easy to generate visual references to different
10972 \begin_layout Standard
10973 \begin_inset Tabular
10974 <lyxtabular version="3" rows="4" columns="2">
10976 <column alignment="center" valignment="top" width="0">
10977 <column alignment="center" valignment="top" width="0">
10979 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
10982 \begin_layout Plain Layout
10988 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
10991 \begin_layout Plain Layout
10999 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
11002 \begin_layout Plain Layout
11010 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
11013 \begin_layout Plain Layout
11017 \begin_layout Plain Layout
11033 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
11036 \begin_layout Plain Layout
11039 chunkref[3]{preamble}
11044 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
11047 \begin_layout Plain Layout
11051 \begin_layout Plain Layout
11055 chunkref[3]{preamble}
11067 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
11070 \begin_layout Plain Layout
11073 chunkref{preamble}[arg1, arg2]
11078 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
11081 \begin_layout Plain Layout
11085 \begin_layout Plain Layout
11089 chunkref{preamble}[arg1, arg2]
11107 \begin_layout Standard
11108 Chunkref can also be used within a code chunk to include another code chunk.
11109 The third optional parameter to chunkref is a comma sepatarated list of
11110 arguments, which will replace defined parameters in the chunkref.
11111 \begin_inset Note Note
11114 \begin_layout Plain Layout
11115 Darn it, if I have: =<
11117 chunkref{new-mode}[{chunks[chunk_name, "language"]},{mode}]> the inner braces
11118 (inside [ ]) cause _ to signify subscript even though we have lst@ReplaceIn
11126 \begin_layout Standard
11127 \begin_inset listings
11131 \begin_layout Plain Layout
11140 \begin_layout Plain Layout
11149 \begin_layout Plain Layout
11160 \begin_layout Plain Layout
11167 \begin_layout Plain Layout
11178 \begin_layout Plain Layout
11183 \begin_layout Plain Layout
11192 \begin_layout Plain Layout
11198 chunkref@i{#1}{#2}}{
11200 chunkref@i{#1}{#2}()}%
11203 \begin_layout Plain Layout
11208 \begin_layout Plain Layout
11214 chunkref@i#1#2(#3){%
11217 \begin_layout Plain Layout
11226 \begin_layout Plain Layout
11235 \begin_layout Plain Layout
11244 \begin_layout Plain Layout
11253 \begin_layout Plain Layout
11264 \begin_layout Plain Layout
11273 \begin_layout Plain Layout
11280 \begin_layout Plain Layout
11291 \begin_layout Plain Layout
11298 \begin_layout Plain Layout
11309 \begin_layout Plain Layout
11320 \begin_layout Plain Layout
11329 \begin_layout Plain Layout
11336 \begin_layout Plain Layout
11341 \begin_layout Plain Layout
11350 \begin_layout Plain Layout
11361 \begin_layout Plain Layout
11368 \begin_layout Plain Layout
11375 \begin_layout Plain Layout
11382 \begin_layout Plain Layout
11393 \begin_layout Plain Layout
11400 \begin_layout Plain Layout
11404 chunkref@args #3,)%
11407 \begin_layout Plain Layout
11414 \begin_layout Plain Layout
11423 \begin_layout Plain Layout
11428 \begin_layout Plain Layout
11433 \begin_layout Plain Layout
11442 \begin_layout Plain Layout
11452 \begin_layout Subsection
11456 \begin_layout Standard
11457 \begin_inset listings
11461 \begin_layout Plain Layout
11466 \begin_layout Plain Layout
11478 \begin_layout Chapter
11479 Extracting newfangle
11482 \begin_layout Section
11483 Extracting from Lyx
11486 \begin_layout Standard
11487 To extract from LyX, you will need to configure LyX as explained in section
11489 \begin_inset CommandInset ref
11491 reference "sub:Configuring-the-build"
11498 \begin_layout Standard
11499 \begin_inset CommandInset label
11501 name "lyx-build-script"
11505 And this lyx-build scrap will extract newfangle for me.
11508 \begin_layout Chunk
11509 lyx-build,language=sh
11512 \begin_layout Standard
11513 \begin_inset listings
11517 \begin_layout Plain Layout
11522 \begin_layout Plain Layout
11527 \begin_layout Plain Layout
11531 \begin_layout Plain Layout
11535 chunkref{lyx-build-helper}>
11538 \begin_layout Plain Layout
11540 cd $PROJECT_DIR || exit 1
11543 \begin_layout Plain Layout
11547 \begin_layout Plain Layout
11549 /usr/local/bin/newfangle -R./newfangle $TEX_SRC > ./newfangle
11552 \begin_layout Plain Layout
11554 /usr/local/bin/newfangle -R./newfangle.module $TEX_SRC > ./newfangle.module
11562 \begin_layout Standard
11563 With a lyx-build-helper
11566 \begin_layout Chunk
11567 lyx-build-helper,language=sh
11570 \begin_layout Standard
11571 \begin_inset listings
11575 \begin_layout Plain Layout
11577 PROJECT_DIR="$LYX_r"
11580 \begin_layout Plain Layout
11582 LYX_SRC="$PROJECT_DIR/${LYX_i%.tex}.lyx"
11585 \begin_layout Plain Layout
11590 \begin_layout Plain Layout
11592 TEX_SRC="$TEX_DIR/$LYX_i"
11600 \begin_layout Section
11601 Extracting from the command line
11604 \begin_layout Standard
11605 First you will need the tex output, then you can extract:
11608 \begin_layout Chunk
11609 lyx-build-manual,language=sh
11612 \begin_layout Standard
11613 \begin_inset listings
11617 \begin_layout Plain Layout
11619 lyx -e latex newfangle.lyx
11622 \begin_layout Plain Layout
11624 newfangle -R./newfangle newfangle.tex > ./newfangle
11627 \begin_layout Plain Layout
11629 newfangle -R./newfangle.module newfangle.tex > ./newfangle.module
11641 \begin_layout Chapter
11645 \begin_layout Chunk
11646 tests-sub,params=THING;colour
11649 \begin_layout Standard
11650 \begin_inset listings
11654 \begin_layout Plain Layout
11656 I see a ${THING} of
11659 \begin_layout Plain Layout
11664 \begin_layout Plain Layout
11668 chunkref{tests-sub-sub}(${colour})>
11676 \begin_layout Chunk
11677 tests-sub-sub,params=colour
11680 \begin_layout Standard
11681 \begin_inset listings
11685 \begin_layout Plain Layout
11687 a funny shade of ${colour}
11695 \begin_layout Chunk
11699 \begin_layout Standard
11700 \begin_inset listings
11704 \begin_layout Plain Layout
11706 What do you see? "=<
11708 chunkref{tests-sub}({joej_joe[hi],red})>"
11711 \begin_layout Plain Layout
11721 \begin_layout Standard
11722 Should generate output:
11725 \begin_layout Chunk
11729 \begin_layout Standard
11730 \begin_inset listings
11734 \begin_layout Plain Layout
11736 What do you see? "I see a joe of
11739 \begin_layout Plain Layout
11744 \begin_layout Plain Layout
11746 looking closer a funny shade of red"
11749 \begin_layout Plain Layout
11754 \begin_layout Plain Layout