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 complicati
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 indentation when using -L for
184 \begin_layout Standard
185 Significantly, newfangle is just one program which replaces various programs
187 Specifically noweave is done away with and implemented directly as LaTeX
188 macros, and noroots is implemented as a function of the untangler
195 \begin_layout Standard
196 Newfangle is written in awk for portability reasons, awk being available
198 A python conversion will probably be attempted for the benefit of LyX.
199 (Hasn't anyone implemented awk in python yet?)
202 \begin_layout Section*
206 \begin_layout Enumerate
207 ^^ is always going to be a problem, see texbytopic 1.2.2 (Work out what I
211 \begin_layout Enumerate
212 copy over up to date Makefile guide from noweb-lyx document
215 \begin_layout Enumerate
216 Make chunk-name settings only apply to chunks with that name
219 \begin_layout Enumerate
220 indent of multi-line chunks may be mode dependant (i.e.
221 not in string literals)
224 \begin_layout Enumerate
225 support chunk-param usage =<
230 \begin_layout Enumerate
231 trim spaces from param
234 \begin_layout Enumerate
235 add support for other commands in =<...>, starting with
237 label which takes the line-number within the chunk, and maybe should also
238 take the chunk name/page
241 \begin_layout Enumerate
242 cant have listing inside a ruled box
245 \begin_layout Enumerate
246 when a parameterized chunk is included as well as the #line emission, say
247 what the paremeters were for that invocation.
250 \begin_layout Enumerate
251 with 2 macro expansions on one line ${} ${} the first is too greedy and
255 \begin_layout Enumerate
258 chunkref[3]{preamble} to include a certain chunk needs to work in newfangle.awk
259 instead of failing to be recognized at all
262 \begin_layout Enumerate
263 make in-listins labels track the chunk ref too, and make
265 chunref{[2],thing}> resolve to 41c (or d, or whatever chunk the 2nd chunk
269 \begin_layout Enumerate
272 chunkref in text needs a trailing space maybe, it keeps butting up to the
276 \begin_layout Enumerate
277 because the white-space indent is output by the parent chunk, the #line
278 is that of the parent chunk.
279 White space indents must be passed to the child chunk
282 \begin_layout Chapter*
286 \begin_layout Standard
287 \begin_inset CommandInset label
293 Newfangle is licensed under the GPL 3
294 \begin_inset CommandInset citation
301 This doesn't mean that you can't use or distribute newfangle with sources
302 of an incompatible license, but it means you must make the source of newfangle
307 gpl3-copyright,language=
310 \begin_layout Standard
311 \begin_inset listings
315 \begin_layout Plain Layout
317 #newfangle - fully featured notangle replacement in awk
320 \begin_layout Plain Layout
325 \begin_layout Plain Layout
327 #Copyright (C) Sam Liddicott 2009
330 \begin_layout Plain Layout
335 \begin_layout Plain Layout
337 #This program is free software: you can redistribute it and/or modify
340 \begin_layout Plain Layout
342 #it under the terms of the GNU General Public License as published by
345 \begin_layout Plain Layout
347 #the Free Software Foundation, either version 3 of the License, or
350 \begin_layout Plain Layout
352 #(at your option) any later version.
355 \begin_layout Plain Layout
360 \begin_layout Plain Layout
362 #This program is distributed in the hope that it will be useful,
365 \begin_layout Plain Layout
367 #but WITHOUT ANY WARRANTY; without even the implied warranty of
370 \begin_layout Plain Layout
372 #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
376 \begin_layout Plain Layout
378 #GNU General Public License for more details.
381 \begin_layout Plain Layout
386 \begin_layout Plain Layout
388 #You should have received a copy of the GNU General Public License
391 \begin_layout Plain Layout
393 #along with this program.
394 If not, see <http://www.gnu.org/licenses/>.
402 \begin_layout Standard
403 \begin_inset CommandInset toc
404 LatexCommand tableofcontents
415 \begin_layout Chapter
419 \begin_layout Standard
420 Newfangle is a replacement for noweb, which consists of
421 \begin_inset Flex CharStyle:Code
424 \begin_layout Plain Layout
431 \begin_inset Flex CharStyle:Code
434 \begin_layout Plain Layout
441 \begin_inset Flex CharStyle:Code
444 \begin_layout Plain Layout
453 \begin_layout Standard
455 \begin_inset Flex CharStyle:Code
458 \begin_layout Plain Layout
465 \begin_inset Flex CharStyle:Code
468 \begin_layout Plain Layout
474 it can read multiple named files, or from stdin.
477 \begin_layout Section
481 \begin_layout Standard
482 The -r option causes newfangle to behave like noroots.
485 \begin_layout LyX-Code
486 newfangle -r filename.tex
489 \begin_layout Standard
490 will print out the newfangle roots of a tex file.
494 \begin_layout Standard
496 \begin_inset Flex CharStyle:Code
499 \begin_layout Plain Layout
505 command, the roots are not enclosed in
506 \begin_inset Flex CharStyle:Code
509 \begin_layout Plain Layout
515 , unless at least one of the roots is defined using the
516 \begin_inset Flex CharStyle:Code
519 \begin_layout Plain Layout
526 \begin_inset Flex CharStyle:Code
529 \begin_layout Plain Layout
538 \begin_layout Standard
539 Also, unlike noroots, it prints out all roots --- not just those that are
541 I find that a root not being used, doesn't make it particularly top level.
542 My convention is that top level roots to be extracted begin with
543 \begin_inset Flex CharStyle:Code
546 \begin_layout Plain Layout
552 and have the form of a filename.
555 \begin_layout Section
559 \begin_layout Standard
561 \begin_inset Flex CharStyle:Code
564 \begin_layout Plain Layout
571 \begin_inset Flex CharStyle:Code
574 \begin_layout Plain Layout
580 options are supported.
583 \begin_layout Standard
584 The standard way to extract a file would be:
587 \begin_layout LyX-Code
588 newfangle -R./Makefile.inc newfangle.tex > ./Makefile.inc
591 \begin_layout Standard
593 \begin_inset Flex CharStyle:Code
596 \begin_layout Plain Layout
603 \begin_inset Flex CharStyle:Code
606 \begin_layout Plain Layout
612 option does not break indenting; also the
613 \begin_inset Flex CharStyle:Code
616 \begin_layout Plain Layout
622 option does not interrupt (and break) multi-line C macros --- or indeed
623 any line ending with a backslash.
624 This does mean that sometimes the compiler might calculate the source line
625 wrongly when generating error messages in such cases, but there isn't any
626 other way around if multi-line macros include other chunks.
629 \begin_layout Section
630 Formatting source in LaTeX
633 \begin_layout Standard
634 The noweave replacement is a set of LaTeX macros dependant upon
638 , and which can be included with:
641 \begin_layout LyX-Code
644 usepackage{newfangle.sty}
647 \begin_layout Standard
648 The LaTeX macros are shown in section
649 \begin_inset CommandInset ref
651 reference "sec:Latex-Macros"
655 , and are part of a LyX module file
656 \begin_inset Flex CharStyle:Code
659 \begin_layout Plain Layout
665 , which automatically includes the macros in the document pre-amble when
666 the newfangle LyX module is used.
669 \begin_layout Standard
670 Because the noweave replacement is impemented in LaTeX, there is no processing
671 stage required before running the
672 \begin_inset Flex CharStyle:Code
675 \begin_layout Plain Layout
682 LaTeX may need running two or more times, so that the code chunk references
683 can be fully calculated.
686 \begin_layout Standard
688 \begin_inset Flex CharStyle:Code
691 \begin_layout Plain Layout
697 package is required as it is used for formatting the code chunk captions
700 \begin_layout Standard
702 \begin_inset Flex CharStyle:Code
705 \begin_layout Plain Layout
711 package is also required, as it is used for formatting the code chunks
715 \begin_layout Standard
717 \begin_inset Flex CharStyle:Code
720 \begin_layout Plain Layout
726 package is also required.
729 \begin_layout Chapter
730 Literate Programming with Newfangle
733 \begin_layout Standard
735 Should really follow on from a part-0 explanation of what literate programming
739 \begin_layout Chapter
740 Using Newfangle with LyX
743 \begin_layout Section
747 \begin_layout Subsection
748 Installing the LyX module
751 \begin_layout Standard
753 \begin_inset Flex CharStyle:Code
756 \begin_layout Plain Layout
762 to your LyX layouts directory, which for unix users will be
763 \begin_inset Flex CharStyle:Code
766 \begin_layout Plain Layout
775 \begin_layout Standard
776 You will need to reconfigure LyX by clicking Tools\SpecialChar \menuseparator
777 Reconfigure, and then
781 \begin_layout Subsection
782 \begin_inset CommandInset label
784 name "sub:Configuring-the-build"
788 Configuring the build script
791 \begin_layout Standard
792 Make sure you don't have a conversion defined for Lyx → Program
795 \begin_layout Standard
796 From the menu Tools\SpecialChar \menuseparator
797 Preferences, add a conversion from Latex(Plain) → Program
801 \begin_layout LyX-Code
802 set -x ; newfangle -Rlyx-build $$i |
805 \begin_layout LyX-Code
806 env LYX_b=$$b LYX_i=$$i LYX_o=$$o LYX_p=$$p LYX_r=$$r bash
809 \begin_layout Standard
810 (But don't cut-n-paste it from this document or you'll be pasting a multi-line
811 string which will break your lyx preferences file).
815 \begin_layout Standard
816 I hope that one day, LyX will set these into the environment when calling
820 \begin_layout Standard
821 You may also want to consider adding options to this conversion\SpecialChar \ldots{}
825 \begin_layout LyX-Code
826 parselog=/usr/share/lyx/scripts/listerrors
829 \begin_layout Standard
830 \SpecialChar \ldots{}
831 but if you do you will lose your stderr
835 \begin_layout Plain Layout
836 There is some bash plumbing to get a copy of stderr but this footnote is
845 \begin_layout Standard
846 Now, a shell script chunk called
847 \begin_inset Flex CharStyle:Code
850 \begin_layout Plain Layout
856 will be extracted and run whenever you choose the Document\SpecialChar \menuseparator
861 \begin_layout Standard
862 The lyx-build script for this document is in section
863 \begin_inset CommandInset ref
865 reference "lyx-build-script"
869 and on a unix system will extract
870 \begin_inset Flex CharStyle:Code
873 \begin_layout Plain Layout
880 \begin_inset Flex CharStyle:Code
883 \begin_layout Plain Layout
892 \begin_layout Subsection
893 Preparing your Lyx document
896 \begin_layout Standard
897 It is not necessary to base your literate document on any of the original
898 LyX literate classes; so select a regular class for your document type.
901 \begin_layout Standard
917 \begin_layout Standard
918 In the drop-down style listbox you should notice a new style defined, called
926 \begin_layout Standard
927 When you wish to insert a literate chunk, you enter it's plain name in the
928 Chunk style, instead of the older method that used
929 \begin_inset Flex CharStyle:Code
932 \begin_layout Plain Layout
939 Following the chunk name, you insert a listing with: Insert\SpecialChar \menuseparator
943 \begin_layout Standard
944 Inside the white listing box you can type (or paste using shift+ctrl+V)
946 There is not need to use ctrl+enter at the end of lines as with some older
947 LyX literate techniques --- just press enter as normal.
950 \begin_layout Subsubsection
951 Customising the listing appearance
954 \begin_layout Standard
955 In the final document, the code is formatted using the
960 The chunk style doesn't just define the chunk name, but can also define
961 any other chunk options supported by the lstlistings package
962 \begin_inset Flex CharStyle:Code
965 \begin_layout Plain Layout
974 In fact, what you type in the chunk style is raw latex.
975 If you want to set the chunk language without having to right-click the
977 \begin_inset Flex CharStyle:Code
980 \begin_layout Plain Layout
986 after the chunk name.
989 \begin_layout Standard
990 Of course you can do this by editing the listings box advanced properties
991 by right-clicking on the listings box, but that takes longer, and you can't
992 see at-a-glance what the advanced settings are while editing the document;
993 also advanced settings apply only to that box --- the chunk settings apply
994 through the rest of the document
998 \begin_layout Plain Layout
999 It ought to apply only to subsequent chunks of the same name.
1006 \begin_inset Note Note
1009 \begin_layout Plain Layout
1010 So make sure they only apply to chunks of that name
1018 \begin_layout Subsubsection
1019 Global customisations
1022 \begin_layout Standard
1027 is used to set the code chunks, it's
1028 \begin_inset Flex CharStyle:Code
1031 \begin_layout Plain Layout
1039 command can be used in the pre-amble to set some document wide settings.
1042 \begin_layout Standard
1043 If your source has many words with long sequences of capital letters, then
1045 \begin_inset Flex CharStyle:Code
1048 \begin_layout Plain Layout
1049 columns=fullflexible
1054 may be a good idea, or the capital letters will get crowded.
1055 (I think lstlistings ought to use a slightly smaller font for captial letters
1056 so that they still fit).
1059 \begin_layout Standard
1061 \begin_inset Flex CharStyle:Code
1064 \begin_layout Plain Layout
1072 looks more normal for code, but has no bold (unless luximono is used, but
1073 it doesn't work for me); so I use
1074 \begin_inset Flex CharStyle:Code
1077 \begin_layout Plain Layout
1087 \begin_inset Flex CharStyle:Code
1090 \begin_layout Plain Layout
1099 \begin_inset Flex CharStyle:Code
1102 \begin_layout Plain Layout
1103 columns=fullflexible
1108 is used or the wrong letter spacing is used.
1111 \begin_layout Standard
1112 In my LeTeX pre-amble I usually specialise my code format with:
1116 document-preamble,language=tex
1119 \begin_layout Standard
1120 \begin_inset listings
1124 \begin_layout Plain Layout
1131 \begin_layout Plain Layout
1135 definecolor{darkgreen}{rgb}{0,0.5,0}
1138 \begin_layout Plain Layout
1142 lstset{numbers=left, stepnumber=5, numbersep=5pt, breaklines=false,
1145 \begin_layout Plain Layout
1154 \begin_layout Plain Layout
1161 \begin_layout Plain Layout
1165 tiny,language=C,columns=fullflexible,
1168 \begin_layout Plain Layout
1170 numberfirstline=true
1173 \begin_layout Plain Layout
1183 \begin_layout Chapter
1184 Newfangle with Makefiles
1187 \begin_layout Standard
1188 \begin_inset Note Note
1191 \begin_layout Plain Layout
1192 This chapter needs revising
1198 \begin_inset Note Greyedout
1201 \begin_layout Plain Layout
1202 This chapter needs revising
1207 Here we describe a Makefile.inc that you can include in your own Makefiles,
1208 or glue as a recursive make to other projects.
1211 \begin_layout Standard
1212 The Makefile.inc described here was put together for a Samba4 vfs module,
1213 but can be used in any Make project, including automake projects.
1216 \begin_layout Section
1217 A word about makefiles formats
1220 \begin_layout Standard
1221 Whitespace formatting is very important in a Makefile.
1222 The first character of each command line must be a TAB.
1225 \begin_layout LyX-Code
1226 target: pre-requisite
1227 \begin_inset Newline newline
1231 \begin_inset Newline newline
1237 \begin_layout Standard
1238 But a TAB is pretty hard to enter into most of the Lyx formats and insets
1240 An alternative is to use a semi-colon after the pre-requisite, and a backslash
1241 at the end of each line (except the last).
1242 Then any whitespace (or none) can prefix each action.
1245 \begin_layout LyX-Code
1246 target: pre-requisite ;
1249 \begin_inset Newline newline
1255 \begin_inset Newline newline
1261 \begin_layout Standard
1262 This is the style that we use and it works pretty well for GNU make at least.
1265 \begin_layout Standard
1266 We also adopt a convention that code chunks whose names beginning with ./
1267 should always be automatically extracted from the document.
1268 Code chunks whose names do not begin with ./ are for internal reference.
1269 (This doesn't prevent such chunks from being extracted directly).
1272 \begin_layout Section
1273 Boot-strapping the extraction
1276 \begin_layout Subsection
1280 \begin_layout Standard
1281 \begin_inset CommandInset label
1283 name "sub:Bootstrap-Using-a-Makefile"
1287 It seems convenient to have the makefile extract or update the C source
1288 files as part of it's operation.
1289 It also seems convenient to have the makefile itself extracted from this
1293 \begin_layout Standard
1294 It would also be convenient to have the code to extract the makefile from
1295 this document to also be part of this document, however we have to start
1296 somewhere and this unfortunately requires us to type at least a few words
1297 by hand to start things off.
1300 \begin_layout Standard
1301 Therefore we will have a minimal root fragment, which, when extracted, can
1302 cope with extracting the rest of the source.
1303 perhaps with this shell script, which could be called
1308 \begin_inset Note Note
1311 \begin_layout Plain Layout
1312 FIX THIS CHUNK AND TEST IT
1324 \begin_layout Standard
1325 \begin_inset listings
1329 \begin_layout Plain Layout
1334 \begin_layout Plain Layout
1338 \begin_layout Plain Layout
1340 MAKE_SRC="${1:-${NW_LYX:-../../noweb-lyx/noweb-lyx3.lyx}}"
1343 \begin_layout Plain Layout
1345 MAKE_SRC=`dirname "$MAKE_SRC"`/`basename "$MAKE_SRC" .lyx`
1348 \begin_layout Plain Layout
1350 NOWEB_SRC="${2:-${NOWEB_SRC:-$MAKE_SRC.lyx}}"
1353 \begin_layout Plain Layout
1355 lyx -e latex $MAKE_SRC
1358 \begin_layout Plain Layout
1362 \begin_layout Plain Layout
1364 newfangle -R./Makefile.inc ${MAKE_SRC}.tex
1369 \begin_layout Plain Layout
1371 | sed "/NEWFANGLE_SOURCE=/s/^/#/;T;aNOWEB_SOURCE=$NEWFANGLE_SRC"
1376 \begin_layout Plain Layout
1378 | cpif ./Makefile.inc
1381 \begin_layout Plain Layout
1385 \begin_layout Plain Layout
1387 make -f ./Makefile.inc newfangle_sources
1395 \begin_layout Standard
1396 The general Makefile can be invoked with
1400 and can also be included into any automake file to automatically re-generate
1404 \begin_layout Standard
1409 can be extracted with this command:
1412 \begin_layout LyX-Code
1413 lyx -e latex newfangle.lyx &&
1418 \begin_layout LyX-Code
1419 newfangle newfangle.lyx > ./autoboot
1422 \begin_layout Standard
1423 This looks simple enough, but as mentioned, newfangle has to be had from
1424 somewhere before it can be extracted.
1427 \begin_layout Subsection
1428 \begin_inset Note Note
1431 \begin_layout Plain Layout
1432 MERGE THIS WITH THE SECTIONS OF THIS DOCUMENT
1437 \SpecialChar \ldots{}
1441 \begin_layout Standard
1442 When the lyx-build chunk is executed, the current directory will be a temporary
1444 \begin_inset Flex CharStyle:Code
1447 \begin_layout Plain Layout
1453 will refer to the tex file in this temporary directory.
1454 This is unfortunate as our makefile wants to run from the project directory
1455 where the Lyx file is kept.
1458 \begin_layout Standard
1459 We can extract the project directory from $$r, and derive the probable Lyx
1460 filename from the noweb file that Lyx generated.
1467 \begin_layout Standard
1468 \begin_inset listings
1472 \begin_layout Plain Layout
1474 PROJECT_DIR="$LYX_r"
1477 \begin_layout Plain Layout
1479 LYX_SRC="$PROJECT_DIR/${LYX_i%.tex}.lyx"
1482 \begin_layout Plain Layout
1487 \begin_layout Plain Layout
1489 TEX_SRC="$TEX_DIR/$LYX_i"
1497 \begin_layout Standard
1498 And then we can define a lyx-build fragment similar to the autoboot fragment
1505 \begin_layout Standard
1506 \begin_inset listings
1510 \begin_layout Plain Layout
1515 \begin_layout Plain Layout
1519 chunkref{lyx-build-helper}>
1522 \begin_layout Plain Layout
1524 cd $PROJECT_DIR || exit 1
1527 \begin_layout Plain Layout
1531 \begin_layout Plain Layout
1533 #/usr/bin/newfangle -filter ./notanglefix-filter
1538 \begin_layout Plain Layout
1540 # -R./Makefile.inc "../../noweb-lyx/noweb-lyx3.lyx"
1545 \begin_layout Plain Layout
1547 # | sed '/NOWEB_SOURCE=/s/=.*/=samba4-dfs.lyx/'
1552 \begin_layout Plain Layout
1557 \begin_layout Plain Layout
1562 \begin_layout Plain Layout
1564 #make -f ./Makefile.inc newfangle_sources
1572 \begin_layout Section
1576 \begin_layout Subsection
1577 Including Makefile.inc
1580 \begin_layout Standard
1581 \begin_inset CommandInset label
1583 name "sub:Keeping-extracted-files"
1587 Makefile.inc will cope with extracting all the other source files from this
1588 document and keeping them up to date.
1592 \begin_layout Standard
1593 It may also be included by a Makefile or Makefile.am defined in a Lyx document
1594 to automatically deal with the extraction of source files and documents.
1597 \begin_layout Standard
1598 A makefile has two parts; variables must be defined before the targets that
1606 \begin_layout Standard
1607 \begin_inset listings
1611 \begin_layout Plain Layout
1615 chunkref{Makefile.inc-vars}>
1618 \begin_layout Plain Layout
1622 chunkref{Makefile.inc-targets}>
1630 \begin_layout Standard
1632 \begin_inset Flex CharStyle:Code
1635 \begin_layout Plain Layout
1641 to hold the name of this Lyx file.
1648 \begin_layout Standard
1649 \begin_inset listings
1653 \begin_layout Plain Layout
1658 \begin_layout Plain Layout
1660 LITERATE_SOURCE=$(LYX_SOURCE)
1668 \begin_layout Subsection
1669 Recursive use of Makefile.inc
1672 \begin_layout Standard
1673 The makefile glue described here is used when building Samba4 vfs modules.
1676 \begin_layout Standard
1677 If you are defining a module of an existing program you may find it easier
1678 to use a slight recursive make instead of including the makefile directly.
1679 This way there is less chance of definitions in Makefile.inc interfering
1680 with definitions in the main makefile, or with definitions in other Makefile.inc
1681 from other noweb modules.
1684 \begin_layout Standard
1685 The glue works by adding a .PHONY target to call the recursive make, and
1686 adding this target as an additional pre-requisite to the existing targets.
1689 \begin_layout Standard
1690 In this example, the existing build system already has a build target for
1692 \begin_inset Flex CharStyle:Code
1695 \begin_layout Plain Layout
1701 , so we just add another pre-requisite to that.
1703 \begin_inset Flex CharStyle:Code
1706 \begin_layout Plain Layout
1712 as a pre-requisite, the stamp file's modified time indicating when all
1713 sources were extracted.
1720 \begin_layout Standard
1721 \begin_inset listings
1725 \begin_layout Plain Layout
1727 $(example_srcdir)/example.o: $(example_srcdir)/example.tex.stamp
1735 \begin_layout Standard
1736 The target for this new pre-requisite is generated by a recursive make using
1737 Makefile.inc which will make sure that the source is up to date, before
1738 it is built by the main projects makefile.
1745 \begin_layout Standard
1746 \begin_inset listings
1750 \begin_layout Plain Layout
1752 $(example_srcdir)/example.tex.stamp: $(example_srcdir)/example.tex ;
1757 \begin_layout Plain Layout
1759 cd $(example_srcdir) &&
1764 \begin_layout Plain Layout
1766 $(MAKE) -f Makefile.inc newfangle_sources
1774 \begin_layout Standard
1775 We can do similar glue for the docs, clean and distclean targets.
1776 In this example our build system is using a double colon for these targets,
1777 so we use the same in our glue.
1784 \begin_layout Standard
1785 \begin_inset listings
1789 \begin_layout Plain Layout
1794 \begin_layout Plain Layout
1796 .PHONY: docs_example
1799 \begin_layout Plain Layout
1801 docs_example:: ; cd $(example_srcdir) &&
1806 \begin_layout Plain Layout
1808 $(MAKE) -f Makefile.inc docs
1811 \begin_layout Plain Layout
1815 \begin_layout Plain Layout
1817 clean:: clean_example
1820 \begin_layout Plain Layout
1822 .PHONEY: clean_example
1825 \begin_layout Plain Layout
1827 clean_example: ; cd $(example_srcdir) &&
1832 \begin_layout Plain Layout
1834 $(MAKE) -f Makefile.inc clean
1837 \begin_layout Plain Layout
1841 \begin_layout Plain Layout
1843 distclean:: distclean_example
1846 \begin_layout Plain Layout
1848 .PHONY: distclean_example
1851 \begin_layout Plain Layout
1853 distclean_example: ; cd $(example_srcdir) &&
1858 \begin_layout Plain Layout
1860 $(MAKE) -f Makefile.inc distclean
1868 \begin_layout Standard
1869 We could do similarly for install targets to install the generated docs.
1872 \begin_layout Subsection
1873 \begin_inset CommandInset label
1875 name "sub:Converting-from-Lyx"
1879 Converting from Lyx to LaTeX
1882 \begin_layout Standard
1883 The first stage will always be to convert the Lyx file to a LaTeX file;
1884 this must be so not only because newfangle needs to to run on a TeX file,
1885 but also because the Lyx command
1887 server-goto-file-line
1891 \begin_layout Plain Layout
1894 server-goto-file-line
1896 is used to position the Lyx cursor at the compiler errors.
1903 insists that the line number provided is a line in the TeX file, and always
1904 reverse maps this to derive the line in the Lyx docment.
1905 \begin_inset Note Note
1908 \begin_layout Plain Layout
1909 The tex file should probably be an automake extra dist sources or something,
1910 so that it gets produced and packaged by make dist
1918 \begin_layout Standard
1919 The command [[lyx -e literate noweb-lyx.lyx]] will produce [[noweb-lyx.nw]]
1920 a tex file, so we define the noweb target to be the same as the Lyx file
1921 but with the .nw extension.
1928 \begin_layout Standard
1929 \begin_inset listings
1933 \begin_layout Plain Layout
1935 TEX_SOURCE=$(LYX_SOURCE:.lyx=.tex)
1944 Makefile.inc-targets
1947 \begin_layout Standard
1948 \begin_inset listings
1952 \begin_layout Plain Layout
1954 $(TEX_SOURCE): $(LYX_SOURCE) ;
1959 \begin_layout Plain Layout
1964 \begin_layout Plain Layout
1966 clean_tex: ; rm -f -- $(TEX_SOURCE)
1974 \begin_layout Subsection
1975 Extracting Program Source
1978 \begin_layout Standard
1979 The program source is extracted using newfangle, which is designed to operate
1980 on a LaTeX document.
1988 \begin_layout Standard
1989 \begin_inset listings
1993 \begin_layout Plain Layout
1995 NEWFANGLE_SOURCE=$(TEX_SOURCE)
2003 \begin_layout Standard
2004 The Lyx document can result in any number of source documents, but not all
2005 of these will be changed each time the Lyx document is updated.
2006 We certainly don't want to update the timestamps of these files and cause
2007 the whole source tree to be recompiled just because the Lyx document was
2012 \begin_layout Standard
2013 To solve this problem we use a stamp file which is always updated each time
2014 the sources are extracted from the LaTeX document.
2015 If the stamp file is older than the LaTeX document, then we can make an
2016 attempt to re-extract the sources.
2023 \begin_layout Standard
2024 \begin_inset listings
2028 \begin_layout Plain Layout
2030 NEWFANGLE_SOURCE_STAMP=$(NEWFANGLE_SOURCE).stamp
2039 Makefile.inc-targets
2042 \begin_layout Standard
2043 \begin_inset listings
2047 \begin_layout Plain Layout
2049 $(NEWFANGLE_SOURCE_STAMP): $(NEWFANGLE_SOURCE)
2054 \begin_layout Plain Layout
2056 $(NEWFANGLE_SOURCES) ;
2061 \begin_layout Plain Layout
2063 echo > $(NEWFANGLE_SOURCE_STAMP)
2066 \begin_layout Plain Layout
2068 clean_stamp: ; rm -f $(NEWFANGLE_SOURCE_STAMP)
2071 \begin_layout Plain Layout
2081 \begin_layout Subsection
2082 Extracting C sources
2085 \begin_layout Standard
2087 \begin_inset Flex CharStyle:Code
2090 \begin_layout Plain Layout
2096 to hold the names of all the C source files defined in this document.
2097 We compute this only once, by means of := in assignent.
2098 The sed deletes the any <
2099 \begin_inset space \hspace*{}
2104 \begin_inset space \hspace*{}
2108 > which may surround the roots names (for noroots compatibility).
2112 \begin_layout Standard
2113 As we use chunk names beginning with ./ to denote top level fragments that
2114 should be extracted, we filter out all fragments that do not begin with
2122 \begin_layout Standard
2123 \begin_inset listings
2127 \begin_layout Plain Layout
2136 \begin_layout Plain Layout
2138 NEWFANGLE_SOURCES:=$(shell
2143 \begin_layout Plain Layout
2145 newfangle -r $(NEWFANGLE_SOURCE) |
2150 \begin_layout Plain Layout
2152 sed -e 's/^[<][<]//;s/[>][>]$$//;/^$(NEWFANGLE_PREFIX)/!d'
2157 \begin_layout Plain Layout
2159 -e 's/^$(NEWFANGLE_PREFIX)/
2166 \begin_layout Plain Layout
2177 Makefile.inc-targets
2180 \begin_layout Standard
2181 \begin_inset listings
2185 \begin_layout Plain Layout
2187 .PHONY: echo_newfangle_sources
2190 \begin_layout Plain Layout
2192 echo_newfangle_sources: ; @echo $(NEWFANGLE_SOURCES)
2200 \begin_layout Standard
2201 We define a convenient target called
2202 \begin_inset Flex CharStyle:Code
2205 \begin_layout Plain Layout
2211 to re-extract the source if the LaTeX file has been updated.
2215 Makefile.inc-targets
2218 \begin_layout Standard
2219 \begin_inset listings
2223 \begin_layout Plain Layout
2225 .PHONY: newfangle_sources
2228 \begin_layout Plain Layout
2230 newfangle_sources: $(NEWFANGLE_SOURCE_STAMP)
2238 \begin_layout Standard
2239 And also a convenient target to remove extracted sources.
2243 Makefile.inc-targets
2246 \begin_layout Standard
2247 \begin_inset listings
2251 \begin_layout Plain Layout
2253 .PHONY: clean_newfangle_sources
2256 \begin_layout Plain Layout
2258 clean_newfangle_sources: ;
2263 \begin_layout Plain Layout
2265 rm -f -- $(NEWFANGLE_SOURCE_STAMP) $(NEWFANGLE_SOURCES)
2273 \begin_layout Standard
2275 \begin_inset Flex CharStyle:Code
2278 \begin_layout Plain Layout
2284 macro takes 4 arguments: the filename (1), some extensions to match (2)
2285 and a some shell command to return if the filename matches the exentions
2293 \begin_layout Standard
2294 \begin_inset listings
2298 \begin_layout Plain Layout
2300 if_extension=$(if $(findstring $(suffix $(1)),$(2)),$(3),$(4))
2308 \begin_layout Standard
2309 For some source files like C files, we want to output the line number and
2310 filename of the original LaTeX document from which the source came.
2313 \begin_layout Standard
2314 To make this easier we define the file extensions for which we want to do
2322 \begin_layout Standard
2323 \begin_inset listings
2327 \begin_layout Plain Layout
2337 \begin_layout Standard
2338 We can then use the if_extensions macro to define a macro which expands
2340 \begin_inset Flex CharStyle:Code
2343 \begin_layout Plain Layout
2349 option if newfangle is being invoked in a C source file, so that C compile
2350 errors will refer to the line number in the Lyx document.
2358 \begin_layout Standard
2359 \begin_inset listings
2363 \begin_layout Plain Layout
2368 \begin_layout Plain Layout
2370 nf_line=-L -T$(TABS)
2373 \begin_layout Plain Layout
2380 \begin_layout Plain Layout
2382 $(call if_extension,$(2),$(C_EXTENSIONS),$(nf_line))
2387 \begin_layout Plain Layout
2397 \begin_layout Standard
2398 We can use a similar trick to define an
2402 macro which takes just the filename as an argument and can return a pipeline
2403 stage calling the indent command.
2404 Indent can be turned off with
2405 \begin_inset Flex CharStyle:Code
2408 \begin_layout Plain Layout
2409 make newfangle_sources indent=
2421 \begin_layout Standard
2422 \begin_inset listings
2426 \begin_layout Plain Layout
2428 indent_options=-npro -kr -i8 -ts8 -sob -l80 -ss -ncs
2431 \begin_layout Plain Layout
2433 indent=$(call if_extension,$(1),$(C_EXTENSIONS),
2438 \begin_layout Plain Layout
2440 | indent $(indent_options))
2448 \begin_layout Standard
2449 We now define the pattern for extracting a file.
2450 The files are written using noweb's
2456 \begin_layout Plain Layout
2459 So you still need noweb installed in order to use cpif
2465 \begin_inset Note Note
2468 \begin_layout Plain Layout
2471 Write an awk version
2478 so that the file timestamp will not be touched if the contents haven't
2480 This avoids the need to rebuild the entire project because of a typographical
2481 change in the documentation, or if only a few C source files have changed.
2488 \begin_layout Standard
2489 \begin_inset listings
2493 \begin_layout Plain Layout
2495 newfangle_extract=@mkdir -p $(dir $(1)) &&
2500 \begin_layout Plain Layout
2502 $(call newfangle,$(2),$(1)) > "$(1).tmp" &&
2507 \begin_layout Plain Layout
2509 cat "$(1).tmp" $(indent) | cpif "$(1)"
2514 \begin_layout Plain Layout
2516 && rm -- "$(1).tmp" ||
2521 \begin_layout Plain Layout
2523 (echo error newfangling $(1) from $(2) ; exit 1)
2531 \begin_layout Standard
2532 We define a target which will extract or update all sources.
2533 To do this we first defined a makefile template that can do this for any
2534 source file in the LaTeX document.
2541 \begin_layout Standard
2542 \begin_inset listings
2546 \begin_layout Plain Layout
2548 define NEWFANGLE_template
2551 \begin_layout Plain Layout
2558 \begin_layout Plain Layout
2560 $$(call newfangle_extract,$(1),$(2))
2563 \begin_layout Plain Layout
2565 NEWFANGLE_TARGETS+=$(1)
2568 \begin_layout Plain Layout
2578 \begin_layout Standard
2579 We then enumerate the discovered
2580 \begin_inset Flex CharStyle:Code
2583 \begin_layout Plain Layout
2589 to generate a makefile rule for each one using the makefile template we
2594 Makefile.inc-targets
2597 \begin_layout Standard
2598 \begin_inset listings
2602 \begin_layout Plain Layout
2604 $(foreach source,$(NEWFANGLE_SOURCES),
2609 \begin_layout Plain Layout
2611 $(eval $(call NEWFANGLE_template,$(source),$(NEWFANGLE_SOURCE)))
2616 \begin_layout Plain Layout
2626 \begin_layout Standard
2627 These will all be built with NEWFANGLE_SOURCE_STAMP.
2630 \begin_layout Standard
2631 We also remove the generated sources on a
2639 Makefile.inc-targets
2642 \begin_layout Standard
2643 \begin_inset listings
2647 \begin_layout Plain Layout
2649 _distclean: clean_newfangle_sources
2657 \begin_layout Subsection
2658 Extracting Documentation
2661 \begin_layout Standard
2662 We then identify the intermediate stages of the documentation and their
2663 build and clean targets.
2666 \begin_layout Subsubsection
2670 \begin_layout Standard
2671 We produce a pdf file from the tex file.
2678 \begin_layout Standard
2679 \begin_inset listings
2683 \begin_layout Plain Layout
2685 NEWFANGLE_PDF=$(TEX_SOURCE:.tex=.pdf)
2693 \begin_layout Standard
2694 We run pdflatex twice to be sure that the contents and aux files are up
2696 We certainly are required to run pdflatex twice if these files do not exist!
2700 Makefile.inc-targets
2703 \begin_layout Standard
2704 \begin_inset listings
2708 \begin_layout Plain Layout
2710 $(NEWFANGLE_PDF): $(TEX_SOURCE); pdflatex $< && pdflatex $<
2713 \begin_layout Plain Layout
2715 clean_pdf: ; rm -f -- $(NEWFANGLE_PDF)
2720 \begin_layout Plain Layout
2722 $(TEX_SOURCE:.tex=.toc)
2727 \begin_layout Plain Layout
2729 $(TEX_SOURCE:.tex=.log)
2734 \begin_layout Plain Layout
2736 $(TEX_SOURCE:.tex=.aux)
2744 \begin_layout Subsubsection
2748 \begin_layout Standard
2749 Currently we only build pdf as a final format, but NEWFANGLE_DOCS may later
2750 hold other output formats.
2757 \begin_layout Standard
2758 \begin_inset listings
2762 \begin_layout Plain Layout
2764 NEWFANGLE_DOCS=$(NEWFANGLE_PDF)
2772 \begin_layout Standard
2773 We also define newfangle_docs as a convenient phony target<
2777 Makefile.inc-targets
2780 \begin_layout Standard
2781 \begin_inset listings
2785 \begin_layout Plain Layout
2787 .PHONY: newfangle_docs
2790 \begin_layout Plain Layout
2792 newfangle_docs: $(NEWFANGLE_DOCS)
2795 \begin_layout Plain Layout
2797 docs: newfangle_docs
2805 \begin_layout Standard
2806 And define a convenient clean_noweb_docs which we add to the regular clean
2811 Makefile.inc-targets
2814 \begin_layout Standard
2815 \begin_inset listings
2819 \begin_layout Plain Layout
2821 .PHONEY: clean_newfangle_docs
2824 \begin_layout Plain Layout
2826 clean_newfangle_docs: clean_tex clean_pdf
2829 \begin_layout Plain Layout
2831 clean: clean_newfangle_docs
2834 \begin_layout Plain Layout
2838 \begin_layout Plain Layout
2840 distclean_newfangle_docs: clean_tex clean_newfangle_docs
2843 \begin_layout Plain Layout
2845 distclean: clean distclean_newfangle_docs
2853 \begin_layout Subsection
2857 \begin_layout Standard
2858 If Makefile.inc is included into Makefile, then extracted files can be updated
2862 \begin_layout LyX-Code
2863 make newfangle_sources
2866 \begin_layout Standard
2870 \begin_layout LyX-Code
2871 make -f Makefile.inc newfangle_sources
2878 \begin_layout Chapter
2879 Newfangle awk source code
2882 \begin_layout Standard
2883 We use the copyright notice from chapter
2884 \begin_inset CommandInset ref
2886 reference "cha:License"
2894 ./newfangle,language=awk,morestring=[b]{/},morekeywords=else
2897 \begin_layout Standard
2898 \begin_inset listings
2902 \begin_layout Plain Layout
2907 \begin_layout Plain Layout
2911 chunkref{gpl3-copyright}>
2919 \begin_layout Standard
2920 We also use code from Arnold Robbins public domain getopt (1993 revision)
2922 \begin_inset CommandInset ref
2924 reference "cha:getopt"
2928 , and naturally want to attribute this appropriately.
2931 \begin_layout Standard
2932 \begin_inset listings
2936 \begin_layout Plain Layout
2940 \begin_layout Plain Layout
2942 # NOTE: Arnold Robbins public domain getopt for awk is also used:
2945 \begin_layout Plain Layout
2949 chunkref{getopt.awk-header}>
2952 \begin_layout Plain Layout
2956 \begin_layout Plain Layout
2960 chunkref{getopt.awk-getopt()}>
2963 \begin_layout Plain Layout
2972 \begin_layout Standard
2973 And include the following chunks
2980 \begin_layout Standard
2981 \begin_inset listings
2985 \begin_layout Plain Layout
2989 chunkref{helper-functions}>
2992 \begin_layout Plain Layout
2996 chunkref{mode-tracker}>
2999 \begin_layout Plain Layout
3003 chunkref{chunk-storage-functions}>
3006 \begin_layout Plain Layout
3010 chunkref{output_chunk_names()}>
3013 \begin_layout Plain Layout
3017 chunkref{output_chunks()}>
3020 \begin_layout Plain Layout
3024 chunkref{write_chunk()}>
3027 \begin_layout Plain Layout
3031 chunkref{expand_chunk_args()}>
3034 \begin_layout Plain Layout
3041 \begin_layout Plain Layout
3045 chunkref{recognize-chunk}>
3048 \begin_layout Plain Layout
3060 \begin_layout Section
3064 \begin_layout Standard
3065 The portable way to erase an array in awk is to split the empty string,
3070 awk-delete-array,params=ARRAY
3073 \begin_layout Standard
3074 \begin_inset listings
3078 \begin_layout Plain Layout
3080 split("", ${ARRAY});
3089 dump-array,params=ARRAY
3092 \begin_layout Standard
3093 \begin_inset listings
3097 \begin_layout Plain Layout
3108 \begin_layout Plain Layout
3110 for (_x in ${ARRAY}) {
3113 \begin_layout Plain Layout
3115 print _x "=" ${ARRAY}[_x] "
3120 \begin_layout Plain Layout
3125 \begin_layout Plain Layout
3141 \begin_layout Section
3145 \begin_layout Standard
3146 Fatal errors are issued with the error function:
3150 error(),append=helper-functions
3153 \begin_layout Standard
3154 \begin_inset listings
3158 \begin_layout Plain Layout
3160 function error(message)
3163 \begin_layout Plain Layout
3168 \begin_layout Plain Layout
3170 print "ERROR: " FILENAME ":" FNR " " message > "/dev/stderr";
3173 \begin_layout Plain Layout
3178 \begin_layout Plain Layout
3188 \begin_layout Standard
3189 \begin_inset listings
3193 \begin_layout Plain Layout
3195 function warning(message)
3198 \begin_layout Plain Layout
3203 \begin_layout Plain Layout
3205 print "WARNING: " FILENAME ":" FNR " " message > "/dev/stderr";
3208 \begin_layout Plain Layout
3213 \begin_layout Plain Layout
3223 \begin_layout Chapter
3227 \begin_layout Standard
3228 LaTeX arguments to lstlistings macros are a comma seperated list of key-value
3230 Values containing commas are enclosed in { braces }.
3233 \begin_layout Standard
3234 We need a function that can parse such an expression and assign the values
3242 \begin_layout Standard
3243 A sample expressions is:
3246 \begin_layout LyX-Code
3247 name=thomas, params={a, b}, something, something-else
3250 \begin_layout Standard
3251 but we see that this is just a simpler form of this expression:
3254 \begin_layout LyX-Code
3255 name=freddie, foo={bar=baz, quux={quirk, a=fleeg}}, etc
3258 \begin_layout Standard
3259 And that it would be a good idea to use a recursive parser into a multi-dimensio
3264 \begin_layout Plain Layout
3265 as AWK doesn't have nested-hash support
3273 \begin_layout Standard
3274 \begin_inset Tabular
3275 <lyxtabular version="3" rows="6" columns="2">
3277 <column alignment="left" valignment="top" width="0">
3278 <column alignment="left" valignment="top" width="0">
3280 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
3283 \begin_layout Plain Layout
3289 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
3292 \begin_layout Plain Layout
3300 <cell alignment="left" valignment="top" topline="true" leftline="true" usebox="none">
3303 \begin_layout Plain Layout
3309 <cell alignment="left" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
3312 \begin_layout Plain Layout
3320 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
3323 \begin_layout Plain Layout
3329 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
3332 \begin_layout Plain Layout
3340 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
3343 \begin_layout Plain Layout
3349 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
3352 \begin_layout Plain Layout
3360 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
3363 \begin_layout Plain Layout
3369 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
3372 \begin_layout Plain Layout
3380 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
3383 \begin_layout Plain Layout
3389 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
3392 \begin_layout Plain Layout
3406 \begin_layout Standard
3407 On reflection it seems that sometimes such nesting is not desirable, as
3408 the braces are also used to delimit values that contain commas --- we may
3412 \begin_layout LyX-Code
3413 name={williamson, freddie}
3416 \begin_layout Standard
3418 \begin_inset Flex CharStyle:Code
3421 \begin_layout Plain Layout
3428 \begin_inset Flex CharStyle:Code
3431 \begin_layout Plain Layout
3437 --- so I may change this behaviour.
3438 \begin_inset Note Note
3441 \begin_layout Plain Layout
3450 \begin_layout Standard
3452 \begin_inset Flex Chunkref
3455 \begin_layout Plain Layout
3461 will accept two paramters,
3462 \begin_inset Flex CharStyle:Code
3465 \begin_layout Plain Layout
3471 being the text to parse, and
3472 \begin_inset Flex CharStyle:Code
3475 \begin_layout Plain Layout
3481 being an array to receive the parsed values as described above.
3482 The optional parameter
3483 \begin_inset Flex CharStyle:Code
3486 \begin_layout Plain Layout
3492 is used during recursion to build up the multi-dimensional array path.
3499 \begin_layout Standard
3500 \begin_inset listings
3504 \begin_layout Plain Layout
3508 chunkref{get_chunk_args()}>
3520 \begin_layout Standard
3521 \begin_inset listings
3525 \begin_layout Plain Layout
3527 function get_chunk_args(text, values,
3530 \begin_layout Plain Layout
3532 # optional parameters
3535 \begin_layout Plain Layout
3537 path, # hierarchical precursors
3540 \begin_layout Plain Layout
3545 \begin_layout Plain Layout
3555 \begin_layout Standard
3556 The strategy is to parse the name, and then look for a value.
3557 If the value begins with a brace
3558 \begin_inset Flex CharStyle:Code
3561 \begin_layout Plain Layout
3567 , then we recurse and consume as much of the text as necessary, returning
3568 the remaining text when we encounter a leading close-brace
3569 \begin_inset Flex CharStyle:Code
3572 \begin_layout Plain Layout
3579 This being the strategy --- and executed in a loop --- we realise that
3580 we must first look for the closing brace (perhaps preceded by white space)
3581 in order to terminate the recursion, and returning remaining text.
3584 \begin_layout Standard
3585 \begin_inset listings
3589 \begin_layout Plain Layout
3594 \begin_layout Plain Layout
3596 split("", next_chunk_args);
3599 \begin_layout Plain Layout
3601 while(length(text)) {
3604 \begin_layout Plain Layout
3606 if (match(text, "^ *}(.*)", a)) {
3609 \begin_layout Plain Layout
3614 \begin_layout Plain Layout
3619 \begin_layout Plain Layout
3623 chunkref{parse-chunk-args}>
3626 \begin_layout Plain Layout
3631 \begin_layout Plain Layout
3636 \begin_layout Plain Layout
3646 \begin_layout Standard
3647 \begin_inset Note Note
3650 \begin_layout Plain Layout
3651 Use BNF package here
3656 We can see that the text could be inspected with this regex:
3663 \begin_layout Standard
3664 \begin_inset listings
3668 \begin_layout Plain Layout
3670 if (! match(text, " *([^,=]*[^,= ]) *(([,=]) *(([^,}]*) *,* *(.*))|)$", a))
3674 \begin_layout Plain Layout
3679 \begin_layout Plain Layout
3689 \begin_layout Standard
3691 \begin_inset Flex CharStyle:Code
3694 \begin_layout Plain Layout
3700 will have the following values:
3703 \begin_layout Standard
3704 \begin_inset Tabular
3705 <lyxtabular version="3" rows="7" columns="2">
3707 <column alignment="center" valignment="top" width="0">
3708 <column alignment="left" valignment="top" width="0">
3710 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
3713 \begin_layout Plain Layout
3719 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
3722 \begin_layout Plain Layout
3730 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
3733 \begin_layout Plain Layout
3739 <cell alignment="left" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
3742 \begin_layout Plain Layout
3750 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
3753 \begin_layout Plain Layout
3759 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
3762 \begin_layout Plain Layout
3763 =freddie, foo={bar=baz, quux={quirk, a=fleeg}}, etc
3770 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
3773 \begin_layout Plain Layout
3779 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
3782 \begin_layout Plain Layout
3790 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
3793 \begin_layout Plain Layout
3799 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
3802 \begin_layout Plain Layout
3803 freddie, foo={bar=baz, quux={quirk, a=fleeg}}, etc
3810 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
3813 \begin_layout Plain Layout
3819 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
3822 \begin_layout Plain Layout
3830 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
3833 \begin_layout Plain Layout
3839 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
3842 \begin_layout Plain Layout
3843 , foo={bar=baz, quux={quirk, a=fleeg}}, etc
3856 \begin_layout Standard
3858 \begin_inset Flex CharStyle:Code
3861 \begin_layout Plain Layout
3868 \begin_inset Flex CharStyle:Code
3871 \begin_layout Plain Layout
3877 and signify whether the option named in
3878 \begin_inset Flex CharStyle:Code
3881 \begin_layout Plain Layout
3887 has a value or not (respectively).
3890 \begin_layout Standard
3891 If the option does have a value, then if the expression
3892 \begin_inset Flex CharStyle:Code
3895 \begin_layout Plain Layout
3902 \begin_inset Flex CharStyle:Code
3905 \begin_layout Plain Layout
3911 it will signify that we need to recurse:
3914 \begin_layout Standard
3915 \begin_inset listings
3919 \begin_layout Plain Layout
3924 \begin_layout Plain Layout
3929 \begin_layout Plain Layout
3931 if (substr(a[4],1,1) == "{") {
3934 \begin_layout Plain Layout
3936 text = get_chunk_args(substr(a[4],2), values, path name SUBSEP);
3939 \begin_layout Plain Layout
3944 \begin_layout Plain Layout
3946 values[path name]=a[5];
3949 \begin_layout Plain Layout
3954 \begin_layout Plain Layout
3959 \begin_layout Plain Layout
3964 \begin_layout Plain Layout
3966 values[path name]="";
3969 \begin_layout Plain Layout
3974 \begin_layout Plain Layout
3984 \begin_layout Standard
3985 We can test this function like this:
3992 \begin_layout Standard
3993 \begin_inset listings
3997 \begin_layout Plain Layout
4001 chunkref{get_chunk_args()}>
4004 \begin_layout Plain Layout
4009 \begin_layout Plain Layout
4014 \begin_layout Plain Layout
4018 \begin_layout Plain Layout
4020 print get_chunk_args("name=freddie, foo={bar=baz, quux={quirk, a=fleeg}},
4024 \begin_layout Plain Layout
4029 \begin_layout Plain Layout
4031 print "a[" b "] => " a[b];
4034 \begin_layout Plain Layout
4039 \begin_layout Plain Layout
4049 \begin_layout Standard
4050 which should give this output:
4054 gca-test.awk-results
4057 \begin_layout Standard
4058 \begin_inset listings
4062 \begin_layout Plain Layout
4064 a[foo.quux.quirk] =>
4067 \begin_layout Plain Layout
4069 a[foo.quux.a] => fleeg
4072 \begin_layout Plain Layout
4077 \begin_layout Plain Layout
4082 \begin_layout Plain Layout
4092 \begin_layout Chapter
4093 Expanding chunk arguments
4096 \begin_layout Standard
4097 \begin_inset CommandInset label
4099 name "cha:Chunk Arguments"
4104 \begin_inset Note Note
4107 \begin_layout Plain Layout
4108 Explain this in the documentation section too
4113 As an extension to many literate-programming styles, newfangle permits code
4114 chunks to take parameters and thus operate somewhat like C pre-processor
4115 macros, or like C++ templates.
4118 \begin_layout Standard
4119 Chunk parameters are declared with a chunk argument called
4120 \begin_inset Flex CharStyle:Code
4123 \begin_layout Plain Layout
4129 , which holds a semi-colon separated list of parameters, like this:
4132 \begin_layout LyX-Code
4133 achunk,language=C,params=name;address
4136 \begin_layout Standard
4137 When such a chunk is included, the arguments are expressed in round brackets
4138 as a comma separated list of optional arguments:
4139 \begin_inset Note Note
4142 \begin_layout Plain Layout
4143 We ought to support qouting in {} like ({Jones, John}, Jones@example.com)
4151 \begin_layout LyX-Code
4154 chunkref{achunk}(John Jones, jones@example.com)
4157 \begin_layout Standard
4158 Within the body of a chunk, the parameters are referred to with:
4159 \begin_inset Flex CharStyle:Code
4162 \begin_layout Plain Layout
4169 \begin_inset Flex CharStyle:Code
4172 \begin_layout Plain Layout
4179 There is a strong case that a LaTeX style notation should be used, like
4182 param{name} which would be expressed in the listing as =<
4184 param{name}> and be rendered as
4185 \begin_inset listings
4189 \begin_layout Plain Layout
4199 Such notation would make me go blind, but I do intend to adopt it.
4202 \begin_layout Standard
4203 We therefore need a function
4204 \begin_inset Flex CharStyle:Code
4207 \begin_layout Plain Layout
4213 which will take a block of text, a list of permitted parameters and the
4214 arguments which must substitute for the parameters.
4215 We also need to be able to parse a parameter list into an array of parameters.
4218 \begin_layout Section
4219 Parsing argument lists
4222 \begin_layout Standard
4223 An argument list may be as simple as in
4224 \begin_inset Flex CharStyle:Code
4227 \begin_layout Plain Layout
4230 chunkref{pull}(thing, otherthing)
4238 \begin_layout LyX-Code
4241 chunkref{pull}(things[x, y], get_other_things(a, "all"))
4244 \begin_layout Standard
4245 --- which for all it's commas and quotes and parenthesis represents only
4249 \begin_layout Standard
4250 How do we stop the comma in
4251 \begin_inset Flex CharStyle:Code
4254 \begin_layout Plain Layout
4260 from splitting it into two arguments
4261 \begin_inset Flex CharStyle:Code
4264 \begin_layout Plain Layout
4271 \begin_inset Flex CharStyle:Code
4274 \begin_layout Plain Layout
4280 --- neither of which make sense on their own?
4283 \begin_layout Standard
4284 One way it could be done is by refusing to split text between maching delimiters
4286 \begin_inset Flex CharStyle:Code
4289 \begin_layout Plain Layout
4296 \begin_inset Flex CharStyle:Code
4299 \begin_layout Plain Layout
4306 \begin_inset Flex CharStyle:Code
4309 \begin_layout Plain Layout
4316 \begin_inset Flex CharStyle:Code
4319 \begin_layout Plain Layout
4326 \begin_inset Flex CharStyle:Code
4329 \begin_layout Plain Layout
4336 \begin_inset Flex CharStyle:Code
4339 \begin_layout Plain Layout
4345 and most likely also
4346 \begin_inset Flex CharStyle:Code
4349 \begin_layout Plain Layout
4356 \begin_inset Flex CharStyle:Code
4359 \begin_layout Plain Layout
4366 \begin_inset Flex CharStyle:Code
4369 \begin_layout Plain Layout
4376 \begin_inset Flex CharStyle:Code
4379 \begin_layout Plain Layout
4386 Of course this also makes it impossible to pass such mis-matched code fragments
4387 as parameters, but I don't think users could cope with people passing such
4388 code unbalanced fragments as chunk parameters
4392 \begin_layout Plain Layout
4393 I know that I couldn't cope with users doing such things, and although the
4394 GPL3 license prevents me from actually forbidding anyone from trying, if
4395 they want it to work they'll have to write the code themselves and not
4396 expect any support from me.
4404 \begin_layout Standard
4405 Unfortunately, the full set of matching delimiters may vary from language
4407 In certain C++ template contexts,
4408 \begin_inset Flex CharStyle:Code
4411 \begin_layout Plain Layout
4418 \begin_inset Flex CharStyle:Code
4421 \begin_layout Plain Layout
4427 would count as delimiters, and yet in other contexts they would not.
4430 \begin_layout Standard
4431 This puts me in the unfortunate position of having to parse-somewhat all
4432 programming languages without knowing what they are! Eventually this will
4433 be managed in the chunk modes in chapter
4434 \begin_inset CommandInset ref
4436 reference "cha:modes"
4443 \begin_layout Standard
4444 Another way, inspired by LaTeX, is if the first character of the parameter
4445 is an opening-delimiter, to read up to the matching closing-delimiter wthout
4446 considering intervening commas; thus the above example could be expressed:
4449 \begin_layout LyX-Code
4452 chunkref{pull}({things[x, y]}, [get_other_things(a, "all")])
4455 \begin_layout Standard
4457 \begin_inset Flex CharStyle:Code
4460 \begin_layout Plain Layout
4467 \begin_inset Flex CharStyle:Code
4470 \begin_layout Plain Layout
4476 to wrap the first agument, and
4477 \begin_inset Flex CharStyle:Code
4480 \begin_layout Plain Layout
4487 \begin_inset Flex CharStyle:Code
4490 \begin_layout Plain Layout
4496 to wrap the second argument and protect the comma.
4499 \begin_layout Standard
4500 In the meantime, I'll work with the first method, and a fixed list of delimiters.
4503 \begin_layout Standard
4511 \begin_layout Standard
4512 \begin_inset listings
4516 \begin_layout Plain Layout
4518 modes["", "", "submodes" ]="
4543 \begin_layout Plain Layout
4545 modes["", "", "delimeters"]=" *, *";
4548 \begin_layout Plain Layout
4557 \begin_layout Plain Layout
4561 "", "terminators"]="
4566 \begin_layout Plain Layout
4568 modes["", "{", "submodes" ]="
4593 \begin_layout Plain Layout
4595 modes["", "{", "delimeters"]=" *, *";
4598 \begin_layout Plain Layout
4600 modes["", "{", "terminators"]="}";
4603 \begin_layout Plain Layout
4605 modes["", "[", "submodes" ]="
4630 \begin_layout Plain Layout
4632 modes["", "[", "delimiters"]=" *, *";
4635 \begin_layout Plain Layout
4637 modes["", "[", "terminators"]="
4644 \begin_layout Plain Layout
4646 modes["", "(", "submodes" ]="
4671 \begin_layout Plain Layout
4673 modes["", "(", "delimiters"]=" *, *";
4676 \begin_layout Plain Layout
4678 modes["", "(", "terminators"]="
4685 \begin_layout Plain Layout
4687 modes["", "'", "submodes" ]="
4698 \begin_layout Plain Layout
4700 modes["", "'", "terminators"]="'";
4703 \begin_layout Plain Layout
4705 modes["", "/*", "submodes"]="
4712 \begin_layout Plain Layout
4714 modes["", "/*", "terminators"]="*/";
4717 \begin_layout Plain Layout
4719 modes["", "//", "submodes"]="
4724 \begin_layout Plain Layout
4726 modes["", "//", "terminators"]="
4731 \begin_layout Plain Layout
4733 modes["", "", "submodes" ]="
4767 \begin_layout Standard
4768 \begin_inset listings
4772 \begin_layout Plain Layout
4774 function parse_chunk_args(language, text, values,
4777 \begin_layout Plain Layout
4779 # optional parameters
4782 \begin_layout Plain Layout
4787 \begin_layout Plain Layout
4789 path, # hierarchical precursors
4792 \begin_layout Plain Layout
4794 stack, # delimiters to be matched
4797 \begin_layout Plain Layout
4802 \begin_layout Plain Layout
4807 \begin_layout Plain Layout
4809 c, a, part, item, name, result, new_values, new_mode)
4812 \begin_layout Plain Layout
4817 \begin_layout Plain Layout
4819 # split(chunklet_parts[2], call_chunk_args, " *, *");
4827 \begin_layout Standard
4828 The strategy is to parse the name, and then look for a value.
4829 If the value begins with a brace
4830 \begin_inset Flex CharStyle:Code
4833 \begin_layout Plain Layout
4839 , then we recurse and consume as much of the text as necessary, returning
4840 the remaining text when we encounter a leading close-brace
4841 \begin_inset Flex CharStyle:Code
4844 \begin_layout Plain Layout
4851 This being the strategy --- and executed in a loop --- we realise that
4852 we must first look for the closing brace (perhaps preceded by white space)
4853 in order to terminate the recursion, and returning remaining text.
4856 \begin_layout Standard
4857 \begin_inset listings
4861 \begin_layout Plain Layout
4863 submodes=modes[language, mode, "submodes"];
4866 \begin_layout Plain Layout
4868 if ((language, mode, "delimiters") in modes) {
4871 \begin_layout Plain Layout
4873 submodes=submodes "|" modes[language, mode, "delimiters"];
4876 \begin_layout Plain Layout
4881 \begin_layout Plain Layout
4883 if ((language, mode, "terminators") in modes) {
4886 \begin_layout Plain Layout
4888 submodes=submodes "|" modes[language, mode, "terminators"];
4891 \begin_layout Plain Layout
4896 \begin_layout Plain Layout
4900 \begin_layout Plain Layout
4902 while(length(text)) {
4905 \begin_layout Plain Layout
4907 if (match(text, "(" submodes ")", a)) {
4910 \begin_layout Plain Layout
4912 part = substr(text, 1, RSTART -1);
4915 \begin_layout Plain Layout
4920 \begin_layout Plain Layout
4922 if (match(a[1], "^" modes[language, mode, "terminators"] "$")) {
4925 \begin_layout Plain Layout
4930 \begin_layout Plain Layout
4932 return result item a[1];
4935 \begin_layout Plain Layout
4940 \begin_layout Plain Layout
4942 if (match(a[1], "^" modes[language, mode, "delimiters"] "$")) {
4945 \begin_layout Plain Layout
4950 \begin_layout Plain Layout
4952 text = substr(text, 1 + length(part) + length(a[1]));
4955 \begin_layout Plain Layout
4957 result = result item a[1];
4960 \begin_layout Plain Layout
4965 \begin_layout Plain Layout
4967 } else if ((language, a[1], "terminators") in modes) {
4970 \begin_layout Plain Layout
4975 \begin_layout Plain Layout
4977 #check if new_mode is defined
4980 \begin_layout Plain Layout
4982 text = substr(text, 1 + length(part) + length(a[1]));
4985 \begin_layout Plain Layout
4987 s = parse_chunk_args(language, text,new_values,new_mode);
4990 \begin_layout Plain Layout
4992 text = substr(text, length(s) +1);
4995 \begin_layout Plain Layout
5000 \begin_layout Plain Layout
5005 \begin_layout Plain Layout
5007 error(sprintf("Submode '%s' set unknown mode in text: %s", new_mode,
5011 \begin_layout Plain Layout
5013 text = substr(text, 1 + length(part) + length(a[1]));
5016 \begin_layout Plain Layout
5021 \begin_layout Plain Layout
5026 \begin_layout Plain Layout
5028 result = result item text;
5031 \begin_layout Plain Layout
5036 \begin_layout Plain Layout
5041 \begin_layout Plain Layout
5046 \begin_layout Plain Layout
5051 \begin_layout Plain Layout
5056 \begin_layout Plain Layout
5058 if (length(item)) values[++c] = item;
5061 \begin_layout Plain Layout
5066 \begin_layout Plain Layout
5076 \begin_layout Standard
5077 We can test this function like this:
5084 \begin_layout Standard
5085 \begin_inset listings
5089 \begin_layout Plain Layout
5096 \begin_layout Plain Layout
5100 chunkref{parse_chunk_args()}>
5103 \begin_layout Plain Layout
5108 \begin_layout Plain Layout
5113 \begin_layout Plain Layout
5117 chunkref{mode-definitions}>
5120 \begin_layout Plain Layout
5124 \begin_layout Plain Layout
5126 # print parse_chunk_args("", "things[x, y], get_other_things(a,
5133 \begin_layout Plain Layout
5135 # print parse_chunk_args("", "1,2,3)", a, "(");
5138 \begin_layout Plain Layout
5140 # print parse_chunk_args("", "joe, red", a, "(");
5143 \begin_layout Plain Layout
5145 print parse_chunk_args("", "${colour}", a, "(");
5148 \begin_layout Plain Layout
5153 \begin_layout Plain Layout
5155 print "a[" b "] => " a[b];
5158 \begin_layout Plain Layout
5163 \begin_layout Plain Layout
5173 \begin_layout Standard
5174 which should give this output:
5178 pca-test.awk-results
5181 \begin_layout Standard
5182 \begin_inset listings
5186 \begin_layout Plain Layout
5188 a[foo.quux.quirk] =>
5191 \begin_layout Plain Layout
5193 a[foo.quux.a] => fleeg
5196 \begin_layout Plain Layout
5201 \begin_layout Plain Layout
5206 \begin_layout Plain Layout
5216 \begin_layout Section
5217 Expanding parameters
5220 \begin_layout Standard
5221 \begin_inset CommandInset label
5223 name "Here-we-split"
5227 Here we split the text on
5228 \begin_inset Flex CharStyle:Code
5231 \begin_layout Plain Layout
5237 which means that all parts except the first will begin with a parameter
5239 The split function will consume the literal
5240 \begin_inset Flex CharStyle:Code
5243 \begin_layout Plain Layout
5256 \begin_layout Standard
5257 \begin_inset listings
5261 \begin_layout Plain Layout
5263 function expand_chunk_args(text, params, args,
5266 \begin_layout Plain Layout
5268 p, text_array, next_text, v, t, l)
5271 \begin_layout Plain Layout
5276 \begin_layout Plain Layout
5278 if (split(text, text_array, "
5285 \begin_layout Plain Layout
5289 chunkref{substitute-chunk-args}>
5292 \begin_layout Plain Layout
5297 \begin_layout Plain Layout
5302 \begin_layout Plain Layout
5312 \begin_layout Standard
5313 First, we produce an associative array of substitution values indexed by
5318 substitute-chunk-args
5321 \begin_layout Standard
5322 \begin_inset listings
5326 \begin_layout Plain Layout
5331 \begin_layout Plain Layout
5333 v[params[p]]=args[p];
5336 \begin_layout Plain Layout
5346 \begin_layout Standard
5347 We accumulate substituted text in the variable
5348 \begin_inset Flex CharStyle:Code
5351 \begin_layout Plain Layout
5358 As the first part of the split function is the part before the delimiter
5360 \begin_inset Flex CharStyle:Code
5363 \begin_layout Plain Layout
5369 in our case --- this part will never contain a parameter reference, so
5370 we assign this directly to the result kept in
5371 \begin_inset Flex CharStyle:Code
5374 \begin_layout Plain Layout
5381 \begin_inset listings
5385 \begin_layout Plain Layout
5395 \begin_layout Standard
5396 We then iterate over the remaining values in the array
5400 \begin_layout Plain Layout
5401 I don't know why I think that it will enumerate the array in order, but
5408 \begin_inset Note Note
5411 \begin_layout Plain Layout
5412 So fix it or porve it
5417 , and substitute each reference for it's argument.
5420 \begin_layout Standard
5421 \begin_inset listings
5425 \begin_layout Plain Layout
5427 for(t in text_array) if (t>1) {
5430 \begin_layout Plain Layout
5434 chunkref{substitute-chunk-arg}>
5437 \begin_layout Plain Layout
5447 \begin_layout Standard
5449 \begin_inset Flex CharStyle:Code
5452 \begin_layout Plain Layout
5458 a valid parameter reference will consist of valid parameter name terminated
5460 \begin_inset Flex CharStyle:Code
5463 \begin_layout Plain Layout
5470 A valid character name begins with the underscore or a letter, and may
5471 contain letters, digits or underscores.
5474 \begin_layout Standard
5475 A valid looking reference that is not actually the name of a parameter will
5476 be and not substituted.
5477 This is good because there is nothing to substitute anyway, and it avoids
5478 clashes when writing code for languages where ${\SpecialChar \ldots{}
5479 } is a valid construct
5480 --- such constructs will not be interfered with unless the parameter name
5485 substitute-chunk-arg
5488 \begin_layout Standard
5489 \begin_inset listings
5493 \begin_layout Plain Layout
5495 if (match(text_array[t], "^([a-zA-Z_][a-zA-Z0-9_]*)}", l) &&
5498 \begin_layout Plain Layout
5503 \begin_layout Plain Layout
5508 \begin_layout Plain Layout
5510 text = text v[l[1]] substr(text_array[t], length(l[1])+2);
5513 \begin_layout Plain Layout
5518 \begin_layout Plain Layout
5520 text = text "${" text_array[t];
5523 \begin_layout Plain Layout
5533 \begin_layout Chapter
5537 \begin_layout Standard
5538 Newfangle recognizes noweb chunks, but as we also want better LaTeX integration
5539 we will recognize any of these:
5542 \begin_layout Itemize
5543 notangle chunks matching the pattern
5544 \begin_inset Flex CharStyle:Code
5547 \begin_layout Plain Layout
5549 \begin_inset space \hspace*{}
5554 \begin_inset space \hspace*{}
5566 \begin_layout Itemize
5567 a chunks beginning with
5568 \begin_inset Flex CharStyle:Code
5571 \begin_layout Plain Layout
5581 Chunk{\SpecialChar \ldots{}
5582 } on the previous line
5585 \begin_layout Itemize
5586 an older form I have used, beginning with
5587 \begin_inset Flex CharStyle:Code
5590 \begin_layout Plain Layout
5593 begin{Chunk}[options]
5598 --- also more suitable for plain LaTeX users
5602 \begin_layout Plain Layout
5603 Is there such a thing as plain LaTeX?
5611 \begin_layout Section
5615 \begin_layout Standard
5617 \begin_inset Flex CharStyle:Code
5620 \begin_layout Plain Layout
5626 is used to signify that we are processing a code chunk and not document.
5627 In such a state, input lines will be assigned to the current chunk; otherwise
5631 \begin_layout Subsection
5635 \begin_layout Standard
5636 Our current scheme is to recognize the new lstlisting chunks, but these
5637 may be preceded by a
5638 \begin_inset Flex CharStyle:Code
5641 \begin_layout Plain Layout
5649 command which in LyX is a more convenient way to pass the chunk name to
5651 \begin_inset Flex CharStyle:Code
5654 \begin_layout Plain Layout
5662 command, and a more visible way to specify other
5663 \begin_inset Flex CharStyle:Code
5666 \begin_layout Plain Layout
5675 \begin_layout Standard
5676 The arguments to the
5677 \begin_inset Flex CharStyle:Code
5680 \begin_layout Plain Layout
5688 command are a name, and then a comma-seperated list of key-value pairs
5690 \begin_inset Flex CharStyle:Code
5693 \begin_layout Plain Layout
5702 (In fact within the LaTeX
5703 \begin_inset Flex CharStyle:Code
5706 \begin_layout Plain Layout
5715 \begin_inset CommandInset ref
5717 reference "sub:The-chunk-command"
5722 \begin_inset Flex CharStyle:Code
5725 \begin_layout Plain Layout
5731 is prefixed to the argument which is then literally passed to
5732 \begin_inset Flex CharStyle:Code
5735 \begin_layout Plain Layout
5750 \begin_layout Standard
5751 \begin_inset listings
5755 \begin_layout Plain Layout
5764 \begin_layout Plain Layout
5774 Chunk{ *([^ ,}]*),?(.*)}", line)) {
5777 \begin_layout Plain Layout
5779 next_chunk_name = line[1];
5782 \begin_layout Plain Layout
5784 get_chunk_args(line[2], next_chunk_args);
5787 \begin_layout Plain Layout
5792 \begin_layout Plain Layout
5797 \begin_layout Plain Layout
5807 \begin_layout Standard
5808 We also make a basic attempt to parse the name out of the
5809 \begin_inset Flex CharStyle:Code
5812 \begin_layout Plain Layout
5816 \begin_inset space \hspace{}
5825 text, otherwise we fall back to the name found in the previous chunk command.
5826 This attempt is very basic and doesn't support commas or spaces or square
5827 brackets as part of the chunkname.
5829 \begin_inset Flex CharStyle:Code
5832 \begin_layout Plain Layout
5840 which is convenient for some users
5844 \begin_layout Plain Layout
5845 but not yet supported in the LaTeX macros
5851 \begin_inset Note Note
5854 \begin_layout Plain Layout
5863 \begin_layout Standard
5864 \begin_inset listings
5868 \begin_layout Plain Layout
5881 \begin_layout Plain Layout
5883 if (match($0, "}.*[[,] *name= *{? *([^], }]*)", line)) {
5886 \begin_layout Plain Layout
5891 \begin_layout Plain Layout
5896 \begin_layout Plain Layout
5898 new_chunk(next_chunk_name, next_chunk_args);
5901 \begin_layout Plain Layout
5906 \begin_layout Plain Layout
5911 \begin_layout Plain Layout
5916 \begin_layout Plain Layout
5926 \begin_layout Subsection
5930 \begin_layout Standard
5931 We recognize notangle style chunks too:
5938 \begin_layout Standard
5939 \begin_inset listings
5943 \begin_layout Plain Layout
5948 \begin_layout Plain Layout
5950 if (match($0, "^[<]<(.*)[>]>= *$", line)) {
5953 \begin_layout Plain Layout
5958 \begin_layout Plain Layout
5963 \begin_layout Plain Layout
5968 \begin_layout Plain Layout
5973 \begin_layout Plain Layout
5978 \begin_layout Plain Layout
5988 \begin_layout Section
5992 \begin_layout Standard
5993 Likewise, we need to recognize when a chunk ends.
5996 \begin_layout Subsection
6000 \begin_layout Standard
6002 \begin_inset Flex CharStyle:Code
6005 \begin_layout Plain Layout
6012 \begin_inset Flex CharStyle:Code
6015 \begin_layout Plain Layout
6021 is surrounded by square brackets so that when this document is processed,
6022 this chunk doesn't terminate early when the lstlistings package recognizes
6023 it's own end-string!
6024 \begin_inset Note Greyedout
6027 \begin_layout Plain Layout
6028 This doesn't make sense as the regex is anchored with ^, which this line
6029 does not begin with!
6035 \begin_inset Note Note
6038 \begin_layout Plain Layout
6051 \begin_layout Standard
6052 \begin_inset listings
6056 \begin_layout Plain Layout
6069 \begin_layout Plain Layout
6074 \begin_layout Plain Layout
6079 \begin_layout Plain Layout
6084 \begin_layout Plain Layout
6094 \begin_layout Subsection
6102 \begin_layout Standard
6103 \begin_inset listings
6107 \begin_layout Plain Layout
6112 \begin_layout Plain Layout
6117 \begin_layout Plain Layout
6122 \begin_layout Plain Layout
6132 \begin_layout Standard
6133 All other recognizers are only of effect if we are chunking; there's no
6134 point in looking at lines if they aren't part of a chunk, so we just ignore
6135 them as efficiently as we can.
6142 \begin_layout Standard
6143 \begin_inset listings
6147 \begin_layout Plain Layout
6149 ! chunking { next; }
6157 \begin_layout Section
6161 \begin_layout Standard
6162 Chunk contents are any lines read while
6163 \begin_inset Flex CharStyle:Code
6166 \begin_layout Plain Layout
6173 Some chunk contents are special in that they refer to other chunks, and
6174 will be replaced by the contents of these chunks when the file is generated.
6177 \begin_layout Standard
6178 \begin_inset CommandInset label
6180 name "sub:ORS-chunk-text"
6184 We add the output record separator
6185 \begin_inset Flex CharStyle:Code
6188 \begin_layout Plain Layout
6194 to the line now, because we will set
6195 \begin_inset Flex CharStyle:Code
6198 \begin_layout Plain Layout
6204 to the empty string when we generate the output
6208 \begin_layout Plain Layout
6209 So that we can print partial lines using
6210 \begin_inset Flex CharStyle:Code
6213 \begin_layout Plain Layout
6220 \begin_inset Flex CharStyle:Code
6223 \begin_layout Plain Layout
6241 \begin_layout Standard
6242 \begin_inset listings
6246 \begin_layout Plain Layout
6248 length(active_chunk) {
6251 \begin_layout Plain Layout
6255 chunkref{process-chunk-tabs}>
6258 \begin_layout Plain Layout
6262 chunkref{process-chunk}>
6265 \begin_layout Plain Layout
6275 \begin_layout Standard
6276 If a chunk just consisted of plain text, we could handle the chunk like
6281 process-chunk-simple
6284 \begin_layout Standard
6285 \begin_inset listings
6289 \begin_layout Plain Layout
6291 chunk_line(active_chunk, $0 ORS);
6299 \begin_layout Standard
6300 but in fact a chunk can include references to other chunks.
6301 Chunk includes are traditionally written as
6302 \begin_inset Flex CharStyle:Code
6305 \begin_layout Plain Layout
6311 , but we support other variations.
6314 \begin_layout Standard
6315 However, we also process tabs at this point, a tab at input can be replaced
6316 by a number of spaces defined by the
6317 \begin_inset Flex CharStyle:Code
6320 \begin_layout Plain Layout
6326 variable, set by the
6327 \begin_inset Flex CharStyle:Code
6330 \begin_layout Plain Layout
6337 Of course this is poor tab behaviour, we should probably have the option
6338 to use proper counted tab-stops and process this on output.
6345 \begin_layout Standard
6346 \begin_inset listings
6350 \begin_layout Plain Layout
6355 \begin_layout Plain Layout
6362 \begin_layout Plain Layout
6372 \begin_layout Subsection
6373 \begin_inset CommandInset label
6375 name "sub:lstlistings-includes"
6382 \begin_layout Standard
6384 \begin_inset Flex CharStyle:Code
6387 \begin_layout Plain Layout
6390 lstset{escapeinside={=<}{>}}
6395 is set, then we can use
6396 \begin_inset Flex CharStyle:Code
6399 \begin_layout Plain Layout
6403 \begin_inset space \hspace{}
6414 \begin_inset Flex CharStyle:Code
6417 \begin_layout Plain Layout
6426 \begin_layout Enumerate
6427 it is a better mnemonic than
6428 \begin_inset Flex CharStyle:Code
6431 \begin_layout Plain Layout
6437 in that the = sign signifies equivalent or substitutability,
6440 \begin_layout Enumerate
6441 and because =< is not valid in C or in any language I can think of
6444 \begin_layout Enumerate
6445 and also because lstlistings doesn't like
6446 \begin_inset Flex CharStyle:Code
6449 \begin_layout Plain Layout
6455 as an end delimiter for the
6459 escape, so we must make do with a single
6460 \begin_inset Flex CharStyle:Code
6463 \begin_layout Plain Layout
6469 , which is better matched by
6470 \begin_inset Flex CharStyle:Code
6473 \begin_layout Plain Layout
6480 \begin_inset Flex CharStyle:Code
6483 \begin_layout Plain Layout
6492 \begin_layout Standard
6493 As each chunk line may contain more than one chunk include, we will split
6494 out chunk includes in an iterative fashion
6498 \begin_layout Plain Layout
6499 Contrary to our use of
6500 \begin_inset Flex CharStyle:Code
6503 \begin_layout Plain Layout
6509 when substituting parameters in chapter
6510 \begin_inset CommandInset ref
6512 reference "Here-we-split"
6524 \begin_layout Standard
6525 First, as long as the chunk contains a
6526 \begin_inset Flex CharStyle:Code
6529 \begin_layout Plain Layout
6537 command we take as much as we can up to the first
6538 \begin_inset Flex CharStyle:Code
6541 \begin_layout Plain Layout
6556 \begin_layout Standard
6557 \begin_inset listings
6561 \begin_layout Plain Layout
6566 \begin_layout Plain Layout
6571 \begin_layout Plain Layout
6576 \begin_layout Plain Layout
6594 )|)>|<<([a-zA-Z_][-a-zA-Z0-9_]*)>>)",
6597 \begin_layout Plain Layout
6604 \begin_layout Plain Layout
6609 \begin_layout Plain Layout
6611 chunklet = substr(chunk, 1, RSTART - 1);
6619 \begin_layout Standard
6620 We keep track of the indent count, by counting the number of literal characters
6622 We can then preserve this indent on each output line when multi-line chunks
6626 \begin_layout Standard
6627 We then process this first part literal text, and set the chunk which is
6628 still to be processed to be the text after the
6629 \begin_inset Flex CharStyle:Code
6632 \begin_layout Plain Layout
6640 command, which we will process next as we continue around the loop.
6643 \begin_layout Standard
6644 \begin_inset listings
6648 \begin_layout Plain Layout
6650 indent += length(chunklet);
6653 \begin_layout Plain Layout
6655 chunk_line(active_chunk, chunklet);
6658 \begin_layout Plain Layout
6660 chunk = substr(chunk, RSTART + RLENGTH);
6668 \begin_layout Standard
6669 We then consider the type of chunk command we have found, whether it is
6670 the newfangle style command beginning with
6671 \begin_inset Flex CharStyle:Code
6674 \begin_layout Plain Layout
6680 or the older notangle style beginning with
6681 \begin_inset Flex CharStyle:Code
6684 \begin_layout Plain Layout
6694 \begin_layout Standard
6695 Newfangle chunks may have parameters contained within square brackets.
6696 These will be matched in
6697 \begin_inset Flex CharStyle:Code
6700 \begin_layout Plain Layout
6706 and are considered at this stage of processing to be part of the name of
6707 the chunk to be included.
6710 \begin_layout Standard
6711 \begin_inset listings
6715 \begin_layout Plain Layout
6717 if (substr(line[1], 1, 1) == "=") {
6720 \begin_layout Plain Layout
6722 # chunk name up to }
6725 \begin_layout Plain Layout
6727 chunk_include(active_chunk, line[2] line[3], indent);
6730 \begin_layout Plain Layout
6732 } else if (substr(line[1], 1, 1) == "<") {
6735 \begin_layout Plain Layout
6737 chunk_include(active_chunk, line[4], indent);
6740 \begin_layout Plain Layout
6745 \begin_layout Plain Layout
6747 error("Unknown chunk fragment: " line[1]);
6750 \begin_layout Plain Layout
6760 \begin_layout Standard
6761 The loop will continue until there are no more chunkref statements in the
6762 text, at which point we process the final part of the chunk.
6765 \begin_layout Standard
6766 \begin_inset listings
6770 \begin_layout Plain Layout
6775 \begin_layout Plain Layout
6777 chunk_line(active_chunk, chunk);
6785 \begin_layout Standard
6786 \begin_inset CommandInset label
6792 We add the newline character as a chunklet on it's own, to make it easier
6793 to detect new lines and thus manage indentation when processing the output.
6796 \begin_layout Standard
6797 \begin_inset listings
6801 \begin_layout Plain Layout
6803 chunk_line(active_chunk, "
6813 \begin_layout Standard
6814 We will also permit a chunk-part number to follow in square brackets, so
6816 \begin_inset Flex CharStyle:Code
6819 \begin_layout Plain Layout
6822 chunkref{chunk-name[1]}>
6827 will refer to the first part only.
6828 This can make it easy to include a C function prototype in a header file,
6829 if the first part of the chunk is just the function prototype without the
6830 trailing semi-colon.
6831 The header file would include the prototype with the trailing semi-colon,
6835 \begin_layout LyX-Code
6838 chunkref{chunk-name[1]}>;
6841 \begin_layout Standard
6842 This is handled in section
6843 \begin_inset CommandInset ref
6845 reference "sub:Chunk-parts"
6852 \begin_layout Standard
6853 We should perhaps introduce a notion of language specific chunk options;
6854 so that perhaps we could specify:
6857 \begin_layout LyX-Code
6860 chunkref{chunk-name[function-declaration]}>;
6863 \begin_layout Standard
6864 which applies a transform
6865 \begin_inset Flex CharStyle:Code
6868 \begin_layout Plain Layout
6869 function-declaration
6874 to the chunk --- which in this case would extract a function prototype
6876 \begin_inset Note Note
6879 \begin_layout Plain Layout
6888 \begin_layout Chapter
6892 \begin_layout Standard
6893 At the start, first we set the default options.
6900 \begin_layout Standard
6901 \begin_inset listings
6905 \begin_layout Plain Layout
6910 \begin_layout Plain Layout
6915 \begin_layout Plain Layout
6920 \begin_layout Plain Layout
6925 \begin_layout Plain Layout
6935 \begin_layout Standard
6936 Then we use getopt the standard way, and null out ARGV afterwards in the
6944 \begin_layout Standard
6945 \begin_inset listings
6949 \begin_layout Plain Layout
6951 Optind = 1 # skip ARGV[0]
6954 \begin_layout Plain Layout
6956 while(getopt(ARGC, ARGV, "R:LdT:hr")!=-1) {
6959 \begin_layout Plain Layout
6963 chunkref{handle-options}>
6966 \begin_layout Plain Layout
6971 \begin_layout Plain Layout
6973 for (i=1; i<Optind; i++) { ARGV[i]=""; }
6981 \begin_layout Standard
6982 This is how we handle our options:
6989 \begin_layout Standard
6990 \begin_inset listings
6994 \begin_layout Plain Layout
6996 if (Optopt == "R") root = Optarg;
6999 \begin_layout Plain Layout
7001 else if (Optopt == "r") root="";
7004 \begin_layout Plain Layout
7006 else if (Optopt == "L") linenos = 1;
7009 \begin_layout Plain Layout
7011 else if (Optopt == "d") debug = 1;
7014 \begin_layout Plain Layout
7016 else if (Optopt == "T") tabs = indent_string(Optarg+0);
7019 \begin_layout Plain Layout
7021 else if (Optopt == "h") help();
7024 \begin_layout Plain Layout
7026 else if (Optopt == "?") help();
7034 \begin_layout Standard
7035 We do all of this at the beginning of the program
7042 \begin_layout Standard
7043 \begin_inset listings
7047 \begin_layout Plain Layout
7052 \begin_layout Plain Layout
7056 chunkref{constants}>
7059 \begin_layout Plain Layout
7063 chunkref{mode-definitions}>
7066 \begin_layout Plain Layout
7070 chunkref{default-options}>
7073 \begin_layout Plain Layout
7077 \begin_layout Plain Layout
7081 chunkref{read-options}>
7084 \begin_layout Plain Layout
7094 \begin_layout Standard
7095 And have a simple help function
7102 \begin_layout Standard
7103 \begin_inset listings
7107 \begin_layout Plain Layout
7112 \begin_layout Plain Layout
7117 \begin_layout Plain Layout
7119 print " newfangle [-L] -R<rootname> [source.tex ...]"
7122 \begin_layout Plain Layout
7124 print " newfangle -r [source.tex ...]"
7127 \begin_layout Plain Layout
7129 print " If the filename, source.tex is not specified then stdin is used"
7132 \begin_layout Plain Layout
7137 \begin_layout Plain Layout
7139 print "-L causes the C statement: #line <lineno>
7146 \begin_layout Plain Layout
7148 print "-R causes the named root to be written to stdout"
7151 \begin_layout Plain Layout
7153 print "-r lists all roots in the file (even those used elsewhere)"
7156 \begin_layout Plain Layout
7161 \begin_layout Plain Layout
7171 \begin_layout Chapter
7172 Chunk Language Modes
7175 \begin_layout Standard
7176 \begin_inset CommandInset label
7183 \begin_inset Note Greyedout
7186 \begin_layout Plain Layout
7187 This feature is in-development and does not work yet
7193 \begin_inset Note Note
7196 \begin_layout Plain Layout
7205 \begin_layout Standard
7206 lstlistings and newfangle both recognize source languages, and perform some
7208 lstlistings can detect strings and comments within a language definition
7209 and perform suitable rendering, such as italics for comments, and visible-space
7213 \begin_layout Standard
7214 Newfangle similarly can recognize strings, and comments, etc, within a language,
7215 so that any chunks included with
7216 \begin_inset Flex CharStyle:Code
7219 \begin_layout Plain Layout
7227 can be suitably quoted.
7230 \begin_layout Standard
7231 For instance, consider this chunk with
7232 \begin_inset Flex CharStyle:Code
7235 \begin_layout Plain Layout
7245 example-perl,language=perl
7248 \begin_layout Standard
7249 \begin_inset listings
7253 \begin_layout Plain Layout
7263 \begin_layout Standard
7264 If it were included in a chunk with
7265 \begin_inset Flex CharStyle:Code
7268 \begin_layout Plain Layout
7278 example-sh,language=sh
7281 \begin_layout Standard
7282 \begin_inset listings
7286 \begin_layout Plain Layout
7290 chunkref{example-perl}>"
7298 \begin_layout Standard
7299 would need to generate output like this if it were to work:
7302 \begin_layout LyX-Code
7310 \begin_layout Standard
7311 See that the double quote " as part of the regex has been quoted with a
7312 slash to protect it from shell interpretation.
7315 \begin_layout Standard
7316 If that were then included in a chunk with
7317 \begin_inset Flex CharStyle:Code
7320 \begin_layout Plain Layout
7330 example-makefile,language=make
7333 \begin_layout Standard
7334 \begin_inset listings
7338 \begin_layout Plain Layout
7343 \begin_layout Plain Layout
7347 chunkref{example-sh}>
7355 \begin_layout Standard
7356 We would need the output to look like this --- note the $$:
7359 \begin_layout LyX-Code
7363 \begin_layout LyX-Code
7371 \begin_layout Standard
7372 In order to make this work, we need to define a mode-tracker for each supported
7373 language, that can detect the various quoting modes, and provide a transformati
7374 on that must be applied to any included text so that included text will
7375 be interpreted correctly after the additional interpolation that it will
7376 be subject to at run-time.
7379 \begin_layout Standard
7380 For example, the transformation for text to be inserted into sh double-quoted
7381 strings would be something like:
7384 \begin_layout LyX-Code
7408 \begin_layout Standard
7410 \begin_inset Flex CharStyle:Code
7413 \begin_layout Plain Layout
7424 \begin_layout Standard
7425 \begin_inset Note Note
7428 \begin_layout Plain Layout
7429 I don't think this example is true
7434 The mode tracker must also track nested mode-changes, as in this
7435 \begin_inset Flex CharStyle:Code
7438 \begin_layout Plain Layout
7447 \begin_layout LyX-Code
7448 echo "hello `id **`"
7451 \begin_layout Standard
7452 Any literal text inserted at the point marked ** would need to be escaped
7453 in all kinds of ways, including
7454 \begin_inset Flex CharStyle:Code
7457 \begin_layout Plain Layout
7464 First it would need escaping for the back-ticks `, and then for the double-quot
7468 \begin_layout Standard
7469 Escaping need not occur if the format and mode of the included chunk matches
7470 that of the including chunk, which would suggest that any back-ticks might
7471 need to be part of the included chunk and not including chunk
7472 \begin_inset Note Note
7475 \begin_layout Plain Layout
7476 or is it the other way around?
7484 \begin_layout Standard
7485 As each chunk is output a new mode tracker for that language is initialized
7486 in it's normal state.
7487 As text is output for that chunk the output mode is tracked.
7488 When a new chunk is included, a transformation appropriate to that mode
7489 is selected and pushed onto a stack of transformations.
7490 Any text to be output is first passed through this stack of transformations.
7493 \begin_layout Standard
7494 It remains to consider if the chunk-include function should return it's
7495 generated text so that the caller can apply any transformations (and formatting
7496 ), or if it should apply the stack of transformations itself.
7499 \begin_layout Standard
7500 Note that the transformed text should have the property of not being able
7501 to change the mode in the current chunk.
7504 \begin_layout Standard
7505 \begin_inset Note Note
7508 \begin_layout Plain Layout
7509 Note chunk parameters should probably also be transformed
7521 \begin_layout Standard
7522 \begin_inset listings
7526 \begin_layout Plain Layout
7528 function new_mode(language, mode) {
7531 \begin_layout Plain Layout
7533 mode["language"] = language;
7536 \begin_layout Plain Layout
7541 \begin_layout Plain Layout
7551 \begin_layout Standard
7552 Because awk functions cannot return an array, we must create the array first
7557 new-mode,params=language;mode
7560 \begin_layout Standard
7561 \begin_inset listings
7565 \begin_layout Plain Layout
7569 chunkref{awk-delete-array}(${mode})>
7572 \begin_layout Plain Layout
7574 new_mode(${language}, ${mode});
7582 \begin_layout Standard
7583 And for tracking modes, we dispatch to a mode-tracker action based on the
7591 \begin_layout Standard
7592 \begin_inset listings
7596 \begin_layout Plain Layout
7598 function track_mode(mode, text) {
7601 \begin_layout Plain Layout
7603 if (mode["language"] == "C") {
7606 \begin_layout Plain Layout
7610 chunkref{track-mode-C}>
7613 \begin_layout Plain Layout
7618 \begin_layout Plain Layout
7623 \begin_layout Plain Layout
7633 \begin_layout Standard
7634 For each mode, we look for a character that has the power to change the
7638 \begin_layout Standard
7643 \labelwidthstring 00.00.0000
7644 \begin_inset Quotes eld
7647 enters double-quote mode
7651 \labelwidthstring 00.00.0000
7652 ' enters single-quote mode
7656 \labelwidthstring 00.00.0000
7659 enters multi-line mode
7663 \labelwidthstring 00.00.0000
7664 # enters #define sub-mode, needs
7666 escaping end of line too
7670 \labelwidthstring 00.00.0000
7671 /* enters comment mode
7674 \begin_layout Standard
7675 In double-quote mode, escape
7678 \begin_inset Quotes eld
7684 \begin_layout Standard
7688 \begin_inset Quotes eld
7694 \begin_layout Standard
7695 \begin_inset Quotes eld
7701 \begin_layout Standard
7702 newline needs to close and re-open string or something
7705 \begin_layout Standard
7706 in single-quote mode escape
7709 \begin_inset Quotes eld
7719 \begin_layout Standard
7720 \begin_inset listings
7724 \begin_layout Plain Layout
7737 \begin_layout Standard
7738 \begin_inset listings
7742 \begin_layout Plain Layout
7746 chunkref{new_mode()}>
7749 \begin_layout Plain Layout
7753 chunkref{parse_chunk_args}>
7761 \begin_layout Chapter
7762 Generating the output
7765 \begin_layout Standard
7766 We generate output by calling output_chunk, or listing the chunk names.
7773 \begin_layout Standard
7774 \begin_inset listings
7778 \begin_layout Plain Layout
7780 if (length(root)) output_chunk(root);
7783 \begin_layout Plain Layout
7785 else output_chunk_names();
7793 \begin_layout Standard
7794 We also have some other output debugging:
7801 \begin_layout Standard
7802 \begin_inset listings
7806 \begin_layout Plain Layout
7811 \begin_layout Plain Layout
7813 print "------ chunk names "
7816 \begin_layout Plain Layout
7818 output_chunk_names();
7821 \begin_layout Plain Layout
7823 print "====== chunks"
7826 \begin_layout Plain Layout
7831 \begin_layout Plain Layout
7833 print "++++++ debug"
7836 \begin_layout Plain Layout
7841 \begin_layout Plain Layout
7843 print a "=" chunks[a];
7846 \begin_layout Plain Layout
7851 \begin_layout Plain Layout
7861 \begin_layout Standard
7862 We do both of these at the end.
7864 \begin_inset Flex CharStyle:Code
7867 \begin_layout Plain Layout
7873 because each chunklet is not necessarily a complete line, and we already
7875 \begin_inset Flex CharStyle:Code
7878 \begin_layout Plain Layout
7884 to each input line in section
7885 \begin_inset CommandInset ref
7887 reference "sub:ORS-chunk-text"
7898 \begin_layout Standard
7899 \begin_inset listings
7903 \begin_layout Plain Layout
7908 \begin_layout Plain Layout
7912 chunkref{debug-output}>
7915 \begin_layout Plain Layout
7920 \begin_layout Plain Layout
7924 chunkref{generate-output}>
7927 \begin_layout Plain Layout
7937 \begin_layout Standard
7938 We write chunk names like this.
7939 If we seem to be running in notangle compatibility mode, then we enclose
7941 \begin_inset Flex CharStyle:Code
7944 \begin_layout Plain Layout
7950 the same way notangle does:
7954 output_chunk_names()
7957 \begin_layout Standard
7958 \begin_inset listings
7962 \begin_layout Plain Layout
7964 function output_chunk_names( c, prefix, suffix)
7967 \begin_layout Plain Layout
7972 \begin_layout Plain Layout
7974 if (notangle_mode) {
7977 \begin_layout Plain Layout
7982 \begin_layout Plain Layout
7987 \begin_layout Plain Layout
7992 \begin_layout Plain Layout
7994 for (c in chunk_names) {
7997 \begin_layout Plain Layout
7999 print prefix c suffix "
8004 \begin_layout Plain Layout
8009 \begin_layout Plain Layout
8019 \begin_layout Standard
8020 This function would write out all chunks
8027 \begin_layout Standard
8028 \begin_inset listings
8032 \begin_layout Plain Layout
8034 function output_chunks( a)
8037 \begin_layout Plain Layout
8042 \begin_layout Plain Layout
8044 for (a in chunk_names) {
8047 \begin_layout Plain Layout
8049 output_chunk(chunk_names[a]);
8052 \begin_layout Plain Layout
8057 \begin_layout Plain Layout
8062 \begin_layout Plain Layout
8066 \begin_layout Plain Layout
8068 function output_chunk(chunk) {
8071 \begin_layout Plain Layout
8076 \begin_layout Plain Layout
8078 lineno_needed = linenos;
8081 \begin_layout Plain Layout
8085 \begin_layout Plain Layout
8090 \begin_layout Plain Layout
8095 \begin_layout Plain Layout
8104 \begin_layout Section
8105 Assembling the chunks
8108 \begin_layout Standard
8109 \begin_inset Flex CharStyle:Code
8112 \begin_layout Plain Layout
8118 holds a string consisting of the names of all the chunks that resulted
8119 in this chunk being output.
8121 \begin_inset Note Note
8124 \begin_layout Plain Layout
8125 Make sure it includes the line numbers too...
8131 It should probably also contain the source line numbers at which each inclusion
8136 write_chunk(),emph={chunk_path}
8139 \begin_layout Standard
8140 \begin_inset listings
8144 \begin_layout Plain Layout
8146 function write_chunk(chunk_name, indent, tail,
8149 \begin_layout Plain Layout
8154 \begin_layout Plain Layout
8156 chunk_path, chunk_args,
8159 \begin_layout Plain Layout
8164 \begin_layout Plain Layout
8166 part, max_part, part_line, frag, max_frag, text,
8169 \begin_layout Plain Layout
8171 chunklet, only_part, call_chunk_args, mode)
8174 \begin_layout Plain Layout
8184 \begin_layout Subsection
8185 \begin_inset CommandInset label
8187 name "sub:Chunk-parts"
8194 \begin_layout Standard
8195 As mentioned in section
8196 \begin_inset CommandInset ref
8198 reference "sub:lstlistings-includes"
8202 , a chunk name may contain a part specifier in square brackets, limiting
8203 the parts that should be emitted.
8206 \begin_layout Standard
8207 \begin_inset listings
8211 \begin_layout Plain Layout
8213 if (match(chunk_name, "^(.*)
8221 ]$", chunk_name_parts)) {
8224 \begin_layout Plain Layout
8226 chunk_name = chunk_name_parts[1];
8229 \begin_layout Plain Layout
8231 only_part = chunk_name_parts[2];
8234 \begin_layout Plain Layout
8244 \begin_layout Standard
8245 We first create the mode tracker for this chunk.
8248 \begin_layout Standard
8251 chunkref{awk-delete-array}(mode)>
8254 \begin_layout Standard
8255 \begin_inset listings
8259 \begin_layout Plain Layout
8264 \begin_layout Plain Layout
8266 new_mode(chunks[chunk_name, "language"], mode);
8274 \begin_layout Standard
8277 chunkref{new-mode}(chunks[chunk_name, "language"], mode)>
8280 \begin_layout Standard
8282 \begin_inset Flex CharStyle:Code
8285 \begin_layout Plain Layout
8291 the names of the parameters that this chunk accepts, whose values were
8292 (optionally) passed in
8293 \begin_inset Flex CharStyle:Code
8296 \begin_layout Plain Layout
8305 \begin_layout Standard
8306 \begin_inset listings
8310 \begin_layout Plain Layout
8312 split(chunks[chunk_name, "params"], chunk_params, " *; *");
8320 \begin_layout Standard
8321 To assemble a chunk, we write out each part.
8328 \begin_layout Standard
8329 \begin_inset listings
8333 \begin_layout Plain Layout
8335 if (! (chunk_name in chunk_names)) {
8338 \begin_layout Plain Layout
8340 error(sprintf(_"The root module <<%s>> was not defined.
8347 \begin_layout Plain Layout
8349 chunk_name, chunk_path));
8352 \begin_layout Plain Layout
8357 \begin_layout Plain Layout
8361 \begin_layout Plain Layout
8363 max_part = chunks[chunk_name, "part"];
8366 \begin_layout Plain Layout
8368 for(part = 1; part <= max_part; part++) {
8371 \begin_layout Plain Layout
8373 if (! only_part || part == only_part) {
8376 \begin_layout Plain Layout
8380 chunkref{write-part}>
8383 \begin_layout Plain Layout
8388 \begin_layout Plain Layout
8393 \begin_layout Plain Layout
8403 \begin_layout Standard
8404 A part can either be a chunklet of lines, or an include of another chunk.
8407 \begin_layout Standard
8408 Chunks may also have parameters, specified in LaTeX style with braces after
8409 the chunk name --- looking like this in the document:
8410 \begin_inset Flex CharStyle:Code
8413 \begin_layout Plain Layout
8414 chunkname{param1, param2}
8420 Arguments are passed in square brackets:
8421 \begin_inset Flex CharStyle:Code
8424 \begin_layout Plain Layout
8427 chunkref{chunkname}[arg1, arg2]
8435 \begin_layout Standard
8436 Before we process each part, we check that the source position hasn't changed
8437 unexpectedly, so that we can know if we need to output a new file-line
8445 \begin_layout Standard
8446 \begin_inset listings
8450 \begin_layout Plain Layout
8454 chunkref{check-source-jump}>
8457 \begin_layout Plain Layout
8461 \begin_layout Plain Layout
8463 chunklet = chunks[chunk_name, "part", part];
8466 \begin_layout Plain Layout
8468 if (chunks[chunk_name, "part", part, "type"] == part_type_chunk) {
8471 \begin_layout Plain Layout
8475 chunkref{write-included-chunk}>
8478 \begin_layout Plain Layout
8480 } else if (chunklet SUBSEP "line" in chunks) {
8483 \begin_layout Plain Layout
8487 chunkref{write-chunklets}>
8490 \begin_layout Plain Layout
8495 \begin_layout Plain Layout
8497 # empty last chunklet
8500 \begin_layout Plain Layout
8510 \begin_layout Standard
8511 To write an included chunk, we must detect any optional chunk arguments
8513 Then we recurse calling
8514 \begin_inset Flex Chunkref
8517 \begin_layout Plain Layout
8527 write-included-chunk
8530 \begin_layout Standard
8531 \begin_inset listings
8535 \begin_layout Plain Layout
8537 if (match(chunklet, "^([^
8549 )$", chunklet_parts)) {
8552 \begin_layout Plain Layout
8554 chunklet = chunklet_parts[1];
8557 \begin_layout Plain Layout
8559 parse_chunk_args("", chunklet_parts[2], call_chunk_args, "(");
8562 \begin_layout Plain Layout
8564 for (c in call_chunk_args) {
8567 \begin_layout Plain Layout
8569 call_chunk_args[c] = expand_chunk_args(call_chunk_args[c], chunk_params,
8573 \begin_layout Plain Layout
8578 \begin_layout Plain Layout
8583 \begin_layout Plain Layout
8585 split("", call_chunk_args);
8588 \begin_layout Plain Layout
8593 \begin_layout Plain Layout
8595 write_chunk(chunklet,
8598 \begin_layout Plain Layout
8600 chunks[chunk_name, "part", part, "indent"] indent,
8603 \begin_layout Plain Layout
8605 chunks[chunk_name, "part", part, "tail"],
8608 \begin_layout Plain Layout
8615 \begin_layout Plain Layout
8625 \begin_layout Standard
8626 Before we output a chunklet of lines, we first emit the file and line number
8627 if we have one, and if it is safe to do so.
8631 \begin_layout Standard
8632 Chunklets are generally broken up by includes, so the start of a chunklet
8633 is a good place to do this.
8634 Then we output each line of the chunklet.
8637 \begin_layout Standard
8638 When it is not safe, such as in the middle of a multi-line macro definition,
8640 \begin_inset Flex CharStyle:Code
8643 \begin_layout Plain Layout
8649 is set to true, and in such a case we note that we want to emit the line
8650 statement when it is next safe.
8657 \begin_layout Standard
8658 \begin_inset listings
8662 \begin_layout Plain Layout
8664 max_frag = chunks[chunklet, "line"];
8667 \begin_layout Plain Layout
8669 for(frag = 1; frag <= max_frag; frag++) {
8672 \begin_layout Plain Layout
8676 chunkref{write-file-line}>
8684 \begin_layout Standard
8685 We then extract the chunklet text and expand any arguments.
8688 \begin_layout Standard
8689 \begin_inset listings
8693 \begin_layout Plain Layout
8697 \begin_layout Plain Layout
8699 text = chunks[chunklet, frag];
8702 \begin_layout Plain Layout
8707 \begin_layout Plain Layout
8712 \begin_layout Plain Layout
8714 text = expand_chunk_args(text, chunk_params, chunk_args);
8722 \begin_layout Standard
8723 If the text is a single newline (which we keep separate - see
8724 \begin_inset CommandInset ref
8726 reference "lone-newline"
8730 ) then we increment the line number.
8731 In the case where this is the last line of a chunk and it is not a top-level
8732 chunk we replace the newline with an empty string --- because the chunk
8733 that included this chunk will have the newline at the end of the line that
8734 included this chunk.
8737 \begin_layout Standard
8739 \begin_inset Flex CharStyle:Code
8742 \begin_layout Plain Layout
8748 that we have started a new line, so that indentation can be managed with
8749 the following piece of text.
8752 \begin_layout Standard
8753 \begin_inset listings
8757 \begin_layout Plain Layout
8761 \begin_layout Plain Layout
8768 \begin_layout Plain Layout
8773 \begin_layout Plain Layout
8775 if (part == max_part && frag == max_frag && length(chunk_path)) {
8778 \begin_layout Plain Layout
8783 \begin_layout Plain Layout
8788 \begin_layout Plain Layout
8793 \begin_layout Plain Layout
8798 \begin_layout Plain Layout
8808 \begin_layout Standard
8809 If this text does not represent a newline, but we see that we are the first
8810 piece of text on a newline, then we prefix our text with the current indent.
8812 \begin_inset Flex CharStyle:Code
8815 \begin_layout Plain Layout
8821 is a global output-state variable, but the
8822 \begin_inset Flex CharStyle:Code
8825 \begin_layout Plain Layout
8835 \begin_layout Standard
8836 \begin_inset listings
8840 \begin_layout Plain Layout
8842 } else if (length(text) || length(tail)) {
8845 \begin_layout Plain Layout
8847 if (newline) text = indent text;
8850 \begin_layout Plain Layout
8855 \begin_layout Plain Layout
8860 \begin_layout Plain Layout
8869 \begin_layout Standard
8870 Tail will soon no longer be relevant once mode-detection is in place.
8873 \begin_layout Standard
8874 \begin_inset listings
8878 \begin_layout Plain Layout
8883 \begin_layout Plain Layout
8885 # track_mode(mode, text);
8888 \begin_layout Plain Layout
8898 \begin_layout Standard
8899 If a line ends in a backslash --- suggesting continuation --- then we supress
8900 outputting file-line as it would probably break the continued lines.
8904 \begin_layout Standard
8905 \begin_inset listings
8909 \begin_layout Plain Layout
8914 \begin_layout Plain Layout
8916 lineno_suppressed = substr(lastline, length(lastline)) == "
8923 \begin_layout Plain Layout
8928 \begin_layout Plain Layout
8938 \begin_layout Standard
8939 Of course there is no point in actually outputting the source filename and
8940 line number (file-line) if they don't say anything new! We only need to
8941 emit them if they aren't what is expected, or if we we not able to emit
8942 one when they had changed.
8949 \begin_layout Standard
8950 \begin_inset listings
8954 \begin_layout Plain Layout
8956 if (newline && lineno_needed && ! lineno_suppressed) {
8959 \begin_layout Plain Layout
8961 filename = a_filename;
8964 \begin_layout Plain Layout
8969 \begin_layout Plain Layout
8971 print "#line " lineno "
8980 \begin_layout Plain Layout
8985 \begin_layout Plain Layout
8995 \begin_layout Standard
8996 We check if a new file-line is needed by checking if the source line matches
8997 what we (or a compiler) would expect.
9005 \begin_layout Standard
9006 \begin_inset listings
9010 \begin_layout Plain Layout
9012 if (linenos && (chunk_name SUBSEP "part" SUBSEP part SUBSEP "FILENAME" in
9016 \begin_layout Plain Layout
9018 a_filename = chunks[chunk_name, "part", part, "FILENAME"];
9021 \begin_layout Plain Layout
9023 a_lineno = chunks[chunk_name, "part", part, "LINENO"];
9026 \begin_layout Plain Layout
9028 if (a_filename != filename || a_lineno != lineno) {
9031 \begin_layout Plain Layout
9036 \begin_layout Plain Layout
9041 \begin_layout Plain Layout
9051 \begin_layout Chapter
9055 \begin_layout Standard
9056 Awk has pretty limited data structures, so we will use two main hashes.
9057 Uninterrupted sequences of a chunk will be stored in
9058 \begin_inset Flex CharStyle:Code
9061 \begin_layout Plain Layout
9067 and the chunklets used in a chunk will be stored in
9068 \begin_inset Flex CharStyle:Code
9071 \begin_layout Plain Layout
9084 \begin_layout Standard
9085 \begin_inset listings
9089 \begin_layout Plain Layout
9094 \begin_layout Plain Layout
9104 \begin_layout Standard
9106 \begin_inset Flex CharStyle:Code
9109 \begin_layout Plain Layout
9115 mentioned are not chunk parameters for parameterized chunks, as mentioned
9117 \begin_inset CommandInset ref
9119 reference "cha:Chunk Arguments"
9123 , but the lstlistings style parameters used in the
9124 \begin_inset Flex CharStyle:Code
9127 \begin_layout Plain Layout
9139 \begin_layout Plain Layout
9141 \begin_inset Flex CharStyle:Code
9144 \begin_layout Plain Layout
9150 parameter is used to hold the parameters for parameterized chunks
9159 chunk-storage-functions
9162 \begin_layout Standard
9163 \begin_inset listings
9167 \begin_layout Plain Layout
9169 function new_chunk(chunk_name, params,
9172 \begin_layout Plain Layout
9177 \begin_layout Plain Layout
9182 \begin_layout Plain Layout
9187 \begin_layout Plain Layout
9189 # HACK WHILE WE CHANGE TO ( ) for PARAM CHUNKS
9192 \begin_layout Plain Layout
9202 )$", "", chunk_name);
9205 \begin_layout Plain Layout
9207 if (! (chunk_name in chunk_names)) {
9210 \begin_layout Plain Layout
9212 if (debug) print "New chunk " chunk_name;
9215 \begin_layout Plain Layout
9217 chunk_names[chunk_name];
9220 \begin_layout Plain Layout
9225 \begin_layout Plain Layout
9227 chunks[chunk_name, p] = params[p];
9230 \begin_layout Plain Layout
9235 \begin_layout Plain Layout
9237 if ("append" in params) {
9240 \begin_layout Plain Layout
9242 append=params["append"];
9245 \begin_layout Plain Layout
9247 if (! (append in chunk_names)) {
9250 \begin_layout Plain Layout
9252 warning("Chunk " chunk_name " is appended to chunk " append " which
9253 is not defined yet");
9256 \begin_layout Plain Layout
9261 \begin_layout Plain Layout
9266 \begin_layout Plain Layout
9268 chunk_include(append, chunk_name);
9271 \begin_layout Plain Layout
9273 chunk_line(append, ORS);
9276 \begin_layout Plain Layout
9281 \begin_layout Plain Layout
9286 \begin_layout Plain Layout
9288 active_chunk = chunk_name;
9291 \begin_layout Plain Layout
9293 prime_chunk(chunk_name);
9296 \begin_layout Plain Layout
9306 \begin_layout Standard
9307 \begin_inset listings
9311 \begin_layout Plain Layout
9315 \begin_layout Plain Layout
9317 function prime_chunk(chunk_name)
9320 \begin_layout Plain Layout
9325 \begin_layout Plain Layout
9327 chunks[chunk_name, "part", ++chunks[chunk_name, "part"] ] =
9332 \begin_layout Plain Layout
9334 chunk_name SUBSEP "chunklet" SUBSEP "" ++chunks[chunk_name, "chunklet"]
9338 \begin_layout Plain Layout
9340 chunks[chunk_name, "part", chunks[chunk_name, "part"], "FILENAME"] = FILENAME;
9343 \begin_layout Plain Layout
9345 chunks[chunk_name, "part", chunks[chunk_name, "part"], "LINENO"] = FNR
9349 \begin_layout Plain Layout
9354 \begin_layout Plain Layout
9358 \begin_layout Plain Layout
9360 function chunk_line(chunk_name, line){
9363 \begin_layout Plain Layout
9365 chunks[chunk_name, "chunklet", chunks[chunk_name, "chunklet"],
9368 \begin_layout Plain Layout
9370 ++chunks[chunk_name, "chunklet", chunks[chunk_name, "chunklet"],
9374 \begin_layout Plain Layout
9379 \begin_layout Plain Layout
9388 \begin_layout Standard
9389 Chunk include represents a
9393 statement, and stores the requirement to include another chunk.
9394 The parameter indent represents the quanity of literal text characters
9399 statement and therefore by how much additional lines of the included chunk
9403 \begin_layout Standard
9404 \begin_inset listings
9408 \begin_layout Plain Layout
9410 function chunk_include(chunk_name, chunk_ref, indent, tail)
9413 \begin_layout Plain Layout
9418 \begin_layout Plain Layout
9420 chunks[chunk_name, "part", ++chunks[chunk_name, "part"] ] = chunk_ref;
9423 \begin_layout Plain Layout
9425 chunks[chunk_name, "part", chunks[chunk_name, "part"], "type" ] = part_type_ch
9429 \begin_layout Plain Layout
9431 chunks[chunk_name, "part", chunks[chunk_name, "part"], "indent" ] = indent_str
9435 \begin_layout Plain Layout
9437 chunks[chunk_name, "part", chunks[chunk_name, "part"], "tail" ] = tail;
9440 \begin_layout Plain Layout
9442 prime_chunk(chunk_name);
9445 \begin_layout Plain Layout
9450 \begin_layout Plain Layout
9459 \begin_layout Standard
9460 The indent is calculated by indent_string, which may in future convert some
9461 spaces into tab characters.
9462 This function works by generating a printf padded format string, like
9463 \begin_inset Flex CharStyle:Code
9466 \begin_layout Plain Layout
9472 for an indent of 22, and then printing an empty string using that format.
9475 \begin_layout Standard
9476 \begin_inset listings
9480 \begin_layout Plain Layout
9482 function indent_string(indent) {
9485 \begin_layout Plain Layout
9487 return sprintf("%" indent "s", "");
9490 \begin_layout Plain Layout
9500 \begin_layout Chapter
9501 \begin_inset CommandInset label
9510 \begin_layout Standard
9511 I use Arnold Robbins public domain getopt (1993 revision).
9512 This is probably the same one that is covered in chapter 12 of
9513 \begin_inset Quotes eld
9516 Edition 3 of GAWK: Effective AWK Programming: A User's Guide for GNU Awk
9517 \begin_inset Quotes erd
9520 but as that is licensed under the GNU Free Documentation License, Version
9521 1.3, which conflicts with the GPL3, I can't use it from there (or it's accompany
9522 ing explanations), so I do my best to explain how it works here.
9525 \begin_layout Standard
9526 The getopt.awk header is:
9530 getopt.awk-header,language=awk,morestring=[b]{/},morekeywords=else
9533 \begin_layout Standard
9534 \begin_inset listings
9538 \begin_layout Plain Layout
9540 # getopt.awk --- do C library getopt(3) function in awk
9543 \begin_layout Plain Layout
9548 \begin_layout Plain Layout
9550 # Arnold Robbins, arnold@skeeve.com, Public Domain
9553 \begin_layout Plain Layout
9558 \begin_layout Plain Layout
9560 # Initial version: March, 1991
9563 \begin_layout Plain Layout
9565 # Revised: May, 1993
9573 \begin_layout Standard
9574 The provided explanation is:
9581 \begin_layout Standard
9582 \begin_inset listings
9586 \begin_layout Plain Layout
9588 # External variables:
9591 \begin_layout Plain Layout
9593 # Optind -- index in ARGV of first nonoption argument
9596 \begin_layout Plain Layout
9598 # Optarg -- string value of argument to current option
9601 \begin_layout Plain Layout
9603 # Opterr -- if nonzero, print our own diagnostic
9606 \begin_layout Plain Layout
9608 # Optopt -- current option letter
9611 \begin_layout Plain Layout
9615 \begin_layout Plain Layout
9620 \begin_layout Plain Layout
9622 # -1 at end of options
9625 \begin_layout Plain Layout
9627 # ? for unrecognized option
9630 \begin_layout Plain Layout
9632 # <c> a character representing the current option
9635 \begin_layout Plain Layout
9639 \begin_layout Plain Layout
9644 \begin_layout Plain Layout
9646 # _opti -- index in multi-flag option, e.g., -abc
9654 \begin_layout Standard
9655 The function follows.
9656 The final two parameters,
9657 \begin_inset Flex CharStyle:Code
9660 \begin_layout Plain Layout
9667 \begin_inset Flex CharStyle:Code
9670 \begin_layout Plain Layout
9676 are local variables and not parameters --- as indicated by the multiple
9677 spaces preceding them.
9678 Awk doesn't care, the multiple spaces are a convention to help us humans.
9685 \begin_layout Standard
9686 \begin_inset listings
9690 \begin_layout Plain Layout
9692 function getopt(argc, argv, options, thisopt, i)
9695 \begin_layout Plain Layout
9700 \begin_layout Plain Layout
9702 if (length(options) == 0) # no options given
9705 \begin_layout Plain Layout
9710 \begin_layout Plain Layout
9712 if (argv[Optind] == "--") { # all done
9715 \begin_layout Plain Layout
9720 \begin_layout Plain Layout
9725 \begin_layout Plain Layout
9730 \begin_layout Plain Layout
9732 } else if (argv[Optind] !~ /^-[^:
9747 \begin_layout Plain Layout
9752 \begin_layout Plain Layout
9757 \begin_layout Plain Layout
9762 \begin_layout Plain Layout
9767 \begin_layout Plain Layout
9772 \begin_layout Plain Layout
9774 thisopt = substr(argv[Optind], _opti, 1)
9777 \begin_layout Plain Layout
9782 \begin_layout Plain Layout
9784 i = index(options, thisopt)
9787 \begin_layout Plain Layout
9792 \begin_layout Plain Layout
9797 \begin_layout Plain Layout
9799 printf("%c -- invalid option
9804 \begin_layout Plain Layout
9806 thisopt) > "/dev/stderr"
9809 \begin_layout Plain Layout
9811 if (_opti >= length(argv[Optind])) {
9814 \begin_layout Plain Layout
9819 \begin_layout Plain Layout
9824 \begin_layout Plain Layout
9829 \begin_layout Plain Layout
9834 \begin_layout Plain Layout
9839 \begin_layout Plain Layout
9849 \begin_layout Standard
9850 At this point, the option has been found and we need to know if it takes
9854 \begin_layout Standard
9855 \begin_inset listings
9859 \begin_layout Plain Layout
9861 if (substr(options, i + 1, 1) == ":") {
9864 \begin_layout Plain Layout
9866 # get option argument
9869 \begin_layout Plain Layout
9871 if (length(substr(argv[Optind], _opti + 1)) > 0)
9874 \begin_layout Plain Layout
9876 Optarg = substr(argv[Optind], _opti + 1)
9879 \begin_layout Plain Layout
9884 \begin_layout Plain Layout
9886 Optarg = argv[++Optind]
9889 \begin_layout Plain Layout
9894 \begin_layout Plain Layout
9899 \begin_layout Plain Layout
9904 \begin_layout Plain Layout
9906 if (_opti == 0 || _opti >= length(argv[Optind])) {
9909 \begin_layout Plain Layout
9914 \begin_layout Plain Layout
9919 \begin_layout Plain Layout
9924 \begin_layout Plain Layout
9929 \begin_layout Plain Layout
9934 \begin_layout Plain Layout
9941 A test program is built in, too
9948 \begin_layout Standard
9949 \begin_inset listings
9953 \begin_layout Plain Layout
9958 \begin_layout Plain Layout
9960 Opterr = 1 # default is to diagnose
9963 \begin_layout Plain Layout
9965 Optind = 1 # skip ARGV[0]
9968 \begin_layout Plain Layout
9973 \begin_layout Plain Layout
9978 \begin_layout Plain Layout
9980 while ((_go_c = getopt(ARGC, ARGV, "ab:cd")) != -1)
9983 \begin_layout Plain Layout
9985 printf("c = <%c>, optarg = <%s>
9990 \begin_layout Plain Layout
9995 \begin_layout Plain Layout
9997 printf("non-option arguments:
10002 \begin_layout Plain Layout
10004 for (; Optind < ARGC; Optind++)
10007 \begin_layout Plain Layout
10016 \begin_layout Plain Layout
10018 Optind, ARGV[Optind])
10021 \begin_layout Plain Layout
10026 \begin_layout Plain Layout
10036 \begin_layout Standard
10037 The entire getopt.awk is made out of these chunks in order
10040 \begin_layout Chunk
10044 \begin_layout Standard
10045 \begin_inset listings
10049 \begin_layout Plain Layout
10053 chunkref{getopt.awk-header}>
10056 \begin_layout Plain Layout
10060 \begin_layout Plain Layout
10064 chunkref{getopt.awk-notes}>
10067 \begin_layout Plain Layout
10071 chunkref{getopt.awk-getopt()}>
10074 \begin_layout Plain Layout
10078 chunkref{getopt.awk-begin}>
10086 \begin_layout Standard
10087 Although we only want the header and function:
10090 \begin_layout Chunk
10094 \begin_layout Standard
10095 \begin_inset listings
10099 \begin_layout Plain Layout
10101 # try: locate getopt.awk for the full original file
10104 \begin_layout Plain Layout
10106 # as part of your standard awk installation
10109 \begin_layout Plain Layout
10113 chunkref{getopt.awk-header}>
10116 \begin_layout Plain Layout
10120 \begin_layout Plain Layout
10124 chunkref{getopt.awk-getopt()}>
10132 \begin_layout Chapter
10133 Newfangle LaTeX source code
10136 \begin_layout Section
10140 \begin_layout Standard
10141 Here we define a Lyx .module file that makes it convenient to use LyX for
10142 writing such literate programs.
10145 \begin_layout Standard
10147 \begin_inset Flex CharStyle:Code
10150 \begin_layout Plain Layout
10156 can be installed in your personal
10157 \begin_inset Flex CharStyle:Code
10160 \begin_layout Plain Layout
10161 .lyx/layouts folder
10167 You will need to Tools Reconfigure so that LyX notices it.
10168 It adds a new format Chunk, which should precede every listing and contain
10173 \begin_layout Chunk
10174 ./newfangle.module,language=
10177 \begin_layout Standard
10178 \begin_inset listings
10182 \begin_layout Plain Layout
10186 DeclareLyXModule{Newfangle Literate Listings}
10189 \begin_layout Plain Layout
10194 \begin_layout Plain Layout
10196 # Newfangle literate listings allow one to write
10199 \begin_layout Plain Layout
10201 # literate programs after the fashion of noweb, but without having
10204 \begin_layout Plain Layout
10206 # to use noweave to generate the documentation.
10207 Instead the listings
10210 \begin_layout Plain Layout
10212 # package is extended in conjunction with the noweb package to implement
10215 \begin_layout Plain Layout
10217 # to code formating directly as latex.
10220 \begin_layout Plain Layout
10222 # The newfangle awk script
10225 \begin_layout Plain Layout
10230 \begin_layout Plain Layout
10234 \begin_layout Plain Layout
10239 \begin_layout Plain Layout
10243 \begin_layout Plain Layout
10248 \begin_layout Plain Layout
10252 chunkref{./newfangle.sty}>
10255 \begin_layout Plain Layout
10260 \begin_layout Plain Layout
10264 \begin_layout Plain Layout
10268 chunkref{chunkstyle}>
10271 \begin_layout Plain Layout
10275 \begin_layout Plain Layout
10279 chunkref{chunkref}>
10287 \begin_layout Subsection
10291 \begin_layout Standard
10296 style is to make it easier for LyX users to provide the name to
10297 \begin_inset Flex CharStyle:Code
10300 \begin_layout Plain Layout
10309 Normally this requires right-clicking on the listing, choosing settings,
10310 advanced, and then typing
10311 \begin_inset Flex CharStyle:Code
10314 \begin_layout Plain Layout
10321 This has the further disadvantage that the name (and other options) are
10322 not generally visible during document editing.
10325 \begin_layout Standard
10326 The chunk style is defined as a LaTeX command, so that all text on the same
10327 line is passed to the LaTeX command
10328 \begin_inset Flex CharStyle:Code
10331 \begin_layout Plain Layout
10338 This makes it easy to parse using
10339 \begin_inset Flex CharStyle:Code
10342 \begin_layout Plain Layout
10348 , and easy to pass these options on to the listings package.
10349 The first word in a chunk section should be the chunk name, and will have
10351 \begin_inset Flex CharStyle:Code
10354 \begin_layout Plain Layout
10361 Any other words are accepted arguments to
10362 \begin_inset Flex CharStyle:Code
10365 \begin_layout Plain Layout
10376 \begin_layout Standard
10377 We set PassThru to 1 because the user is actually entering raw latex.
10380 \begin_layout Chunk
10384 \begin_layout Standard
10385 \begin_inset listings
10389 \begin_layout Plain Layout
10394 \begin_layout Plain Layout
10399 \begin_layout Plain Layout
10404 \begin_layout Plain Layout
10406 Margin First_Dynamic
10409 \begin_layout Plain Layout
10411 LeftMargin Chunk:xxx
10414 \begin_layout Plain Layout
10419 \begin_layout Plain Layout
10424 \begin_layout Plain Layout
10426 LabelString "Chunk:"
10429 \begin_layout Plain Layout
10434 \begin_layout Plain Layout
10439 \begin_layout Plain Layout
10448 \begin_layout Standard
10449 To make the label very visible we choose a larger font coloured red.
10452 \begin_layout Standard
10453 \begin_inset listings
10457 \begin_layout Plain Layout
10462 \begin_layout Plain Layout
10467 \begin_layout Plain Layout
10472 \begin_layout Plain Layout
10477 \begin_layout Plain Layout
10482 \begin_layout Plain Layout
10487 \begin_layout Plain Layout
10492 \begin_layout Plain Layout
10502 \begin_layout Subsection
10506 \begin_layout Standard
10507 We also define the Chunkref style which can be used to express cross references
10511 \begin_layout Chunk
10515 \begin_layout Standard
10516 \begin_inset listings
10520 \begin_layout Plain Layout
10522 InsetLayout Chunkref
10525 \begin_layout Plain Layout
10530 \begin_layout Plain Layout
10535 \begin_layout Plain Layout
10540 \begin_layout Plain Layout
10545 \begin_layout Plain Layout
10550 \begin_layout Plain Layout
10555 \begin_layout Plain Layout
10560 \begin_layout Plain Layout
10565 \begin_layout Plain Layout
10575 \begin_layout Section
10576 \begin_inset CommandInset label
10578 name "sec:Latex-Macros"
10585 \begin_layout Standard
10599 As noweb defines it's own
10600 \begin_inset Flex CharStyle:Code
10603 \begin_layout Plain Layout
10611 environment, we re-define the one that LyX logical markup module expects
10615 \begin_layout Chunk
10616 ./newfangle.sty,language=tex,basicstyle=
10621 \begin_layout Standard
10622 \begin_inset listings
10626 \begin_layout Plain Layout
10630 usepackage{listings}%
10633 \begin_layout Plain Layout
10640 \begin_layout Plain Layout
10647 \begin_layout Plain Layout
10663 \begin_layout Standard
10665 \begin_inset Flex CharStyle:Code
10668 \begin_layout Plain Layout
10675 \begin_inset Flex CharStyle:Code
10678 \begin_layout Plain Layout
10686 which will need renaming to
10687 \begin_inset Flex CharStyle:Code
10690 \begin_layout Plain Layout
10698 when I can do this without clashing with
10699 \begin_inset Flex CharStyle:Code
10702 \begin_layout Plain Layout
10713 \begin_layout Standard
10714 \begin_inset listings
10718 \begin_layout Plain Layout
10722 lstnewenvironment{Chunk}{
10734 \begin_layout Standard
10735 We also define a suitable
10736 \begin_inset Flex CharStyle:Code
10739 \begin_layout Plain Layout
10747 of parameters that suit the literate programming style after the fashion
10755 \begin_layout Standard
10756 \begin_inset listings
10760 \begin_layout Plain Layout
10764 lstset{numbers=left, stepnumber=5, numbersep=5pt,
10767 \begin_layout Plain Layout
10769 breaklines=false,basicstyle=
10774 \begin_layout Plain Layout
10786 \begin_layout Standard
10787 We also define a notangle-like mechanism for
10791 to LaTeX from the listing, and by which we can refer to other listings.
10793 \begin_inset Flex CharStyle:Code
10796 \begin_layout Plain Layout
10797 =<\SpecialChar \ldots{}
10803 sequence to contain LaTeX code, and include another like this chunk:
10804 \begin_inset Flex CharStyle:Code
10807 \begin_layout Plain Layout
10810 chunkref{chunkname}>
10817 \begin_inset Flex CharStyle:Code
10820 \begin_layout Plain Layout
10821 =<\SpecialChar \ldots{}
10827 is already defined to contain LaTeX code for this document --- this is
10832 document after all --- the code fragment below effectively contains the
10834 \begin_inset Flex CharStyle:Code
10837 \begin_layout Plain Layout
10844 To avoid problems with document generation, I had to declare an lstlistings
10846 \begin_inset Flex CharStyle:Code
10849 \begin_layout Plain Layout
10855 for this listing only; which in LyX was done by right-clicking the listings
10857 \begin_inset Flex CharStyle:Code
10860 \begin_layout Plain Layout
10866 \SpecialChar \menuseparator
10868 \begin_inset Flex CharStyle:Code
10871 \begin_layout Plain Layout
10880 \begin_layout Standard
10881 \begin_inset Note Note
10884 \begin_layout Plain Layout
10885 =< isn't enjoyed literally here, in a listing when the escape sequence is
10886 already defined as shown...
10887 we need to somehow escape this representation...
10895 \begin_layout Standard
10896 \begin_inset listings
10897 lstparams "escapeinside={}"
10901 \begin_layout Plain Layout
10905 lstset{escapeinside={=<}{>}}%
10913 \begin_layout Standard
10914 Although our macros will contain the @ symbol, they will be included in
10916 \begin_inset Flex CharStyle:Code
10919 \begin_layout Plain Layout
10927 section by LyX; however we keep the commented out
10928 \begin_inset Flex CharStyle:Code
10931 \begin_layout Plain Layout
10940 The listings package likes to centre the titles, but noweb titles are specially
10941 formatted and must be left aligned.
10942 The simplest way to do this turned out to be by removing the definition
10944 \begin_inset Flex CharStyle:Code
10947 \begin_layout Plain Layout
10956 This may interact badly if other listings want a regular title or caption.
10957 We remember the old maketitle in case we need it.
10960 \begin_layout Standard
10961 \begin_inset listings
10965 \begin_layout Plain Layout
10972 \begin_layout Plain Layout
10974 %somehow re-defining maketitle gives us a left-aligned title
10977 \begin_layout Plain Layout
10979 %which is extactly what our specially formatted title needs!
10982 \begin_layout Plain Layout
10990 newfangle@lst@maketitle
10995 \begin_layout Plain Layout
11011 \begin_layout Subsection
11012 \begin_inset CommandInset label
11014 name "sub:The-chunk-command"
11021 \begin_layout Standard
11022 Our chunk command accepts one argument, and calls
11023 \begin_inset Flex CharStyle:Code
11026 \begin_layout Plain Layout
11036 \begin_inset Flex CharStyle:Code
11039 \begin_layout Plain Layout
11047 will note the name, this is erased when the next
11048 \begin_inset Flex CharStyle:Code
11051 \begin_layout Plain Layout
11059 starts, so we make a note of this in
11060 \begin_inset Flex CharStyle:Code
11063 \begin_layout Plain Layout
11071 and restore in in lstlistings Init hook.
11074 \begin_layout Standard
11075 \begin_inset listings
11079 \begin_layout Plain Layout
11088 \begin_layout Plain Layout
11094 newfanglecaption},name=#1}%
11097 \begin_layout Plain Layout
11110 \begin_layout Plain Layout
11115 \begin_layout Plain Layout
11131 \begin_layout Subsubsection
11135 \begin_layout Standard
11136 Newfangle permits parameterized chunks, and requires the paramters to be
11137 specified as listings options.
11138 The newfangle script uses this, and although we don't do anything with
11139 these in the LaTeX code right now, we need to stop the listings package
11143 \begin_layout Standard
11144 \begin_inset listings
11148 \begin_layout Plain Layout
11158 newfangle@chunk@params{#1}}%
11166 \begin_layout Standard
11167 As it is common to define a chunk which then needs appending to another
11168 chunk, and annoying to have to declare a single line chunk to manage the
11169 include, we support an
11170 \begin_inset Flex CharStyle:Code
11173 \begin_layout Plain Layout
11183 \begin_layout Standard
11184 \begin_inset listings
11188 \begin_layout Plain Layout
11198 newfangle@chunk@append{#1}}%
11206 \begin_layout Subsection
11207 The noweb styled caption
11210 \begin_layout Standard
11211 We define a public macro
11212 \begin_inset Flex CharStyle:Code
11215 \begin_layout Plain Layout
11223 which can be set as a regular title.
11225 \begin_inset Flex CharStyle:Code
11228 \begin_layout Plain Layout
11237 \begin_inset Flex CharStyle:Code
11240 \begin_layout Plain Layout
11248 at the appriate time when the caption is emitted.
11251 \begin_layout Standard
11252 \begin_inset listings
11256 \begin_layout Plain Layout
11266 newfangle@caption}%
11274 \begin_layout Standard
11275 \begin_inset Float figure
11281 \begin_layout Plain Layout
11282 \begin_inset Box Boxed
11291 height_special "totalheight"
11294 \begin_layout Plain Layout
11296 \begin_inset space \qquad{}
11304 \begin_inset Formula $\equiv+$
11308 \begin_inset space \qquad{}
11312 \begin_inset space \qquad{}
11316 \begin_inset space \qquad{}
11320 \begin_inset Formula $\triangleleft$
11324 \begin_inset space \quad{}
11328 \begin_inset Formula $\triangleright$
11334 \begin_layout Plain Layout
11337 In this example, the current chunk is 22c, and therefore the third chunk
11341 \begin_layout Plain Layout
11352 \begin_layout Plain Layout
11355 The first chunk with this name (19b) occurs as the second chunk on page
11359 \begin_layout Plain Layout
11362 The previous chunk (22d) with the same name is the second chunk on page
11366 \begin_layout Plain Layout
11369 The next chunk (24d) is the fourth chunk on page 24.
11372 \begin_layout Plain Layout
11373 \begin_inset Caption
11375 \begin_layout Plain Layout
11391 The general noweb output format compactly identifies the current chunk,
11392 and references to the first chunk, and the previous and next chunks that
11393 have the same name.
11397 \begin_layout Standard
11398 This means that we need to keep a counter for each chunk-name, that we use
11399 to count chunks of the same name.
11403 \begin_layout Subsection
11407 \begin_layout Standard
11408 It would be natural to have a counter for each chunk name, but TeX would
11409 soon run out of counters
11413 \begin_layout Plain Layout
11414 \SpecialChar \ldots{}
11419 run out of counters and so I had to re-write the LaTeX macros to share
11420 a counter as described here
11425 , so we have one counter which we save at the end of a chunk and restore
11426 at the beginning of a chunk.
11429 \begin_layout Standard
11430 \begin_inset listings
11434 \begin_layout Plain Layout
11438 newcounter{newfangle@chunkcounter}%
11446 \begin_layout Standard
11447 We construct the name of this variable to store the counter to be the text
11449 \begin_inset Flex CharStyle:Code
11452 \begin_layout Plain Layout
11458 prefixed onto the chunks own name, and store it in
11459 \begin_inset Flex CharStyle:Code
11462 \begin_layout Plain Layout
11474 \begin_layout Standard
11475 We save the counter like this:
11478 \begin_layout Chunk
11482 \begin_layout Standard
11483 \begin_inset listings
11487 \begin_layout Plain Layout
11503 arabic{newfangle@chunkcounter}}%
11511 \begin_layout Standard
11512 and restore the counter like this:
11515 \begin_layout Chunk
11519 \begin_layout Standard
11520 \begin_inset listings
11524 \begin_layout Plain Layout
11528 setcounter{newfangle@chunkcounter}{
11542 \begin_layout Chunk
11546 \begin_layout Standard
11547 If there does not already exist a variable whose name is stored in
11548 \begin_inset Flex CharStyle:Code
11551 \begin_layout Plain Layout
11559 , then we know we are the first chunk with this name, and then define a
11564 \begin_layout Standard
11565 Although chunks of the same name share a common counter, they must still
11567 We use is the internal name of the listing, suffixed by the counter value.
11568 So the first chunk might be
11569 \begin_inset Flex CharStyle:Code
11572 \begin_layout Plain Layout
11578 and the second chunk be
11579 \begin_inset Flex CharStyle:Code
11582 \begin_layout Plain Layout
11591 \begin_layout Standard
11592 We also calculate the name of the previous chunk if we can (before we increment
11593 the chunk counter).
11594 If this is the first chunk of that name, then
11595 \begin_inset Flex CharStyle:Code
11598 \begin_layout Plain Layout
11607 \begin_inset Flex CharStyle:Code
11610 \begin_layout Plain Layout
11618 which the noweb package will interpret as not existing.
11621 \begin_layout Standard
11622 \begin_inset listings
11626 \begin_layout Plain Layout
11632 newfangle@caption{%
11635 \begin_layout Plain Layout
11641 chunkcount{lst-chunk-
11646 \begin_layout Plain Layout
11655 \begin_layout Plain Layout
11670 \begin_layout Plain Layout
11674 setcounter{newfangle@chunkcounter}{
11683 \begin_layout Plain Layout
11694 \begin_layout Plain Layout
11699 \begin_layout Plain Layout
11703 setcounter{newfangle@chunkcounter}{
11712 \begin_layout Plain Layout
11722 arabic{newfangle@chunkcounter}}%
11725 \begin_layout Plain Layout
11735 \begin_layout Standard
11736 After incrementing the chunk counter, we then define the name of this chunk,
11737 as well as the name of the first chunk.
11740 \begin_layout Standard
11741 \begin_inset listings
11745 \begin_layout Plain Layout
11749 addtocounter{newfangle@chunkcounter}{1}%
11752 \begin_layout Plain Layout
11768 arabic{newfangle@chunkcounter}}%
11771 \begin_layout Plain Layout
11781 arabic{newfangle@chunkcounter}}%
11784 \begin_layout Plain Layout
11800 \begin_layout Standard
11801 We now need to calculate the name of the next chunk.
11802 We do this by temporarily skipping the counter on by one; however there
11803 may not actually be another chunk with this name! We detect this by also
11804 defining a label for each chunk based on the chunkname.
11805 If there is a next chunkname then it will define a label with that name.
11806 As labels are persistent, we can at least tell the second time LaTeX is
11808 If we don't find such a defined label then we define
11809 \begin_inset Flex CharStyle:Code
11812 \begin_layout Plain Layout
11821 \begin_inset Flex CharStyle:Code
11824 \begin_layout Plain Layout
11835 \begin_layout Standard
11836 \begin_inset listings
11840 \begin_layout Plain Layout
11844 addtocounter{newfangle@chunkcounter}{1}%
11847 \begin_layout Plain Layout
11857 arabic{newfangle@chunkcounter}}%
11860 \begin_layout Plain Layout
11864 @ifundefined{r@label-
11880 \begin_layout Standard
11881 The noweb package requires that we define a
11882 \begin_inset Flex CharStyle:Code
11885 \begin_layout Plain Layout
11893 for every chunk, with a unique name, which is then used to print out it's
11897 \begin_layout Standard
11898 We also define a regular label for this chunk, as was mentioned above when
11900 \begin_inset Flex CharStyle:Code
11903 \begin_layout Plain Layout
11912 This requires LaTeX to be run at least twice after new chunk sections are
11913 added --- but noweb requried that anyway.
11916 \begin_layout Standard
11917 \begin_inset listings
11921 \begin_layout Plain Layout
11930 \begin_layout Plain Layout
11932 % define this label for every chunk instance, so we
11935 \begin_layout Plain Layout
11937 % can tell when we are the last chunk of this name
11940 \begin_layout Plain Layout
11954 \begin_layout Standard
11955 We also try and add the chunk to the list of listings, but I'm afraid we
11956 don't do very well.
11957 We want each chunk name listing once, with all of it's references.
11960 \begin_layout Standard
11961 \begin_inset listings
11965 \begin_layout Plain Layout
11969 addcontentsline{lol}{lstlisting}{
11985 \begin_layout Standard
11986 We then call the noweb output macros in the same way that noweave generates
11987 them, except that we don't need to call
11988 \begin_inset Flex CharStyle:Code
11991 \begin_layout Plain Layout
11994 nwstartdeflinemarkup
12000 \begin_inset Flex CharStyle:Code
12003 \begin_layout Plain Layout
12011 -- and if we do it messes up the output somewhat.
12014 \begin_layout Standard
12015 \begin_inset listings
12019 \begin_layout Plain Layout
12026 \begin_layout Plain Layout
12031 \begin_layout Plain Layout
12038 \begin_layout Plain Layout
12047 \begin_layout Plain Layout
12052 \begin_layout Plain Layout
12057 \begin_layout Plain Layout
12062 \begin_layout Plain Layout
12069 \begin_layout Plain Layout
12076 \begin_layout Plain Layout
12081 \begin_layout Plain Layout
12090 \begin_layout Plain Layout
12094 @ifundefined{newfangle@chunk@params}{}{%
12097 \begin_layout Plain Layout
12101 newfangle@chunk@params)%
12104 \begin_layout Plain Layout
12109 \begin_layout Plain Layout
12120 \begin_layout Plain Layout
12129 \begin_layout Plain Layout
12134 \begin_layout Plain Layout
12138 @ifundefined{newfangle@chunk@append}{}{%
12141 \begin_layout Plain Layout
12147 newfangle@chunk@append{x}
12152 \begin_layout Plain Layout
12156 newfangle@chunk@append%
12159 \begin_layout Plain Layout
12166 \begin_layout Plain Layout
12171 \begin_layout Plain Layout
12179 newfangle@chunk@append{}%
12182 \begin_layout Plain Layout
12189 \begin_layout Plain Layout
12194 \begin_layout Plain Layout
12199 \begin_layout Plain Layout
12218 \begin_layout Plain Layout
12222 nwstartdeflinemarkup%
12225 \begin_layout Plain Layout
12236 \begin_layout Plain Layout
12240 nwenddeflinemarkup%
12243 \begin_layout Plain Layout
12253 \begin_layout Standard
12254 Originally this was developed as a
12255 \begin_inset Flex CharStyle:Code
12258 \begin_layout Plain Layout
12264 aspect, in the Init hook, but it was found easier to affect the title without
12266 \begin_inset Flex CharStyle:Code
12269 \begin_layout Plain Layout
12272 lst@AddToHookExe{PreSet}
12277 is still required to set the listings name to the name passed to the
12278 \begin_inset Flex CharStyle:Code
12281 \begin_layout Plain Layout
12292 \begin_layout Standard
12293 \begin_inset listings
12297 \begin_layout Plain Layout
12301 lst@BeginAspect{newfangle}
12304 \begin_layout Plain Layout
12308 lst@Key{newfangle}{true}[t]{
12310 lstKV@SetIf{#1}{true}}
12313 \begin_layout Plain Layout
12317 lst@AddToHookExe{PreSet}{
12328 \begin_layout Plain Layout
12332 lst@AddToHook{Init}{}%
12337 \begin_layout Plain Layout
12349 \begin_layout Subsection
12353 \begin_layout Standard
12356 chunkref command which makes it easy to generate visual references to different
12360 \begin_layout Standard
12361 \begin_inset Tabular
12362 <lyxtabular version="3" rows="4" columns="2">
12364 <column alignment="center" valignment="top" width="0">
12365 <column alignment="center" valignment="top" width="0">
12367 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
12370 \begin_layout Plain Layout
12376 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
12379 \begin_layout Plain Layout
12387 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
12390 \begin_layout Plain Layout
12398 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
12401 \begin_layout Plain Layout
12405 \begin_layout Plain Layout
12421 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
12424 \begin_layout Plain Layout
12427 chunkref[3]{preamble}
12432 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
12435 \begin_layout Plain Layout
12439 \begin_layout Plain Layout
12443 chunkref[3]{preamble}
12455 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
12458 \begin_layout Plain Layout
12461 chunkref{preamble}[arg1, arg2]
12466 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
12469 \begin_layout Plain Layout
12473 \begin_layout Plain Layout
12477 chunkref{preamble}[arg1, arg2]
12495 \begin_layout Standard
12496 Chunkref can also be used within a code chunk to include another code chunk.
12497 The third optional parameter to chunkref is a comma sepatarated list of
12498 arguments, which will replace defined parameters in the chunkref.
12499 \begin_inset Note Note
12502 \begin_layout Plain Layout
12503 Darn it, if I have: =<
12505 chunkref{new-mode}[{chunks[chunk_name, "language"]},{mode}]> the inner braces
12506 (inside [ ]) cause _ to signify subscript even though we have lst@ReplaceIn
12514 \begin_layout Standard
12515 \begin_inset listings
12519 \begin_layout Plain Layout
12528 \begin_layout Plain Layout
12537 \begin_layout Plain Layout
12548 \begin_layout Plain Layout
12555 \begin_layout Plain Layout
12566 \begin_layout Plain Layout
12571 \begin_layout Plain Layout
12580 \begin_layout Plain Layout
12586 chunkref@i{#1}{#2}}{
12588 chunkref@i{#1}{#2}()}%
12591 \begin_layout Plain Layout
12596 \begin_layout Plain Layout
12602 chunkref@i#1#2(#3){%
12605 \begin_layout Plain Layout
12614 \begin_layout Plain Layout
12623 \begin_layout Plain Layout
12632 \begin_layout Plain Layout
12641 \begin_layout Plain Layout
12652 \begin_layout Plain Layout
12661 \begin_layout Plain Layout
12668 \begin_layout Plain Layout
12679 \begin_layout Plain Layout
12686 \begin_layout Plain Layout
12697 \begin_layout Plain Layout
12708 \begin_layout Plain Layout
12717 \begin_layout Plain Layout
12724 \begin_layout Plain Layout
12729 \begin_layout Plain Layout
12738 \begin_layout Plain Layout
12749 \begin_layout Plain Layout
12756 \begin_layout Plain Layout
12763 \begin_layout Plain Layout
12770 \begin_layout Plain Layout
12781 \begin_layout Plain Layout
12788 \begin_layout Plain Layout
12792 chunkref@args #3,)%
12795 \begin_layout Plain Layout
12802 \begin_layout Plain Layout
12811 \begin_layout Plain Layout
12816 \begin_layout Plain Layout
12821 \begin_layout Plain Layout
12830 \begin_layout Plain Layout
12840 \begin_layout Subsection
12844 \begin_layout Standard
12845 \begin_inset listings
12849 \begin_layout Plain Layout
12854 \begin_layout Plain Layout
12866 \begin_layout Chapter
12867 Extracting newfangle
12870 \begin_layout Section
12871 Extracting from Lyx
12874 \begin_layout Standard
12875 To extract from LyX, you will need to configure LyX as explained in section
12877 \begin_inset CommandInset ref
12879 reference "sub:Configuring-the-build"
12886 \begin_layout Standard
12887 \begin_inset CommandInset label
12889 name "lyx-build-script"
12893 And this lyx-build scrap will extract newfangle for me.
12896 \begin_layout Chunk
12897 lyx-build,language=sh
12900 \begin_layout Standard
12901 \begin_inset listings
12905 \begin_layout Plain Layout
12910 \begin_layout Plain Layout
12915 \begin_layout Plain Layout
12919 \begin_layout Plain Layout
12923 chunkref{lyx-build-helper}>
12926 \begin_layout Plain Layout
12928 cd $PROJECT_DIR || exit 1
12931 \begin_layout Plain Layout
12935 \begin_layout Plain Layout
12937 /usr/local/bin/newfangle -R./newfangle $TEX_SRC > ./newfangle
12940 \begin_layout Plain Layout
12942 /usr/local/bin/newfangle -R./newfangle.module $TEX_SRC > ./newfangle.module
12950 \begin_layout Standard
12951 With a lyx-build-helper
12954 \begin_layout Chunk
12955 lyx-build-helper,language=sh
12958 \begin_layout Standard
12959 \begin_inset listings
12963 \begin_layout Plain Layout
12965 PROJECT_DIR="$LYX_r"
12968 \begin_layout Plain Layout
12970 LYX_SRC="$PROJECT_DIR/${LYX_i%.tex}.lyx"
12973 \begin_layout Plain Layout
12978 \begin_layout Plain Layout
12980 TEX_SRC="$TEX_DIR/$LYX_i"
12988 \begin_layout Section
12989 Extracting from the command line
12992 \begin_layout Standard
12993 First you will need the tex output, then you can extract:
12996 \begin_layout Chunk
12997 lyx-build-manual,language=sh
13000 \begin_layout Standard
13001 \begin_inset listings
13005 \begin_layout Plain Layout
13007 lyx -e latex newfangle.lyx
13010 \begin_layout Plain Layout
13012 newfangle -R./newfangle newfangle.tex > ./newfangle
13015 \begin_layout Plain Layout
13017 newfangle -R./newfangle.module newfangle.tex > ./newfangle.module
13029 \begin_layout Chapter
13033 \begin_layout Chunk
13034 tests-sub,params=THING;colour
13037 \begin_layout Standard
13038 \begin_inset listings
13042 \begin_layout Plain Layout
13044 I see a ${THING} of
13047 \begin_layout Plain Layout
13052 \begin_layout Plain Layout
13056 chunkref{tests-sub-sub}(${colour})>
13064 \begin_layout Chunk
13065 tests-sub-sub,params=colour
13068 \begin_layout Standard
13069 \begin_inset listings
13073 \begin_layout Plain Layout
13075 a funny shade of ${colour}
13083 \begin_layout Chunk
13087 \begin_layout Standard
13088 \begin_inset listings
13092 \begin_layout Plain Layout
13094 What do you see? "=<
13096 chunkref{tests-sub}(joe, red)>"
13099 \begin_layout Plain Layout
13109 \begin_layout Standard
13110 Should generate output:
13113 \begin_layout Chunk
13117 \begin_layout Standard
13118 \begin_inset listings
13122 \begin_layout Plain Layout
13124 What do you see? "I see a joe of
13127 \begin_layout Plain Layout
13132 \begin_layout Plain Layout
13134 looking closer a funny shade of red"
13137 \begin_layout Plain Layout
13142 \begin_layout Plain Layout