Mode tracking now checks for syntactic complete blobs
[newfangle.git] / newfangle.lyx
blobda76c223685c53bd575152323171d4e12b89b5b4
1 #LyX 1.6.4 created this file. For more info see http://www.lyx.org/
2 \lyxformat 345
3 \begin_document
4 \begin_header
5 \textclass book
6 \begin_preamble
7 %\usepackage{xcolor}
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,
13 numberfirstline=true}
14 \end_preamble
15 \use_default_options true
16 \begin_modules
17 logicalmkup
18 newfangle
19 \end_modules
20 \language english
21 \inputencoding auto
22 \font_roman default
23 \font_sans default
24 \font_typewriter default
25 \font_default_family default
26 \font_sc false
27 \font_osf false
28 \font_sf_scale 100
29 \font_tt_scale 100
31 \graphics default
32 \paperfontsize default
33 \spacing single
34 \use_hyperref true
35 \pdf_title "Newfangle"
36 \pdf_author "Sam Liddicott"
37 \pdf_subject "Literate Programing"
38 \pdf_keywords "notangle noweb noweave literate programming cweb"
39 \pdf_bookmarks true
40 \pdf_bookmarksnumbered false
41 \pdf_bookmarksopen false
42 \pdf_bookmarksopenlevel 1
43 \pdf_breaklinks false
44 \pdf_pdfborder false
45 \pdf_colorlinks true
46 \pdf_backref false
47 \pdf_pdfusetitle true
48 \papersize default
49 \use_geometry false
50 \use_amsmath 1
51 \use_esint 1
52 \cite_engine basic
53 \use_bibtopic false
54 \paperorientation portrait
55 \secnumdepth 3
56 \tocdepth 3
57 \paragraph_separation skip
58 \defskip medskip
59 \quotes_language english
60 \papercolumns 1
61 \papersides 1
62 \paperpagestyle default
63 \tracking_changes false
64 \output_changes false
65 \author "" 
66 \author "" 
67 \end_header
69 \begin_body
71 \begin_layout Title
72 newfangle
73 \end_layout
75 \begin_layout Author
76 Sam Liddicott
77 \end_layout
79 \begin_layout Date
80 August 2009
81 \end_layout
83 \begin_layout Chapter*
84 Introduction
85 \end_layout
87 \begin_layout Standard
89 \noun on
90 Newfangle
91 \noun default
92  is a tool for newfangled literate programming.
93  Newfangled is defined as 
94 \emph on
95 New and often needlessly novel
96 \emph default
97  by 
98 \noun on
99 TheFreeDictionary.com
100 \noun default
102 \end_layout
104 \begin_layout Standard
105 In this case, newfangled means yet another new and improved method for literate
106  programming.
107 \end_layout
109 \begin_layout Standard
111 \noun on
112 Literate Programming
113 \noun default
114  has a long history starting with the great 
115 \noun on
116 Donald Knuth
117 \noun default
118  himself, whose literate programming tools seem to make use of as many escaped
119  abbreviations for semantic markup as TeX itself.
120 \end_layout
122 \begin_layout Standard
124 \noun on
125 Norman Ramsey
126 \noun default
127  wrote the 
128 \noun on
129 noweb
130 \noun default
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
134 status collapsed
136 \begin_layout Plain Layout
138 \end_layout
140 \end_inset
142  and 
143 \begin_inset Flex CharStyle:Code
144 status collapsed
146 \begin_layout Plain Layout
148 \end_layout
150 \end_inset
152 , and in doing so brought the wonders of literate programming within my
153  reach.
154 \end_layout
156 \begin_layout Standard
157 While using the LyX editor for LaTeX editing I had various troubles with
158  the noweb tools, some of which were my fault, some of which were noweb's
159  fault and some of which were LyX's fault.
160 \end_layout
162 \begin_layout Standard
164 \noun on
165 Noweb
166 \noun default
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
170 ons in their place.
171 \end_layout
173 \begin_layout Standard
175 \noun on
176 Newfangle
177 \noun default
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
181  line numbers.
182 \end_layout
184 \begin_layout Standard
185 Significantly, newfangle is just one program which replaces various programs
186  in Noweb.
187  Specifically noweave is done away with and implemented directly as LaTeX
188  macros, and noroots is implemented as a function of the untangler 
189 \noun on
190 newfangle
191 \noun default
193 \end_layout
195 \begin_layout Standard
196 Newfangle is written in awk for portability reasons, awk being available
197  for most platforms.
198  A python conversion will probably be attempted for the benefit of LyX.
199  (Hasn't anyone implemented awk in python yet?)
200 \end_layout
202 \begin_layout Section*
203 Todo
204 \end_layout
206 \begin_layout Enumerate
207 ^^ is always going to be a problem, see texbytopic 1.2.2 (Work out what I
208  meant by this).
209 \end_layout
211 \begin_layout Enumerate
212 copy over up to date Makefile guide from noweb-lyx document
213 \end_layout
215 \begin_layout Enumerate
216 Make chunk-name settings only apply to chunks with that name
217 \end_layout
219 \begin_layout Enumerate
220 indent of multi-line chunks may be mode dependant (i.e.
221  not in string literals)
222 \end_layout
224 \begin_layout Enumerate
225 support chunk-param usage =<
226 \backslash
227 param{name}>
228 \end_layout
230 \begin_layout Enumerate
231 trim spaces from param
232 \end_layout
234 \begin_layout Enumerate
235 add support for other commands in =<...>, starting with 
236 \backslash
237 label which takes the line-number within the chunk, and maybe should also
238  take the chunk name/page
239 \end_layout
241 \begin_layout Enumerate
242 cant have listing inside a ruled box
243 \end_layout
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.
248 \end_layout
250 \begin_layout Enumerate
251 with 2 macro expansions on one line ${} ${} the first is too greedy and
252  looks to the final }
253 \end_layout
255 \begin_layout Enumerate
257 \backslash
258 chunkref[3]{preamble} to include a certain chunk needs to work in newfangle.awk
259  instead of failing to be recognized at all
260 \end_layout
262 \begin_layout Enumerate
263 make in-listins labels track the chunk ref too, and make 
264 \backslash
265 chunref{[2],thing}> resolve to 41c (or d, or whatever chunk the 2nd chunk
266  of thing is
267 \end_layout
269 \begin_layout Enumerate
271 \backslash
272 chunkref in text needs a trailing space maybe, it keeps butting up to the
273  next word
274 \end_layout
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
280 \end_layout
282 \begin_layout Chapter*
283 License
284 \end_layout
286 \begin_layout Standard
287 \begin_inset CommandInset label
288 LatexCommand label
289 name "cha:License"
291 \end_inset
293 Newfangle is licensed under the GPL 3
294 \begin_inset CommandInset citation
295 LatexCommand cite
296 key "gpl-licenses"
298 \end_inset
300  (or later).
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
303  available too.
304 \end_layout
306 \begin_layout Chunk
307 gpl3-copyright,language=
308 \end_layout
310 \begin_layout Standard
311 \begin_inset listings
312 inline false
313 status open
315 \begin_layout Plain Layout
317 #newfangle - fully featured notangle replacement in awk
318 \end_layout
320 \begin_layout Plain Layout
323 \end_layout
325 \begin_layout Plain Layout
327 #Copyright (C) Sam Liddicott 2009
328 \end_layout
330 \begin_layout Plain Layout
333 \end_layout
335 \begin_layout Plain Layout
337 #This program is free software: you can redistribute it and/or modify
338 \end_layout
340 \begin_layout Plain Layout
342 #it under the terms of the GNU General Public License as published by
343 \end_layout
345 \begin_layout Plain Layout
347 #the Free Software Foundation, either version 3 of the License, or
348 \end_layout
350 \begin_layout Plain Layout
352 #(at your option) any later version.
353 \end_layout
355 \begin_layout Plain Layout
358 \end_layout
360 \begin_layout Plain Layout
362 #This program is distributed in the hope that it will be useful,
363 \end_layout
365 \begin_layout Plain Layout
367 #but WITHOUT ANY WARRANTY; without even the implied warranty of
368 \end_layout
370 \begin_layout Plain Layout
372 #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
373   See the
374 \end_layout
376 \begin_layout Plain Layout
378 #GNU General Public License for more details.
379 \end_layout
381 \begin_layout Plain Layout
384 \end_layout
386 \begin_layout Plain Layout
388 #You should have received a copy of the GNU General Public License
389 \end_layout
391 \begin_layout Plain Layout
393 #along with this program.
394   If not, see <http://www.gnu.org/licenses/>.
395 \end_layout
397 \end_inset
400 \end_layout
402 \begin_layout Standard
403 \begin_inset CommandInset toc
404 LatexCommand tableofcontents
406 \end_inset
409 \end_layout
411 \begin_layout Part
412 Using Newfangle
413 \end_layout
415 \begin_layout Chapter
416 Running Newfangle
417 \end_layout
419 \begin_layout Standard
420 Newfangle is a replacement for noweb, which consists of 
421 \begin_inset Flex CharStyle:Code
422 status collapsed
424 \begin_layout Plain Layout
425 notangle
426 \end_layout
428 \end_inset
431 \begin_inset Flex CharStyle:Code
432 status collapsed
434 \begin_layout Plain Layout
435 noroots
436 \end_layout
438 \end_inset
440  and 
441 \begin_inset Flex CharStyle:Code
442 status collapsed
444 \begin_layout Plain Layout
445 noweave
446 \end_layout
448 \end_inset
451 \end_layout
453 \begin_layout Standard
454 Like 
455 \begin_inset Flex CharStyle:Code
456 status collapsed
458 \begin_layout Plain Layout
459 notangle
460 \end_layout
462 \end_inset
464  and 
465 \begin_inset Flex CharStyle:Code
466 status collapsed
468 \begin_layout Plain Layout
469 noroots
470 \end_layout
472 \end_inset
474  it can read multiple named files, or from stdin.
475 \end_layout
477 \begin_layout Section
478 Listing roots
479 \end_layout
481 \begin_layout Standard
482 The -r option causes newfangle to behave like noroots.
483 \end_layout
485 \begin_layout LyX-Code
486 newfangle -r filename.tex
487 \end_layout
489 \begin_layout Standard
490 will print out the newfangle roots of a tex file.
492 \end_layout
494 \begin_layout Standard
495 Unlike the 
496 \begin_inset Flex CharStyle:Code
497 status collapsed
499 \begin_layout Plain Layout
500 noroots
501 \end_layout
503 \end_inset
505  command, the roots are not enclosed in 
506 \begin_inset Flex CharStyle:Code
507 status collapsed
509 \begin_layout Plain Layout
510 <<name>>
511 \end_layout
513 \end_inset
515 , unless at least one of the roots is defined using the 
516 \begin_inset Flex CharStyle:Code
517 status collapsed
519 \begin_layout Plain Layout
520 notangle
521 \end_layout
523 \end_inset
525  style 
526 \begin_inset Flex CharStyle:Code
527 status collapsed
529 \begin_layout Plain Layout
530 <<name>>=
531 \end_layout
533 \end_inset
536 \end_layout
538 \begin_layout Standard
539 Also, unlike noroots, it prints out all roots --- not just those that are
540  not used elsewhere.
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
544 status collapsed
546 \begin_layout Plain Layout
548 \end_layout
550 \end_inset
552  and have the form of a filename.
553 \end_layout
555 \begin_layout Section
556 Extracting roots
557 \end_layout
559 \begin_layout Standard
560 notangle's 
561 \begin_inset Flex CharStyle:Code
562 status collapsed
564 \begin_layout Plain Layout
566 \end_layout
568 \end_inset
570  and 
571 \begin_inset Flex CharStyle:Code
572 status collapsed
574 \begin_layout Plain Layout
576 \end_layout
578 \end_inset
580  options are supported.
581 \end_layout
583 \begin_layout Standard
584 The standard way to extract a file would be:
585 \end_layout
587 \begin_layout LyX-Code
588 newfangle -R./Makefile.inc newfangle.tex > ./Makefile.inc
589 \end_layout
591 \begin_layout Standard
592 Unlike the 
593 \begin_inset Flex CharStyle:Code
594 status collapsed
596 \begin_layout Plain Layout
597 noroots
598 \end_layout
600 \end_inset
602  command, the 
603 \begin_inset Flex CharStyle:Code
604 status collapsed
606 \begin_layout Plain Layout
608 \end_layout
610 \end_inset
612  option does not break indenting; also the 
613 \begin_inset Flex CharStyle:Code
614 status collapsed
616 \begin_layout Plain Layout
618 \end_layout
620 \end_inset
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.
627 \end_layout
629 \begin_layout Section
630 Formatting source in LaTeX
631 \end_layout
633 \begin_layout Standard
634 The noweave replacement is a set of LaTeX macros dependant upon 
635 \emph on
636 noweb.sty
637 \emph default
638 , and which can be included with:
639 \end_layout
641 \begin_layout LyX-Code
643 \backslash
644 usepackage{newfangle.sty}
645 \end_layout
647 \begin_layout Standard
648 The LaTeX macros are shown in section 
649 \begin_inset CommandInset ref
650 LatexCommand ref
651 reference "sec:Latex-Macros"
653 \end_inset
655 , and are part of a LyX module file 
656 \begin_inset Flex CharStyle:Code
657 status collapsed
659 \begin_layout Plain Layout
660 newfangle.module
661 \end_layout
663 \end_inset
665 , which automatically includes the macros in the document pre-amble when
666  the newfangle LyX module is used.
667 \end_layout
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
673 status collapsed
675 \begin_layout Plain Layout
676 latex
677 \end_layout
679 \end_inset
681  command.
682  LaTeX may need running two or more times, so that the code chunk references
683  can be fully calculated.
684 \end_layout
686 \begin_layout Standard
687 The 
688 \begin_inset Flex CharStyle:Code
689 status collapsed
691 \begin_layout Plain Layout
692 noweb.sty
693 \end_layout
695 \end_inset
697  package is required as it is used for formatting the code chunk captions
698 \end_layout
700 \begin_layout Standard
701 The 
702 \begin_inset Flex CharStyle:Code
703 status collapsed
705 \begin_layout Plain Layout
706 listings.sty
707 \end_layout
709 \end_inset
711  package is also required, as it is used for formatting the code chunks
712  themselves.
713 \end_layout
715 \begin_layout Standard
716 The 
717 \begin_inset Flex CharStyle:Code
718 status collapsed
720 \begin_layout Plain Layout
721 xargs.sty
722 \end_layout
724 \end_inset
726  package is also required.
727 \end_layout
729 \begin_layout Chapter
730 Literate Programming with Newfangle
731 \end_layout
733 \begin_layout Standard
734 Todo.
735  Should really follow on from a part-0 explanation of what literate programming
736  is.
737 \end_layout
739 \begin_layout Chapter
740 Using Newfangle with LyX
741 \end_layout
743 \begin_layout Section
744 Setting up Lyx
745 \end_layout
747 \begin_layout Subsection
748 Installing the LyX module
749 \end_layout
751 \begin_layout Standard
752 Copy 
753 \begin_inset Flex CharStyle:Code
754 status collapsed
756 \begin_layout Plain Layout
757 newfangle.module
758 \end_layout
760 \end_inset
762  to your LyX layouts directory, which for unix users will be 
763 \begin_inset Flex CharStyle:Code
764 status collapsed
766 \begin_layout Plain Layout
767 ~/.lyx/layouts
768 \end_layout
770 \end_inset
773 \end_layout
775 \begin_layout Standard
776 You will need to reconfigure LyX by clicking Tools\SpecialChar \menuseparator
777 Reconfigure, and then
778  re-start LyX.
779 \end_layout
781 \begin_layout Subsection
782 \begin_inset CommandInset label
783 LatexCommand label
784 name "sub:Configuring-the-build"
786 \end_inset
788 Configuring the build script
789 \end_layout
791 \begin_layout Standard
792 Make sure you don't have a conversion defined for Lyx → Program
793 \end_layout
795 \begin_layout Standard
796 From the menu Tools\SpecialChar \menuseparator
797 Preferences, add a conversion from Latex(Plain) → Program
798  as:
799 \end_layout
801 \begin_layout LyX-Code
802 set -x ; newfangle -Rlyx-build $$i | 
803 \end_layout
805 \begin_layout LyX-Code
806   env LYX_b=$$b LYX_i=$$i LYX_o=$$o LYX_p=$$p LYX_r=$$r bash
807 \end_layout
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).
813 \end_layout
815 \begin_layout Standard
816 I hope that one day, LyX will set these into the environment when calling
817  the build script.
818 \end_layout
820 \begin_layout Standard
821 You may also want to consider adding options to this conversion\SpecialChar \ldots{}
823 \end_layout
825 \begin_layout LyX-Code
826 parselog=/usr/share/lyx/scripts/listerrors
827 \end_layout
829 \begin_layout Standard
830 \SpecialChar \ldots{}
831 but if you do you will lose your stderr
832 \begin_inset Foot
833 status collapsed
835 \begin_layout Plain Layout
836 There is some bash plumbing to get a copy of stderr but this footnote is
837  too small
838 \end_layout
840 \end_inset
843 \end_layout
845 \begin_layout Standard
846 Now, a shell script chunk called 
847 \begin_inset Flex CharStyle:Code
848 status collapsed
850 \begin_layout Plain Layout
851 lyx-build
852 \end_layout
854 \end_inset
856  will be extracted and run whenever you choose the Document\SpecialChar \menuseparator
857 Build Program
858  menu item.
859 \end_layout
861 \begin_layout Standard
862 The lyx-build script for this document is in section 
863 \begin_inset CommandInset ref
864 LatexCommand ref
865 reference "lyx-build-script"
867 \end_inset
869  and on a unix system will extract 
870 \begin_inset Flex CharStyle:Code
871 status collapsed
873 \begin_layout Plain Layout
874 newfangle.module
875 \end_layout
877 \end_inset
879  and the 
880 \begin_inset Flex CharStyle:Code
881 status collapsed
883 \begin_layout Plain Layout
884 newfangle
885 \end_layout
887 \end_inset
889  awk script.
890 \end_layout
892 \begin_layout Subsection
893 Preparing your Lyx document
894 \end_layout
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.
899 \end_layout
901 \begin_layout Standard
902 Add the new module 
903 \emph on
904 Newfangle Literate
905 \emph default
907 \emph on
908 Listings
909 \emph default
910  and possibly also 
911 \emph on
912 Logical Markup
913 \emph default
915 \end_layout
917 \begin_layout Standard
918 In the drop-down style listbox you should notice a new style defined, called
920 \emph on
921 Chunk
922 \emph default
924 \end_layout
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
930 status collapsed
932 \begin_layout Plain Layout
933 <<name>>=
934 \end_layout
936 \end_inset
938  type tags.
939  Following the chunk name, you insert a listing with: Insert\SpecialChar \menuseparator
940 Program Listing.
941 \end_layout
943 \begin_layout Standard
944 Inside the white listing box you can type (or paste using shift+ctrl+V)
945  your listing.
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.
948 \end_layout
950 \begin_layout Subsubsection
951 Customising the listing appearance
952 \end_layout
954 \begin_layout Standard
955 In the final document, the code is formatted using the 
956 \noun on
957 lstlistings
958 \noun default
959  package.
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
963 status collapsed
965 \begin_layout Plain Layout
967 \backslash
968 lstset
969 \end_layout
971 \end_inset
973  command.
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
976  listing, just add 
977 \begin_inset Flex CharStyle:Code
978 status collapsed
980 \begin_layout Plain Layout
981 ,lanuage=C
982 \end_layout
984 \end_inset
986  after the chunk name.
987 \end_layout
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
995 \begin_inset Foot
996 status collapsed
998 \begin_layout Plain Layout
999 It ought to apply only to subsequent chunks of the same name.
1000  I'll fix that later
1001 \end_layout
1003 \end_inset
1006 \begin_inset Note Note
1007 status collapsed
1009 \begin_layout Plain Layout
1010 So make sure they only apply to chunks of that name
1011 \end_layout
1013 \end_inset
1016 \end_layout
1018 \begin_layout Subsubsection
1019 Global customisations
1020 \end_layout
1022 \begin_layout Standard
1023 As 
1024 \emph on
1025 lstlistings
1026 \emph default
1027  is used to set the code chunks, it's 
1028 \begin_inset Flex CharStyle:Code
1029 status collapsed
1031 \begin_layout Plain Layout
1033 \backslash
1034 lstset
1035 \end_layout
1037 \end_inset
1039  command can be used in the pre-amble to set some document wide settings.
1040 \end_layout
1042 \begin_layout Standard
1043 If your source has many words with long sequences of capital letters, then
1045 \begin_inset Flex CharStyle:Code
1046 status collapsed
1048 \begin_layout Plain Layout
1049 columns=fullflexible
1050 \end_layout
1052 \end_inset
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).
1057 \end_layout
1059 \begin_layout Standard
1060 The font family 
1061 \begin_inset Flex CharStyle:Code
1062 status collapsed
1064 \begin_layout Plain Layout
1066 \backslash
1067 ttfamily
1068 \end_layout
1070 \end_inset
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
1075 status collapsed
1077 \begin_layout Plain Layout
1079 \backslash
1080 color{darkgreen}
1081 \end_layout
1083 \end_inset
1085  for my keywords.
1086  With 
1087 \begin_inset Flex CharStyle:Code
1088 status collapsed
1090 \begin_layout Plain Layout
1092 \backslash
1093 ttfamily
1094 \end_layout
1096 \end_inset
1099 \begin_inset Flex CharStyle:Code
1100 status collapsed
1102 \begin_layout Plain Layout
1103 columns=fullflexible
1104 \end_layout
1106 \end_inset
1108  is used or the wrong letter spacing is used.
1109 \end_layout
1111 \begin_layout Standard
1112 In my LeTeX pre-amble I usually specialise my code format with:
1113 \end_layout
1115 \begin_layout Chunk
1116 document-preamble,language=tex
1117 \end_layout
1119 \begin_layout Standard
1120 \begin_inset listings
1121 inline false
1122 status open
1124 \begin_layout Plain Layout
1127 \backslash
1128 usepackage{xcolor}
1129 \end_layout
1131 \begin_layout Plain Layout
1134 \backslash
1135 definecolor{darkgreen}{rgb}{0,0.5,0}
1136 \end_layout
1138 \begin_layout Plain Layout
1141 \backslash
1142 lstset{numbers=left, stepnumber=5, numbersep=5pt, breaklines=false,
1143 \end_layout
1145 \begin_layout Plain Layout
1147   basicstyle=
1148 \backslash
1149 footnotesize
1150 \backslash
1151 ttfamily,
1152 \end_layout
1154 \begin_layout Plain Layout
1156   keywordstyle=
1157 \backslash
1158 color{darkgreen},
1159 \end_layout
1161 \begin_layout Plain Layout
1163   numberstyle=
1164 \backslash
1165 tiny,language=C,columns=fullflexible,
1166 \end_layout
1168 \begin_layout Plain Layout
1170   numberfirstline=true
1171 \end_layout
1173 \begin_layout Plain Layout
1176 \end_layout
1178 \end_inset
1181 \end_layout
1183 \begin_layout Chapter
1184 Newfangle with Makefiles
1185 \end_layout
1187 \begin_layout Standard
1188 \begin_inset Note Note
1189 status open
1191 \begin_layout Plain Layout
1192 This chapter needs revising
1193 \end_layout
1195 \end_inset
1198 \begin_inset Note Greyedout
1199 status open
1201 \begin_layout Plain Layout
1202 This chapter needs revising
1203 \end_layout
1205 \end_inset
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.
1209 \end_layout
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.
1214 \end_layout
1216 \begin_layout Section
1217 A word about makefiles formats
1218 \end_layout
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.
1223 \end_layout
1225 \begin_layout LyX-Code
1226 target: pre-requisite
1227 \begin_inset Newline newline
1228 \end_inset
1230    →    action
1231 \begin_inset Newline newline
1232 \end_inset
1234    →    action
1235 \end_layout
1237 \begin_layout Standard
1238 But a TAB is pretty hard to enter into most of the Lyx formats and insets
1239  I've been using.
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.
1243 \end_layout
1245 \begin_layout LyX-Code
1246 target: pre-requisite ; 
1247 \backslash
1249 \begin_inset Newline newline
1250 \end_inset
1252 ␣␣action 
1253 \backslash
1255 \begin_inset Newline newline
1256 \end_inset
1258 ␣␣action
1259 \end_layout
1261 \begin_layout Standard
1262 This is the style that we use and it works pretty well for GNU make at least.
1263 \end_layout
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).
1270 \end_layout
1272 \begin_layout Section
1273 Boot-strapping the extraction
1274 \end_layout
1276 \begin_layout Subsection
1277 Using a Makefile
1278 \end_layout
1280 \begin_layout Standard
1281 \begin_inset CommandInset label
1282 LatexCommand label
1283 name "sub:Bootstrap-Using-a-Makefile"
1285 \end_inset
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
1290  document.
1291 \end_layout
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.
1298 \end_layout
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 
1304 \emph on
1305 autoboot
1306 \emph default
1308 \begin_inset Note Note
1309 status open
1311 \begin_layout Plain Layout
1312 FIX THIS CHUNK AND TEST IT
1313 \end_layout
1315 \end_inset
1318 \end_layout
1320 \begin_layout Chunk
1322 \end_layout
1324 \begin_layout Standard
1325 \begin_inset listings
1326 inline false
1327 status open
1329 \begin_layout Plain Layout
1331 #! /bin/sh
1332 \end_layout
1334 \begin_layout Plain Layout
1336 \end_layout
1338 \begin_layout Plain Layout
1340 MAKE_SRC="${1:-${NW_LYX:-../../noweb-lyx/noweb-lyx3.lyx}}"
1341 \end_layout
1343 \begin_layout Plain Layout
1345 MAKE_SRC=`dirname "$MAKE_SRC"`/`basename "$MAKE_SRC" .lyx`
1346 \end_layout
1348 \begin_layout Plain Layout
1350 NOWEB_SRC="${2:-${NOWEB_SRC:-$MAKE_SRC.lyx}}"
1351 \end_layout
1353 \begin_layout Plain Layout
1355 lyx -e latex $MAKE_SRC
1356 \end_layout
1358 \begin_layout Plain Layout
1360 \end_layout
1362 \begin_layout Plain Layout
1364 newfangle -R./Makefile.inc ${MAKE_SRC}.tex 
1365 \backslash
1367 \end_layout
1369 \begin_layout Plain Layout
1371   | sed "/NEWFANGLE_SOURCE=/s/^/#/;T;aNOWEB_SOURCE=$NEWFANGLE_SRC" 
1372 \backslash
1374 \end_layout
1376 \begin_layout Plain Layout
1378   | cpif ./Makefile.inc
1379 \end_layout
1381 \begin_layout Plain Layout
1383 \end_layout
1385 \begin_layout Plain Layout
1387 make -f ./Makefile.inc newfangle_sources
1388 \end_layout
1390 \end_inset
1393 \end_layout
1395 \begin_layout Standard
1396 The general Makefile can be invoked with 
1397 \emph on
1398 ./autoboot
1399 \emph default
1400  and can also be included into any automake file to automatically re-generate
1401  the source files.
1402 \end_layout
1404 \begin_layout Standard
1405 The 
1406 \emph on
1407 autoboot
1408 \emph default
1409  can be extracted with this command:
1410 \end_layout
1412 \begin_layout LyX-Code
1413 lyx -e latex newfangle.lyx && 
1414 \backslash
1416 \end_layout
1418 \begin_layout LyX-Code
1419 newfangle newfangle.lyx > ./autoboot
1420 \end_layout
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.
1425 \end_layout
1427 \begin_layout Subsection
1428 \begin_inset Note Note
1429 status collapsed
1431 \begin_layout Plain Layout
1432 MERGE THIS WITH THE SECTIONS OF THIS DOCUMENT
1433 \end_layout
1435 \end_inset
1437 \SpecialChar \ldots{}
1439 \end_layout
1441 \begin_layout Standard
1442 When the lyx-build chunk is executed, the current directory will be a temporary
1443  directory, and 
1444 \begin_inset Flex CharStyle:Code
1445 status collapsed
1447 \begin_layout Plain Layout
1448 LYX_SOURCE
1449 \end_layout
1451 \end_inset
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.
1456 \end_layout
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.
1461 \end_layout
1463 \begin_layout Chunk
1464 lyx-build-helper
1465 \end_layout
1467 \begin_layout Standard
1468 \begin_inset listings
1469 inline false
1470 status open
1472 \begin_layout Plain Layout
1474 PROJECT_DIR="$LYX_r"
1475 \end_layout
1477 \begin_layout Plain Layout
1479 LYX_SRC="$PROJECT_DIR/${LYX_i%.tex}.lyx"
1480 \end_layout
1482 \begin_layout Plain Layout
1484 TEX_DIR="$LYX_p"
1485 \end_layout
1487 \begin_layout Plain Layout
1489 TEX_SRC="$TEX_DIR/$LYX_i"
1490 \end_layout
1492 \end_inset
1495 \end_layout
1497 \begin_layout Standard
1498 And then we can define a lyx-build fragment similar to the autoboot fragment
1499 \end_layout
1501 \begin_layout Chunk
1502 lyx-build
1503 \end_layout
1505 \begin_layout Standard
1506 \begin_inset listings
1507 inline false
1508 status open
1510 \begin_layout Plain Layout
1512 #! /bin/sh
1513 \end_layout
1515 \begin_layout Plain Layout
1518 \backslash
1519 chunkref{lyx-build-helper}>
1520 \end_layout
1522 \begin_layout Plain Layout
1524 cd $PROJECT_DIR || exit 1
1525 \end_layout
1527 \begin_layout Plain Layout
1529 \end_layout
1531 \begin_layout Plain Layout
1533 #/usr/bin/newfangle -filter ./notanglefix-filter 
1534 \backslash
1536 \end_layout
1538 \begin_layout Plain Layout
1540 #  -R./Makefile.inc "../../noweb-lyx/noweb-lyx3.lyx" 
1541 \backslash
1543 \end_layout
1545 \begin_layout Plain Layout
1547 #  | sed '/NOWEB_SOURCE=/s/=.*/=samba4-dfs.lyx/' 
1548 \backslash
1550 \end_layout
1552 \begin_layout Plain Layout
1554 #  > ./Makefile.inc
1555 \end_layout
1557 \begin_layout Plain Layout
1560 \end_layout
1562 \begin_layout Plain Layout
1564 #make -f ./Makefile.inc newfangle_sources
1565 \end_layout
1567 \end_inset
1570 \end_layout
1572 \begin_layout Section
1573 Extracting Sources
1574 \end_layout
1576 \begin_layout Subsection
1577 Including Makefile.inc
1578 \end_layout
1580 \begin_layout Standard
1581 \begin_inset CommandInset label
1582 LatexCommand label
1583 name "sub:Keeping-extracted-files"
1585 \end_inset
1587 Makefile.inc will cope with extracting all the other source files from this
1588  document and keeping them up to date.
1590 \end_layout
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.
1595 \end_layout
1597 \begin_layout Standard
1598 A makefile has two parts; variables must be defined before the targets that
1599  use them.
1600 \end_layout
1602 \begin_layout Chunk
1603 ./Makefile.inc
1604 \end_layout
1606 \begin_layout Standard
1607 \begin_inset listings
1608 inline false
1609 status open
1611 \begin_layout Plain Layout
1614 \backslash
1615 chunkref{Makefile.inc-vars}>
1616 \end_layout
1618 \begin_layout Plain Layout
1621 \backslash
1622 chunkref{Makefile.inc-targets}>
1623 \end_layout
1625 \end_inset
1628 \end_layout
1630 \begin_layout Standard
1631 We first define 
1632 \begin_inset Flex CharStyle:Code
1633 status collapsed
1635 \begin_layout Plain Layout
1636 NOWEB_SOURCE
1637 \end_layout
1639 \end_inset
1641  to hold the name of this Lyx file.
1642 \end_layout
1644 \begin_layout Chunk
1645 Makefile.inc-vars
1646 \end_layout
1648 \begin_layout Standard
1649 \begin_inset listings
1650 inline false
1651 status open
1653 \begin_layout Plain Layout
1655 LYX_SOURCE=
1656 \end_layout
1658 \begin_layout Plain Layout
1660 LITERATE_SOURCE=$(LYX_SOURCE)
1661 \end_layout
1663 \end_inset
1666 \end_layout
1668 \begin_layout Subsection
1669 Recursive use of Makefile.inc
1670 \end_layout
1672 \begin_layout Standard
1673 The makefile glue described here is used when building Samba4 vfs modules.
1674 \end_layout
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.
1682 \end_layout
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.
1687 \end_layout
1689 \begin_layout Standard
1690 In this example, the existing build system already has a build target for
1692 \begin_inset Flex CharStyle:Code
1693 status collapsed
1695 \begin_layout Plain Layout
1696 example.o
1697 \end_layout
1699 \end_inset
1701 , so we just add another pre-requisite to that.
1702  In this case we use 
1703 \begin_inset Flex CharStyle:Code
1704 status collapsed
1706 \begin_layout Plain Layout
1707 example.tex.stamp
1708 \end_layout
1710 \end_inset
1712  as a pre-requisite, the stamp file's modified time indicating when all
1713  sources were extracted.
1714 \end_layout
1716 \begin_layout Chunk
1717 makefile-glue
1718 \end_layout
1720 \begin_layout Standard
1721 \begin_inset listings
1722 inline false
1723 status open
1725 \begin_layout Plain Layout
1727 $(example_srcdir)/example.o: $(example_srcdir)/example.tex.stamp
1728 \end_layout
1730 \end_inset
1733 \end_layout
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.
1739 \end_layout
1741 \begin_layout Chunk
1742 makefile-glue
1743 \end_layout
1745 \begin_layout Standard
1746 \begin_inset listings
1747 inline false
1748 status open
1750 \begin_layout Plain Layout
1752 $(example_srcdir)/example.tex.stamp: $(example_srcdir)/example.tex ; 
1753 \backslash
1755 \end_layout
1757 \begin_layout Plain Layout
1759         cd $(example_srcdir) && 
1760 \backslash
1762 \end_layout
1764 \begin_layout Plain Layout
1766         $(MAKE) -f Makefile.inc newfangle_sources
1767 \end_layout
1769 \end_inset
1772 \end_layout
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.
1778 \end_layout
1780 \begin_layout Chunk
1781 makefile-glue
1782 \end_layout
1784 \begin_layout Standard
1785 \begin_inset listings
1786 inline false
1787 status open
1789 \begin_layout Plain Layout
1791 docs:: docs_example
1792 \end_layout
1794 \begin_layout Plain Layout
1796 .PHONY: docs_example
1797 \end_layout
1799 \begin_layout Plain Layout
1801 docs_example:: ; cd $(example_srcdir) && 
1802 \backslash
1804 \end_layout
1806 \begin_layout Plain Layout
1808         $(MAKE) -f Makefile.inc docs
1809 \end_layout
1811 \begin_layout Plain Layout
1813 \end_layout
1815 \begin_layout Plain Layout
1817 clean:: clean_example
1818 \end_layout
1820 \begin_layout Plain Layout
1822 .PHONEY: clean_example
1823 \end_layout
1825 \begin_layout Plain Layout
1827 clean_example: ; cd $(example_srcdir) && 
1828 \backslash
1830 \end_layout
1832 \begin_layout Plain Layout
1834         $(MAKE) -f Makefile.inc clean
1835 \end_layout
1837 \begin_layout Plain Layout
1839 \end_layout
1841 \begin_layout Plain Layout
1843 distclean:: distclean_example
1844 \end_layout
1846 \begin_layout Plain Layout
1848 .PHONY: distclean_example
1849 \end_layout
1851 \begin_layout Plain Layout
1853 distclean_example: ; cd $(example_srcdir) && 
1854 \backslash
1856 \end_layout
1858 \begin_layout Plain Layout
1860         $(MAKE) -f Makefile.inc distclean
1861 \end_layout
1863 \end_inset
1866 \end_layout
1868 \begin_layout Standard
1869 We could do similarly for install targets to install the generated docs.
1870 \end_layout
1872 \begin_layout Subsection
1873 \begin_inset CommandInset label
1874 LatexCommand label
1875 name "sub:Converting-from-Lyx"
1877 \end_inset
1879 Converting from Lyx to LaTeX
1880 \end_layout
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 
1886 \emph on
1887 server-goto-file-line
1888 \begin_inset Foot
1889 status collapsed
1891 \begin_layout Plain Layout
1892 The Lyx command 
1893 \emph on
1894 server-goto-file-line
1895 \emph default
1896  is used to position the Lyx cursor at the compiler errors.
1897 \end_layout
1899 \end_inset
1902 \emph default
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
1906 status collapsed
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
1911 \end_layout
1913 \end_inset
1916 \end_layout
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.
1922 \end_layout
1924 \begin_layout Chunk
1925 Makefile.inc-vars
1926 \end_layout
1928 \begin_layout Standard
1929 \begin_inset listings
1930 inline false
1931 status open
1933 \begin_layout Plain Layout
1935 TEX_SOURCE=$(LYX_SOURCE:.lyx=.tex)
1936 \end_layout
1938 \end_inset
1941 \end_layout
1943 \begin_layout Chunk
1944 Makefile.inc-targets
1945 \end_layout
1947 \begin_layout Standard
1948 \begin_inset listings
1949 inline false
1950 status open
1952 \begin_layout Plain Layout
1954 $(TEX_SOURCE): $(LYX_SOURCE) ;
1955 \backslash
1957 \end_layout
1959 \begin_layout Plain Layout
1961         lyx -e latex $<
1962 \end_layout
1964 \begin_layout Plain Layout
1966 clean_tex: ; rm -f -- $(TEX_SOURCE)
1967 \end_layout
1969 \end_inset
1972 \end_layout
1974 \begin_layout Subsection
1975 Extracting Program Source
1976 \end_layout
1978 \begin_layout Standard
1979 The program source is extracted using newfangle, which is designed to operate
1980  on a LaTeX document.
1982 \end_layout
1984 \begin_layout Chunk
1985 Makefile.inc-vars
1986 \end_layout
1988 \begin_layout Standard
1989 \begin_inset listings
1990 inline false
1991 status open
1993 \begin_layout Plain Layout
1995 NEWFANGLE_SOURCE=$(TEX_SOURCE)
1996 \end_layout
1998 \end_inset
2001 \end_layout
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
2008  edited.
2010 \end_layout
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.
2017 \end_layout
2019 \begin_layout Chunk
2020 Makefile.inc-vars
2021 \end_layout
2023 \begin_layout Standard
2024 \begin_inset listings
2025 inline false
2026 status open
2028 \begin_layout Plain Layout
2030 NEWFANGLE_SOURCE_STAMP=$(NEWFANGLE_SOURCE).stamp
2031 \end_layout
2033 \end_inset
2036 \end_layout
2038 \begin_layout Chunk
2039 Makefile.inc-targets
2040 \end_layout
2042 \begin_layout Standard
2043 \begin_inset listings
2044 inline false
2045 status open
2047 \begin_layout Plain Layout
2049 $(NEWFANGLE_SOURCE_STAMP): $(NEWFANGLE_SOURCE) 
2050 \backslash
2052 \end_layout
2054 \begin_layout Plain Layout
2056                            $(NEWFANGLE_SOURCES) ; 
2057 \backslash
2059 \end_layout
2061 \begin_layout Plain Layout
2063         echo > $(NEWFANGLE_SOURCE_STAMP)
2064 \end_layout
2066 \begin_layout Plain Layout
2068 clean_stamp: ; rm -f $(NEWFANGLE_SOURCE_STAMP)
2069 \end_layout
2071 \begin_layout Plain Layout
2073 clean: clean_stamp
2074 \end_layout
2076 \end_inset
2079 \end_layout
2081 \begin_layout Subsection
2082 Extracting C sources
2083 \end_layout
2085 \begin_layout Standard
2086 We compute 
2087 \begin_inset Flex CharStyle:Code
2088 status collapsed
2090 \begin_layout Plain Layout
2091 NEWFANGLE_SOURCES
2092 \end_layout
2094 \end_inset
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*{}
2100 \length 0in
2101 \end_inset
2103 < and >
2104 \begin_inset space \hspace*{}
2105 \length 0in
2106 \end_inset
2108 > which may surround the roots names (for noroots compatibility).
2110 \end_layout
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
2115  ./
2116 \end_layout
2118 \begin_layout Chunk
2119 Makefile.inc-vars
2120 \end_layout
2122 \begin_layout Standard
2123 \begin_inset listings
2124 inline false
2125 status open
2127 \begin_layout Plain Layout
2129 NEWFANGLE_PREFIX:=
2130 \backslash
2132 \backslash
2134 \end_layout
2136 \begin_layout Plain Layout
2138 NEWFANGLE_SOURCES:=$(shell 
2139 \backslash
2141 \end_layout
2143 \begin_layout Plain Layout
2145   newfangle -r $(NEWFANGLE_SOURCE) |
2146 \backslash
2148 \end_layout
2150 \begin_layout Plain Layout
2152   sed -e 's/^[<][<]//;s/[>][>]$$//;/^$(NEWFANGLE_PREFIX)/!d' 
2153 \backslash
2155 \end_layout
2157 \begin_layout Plain Layout
2159       -e 's/^$(NEWFANGLE_PREFIX)/
2160 \backslash
2162 \backslash
2163 //' )
2164 \end_layout
2166 \begin_layout Plain Layout
2169 \end_layout
2171 \end_inset
2174 \end_layout
2176 \begin_layout Chunk
2177 Makefile.inc-targets
2178 \end_layout
2180 \begin_layout Standard
2181 \begin_inset listings
2182 inline false
2183 status open
2185 \begin_layout Plain Layout
2187 .PHONY: echo_newfangle_sources
2188 \end_layout
2190 \begin_layout Plain Layout
2192 echo_newfangle_sources: ; @echo $(NEWFANGLE_SOURCES)
2193 \end_layout
2195 \end_inset
2198 \end_layout
2200 \begin_layout Standard
2201 We define a convenient target called 
2202 \begin_inset Flex CharStyle:Code
2203 status collapsed
2205 \begin_layout Plain Layout
2206 newfangle_sources
2207 \end_layout
2209 \end_inset
2211  to re-extract the source if the LaTeX file has been updated.
2212 \end_layout
2214 \begin_layout Chunk
2215 Makefile.inc-targets
2216 \end_layout
2218 \begin_layout Standard
2219 \begin_inset listings
2220 inline false
2221 status open
2223 \begin_layout Plain Layout
2225 .PHONY: newfangle_sources
2226 \end_layout
2228 \begin_layout Plain Layout
2230 newfangle_sources: $(NEWFANGLE_SOURCE_STAMP)
2231 \end_layout
2233 \end_inset
2236 \end_layout
2238 \begin_layout Standard
2239 And also a convenient target to remove extracted sources.
2240 \end_layout
2242 \begin_layout Chunk
2243 Makefile.inc-targets
2244 \end_layout
2246 \begin_layout Standard
2247 \begin_inset listings
2248 inline false
2249 status open
2251 \begin_layout Plain Layout
2253 .PHONY: clean_newfangle_sources
2254 \end_layout
2256 \begin_layout Plain Layout
2258 clean_newfangle_sources: ; 
2259 \backslash
2261 \end_layout
2263 \begin_layout Plain Layout
2265         rm -f -- $(NEWFANGLE_SOURCE_STAMP) $(NEWFANGLE_SOURCES)
2266 \end_layout
2268 \end_inset
2271 \end_layout
2273 \begin_layout Standard
2274 This 
2275 \begin_inset Flex CharStyle:Code
2276 status collapsed
2278 \begin_layout Plain Layout
2279 if_extension
2280 \end_layout
2282 \end_inset
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
2286  (3), or not (4).
2287 \end_layout
2289 \begin_layout Chunk
2290 Makefile.inc-vars
2291 \end_layout
2293 \begin_layout Standard
2294 \begin_inset listings
2295 inline false
2296 status open
2298 \begin_layout Plain Layout
2300 if_extension=$(if $(findstring $(suffix $(1)),$(2)),$(3),$(4))
2301 \end_layout
2303 \end_inset
2306 \end_layout
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.
2311 \end_layout
2313 \begin_layout Standard
2314 To make this easier we define the file extensions for which we want to do
2315  this.
2316 \end_layout
2318 \begin_layout Chunk
2319 Makefile.inc-vars
2320 \end_layout
2322 \begin_layout Standard
2323 \begin_inset listings
2324 inline false
2325 status open
2327 \begin_layout Plain Layout
2329 C_EXTENSIONS=.c .h
2330 \end_layout
2332 \end_inset
2335 \end_layout
2337 \begin_layout Standard
2338 We can then use the if_extensions macro to define a macro which expands
2339  out to the 
2340 \begin_inset Flex CharStyle:Code
2341 status collapsed
2343 \begin_layout Plain Layout
2345 \end_layout
2347 \end_inset
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.
2352 \end_layout
2354 \begin_layout Chunk
2355 Makefile.inc-vars
2356 \end_layout
2358 \begin_layout Standard
2359 \begin_inset listings
2360 inline false
2361 status open
2363 \begin_layout Plain Layout
2365 TABS=8
2366 \end_layout
2368 \begin_layout Plain Layout
2370 nf_line=-L -T$(TABS)
2371 \end_layout
2373 \begin_layout Plain Layout
2375 newfangle=newfangle 
2376 \backslash
2378 \end_layout
2380 \begin_layout Plain Layout
2382   $(call if_extension,$(2),$(C_EXTENSIONS),$(nf_line)) 
2383 \backslash
2385 \end_layout
2387 \begin_layout Plain Layout
2389     -R"$(2)" $(1)
2390 \end_layout
2392 \end_inset
2395 \end_layout
2397 \begin_layout Standard
2398 We can use a similar trick to define an 
2399 \emph on
2400 indent
2401 \emph default
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
2406 status collapsed
2408 \begin_layout Plain Layout
2409 make newfangle_sources indent=
2410 \end_layout
2412 \end_inset
2415 \end_layout
2417 \begin_layout Chunk
2418 Makefile.inc-vars
2419 \end_layout
2421 \begin_layout Standard
2422 \begin_inset listings
2423 inline false
2424 status open
2426 \begin_layout Plain Layout
2428 indent_options=-npro -kr -i8 -ts8 -sob -l80 -ss -ncs
2429 \end_layout
2431 \begin_layout Plain Layout
2433 indent=$(call if_extension,$(1),$(C_EXTENSIONS),
2434 \backslash
2436 \end_layout
2438 \begin_layout Plain Layout
2440               | indent $(indent_options))
2441 \end_layout
2443 \end_inset
2446 \end_layout
2448 \begin_layout Standard
2449 We now define the pattern for extracting a file.
2450  The files are written using noweb's 
2451 \emph on
2452 cpif
2453 \begin_inset Foot
2454 status collapsed
2456 \begin_layout Plain Layout
2458 \emph on
2459 So you still need noweb installed in order to use cpif
2460 \end_layout
2462 \end_inset
2465 \begin_inset Note Note
2466 status collapsed
2468 \begin_layout Plain Layout
2470 \emph on
2471 Write an awk version
2472 \end_layout
2474 \end_inset
2477 \emph default
2478  so that the file timestamp will not be touched if the contents haven't
2479  changed.
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.
2482 \end_layout
2484 \begin_layout Chunk
2485 Makefile.inc-vars
2486 \end_layout
2488 \begin_layout Standard
2489 \begin_inset listings
2490 inline false
2491 status open
2493 \begin_layout Plain Layout
2495 newfangle_extract=@mkdir -p $(dir $(1)) && 
2496 \backslash
2498 \end_layout
2500 \begin_layout Plain Layout
2502   $(call newfangle,$(2),$(1)) > "$(1).tmp" && 
2503 \backslash
2505 \end_layout
2507 \begin_layout Plain Layout
2509   cat "$(1).tmp" $(indent) | cpif "$(1)" 
2510 \backslash
2512 \end_layout
2514 \begin_layout Plain Layout
2516   && rm -- "$(1).tmp" || 
2517 \backslash
2519 \end_layout
2521 \begin_layout Plain Layout
2523   (echo error newfangling $(1) from $(2) ; exit 1)
2524 \end_layout
2526 \end_inset
2529 \end_layout
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.
2535 \end_layout
2537 \begin_layout Chunk
2538 Makefile.inc-vars
2539 \end_layout
2541 \begin_layout Standard
2542 \begin_inset listings
2543 inline false
2544 status open
2546 \begin_layout Plain Layout
2548 define NEWFANGLE_template
2549 \end_layout
2551 \begin_layout Plain Layout
2553   $(1): $(2); 
2554 \backslash
2556 \end_layout
2558 \begin_layout Plain Layout
2560     $$(call newfangle_extract,$(1),$(2))
2561 \end_layout
2563 \begin_layout Plain Layout
2565   NEWFANGLE_TARGETS+=$(1)
2566 \end_layout
2568 \begin_layout Plain Layout
2570 endef
2571 \end_layout
2573 \end_inset
2576 \end_layout
2578 \begin_layout Standard
2579 We then enumerate the discovered 
2580 \begin_inset Flex CharStyle:Code
2581 status collapsed
2583 \begin_layout Plain Layout
2584 NEWTANGLE_SOURCES
2585 \end_layout
2587 \end_inset
2589  to generate a makefile rule for each one using the makefile template we
2590  defined above.
2591 \end_layout
2593 \begin_layout Chunk
2594 Makefile.inc-targets
2595 \end_layout
2597 \begin_layout Standard
2598 \begin_inset listings
2599 inline false
2600 status open
2602 \begin_layout Plain Layout
2604 $(foreach source,$(NEWFANGLE_SOURCES),
2605 \backslash
2607 \end_layout
2609 \begin_layout Plain Layout
2611   $(eval $(call NEWFANGLE_template,$(source),$(NEWFANGLE_SOURCE))) 
2612 \backslash
2614 \end_layout
2616 \begin_layout Plain Layout
2619 \end_layout
2621 \end_inset
2624 \end_layout
2626 \begin_layout Standard
2627 These will all be built with NEWFANGLE_SOURCE_STAMP.
2628 \end_layout
2630 \begin_layout Standard
2631 We also remove the generated sources on a 
2632 \emph on
2633 make distclean
2634 \emph default
2636 \end_layout
2638 \begin_layout Chunk
2639 Makefile.inc-targets
2640 \end_layout
2642 \begin_layout Standard
2643 \begin_inset listings
2644 inline false
2645 status open
2647 \begin_layout Plain Layout
2649 _distclean: clean_newfangle_sources
2650 \end_layout
2652 \end_inset
2655 \end_layout
2657 \begin_layout Subsection
2658 Extracting Documentation
2659 \end_layout
2661 \begin_layout Standard
2662 We then identify the intermediate stages of the documentation and their
2663  build and clean targets.
2664 \end_layout
2666 \begin_layout Subsubsection
2667 Running pdflatex
2668 \end_layout
2670 \begin_layout Standard
2671 We produce a pdf file from the tex file.
2672 \end_layout
2674 \begin_layout Chunk
2675 Makefile.inc-vars
2676 \end_layout
2678 \begin_layout Standard
2679 \begin_inset listings
2680 inline false
2681 status open
2683 \begin_layout Plain Layout
2685 NEWFANGLE_PDF=$(TEX_SOURCE:.tex=.pdf)
2686 \end_layout
2688 \end_inset
2691 \end_layout
2693 \begin_layout Standard
2694 We run pdflatex twice to be sure that the contents and aux files are up
2695  to date.
2696  We certainly are required to run pdflatex twice if these files do not exist!
2697 \end_layout
2699 \begin_layout Chunk
2700 Makefile.inc-targets
2701 \end_layout
2703 \begin_layout Standard
2704 \begin_inset listings
2705 inline false
2706 status open
2708 \begin_layout Plain Layout
2710 $(NEWFANGLE_PDF): $(TEX_SOURCE); pdflatex $< && pdflatex $<
2711 \end_layout
2713 \begin_layout Plain Layout
2715 clean_pdf: ; rm -f -- $(NEWFANGLE_PDF) 
2716 \backslash
2718 \end_layout
2720 \begin_layout Plain Layout
2722                       $(TEX_SOURCE:.tex=.toc) 
2723 \backslash
2725 \end_layout
2727 \begin_layout Plain Layout
2729                       $(TEX_SOURCE:.tex=.log) 
2730 \backslash
2732 \end_layout
2734 \begin_layout Plain Layout
2736                       $(TEX_SOURCE:.tex=.aux)
2737 \end_layout
2739 \end_inset
2742 \end_layout
2744 \begin_layout Subsubsection
2745 The docs as a whole
2746 \end_layout
2748 \begin_layout Standard
2749 Currently we only build pdf as a final format, but NEWFANGLE_DOCS may later
2750  hold other output formats.
2751 \end_layout
2753 \begin_layout Chunk
2754 Makefile.inc-vars
2755 \end_layout
2757 \begin_layout Standard
2758 \begin_inset listings
2759 inline false
2760 status open
2762 \begin_layout Plain Layout
2764 NEWFANGLE_DOCS=$(NEWFANGLE_PDF)
2765 \end_layout
2767 \end_inset
2770 \end_layout
2772 \begin_layout Standard
2773 We also define newfangle_docs as a convenient phony target<
2774 \end_layout
2776 \begin_layout Chunk
2777 Makefile.inc-targets
2778 \end_layout
2780 \begin_layout Standard
2781 \begin_inset listings
2782 inline false
2783 status open
2785 \begin_layout Plain Layout
2787 .PHONY: newfangle_docs
2788 \end_layout
2790 \begin_layout Plain Layout
2792 newfangle_docs: $(NEWFANGLE_DOCS)
2793 \end_layout
2795 \begin_layout Plain Layout
2797 docs: newfangle_docs
2798 \end_layout
2800 \end_inset
2803 \end_layout
2805 \begin_layout Standard
2806 And define a convenient clean_noweb_docs which we add to the regular clean
2807  target
2808 \end_layout
2810 \begin_layout Chunk
2811 Makefile.inc-targets
2812 \end_layout
2814 \begin_layout Standard
2815 \begin_inset listings
2816 inline false
2817 status open
2819 \begin_layout Plain Layout
2821 .PHONEY: clean_newfangle_docs
2822 \end_layout
2824 \begin_layout Plain Layout
2826 clean_newfangle_docs: clean_tex clean_pdf
2827 \end_layout
2829 \begin_layout Plain Layout
2831 clean: clean_newfangle_docs
2832 \end_layout
2834 \begin_layout Plain Layout
2836 \end_layout
2838 \begin_layout Plain Layout
2840 distclean_newfangle_docs: clean_tex clean_newfangle_docs
2841 \end_layout
2843 \begin_layout Plain Layout
2845 distclean: clean distclean_newfangle_docs
2846 \end_layout
2848 \end_inset
2851 \end_layout
2853 \begin_layout Subsection
2854 Other helpers
2855 \end_layout
2857 \begin_layout Standard
2858 If Makefile.inc is included into Makefile, then extracted files can be updated
2859  with this command:
2860 \end_layout
2862 \begin_layout LyX-Code
2863 make newfangle_sources
2864 \end_layout
2866 \begin_layout Standard
2867 otherwise, with:
2868 \end_layout
2870 \begin_layout LyX-Code
2871 make -f Makefile.inc newfangle_sources
2872 \end_layout
2874 \begin_layout Part
2875 Source Code
2876 \end_layout
2878 \begin_layout Chapter
2879 Newfangle awk source code
2880 \end_layout
2882 \begin_layout Standard
2883 We use the copyright notice from chapter 
2884 \begin_inset CommandInset ref
2885 LatexCommand vref
2886 reference "cha:License"
2888 \end_inset
2891 \end_layout
2893 \begin_layout Chunk
2894 ./newfangle,language=awk,morestring=[b]{/},morekeywords=else
2895 \end_layout
2897 \begin_layout Standard
2898 \begin_inset listings
2899 inline false
2900 status open
2902 \begin_layout Plain Layout
2904 #! /usr/bin/awk -f
2905 \end_layout
2907 \begin_layout Plain Layout
2910 \backslash
2911 chunkref{gpl3-copyright}>
2912 \end_layout
2914 \end_inset
2917 \end_layout
2919 \begin_layout Standard
2920 We also use code from Arnold Robbins public domain getopt (1993 revision)
2921  defined in chapter 
2922 \begin_inset CommandInset ref
2923 LatexCommand ref
2924 reference "cha:getopt"
2926 \end_inset
2928 , and naturally want to attribute this appropriately.
2929 \end_layout
2931 \begin_layout Standard
2932 \begin_inset listings
2933 inline false
2934 status open
2936 \begin_layout Plain Layout
2938 \end_layout
2940 \begin_layout Plain Layout
2942 # NOTE: Arnold Robbins public domain getopt for awk is also used:
2943 \end_layout
2945 \begin_layout Plain Layout
2948 \backslash
2949 chunkref{getopt.awk-header}>
2950 \end_layout
2952 \begin_layout Plain Layout
2954 \end_layout
2956 \begin_layout Plain Layout
2959 \backslash
2960 chunkref{getopt.awk-getopt()}>
2961 \end_layout
2963 \begin_layout Plain Layout
2965 \end_layout
2967 \end_inset
2970 \end_layout
2972 \begin_layout Standard
2973 And include the following chunks
2974 \end_layout
2976 \begin_layout Chunk
2977 ./newfangle
2978 \end_layout
2980 \begin_layout Standard
2981 \begin_inset listings
2982 inline false
2983 status open
2985 \begin_layout Plain Layout
2988 \backslash
2989 chunkref{helper-functions}>
2990 \end_layout
2992 \begin_layout Plain Layout
2995 \backslash
2996 chunkref{mode-tracker}>
2997 \end_layout
2999 \begin_layout Plain Layout
3002 \backslash
3003 chunkref{parse_chunk_args}>
3004 \end_layout
3006 \begin_layout Plain Layout
3009 \backslash
3010 chunkref{chunk-storage-functions}>
3011 \end_layout
3013 \begin_layout Plain Layout
3016 \backslash
3017 chunkref{output_chunk_names()}>
3018 \end_layout
3020 \begin_layout Plain Layout
3023 \backslash
3024 chunkref{output_chunks()}>
3025 \end_layout
3027 \begin_layout Plain Layout
3030 \backslash
3031 chunkref{write_chunk()}>
3032 \end_layout
3034 \begin_layout Plain Layout
3037 \backslash
3038 chunkref{expand_chunk_args()}>
3039 \end_layout
3041 \begin_layout Plain Layout
3044 \backslash
3045 chunkref{begin}>
3046 \end_layout
3048 \begin_layout Plain Layout
3051 \backslash
3052 chunkref{recognize-chunk}>
3053 \end_layout
3055 \begin_layout Plain Layout
3058 \backslash
3059 chunkref{end}>
3060 \end_layout
3062 \end_inset
3065 \end_layout
3067 \begin_layout Section
3068 AWK tricks
3069 \end_layout
3071 \begin_layout Standard
3072 The portable way to erase an array in awk is to split the empty string,
3073  like this:
3074 \end_layout
3076 \begin_layout Chunk
3077 awk-delete-array,params=ARRAY
3078 \end_layout
3080 \begin_layout Standard
3081 \begin_inset listings
3082 inline false
3083 status open
3085 \begin_layout Plain Layout
3087 split("", ${ARRAY});
3088 \end_layout
3090 \end_inset
3093 \end_layout
3095 \begin_layout Chunk
3096 dump-array,params=ARRAY
3097 \end_layout
3099 \begin_layout Standard
3100 \begin_inset listings
3101 inline false
3102 status open
3104 \begin_layout Plain Layout
3106 print "
3107 \backslash
3108 nDump: ${ARRAY}
3109 \backslash
3110 n--------
3111 \backslash
3112 n" > "/dev/stderr";
3113 \end_layout
3115 \begin_layout Plain Layout
3117 for (_x in ${ARRAY}) {
3118 \end_layout
3120 \begin_layout Plain Layout
3122   print _x "=" ${ARRAY}[_x] "
3123 \backslash
3124 n" > "/dev/stderr";
3125 \end_layout
3127 \begin_layout Plain Layout
3130 \end_layout
3132 \begin_layout Plain Layout
3134 print "========
3135 \backslash
3136 n" > "/dev/stderr";
3137 \end_layout
3139 \end_inset
3142 \end_layout
3144 \begin_layout Chunk
3145 ,params=
3146 \end_layout
3148 \begin_layout Section
3149 Catching errors
3150 \end_layout
3152 \begin_layout Standard
3153 Fatal errors are issued with the error function:
3154 \end_layout
3156 \begin_layout Chunk
3157 error(),append=helper-functions
3158 \end_layout
3160 \begin_layout Standard
3161 \begin_inset listings
3162 inline false
3163 status open
3165 \begin_layout Plain Layout
3167 function error(message)
3168 \end_layout
3170 \begin_layout Plain Layout
3173 \end_layout
3175 \begin_layout Plain Layout
3177   print "ERROR: " FILENAME ":" FNR " " message > "/dev/stderr";
3178 \end_layout
3180 \begin_layout Plain Layout
3182   exit 1;
3183 \end_layout
3185 \begin_layout Plain Layout
3188 \end_layout
3190 \end_inset
3193 \end_layout
3195 \begin_layout Standard
3196 \begin_inset listings
3197 inline false
3198 status open
3200 \begin_layout Plain Layout
3202 function warning(message)
3203 \end_layout
3205 \begin_layout Plain Layout
3208 \end_layout
3210 \begin_layout Plain Layout
3212   print "WARNING: " FILENAME ":" FNR " " message > "/dev/stderr";
3213 \end_layout
3215 \begin_layout Plain Layout
3217   warnings++;
3218 \end_layout
3220 \begin_layout Plain Layout
3223 \end_layout
3225 \end_inset
3228 \end_layout
3230 \begin_layout Chapter
3231 lstlistings
3232 \end_layout
3234 \begin_layout Standard
3235 LaTeX arguments to lstlistings macros are a comma seperated list of key-value
3236  pairs.
3237  Values containing commas are enclosed in { braces }.
3238 \end_layout
3240 \begin_layout Standard
3241 We need a function that can parse such an expression and assign the values
3242  to an 
3243 \noun on
3245 \noun default
3246  associated array.
3247 \end_layout
3249 \begin_layout Standard
3250 A sample expressions is:
3251 \end_layout
3253 \begin_layout LyX-Code
3254 name=thomas, params={a, b}, something, something-else
3255 \end_layout
3257 \begin_layout Standard
3258 but we see that this is just a simpler form of this expression:
3259 \end_layout
3261 \begin_layout LyX-Code
3262 name=freddie, foo={bar=baz, quux={quirk, a=fleeg}}, etc
3263 \end_layout
3265 \begin_layout Standard
3266 And that it would be a good idea to use a recursive parser into a multi-dimensio
3267 nal hash
3268 \begin_inset Foot
3269 status collapsed
3271 \begin_layout Plain Layout
3272 as AWK doesn't have nested-hash support
3273 \end_layout
3275 \end_inset
3277 , resulting in:
3278 \end_layout
3280 \begin_layout Standard
3281 \begin_inset Tabular
3282 <lyxtabular version="3" rows="6" columns="2">
3283 <features>
3284 <column alignment="left" valignment="top" width="0">
3285 <column alignment="left" valignment="top" width="0">
3286 <row>
3287 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
3288 \begin_inset Text
3290 \begin_layout Plain Layout
3292 \end_layout
3294 \end_inset
3295 </cell>
3296 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
3297 \begin_inset Text
3299 \begin_layout Plain Layout
3300 value
3301 \end_layout
3303 \end_inset
3304 </cell>
3305 </row>
3306 <row>
3307 <cell alignment="left" valignment="top" topline="true" leftline="true" usebox="none">
3308 \begin_inset Text
3310 \begin_layout Plain Layout
3311 a[name]
3312 \end_layout
3314 \end_inset
3315 </cell>
3316 <cell alignment="left" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
3317 \begin_inset Text
3319 \begin_layout Plain Layout
3320 freddie
3321 \end_layout
3323 \end_inset
3324 </cell>
3325 </row>
3326 <row>
3327 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
3328 \begin_inset Text
3330 \begin_layout Plain Layout
3331 a[foo, bar]
3332 \end_layout
3334 \end_inset
3335 </cell>
3336 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
3337 \begin_inset Text
3339 \begin_layout Plain Layout
3341 \end_layout
3343 \end_inset
3344 </cell>
3345 </row>
3346 <row>
3347 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
3348 \begin_inset Text
3350 \begin_layout Plain Layout
3351 a[foo, quux, quirk]
3352 \end_layout
3354 \end_inset
3355 </cell>
3356 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
3357 \begin_inset Text
3359 \begin_layout Plain Layout
3361 \end_layout
3363 \end_inset
3364 </cell>
3365 </row>
3366 <row>
3367 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
3368 \begin_inset Text
3370 \begin_layout Plain Layout
3371 a[foo, quux, a]
3372 \end_layout
3374 \end_inset
3375 </cell>
3376 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
3377 \begin_inset Text
3379 \begin_layout Plain Layout
3380 fleeg
3381 \end_layout
3383 \end_inset
3384 </cell>
3385 </row>
3386 <row>
3387 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
3388 \begin_inset Text
3390 \begin_layout Plain Layout
3391 a[etc]
3392 \end_layout
3394 \end_inset
3395 </cell>
3396 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
3397 \begin_inset Text
3399 \begin_layout Plain Layout
3401 \end_layout
3403 \end_inset
3404 </cell>
3405 </row>
3406 </lyxtabular>
3408 \end_inset
3411 \end_layout
3413 \begin_layout Standard
3414 On reflection it seems that sometimes such nesting is not desirable, as
3415  the braces are also used to delimit values that contain commas --- we may
3416  consider that
3417 \end_layout
3419 \begin_layout LyX-Code
3420 name={williamson, freddie}
3421 \end_layout
3423 \begin_layout Standard
3424 should assign 
3425 \begin_inset Flex CharStyle:Code
3426 status collapsed
3428 \begin_layout Plain Layout
3429 williamson, freddie
3430 \end_layout
3432 \end_inset
3434  to 
3435 \begin_inset Flex CharStyle:Code
3436 status collapsed
3438 \begin_layout Plain Layout
3439 name
3440 \end_layout
3442 \end_inset
3444  --- so I may change this behaviour.
3445 \begin_inset Note Note
3446 status collapsed
3448 \begin_layout Plain Layout
3449 So change it
3450 \end_layout
3452 \end_inset
3455 \end_layout
3457 \begin_layout Standard
3458 Function 
3459 \begin_inset Flex Chunkref
3460 status collapsed
3462 \begin_layout Plain Layout
3463 get_chunk_args()
3464 \end_layout
3466 \end_inset
3468  will accept two paramters, 
3469 \begin_inset Flex CharStyle:Code
3470 status collapsed
3472 \begin_layout Plain Layout
3473 text
3474 \end_layout
3476 \end_inset
3478  being the text to parse, and 
3479 \begin_inset Flex CharStyle:Code
3480 status collapsed
3482 \begin_layout Plain Layout
3483 values
3484 \end_layout
3486 \end_inset
3488  being an array to receive the parsed values as described above.
3489  The optional parameter 
3490 \begin_inset Flex CharStyle:Code
3491 status collapsed
3493 \begin_layout Plain Layout
3494 path
3495 \end_layout
3497 \end_inset
3499  is used during recursion to build up the multi-dimensional array path.
3500 \end_layout
3502 \begin_layout Chunk
3503 ./newfangle
3504 \end_layout
3506 \begin_layout Standard
3507 \begin_inset listings
3508 inline false
3509 status open
3511 \begin_layout Plain Layout
3514 \backslash
3515 chunkref{get_chunk_args()}>
3516 \end_layout
3518 \end_inset
3521 \end_layout
3523 \begin_layout Chunk
3524 get_chunk_args()
3525 \end_layout
3527 \begin_layout Standard
3528 \begin_inset listings
3529 inline false
3530 status open
3532 \begin_layout Plain Layout
3534 function get_chunk_args(text, values,
3535 \end_layout
3537 \begin_layout Plain Layout
3539   # optional parameters
3540 \end_layout
3542 \begin_layout Plain Layout
3544   path, # hierarchical precursors
3545 \end_layout
3547 \begin_layout Plain Layout
3549   # local vars
3550 \end_layout
3552 \begin_layout Plain Layout
3554   a, name)
3555 \end_layout
3557 \end_inset
3560 \end_layout
3562 \begin_layout Standard
3563 The strategy is to parse the name, and then look for a value.
3564  If the value begins with a brace 
3565 \begin_inset Flex CharStyle:Code
3566 status collapsed
3568 \begin_layout Plain Layout
3570 \end_layout
3572 \end_inset
3574 , then we recurse and consume as much of the text as necessary, returning
3575  the remaining text when we encounter a leading close-brace 
3576 \begin_inset Flex CharStyle:Code
3577 status collapsed
3579 \begin_layout Plain Layout
3581 \end_layout
3583 \end_inset
3586  This being the strategy --- and executed in a loop --- we realise that
3587  we must first look for the closing brace (perhaps preceded by white space)
3588  in order to terminate the recursion, and returning remaining text.
3589 \end_layout
3591 \begin_layout Standard
3592 \begin_inset listings
3593 inline false
3594 status open
3596 \begin_layout Plain Layout
3599 \end_layout
3601 \begin_layout Plain Layout
3603   split("", next_chunk_args);
3604 \end_layout
3606 \begin_layout Plain Layout
3608   while(length(text)) {
3609 \end_layout
3611 \begin_layout Plain Layout
3613     if (match(text, "^ *}(.*)", a)) {
3614 \end_layout
3616 \begin_layout Plain Layout
3618       return a[1];
3619 \end_layout
3621 \begin_layout Plain Layout
3623     }
3624 \end_layout
3626 \begin_layout Plain Layout
3628     =<
3629 \backslash
3630 chunkref{parse-chunk-args}>
3631 \end_layout
3633 \begin_layout Plain Layout
3635   }
3636 \end_layout
3638 \begin_layout Plain Layout
3640   return text;
3641 \end_layout
3643 \begin_layout Plain Layout
3646 \end_layout
3648 \end_inset
3651 \end_layout
3653 \begin_layout Standard
3654 \begin_inset Note Note
3655 status collapsed
3657 \begin_layout Plain Layout
3658 Use BNF package here
3659 \end_layout
3661 \end_inset
3663 We can see that the text could be inspected with this regex:
3664 \end_layout
3666 \begin_layout Chunk
3667 parse-chunk-args
3668 \end_layout
3670 \begin_layout Standard
3671 \begin_inset listings
3672 inline false
3673 status open
3675 \begin_layout Plain Layout
3677 if (! match(text, " *([^,=]*[^,= ]) *(([,=]) *(([^,}]*) *,* *(.*))|)$", a))
3679 \end_layout
3681 \begin_layout Plain Layout
3683   return text;
3684 \end_layout
3686 \begin_layout Plain Layout
3689 \end_layout
3691 \end_inset
3694 \end_layout
3696 \begin_layout Standard
3697 and that 
3698 \begin_inset Flex CharStyle:Code
3699 status collapsed
3701 \begin_layout Plain Layout
3703 \end_layout
3705 \end_inset
3707  will have the following values:
3708 \end_layout
3710 \begin_layout Standard
3711 \begin_inset Tabular
3712 <lyxtabular version="3" rows="7" columns="2">
3713 <features>
3714 <column alignment="center" valignment="top" width="0">
3715 <column alignment="left" valignment="top" width="0">
3716 <row>
3717 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
3718 \begin_inset Text
3720 \begin_layout Plain Layout
3721 a[n]
3722 \end_layout
3724 \end_inset
3725 </cell>
3726 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
3727 \begin_inset Text
3729 \begin_layout Plain Layout
3730 assigned text
3731 \end_layout
3733 \end_inset
3734 </cell>
3735 </row>
3736 <row>
3737 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
3738 \begin_inset Text
3740 \begin_layout Plain Layout
3742 \end_layout
3744 \end_inset
3745 </cell>
3746 <cell alignment="left" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
3747 \begin_inset Text
3749 \begin_layout Plain Layout
3750 freddie
3751 \end_layout
3753 \end_inset
3754 </cell>
3755 </row>
3756 <row>
3757 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
3758 \begin_inset Text
3760 \begin_layout Plain Layout
3762 \end_layout
3764 \end_inset
3765 </cell>
3766 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
3767 \begin_inset Text
3769 \begin_layout Plain Layout
3770 =freddie, foo={bar=baz, quux={quirk, a=fleeg}}, etc
3771 \end_layout
3773 \end_inset
3774 </cell>
3775 </row>
3776 <row>
3777 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
3778 \begin_inset Text
3780 \begin_layout Plain Layout
3782 \end_layout
3784 \end_inset
3785 </cell>
3786 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
3787 \begin_inset Text
3789 \begin_layout Plain Layout
3791 \end_layout
3793 \end_inset
3794 </cell>
3795 </row>
3796 <row>
3797 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
3798 \begin_inset Text
3800 \begin_layout Plain Layout
3802 \end_layout
3804 \end_inset
3805 </cell>
3806 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
3807 \begin_inset Text
3809 \begin_layout Plain Layout
3810 freddie, foo={bar=baz, quux={quirk, a=fleeg}}, etc
3811 \end_layout
3813 \end_inset
3814 </cell>
3815 </row>
3816 <row>
3817 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
3818 \begin_inset Text
3820 \begin_layout Plain Layout
3822 \end_layout
3824 \end_inset
3825 </cell>
3826 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
3827 \begin_inset Text
3829 \begin_layout Plain Layout
3830 freddie
3831 \end_layout
3833 \end_inset
3834 </cell>
3835 </row>
3836 <row>
3837 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
3838 \begin_inset Text
3840 \begin_layout Plain Layout
3842 \end_layout
3844 \end_inset
3845 </cell>
3846 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
3847 \begin_inset Text
3849 \begin_layout Plain Layout
3850 , foo={bar=baz, quux={quirk, a=fleeg}}, etc
3851 \end_layout
3853 \end_inset
3854 </cell>
3855 </row>
3856 </lyxtabular>
3858 \end_inset
3861 \end_layout
3863 \begin_layout Standard
3864 a[3] will be either 
3865 \begin_inset Flex CharStyle:Code
3866 status collapsed
3868 \begin_layout Plain Layout
3870 \end_layout
3872 \end_inset
3874  or 
3875 \begin_inset Flex CharStyle:Code
3876 status collapsed
3878 \begin_layout Plain Layout
3880 \end_layout
3882 \end_inset
3884  and signify whether the option named in 
3885 \begin_inset Flex CharStyle:Code
3886 status collapsed
3888 \begin_layout Plain Layout
3889 a[1]
3890 \end_layout
3892 \end_inset
3894  has a value or not (respectively).
3895 \end_layout
3897 \begin_layout Standard
3898 If the option does have a value, then if the expression 
3899 \begin_inset Flex CharStyle:Code
3900 status collapsed
3902 \begin_layout Plain Layout
3903 substr(a[4],1,1)
3904 \end_layout
3906 \end_inset
3908  returns a brace 
3909 \begin_inset Flex CharStyle:Code
3910 status collapsed
3912 \begin_layout Plain Layout
3914 \end_layout
3916 \end_inset
3918  it will signify that we need to recurse:
3919 \end_layout
3921 \begin_layout Standard
3922 \begin_inset listings
3923 inline false
3924 status open
3926 \begin_layout Plain Layout
3928 name=a[1];
3929 \end_layout
3931 \begin_layout Plain Layout
3933 if (a[3] == "=") {
3934 \end_layout
3936 \begin_layout Plain Layout
3938   if (substr(a[4],1,1) == "{") {
3939 \end_layout
3941 \begin_layout Plain Layout
3943     text = get_chunk_args(substr(a[4],2), values, path name SUBSEP);
3944 \end_layout
3946 \begin_layout Plain Layout
3948   } else {
3949 \end_layout
3951 \begin_layout Plain Layout
3953     values[path name]=a[5];
3954 \end_layout
3956 \begin_layout Plain Layout
3958     text = a[6];
3959 \end_layout
3961 \begin_layout Plain Layout
3963   }
3964 \end_layout
3966 \begin_layout Plain Layout
3968 } else {
3969 \end_layout
3971 \begin_layout Plain Layout
3973   values[path name]="";
3974 \end_layout
3976 \begin_layout Plain Layout
3978   text = a[2];
3979 \end_layout
3981 \begin_layout Plain Layout
3984 \end_layout
3986 \end_inset
3989 \end_layout
3991 \begin_layout Standard
3992 We can test this function like this:
3993 \end_layout
3995 \begin_layout Chunk
3996 gca-test.awk
3997 \end_layout
3999 \begin_layout Standard
4000 \begin_inset listings
4001 inline false
4002 status open
4004 \begin_layout Plain Layout
4007 \backslash
4008 chunkref{get_chunk_args()}>
4009 \end_layout
4011 \begin_layout Plain Layout
4013 BEGIN {
4014 \end_layout
4016 \begin_layout Plain Layout
4018   SUBSEP=".";
4019 \end_layout
4021 \begin_layout Plain Layout
4023 \end_layout
4025 \begin_layout Plain Layout
4027   print get_chunk_args("name=freddie, foo={bar=baz, quux={quirk, a=fleeg}},
4028  etc", a);
4029 \end_layout
4031 \begin_layout Plain Layout
4033   for (b in a) {
4034 \end_layout
4036 \begin_layout Plain Layout
4038     print "a[" b "] => " a[b];
4039 \end_layout
4041 \begin_layout Plain Layout
4043   }
4044 \end_layout
4046 \begin_layout Plain Layout
4049 \end_layout
4051 \end_inset
4054 \end_layout
4056 \begin_layout Standard
4057 which should give this output:
4058 \end_layout
4060 \begin_layout Chunk
4061 gca-test.awk-results
4062 \end_layout
4064 \begin_layout Standard
4065 \begin_inset listings
4066 inline false
4067 status open
4069 \begin_layout Plain Layout
4071 a[foo.quux.quirk] => 
4072 \end_layout
4074 \begin_layout Plain Layout
4076 a[foo.quux.a] => fleeg
4077 \end_layout
4079 \begin_layout Plain Layout
4081 a[foo.bar] => baz
4082 \end_layout
4084 \begin_layout Plain Layout
4086 a[etc] => 
4087 \end_layout
4089 \begin_layout Plain Layout
4091 a[name] => freddie
4092 \end_layout
4094 \end_inset
4097 \end_layout
4099 \begin_layout Chapter
4100 Language Modes
4101 \end_layout
4103 \begin_layout Standard
4104 \begin_inset CommandInset label
4105 LatexCommand label
4106 name "cha:modes"
4108 \end_inset
4111 \begin_inset Note Greyedout
4112 status open
4114 \begin_layout Plain Layout
4115 This feature is in-development and does not work yet
4116 \end_layout
4118 \end_inset
4121 \begin_inset Note Note
4122 status open
4124 \begin_layout Plain Layout
4125 In Progress!
4126 \end_layout
4128 \end_inset
4131 \end_layout
4133 \begin_layout Standard
4134 lstlistings and newfangle both recognize source languages, and perform some
4135  basic parsing.
4136  lstlistings can detect strings and comments within a language definition
4137  and perform suitable rendering, such as italics for comments, and visible-space
4138 s within strings.
4139 \end_layout
4141 \begin_layout Standard
4142 Newfangle similarly can recognize strings, and comments, etc, within a language,
4143  so that any chunks included with 
4144 \begin_inset Flex CharStyle:Code
4145 status collapsed
4147 \begin_layout Plain Layout
4149 \backslash
4150 chunkref
4151 \end_layout
4153 \end_inset
4155  can be suitably escape or quoted.
4156 \end_layout
4158 \begin_layout Standard
4159 For instance, consider this chunk with 
4160 \begin_inset Flex CharStyle:Code
4161 status collapsed
4163 \begin_layout Plain Layout
4164 language=perl
4165 \end_layout
4167 \end_inset
4170 \end_layout
4172 \begin_layout Chunk
4173 example-perl,language=perl
4174 \end_layout
4176 \begin_layout Standard
4177 \begin_inset listings
4178 inline false
4179 status open
4181 \begin_layout Plain Layout
4183 s/"$/'/;
4184 \end_layout
4186 \end_inset
4189 \end_layout
4191 \begin_layout Standard
4192 If it were included in a chunk with 
4193 \begin_inset Flex CharStyle:Code
4194 status collapsed
4196 \begin_layout Plain Layout
4197 language=sh
4198 \end_layout
4200 \end_inset
4202 , like this:
4203 \end_layout
4205 \begin_layout Chunk
4206 example-sh,language=sh
4207 \end_layout
4209 \begin_layout Standard
4210 \begin_inset listings
4211 inline false
4212 status open
4214 \begin_layout Plain Layout
4216 perl -pe "=<
4217 \backslash
4218 chunkref{example-perl}>"
4219 \end_layout
4221 \end_inset
4224 \end_layout
4226 \begin_layout Standard
4227 newfangle would need to generate output like this if it were to work: 
4228 \end_layout
4230 \begin_layout LyX-Code
4231 perl -pe "s/
4232 \backslash
4234 \backslash
4235 $/'/;"
4236 \end_layout
4238 \begin_layout Standard
4239 See that the double quote 
4240 \begin_inset Flex CharStyle:Code
4241 status collapsed
4243 \begin_layout Plain Layout
4245 \end_layout
4247 \end_inset
4249 , and 
4250 \begin_inset Flex CharStyle:Code
4251 status collapsed
4253 \begin_layout Plain Layout
4255 \end_layout
4257 \end_inset
4259  in the regex have been quoted with a back-slash to protect them from shell
4260  interpretation.
4261 \end_layout
4263 \begin_layout Standard
4264 If that were then included in a chunk with 
4265 \begin_inset Flex CharStyle:Code
4266 status collapsed
4268 \begin_layout Plain Layout
4269 language=make
4270 \end_layout
4272 \end_inset
4274 , like this:
4275 \end_layout
4277 \begin_layout Chunk
4278 example-makefile,language=make
4279 \end_layout
4281 \begin_layout Standard
4282 \begin_inset listings
4283 inline false
4284 status open
4286 \begin_layout Plain Layout
4288 target: pre-req
4289 \end_layout
4291 \begin_layout Plain Layout
4293                 =<
4294 \backslash
4295 chunkref{example-sh}>
4296 \end_layout
4298 \end_inset
4301 \end_layout
4303 \begin_layout Standard
4304 We would need the output to look like this --- note the $$:
4305 \end_layout
4307 \begin_layout LyX-Code
4308 target: pre-req
4309 \end_layout
4311 \begin_layout LyX-Code
4312         perl -pe "s/
4313 \backslash
4315 \backslash
4316 $$/'/;"
4317 \end_layout
4319 \begin_layout Standard
4320 In order to make this work, we need to define a mode-tracker supporting
4321  each language, that can detect the various quoting modes, and provide a
4322  transformation that must be applied to any included text so that included
4323  text will be interpreted correctly after any interpolation that it may
4324  be subject to at run-time.
4325 \end_layout
4327 \begin_layout Standard
4328 For example, the sed transformation for text to be inserted into sh double-quote
4329 d strings would be something like:
4330 \end_layout
4332 \begin_layout LyX-Code
4334 \backslash
4336 \backslash
4338 \backslash
4340 \backslash
4342 \backslash
4344 \backslash
4345 /g;s/$/
4346 \backslash
4348 \backslash
4349 $/g;s/"/
4350 \backslash
4352 \backslash
4353 "/g;
4354 \end_layout
4356 \begin_layout Standard
4357 which protects 
4358 \begin_inset Flex CharStyle:Code
4359 status collapsed
4361 \begin_layout Plain Layout
4363 \backslash
4364  $ "
4365 \end_layout
4367 \end_inset
4370 \end_layout
4372 \begin_layout Standard
4373 \begin_inset Note Note
4374 status collapsed
4376 \begin_layout Plain Layout
4377 I don't think this example is true
4378 \end_layout
4380 \end_inset
4382 The mode tracker must also track nested mode-changes, as in this 
4383 \begin_inset Flex CharStyle:Code
4384 status collapsed
4386 \begin_layout Plain Layout
4388 \end_layout
4390 \end_inset
4392  example.
4393 \end_layout
4395 \begin_layout LyX-Code
4396 echo "hello `id \SpecialChar \ldots{}
4398 \end_layout
4400 \begin_layout LyX-Code
4401 \begin_inset ERT
4402 status open
4404 \begin_layout Plain Layout
4407 \backslash
4408 noindent
4409 \backslash
4410 hphantom{echo "hello `id}
4411 \end_layout
4413 \end_inset
4416 \end_layout
4418 \begin_layout Standard
4419 Any characters inserted at the point marked ↑ would need to be escaped,
4420  including 
4421 \begin_inset Flex CharStyle:Code
4422 status collapsed
4424 \begin_layout Plain Layout
4425 ` | *
4426 \end_layout
4428 \end_inset
4430  among others.
4431  First it would need escaping for the back-ticks `, and then for the double-quot
4432 es ".
4433 \end_layout
4435 \begin_layout Standard
4436 Escaping need not occur if the format and mode of the included chunk matches
4437  that of the including chunk.
4438 \end_layout
4440 \begin_layout Standard
4441 As each chunk is output a new mode tracker for that language is initialized
4442  in it's normal state.
4443  As text is output for that chunk the output mode is tracked.
4444  When a new chunk is included, a transformation appropriate to that mode
4445  is selected and pushed onto a stack of transformations.
4446  Any text to be output is first passed through this stack of transformations.
4447 \end_layout
4449 \begin_layout Standard
4450 It remains to consider if the chunk-include function should return it's
4451  generated text so that the caller can apply any transformations (and formatting
4452 ), or if it should apply the stack of transformations itself.
4453 \end_layout
4455 \begin_layout Standard
4456 Note that the transformed text should have the property of not being able
4457  to change the mode in the current chunk.
4458 \end_layout
4460 \begin_layout Standard
4461 \begin_inset Note Note
4462 status open
4464 \begin_layout Plain Layout
4465 Note chunk parameters should probably also be transformed
4466 \end_layout
4468 \end_inset
4471 \end_layout
4473 \begin_layout Section
4474 Constructor
4475 \end_layout
4477 \begin_layout Standard
4478 The mode tracker holds its state in a stack based on a hash.
4479  This function, when passed an empty hash will intialize it.
4480 \end_layout
4482 \begin_layout Chunk
4483 new_mode_tracker()
4484 \end_layout
4486 \begin_layout Standard
4487 \begin_inset listings
4488 inline false
4489 status open
4491 \begin_layout Plain Layout
4493 function new_mode_tracker(context, language, mode) {
4494 \end_layout
4496 \begin_layout Plain Layout
4498   context[""] = 0;
4499 \end_layout
4501 \begin_layout Plain Layout
4503   context[0, "language"] = language;
4504 \end_layout
4506 \begin_layout Plain Layout
4508   context[0, "mode"] = mode;
4509 \end_layout
4511 \begin_layout Plain Layout
4514 \end_layout
4516 \end_inset
4519 \end_layout
4521 \begin_layout Standard
4522 Because awk functions cannot return an array, we must create the array first
4523  and pass it in, so we have a newfangle macro to do this:
4524 \end_layout
4526 \begin_layout Chunk
4527 new-mode-tracker,params=context;language;mode
4528 \end_layout
4530 \begin_layout Standard
4531 \begin_inset listings
4532 inline false
4533 status open
4535 \begin_layout Plain Layout
4538 \backslash
4539 chunkref{awk-delete-array}(${context})>
4540 \end_layout
4542 \begin_layout Plain Layout
4544 new_mode_tracker(${context}, ${language}, ${mode});
4545 \end_layout
4547 \end_inset
4550 \end_layout
4552 \begin_layout Standard
4553 And for tracking modes, we dispatch to a mode-tracker action based on the
4554  current language
4555 \end_layout
4557 \begin_layout Chunk
4558 mode_tracker
4559 \end_layout
4561 \begin_layout Standard
4562 \begin_inset listings
4563 inline false
4564 status open
4566 \begin_layout Plain Layout
4568 function push_mode_tracker(context, language, mode,
4569 \end_layout
4571 \begin_layout Plain Layout
4573   # local vars
4574 \end_layout
4576 \begin_layout Plain Layout
4578   top)
4579 \end_layout
4581 \begin_layout Plain Layout
4584 \end_layout
4586 \begin_layout Plain Layout
4588   if (! ("" in context)) {
4589 \end_layout
4591 \begin_layout Plain Layout
4593     =<
4594 \backslash
4595 chunkref{new-mode-tracker}(context, language, mode)>
4596 \end_layout
4598 \begin_layout Plain Layout
4600   } else {
4601 \end_layout
4603 \begin_layout Plain Layout
4605     top = context[""];
4606 \end_layout
4608 \begin_layout Plain Layout
4610     if (context[top, "language"] == language && mode=="") mode = context[top,
4611  "mode"];
4612 \end_layout
4614 \begin_layout Plain Layout
4616     top++;
4617 \end_layout
4619 \begin_layout Plain Layout
4621     context[top, "language"] = language;
4622 \end_layout
4624 \begin_layout Plain Layout
4626     context[top, "mode"] = mode;
4627 \end_layout
4629 \begin_layout Plain Layout
4631     context[""] = top;
4632 \end_layout
4634 \begin_layout Plain Layout
4636   }
4637 \end_layout
4639 \begin_layout Plain Layout
4642 \end_layout
4644 \end_inset
4647 \end_layout
4649 \begin_layout Standard
4650 \begin_inset listings
4651 inline false
4652 status open
4654 \begin_layout Plain Layout
4656 function finalize_mode_tracker(context,
4657 \end_layout
4659 \begin_layout Plain Layout
4661   # local vars
4662 \end_layout
4664 \begin_layout Plain Layout
4666   top)
4667 \end_layout
4669 \begin_layout Plain Layout
4672 \end_layout
4674 \begin_layout Plain Layout
4676   if ( ("" in context) && context[""] != 0) return 0;
4677 \end_layout
4679 \begin_layout Plain Layout
4681   return 1;
4682 \end_layout
4684 \begin_layout Plain Layout
4687 \end_layout
4689 \end_inset
4692 \end_layout
4694 \begin_layout Standard
4695 This implies that any chunk must be syntactically whole; for instance, this
4696  is fine:
4697 \end_layout
4699 \begin_layout Chunk
4700 test:whole-chunk
4701 \end_layout
4703 \begin_layout Standard
4704 \begin_inset listings
4705 inline false
4706 status open
4708 \begin_layout Plain Layout
4710 if (1) {
4711 \end_layout
4713 \begin_layout Plain Layout
4715   =<
4716 \backslash
4717 chunkref{test:say-hello}>
4718 \end_layout
4720 \begin_layout Plain Layout
4723 \end_layout
4725 \end_inset
4728 \end_layout
4730 \begin_layout Chunk
4731 test:say-hello
4732 \end_layout
4734 \begin_layout Standard
4735 \begin_inset listings
4736 inline false
4737 status open
4739 \begin_layout Plain Layout
4741 print "hello";
4742 \end_layout
4744 \end_inset
4747 \end_layout
4749 \begin_layout Standard
4750 But this is not fine; the chunk 
4751 \begin_inset Flex Chunkref
4752 status collapsed
4754 \begin_layout Plain Layout
4755 test:hidden-else
4756 \end_layout
4758 \end_inset
4760  is not properly cromulent.
4761 \end_layout
4763 \begin_layout Chunk
4764 test:partial-chunk
4765 \end_layout
4767 \begin_layout Standard
4768 \begin_inset listings
4769 inline false
4770 status open
4772 \begin_layout Plain Layout
4774 if (1) {
4775 \end_layout
4777 \begin_layout Plain Layout
4779   =<
4780 \backslash
4781 chunkref{test:hidden-else}>
4782 \end_layout
4784 \begin_layout Plain Layout
4787 \end_layout
4789 \end_inset
4792 \end_layout
4794 \begin_layout Chunk
4795 test:hidden-else
4796 \end_layout
4798 \begin_layout Standard
4799 \begin_inset listings
4800 inline false
4801 status open
4803 \begin_layout Plain Layout
4805   print "I'm fine";
4806 \end_layout
4808 \begin_layout Plain Layout
4810 } else {
4811 \end_layout
4813 \begin_layout Plain Layout
4815   print "I'm not";
4816 \end_layout
4818 \end_inset
4821 \end_layout
4823 \begin_layout Standard
4824 These tests will check for correct behaviour:
4825 \end_layout
4827 \begin_layout Chunk
4828 test:cromulence
4829 \end_layout
4831 \begin_layout Standard
4832 \begin_inset listings
4833 inline false
4834 status open
4836 \begin_layout Plain Layout
4838 echo Cromulence test
4839 \end_layout
4841 \begin_layout Plain Layout
4843 passtest ./newfangle -Rtest:whole-chunk $TEX_SRC &>/dev/null || ( echo "Whole
4844  chunk failed" && exit 1 )
4845 \end_layout
4847 \begin_layout Plain Layout
4849 failtest ./newfangle -Rtest:partial-chunk $TEX_SRC &>/dev/null || ( echo
4850  "Partial chunk failed" && exit 1 )
4851 \end_layout
4853 \end_inset
4856 \end_layout
4858 \begin_layout Section
4859 Processor
4860 \end_layout
4862 \begin_layout Standard
4863 In the C language there are a few parse modes, affecting the interpretation
4864  of characters.
4865 \end_layout
4867 \begin_layout Standard
4868 One parse mode is the strings mode.
4869  The string mode is commenced by an un-escaped quotation mark 
4870 \begin_inset Flex CharStyle:Code
4871 status collapsed
4873 \begin_layout Plain Layout
4875 \end_layout
4877 \end_inset
4879  and terminated by the same.
4880  Within the string mode, only one additional mode can be commenced, it is
4881  the backslash mode 
4882 \begin_inset Flex CharStyle:Code
4883 status collapsed
4885 \begin_layout Plain Layout
4887 \backslash
4889 \end_layout
4891 \end_inset
4893 , which is always terminated by the folloing character.
4894 \end_layout
4896 \begin_layout Standard
4897 Other modes are 
4898 \begin_inset Flex CharStyle:Code
4899 status collapsed
4901 \begin_layout Plain Layout
4903 \end_layout
4905 \end_inset
4907  which is terminated by a 
4908 \begin_inset Flex CharStyle:Code
4909 status collapsed
4911 \begin_layout Plain Layout
4913 \end_layout
4915 \end_inset
4917  (unless it occurs in a string).
4918 \end_layout
4920 \begin_layout Standard
4921 Consider this line of C code:
4922 \end_layout
4924 \begin_layout Standard
4925 \begin_inset Formula $\mathtt{things\underbrace{[\mathtt{x,\ y}]}_{1.\ [\ mode},\ get\_other\_things\underbrace{(\mathtt{a,\overbrace{"\mathtt{(all)}"}})}_{2.\ (\ mode}^{3.\ "\ mode}}$
4926 \end_inset
4929 \end_layout
4931 \begin_layout Standard
4932 Mode nesting prevents the close parenthesis in quote mode (part 3) from
4933  terminating the parenthesis mode (part 2).
4934 \end_layout
4936 \begin_layout Standard
4937 Each language has a set of modes, the default mode being the null mode.
4938  Each mode can lead to other modes.
4939 \end_layout
4941 \begin_layout Subsection
4942 Definitions
4943 \end_layout
4945 \begin_layout Standard
4946 All modes are stored in a single multi-dimensional hash.
4947  The first index is the language, and the second index is the mode-identifier.
4948  The third indexes are terminators, and optionally, submodes, and delimiters.
4949 \end_layout
4951 \begin_layout Standard
4952 A useful set of mode definitions for a nameless general C-type language
4953  is shown here.
4954  (Don't be confused by the double backslash escaping needed in awk.
4955  One set of escaping is for the string, and the second set of escaping is
4956  for the regex).
4957  TODO: Add =<
4958 \backslash
4959 mode{}> command which will allow us to signify that a string is regex and
4960  thus newfangle will quote it for us.
4961 \end_layout
4963 \begin_layout Standard
4964 Submodes are entered by the characters 
4965 \begin_inset Flex CharStyle:Code
4966 status collapsed
4968 \begin_layout Plain Layout
4970 \backslash
4972 \end_layout
4974 \end_inset
4977 \begin_inset Flex CharStyle:Code
4978 status collapsed
4980 \begin_layout Plain Layout
4981 \begin_inset Quotes eld
4982 \end_inset
4985 \end_layout
4987 \end_inset
4990 \begin_inset Flex CharStyle:Code
4991 status collapsed
4993 \begin_layout Plain Layout
4995 \end_layout
4997 \end_inset
5000 \begin_inset Flex CharStyle:Code
5001 status collapsed
5003 \begin_layout Plain Layout
5005 \end_layout
5007 \end_inset
5010 \begin_inset Flex CharStyle:Code
5011 status collapsed
5013 \begin_layout Plain Layout
5015 \end_layout
5017 \end_inset
5020 \begin_inset Flex CharStyle:Code
5021 status collapsed
5023 \begin_layout Plain Layout
5025 \end_layout
5027 \end_inset
5030 \end_layout
5032 \begin_layout Chunk
5033 mode-definitions
5034 \end_layout
5036 \begin_layout Standard
5037 \begin_inset listings
5038 inline false
5039 status open
5041 \begin_layout Plain Layout
5043 modes["", "",  "submodes" ]="
5044 \backslash
5046 \backslash
5048 \backslash
5050 \backslash
5052 \backslash
5053 "|'|{|
5054 \backslash
5056 \backslash
5058 \backslash
5060 \backslash
5062 \backslash
5064 \backslash
5066 \end_layout
5068 \end_inset
5071 \end_layout
5073 \begin_layout Standard
5074 In the default mode, a comma surrounded by un-important white space is a
5075  delimiter of language items.
5076 \end_layout
5078 \begin_layout Standard
5079 \begin_inset listings
5080 inline false
5081 status open
5083 \begin_layout Plain Layout
5085 modes["", "",  "delimiters"]=" *, *";
5086 \end_layout
5088 \end_inset
5091 \end_layout
5093 \begin_layout Standard
5094 and should pass this test:
5095 \end_layout
5097 \begin_layout Standard
5098 \begin_inset Note Note
5099 status open
5101 \begin_layout Plain Layout
5102 Why do the tests run in 
5103 \begin_inset Quotes eld
5104 \end_inset
5107 \begin_inset Quotes erd
5108 \end_inset
5110  mode and not 
5111 \begin_inset Quotes eld
5112 \end_inset
5115 \begin_inset Quotes erd
5116 \end_inset
5118  mode
5119 \end_layout
5121 \end_inset
5124 \end_layout
5126 \begin_layout Chunk
5127 test:mode-definitions
5128 \end_layout
5130 \begin_layout Standard
5131 \begin_inset listings
5132 inline false
5133 status open
5135 \begin_layout Plain Layout
5137 parse_chunk_args("", "1,2,3", a, "");
5138 \end_layout
5140 \begin_layout Plain Layout
5142 if (a[1] != "1") e++;
5143 \end_layout
5145 \begin_layout Plain Layout
5147 if (a[2] != "2") e++;
5148 \end_layout
5150 \begin_layout Plain Layout
5152 if (a[3] != "3") e++;
5153 \end_layout
5155 \begin_layout Plain Layout
5157 if (length(a) != 3) e++;
5158 \end_layout
5160 \begin_layout Plain Layout
5163 \backslash
5164 chunkref{pca-test.awk:summary}>
5165 \end_layout
5167 \begin_layout Plain Layout
5169 \end_layout
5171 \begin_layout Plain Layout
5173 parse_chunk_args("", "joe, red", a, "");
5174 \end_layout
5176 \begin_layout Plain Layout
5178 if (a[1] != "joe") e++;
5179 \end_layout
5181 \begin_layout Plain Layout
5183 if (a[2] != "red") e++;
5184 \end_layout
5186 \begin_layout Plain Layout
5188 if (length(a) != 2) e++;
5189 \end_layout
5191 \begin_layout Plain Layout
5194 \backslash
5195 chunkref{pca-test.awk:summary}>
5196 \end_layout
5198 \begin_layout Plain Layout
5200 \end_layout
5202 \begin_layout Plain Layout
5204 parse_chunk_args("", "${colour}", a, "");
5205 \end_layout
5207 \begin_layout Plain Layout
5209 if (a[1] != "${colour}") e++;
5210 \end_layout
5212 \begin_layout Plain Layout
5214 if (length(a) != 1) e++;
5215 \end_layout
5217 \begin_layout Plain Layout
5220 \backslash
5221 chunkref{pca-test.awk:summary}>
5222 \end_layout
5224 \end_inset
5227 \end_layout
5229 \begin_layout Standard
5230 Nested modes are identified by a backslash, a double or single quote, various
5231  bracket styles or a /* comment.
5232 \end_layout
5234 \begin_layout Standard
5235 For each of these sub-modes modes we must also identify at a mode terminator,
5236  and any sub-modes or delimiters that may be entered
5237 \begin_inset Foot
5238 status collapsed
5240 \begin_layout Plain Layout
5241 Because we are using the sub-mode characters as the mode identifier it means
5242  we can't currently have a mode character dependant on it's context; i.e.
5244 \begin_inset Flex CharStyle:Code
5245 status collapsed
5247 \begin_layout Plain Layout
5249 \end_layout
5251 \end_inset
5253  can't behave differently when it is inside 
5254 \begin_inset Flex CharStyle:Code
5255 status collapsed
5257 \begin_layout Plain Layout
5259 \end_layout
5261 \end_inset
5264 \end_layout
5266 \end_inset
5269 \end_layout
5271 \begin_layout Subsection
5272 Backslash
5273 \end_layout
5275 \begin_layout Standard
5276 The backslash mode has no submodes or delimiters, and is terminated by any
5277  character.
5278  Note that we are not so much interested in evaluating or interpolating
5279  content as we are in delineating content.
5280  It is no matter that a double backslash (
5281 \begin_inset Flex CharStyle:Code
5282 status collapsed
5284 \begin_layout Plain Layout
5286 \backslash
5288 \backslash
5290 \end_layout
5292 \end_inset
5294 ) may represent a single backslash while a backslash-newline may represent
5295  white space, but it does matter that the newline in a backslash newline
5296  should not be able to terminate a C pre-processor statement; and so the
5297  newline will be consumed by the backslash however it is to be interpreted.
5298 \end_layout
5300 \begin_layout Chunk
5301 mode-definitions
5302 \end_layout
5304 \begin_layout Standard
5305 \begin_inset listings
5306 inline false
5307 status open
5309 \begin_layout Plain Layout
5311 modes["", "
5312 \backslash
5314 \backslash
5315 ", "terminators"]=".";
5316 \end_layout
5318 \end_inset
5321 \end_layout
5323 \begin_layout Subsection
5324 Strings
5325 \end_layout
5327 \begin_layout Standard
5328 In a string we have one special mode, which is the backslash.
5329  This may escape an embedded quote and prevent us thinking that it should
5330  terminate the string.
5331  Otherwise, the string will be terminated by a double-quote.
5332 \end_layout
5334 \begin_layout Standard
5335 \begin_inset listings
5336 inline false
5337 status open
5339 \begin_layout Plain Layout
5341 modes["", "
5342 \backslash
5343 "", "submodes" ]="
5344 \backslash
5346 \backslash
5348 \backslash
5350 \backslash
5352 \end_layout
5354 \begin_layout Plain Layout
5356 modes["", "
5357 \backslash
5358 "", "terminators"]="
5359 \backslash
5361 \end_layout
5363 \end_inset
5366 \end_layout
5368 \begin_layout Standard
5369 Working strings should pass this test:
5370 \end_layout
5372 \begin_layout Chunk
5373 test:mode-definitions
5374 \end_layout
5376 \begin_layout Standard
5377 \begin_inset listings
5378 inline false
5379 status open
5381 \begin_layout Plain Layout
5383 parse_chunk_args("", "say 
5384 \backslash
5385 "I said, 
5386 \backslash
5388 \backslash
5390 \backslash
5391 "Hello, how are you
5392 \backslash
5394 \backslash
5396 \backslash
5398 \backslash
5399 ", for me", a, "");
5400 \end_layout
5402 \begin_layout Plain Layout
5404 if (a[1] != "say 
5405 \backslash
5406 "I said, 
5407 \backslash
5409 \backslash
5411 \backslash
5412 "Hello, how are you
5413 \backslash
5415 \backslash
5417 \backslash
5419 \backslash
5420 "") e++;
5421 \end_layout
5423 \begin_layout Plain Layout
5425 if (a[2] != "for me") e++;
5426 \end_layout
5428 \begin_layout Plain Layout
5430 if (length(a) != 2) e++;
5431 \end_layout
5433 \begin_layout Plain Layout
5436 \backslash
5437 chunkref{pca-test.awk:summary}>
5438 \end_layout
5440 \end_inset
5443 \end_layout
5445 \begin_layout Standard
5446 Also, the parser must return any spare text at the end that has not been
5447  processed due to a mode terminator being found.
5448 \end_layout
5450 \begin_layout Standard
5451 \begin_inset listings
5452 inline false
5453 status open
5455 \begin_layout Plain Layout
5457 rest = parse_chunk_args("", "1, 2, 3) spare", a, "(");
5458 \end_layout
5460 \begin_layout Plain Layout
5462 if (a[1] != 1) e++;
5463 \end_layout
5465 \begin_layout Plain Layout
5467 if (a[2] != 2) e++;
5468 \end_layout
5470 \begin_layout Plain Layout
5472 if (a[3] != 3) e++;
5473 \end_layout
5475 \begin_layout Plain Layout
5477 if (length(a) != 3) e++;
5478 \end_layout
5480 \begin_layout Plain Layout
5482 if (rest != " spare") e++;
5483 \end_layout
5485 \begin_layout Plain Layout
5488 \backslash
5489 chunkref{pca-test.awk:summary}>
5490 \end_layout
5492 \end_inset
5495 \end_layout
5497 \begin_layout Chunk
5498 mode-definitions
5499 \end_layout
5501 \begin_layout Standard
5502 \begin_inset listings
5503 inline false
5504 status open
5506 \begin_layout Plain Layout
5508 modes["", "{",  "submodes" ]="
5509 \backslash
5511 \backslash
5513 \backslash
5515 \backslash
5517 \backslash
5518 "|{|
5519 \backslash
5521 \backslash
5523 \backslash
5525 \backslash
5526 [|'|/
5527 \backslash
5529 \backslash
5531 \end_layout
5533 \begin_layout Plain Layout
5535 modes["", "{",  "delimeters"]=" *, *";
5536 \end_layout
5538 \begin_layout Plain Layout
5540 modes["", "{",  "terminators"]="}";
5541 \end_layout
5543 \begin_layout Plain Layout
5545 modes["", "[",  "submodes" ]="
5546 \backslash
5548 \backslash
5550 \backslash
5552 \backslash
5554 \backslash
5555 "|{|
5556 \backslash
5558 \backslash
5560 \backslash
5562 \backslash
5563 [|'|/
5564 \backslash
5566 \backslash
5568 \end_layout
5570 \begin_layout Plain Layout
5572 modes["", "[",  "delimiters"]=" *, *";
5573 \end_layout
5575 \begin_layout Plain Layout
5577 modes["", "[",  "terminators"]="
5578 \backslash
5580 \backslash
5582 \end_layout
5584 \begin_layout Plain Layout
5586 modes["", "(",  "submodes" ]="
5587 \backslash
5589 \backslash
5591 \backslash
5593 \backslash
5595 \backslash
5596 "|{|
5597 \backslash
5599 \backslash
5601 \backslash
5603 \backslash
5604 [|'|/
5605 \backslash
5607 \backslash
5609 \end_layout
5611 \begin_layout Plain Layout
5613 modes["", "(",  "delimiters"]=" *, *";
5614 \end_layout
5616 \begin_layout Plain Layout
5618 modes["", "(",  "terminators"]="
5619 \backslash
5621 \backslash
5623 \end_layout
5625 \begin_layout Plain Layout
5627 modes["", "'",  "submodes" ]="
5628 \backslash
5630 \backslash
5632 \backslash
5634 \backslash
5636 \end_layout
5638 \begin_layout Plain Layout
5640 modes["", "'",  "terminators"]="'";
5641 \end_layout
5643 \begin_layout Plain Layout
5645 modes["", "/*", "submodes"]="
5646 \backslash
5648 \backslash
5649 */";
5650 \end_layout
5652 \begin_layout Plain Layout
5654 modes["", "/*", "terminators"]="*/";
5655 \end_layout
5657 \begin_layout Plain Layout
5659 modes["", "//", "submodes"]="
5660 \backslash
5662 \end_layout
5664 \begin_layout Plain Layout
5666 modes["", "//", "terminators"]="
5667 \backslash
5669 \end_layout
5671 \begin_layout Plain Layout
5673 modes["", "",   "submodes" ]="
5674 \backslash
5676 \backslash
5678 \backslash
5680 \backslash
5682 \backslash
5683 "|{|
5684 \backslash
5686 \backslash
5688 \backslash
5690 \backslash
5691 [|'|/
5692 \backslash
5694 \backslash
5696 \end_layout
5698 \end_inset
5701 \end_layout
5703 \begin_layout Standard
5704 This test should also pass.
5705 \end_layout
5707 \begin_layout Chunk
5708 test:mode-definitions
5709 \end_layout
5711 \begin_layout Standard
5712 \begin_inset listings
5713 inline false
5714 status open
5716 \begin_layout Plain Layout
5718 parse_chunk_args("", "things[x, y], get_other_things(a, 
5719 \backslash
5720 "(all)
5721 \backslash
5722 "), 99", a, "(");
5723 \end_layout
5725 \begin_layout Plain Layout
5727 if (a[1] != "things[x, y]") e++;
5728 \end_layout
5730 \begin_layout Plain Layout
5732 if (a[2] != "get_other_things(a, 
5733 \backslash
5734 "(all)
5735 \backslash
5736 ")") e++;
5737 \end_layout
5739 \begin_layout Plain Layout
5741 if (a[3] != "99") e++;
5742 \end_layout
5744 \begin_layout Plain Layout
5746 if (length(a) != 3) e++;
5747 \end_layout
5749 \begin_layout Plain Layout
5752 \backslash
5753 chunkref{pca-test.awk:summary}>
5754 \end_layout
5756 \end_inset
5759 \end_layout
5761 \begin_layout Subsection
5762 A non-recursive mode tracker
5763 \end_layout
5765 \begin_layout Standard
5766 We must avoid recursion as a language construct because we intend to employ
5767  mode-tracking to track language mode of emitted code, and the code is emitted
5768  from a function which is itself recursive, so instead we implement psuedo-recur
5769 sion using our own stack based on a hash.
5770 \end_layout
5772 \begin_layout Chunk
5773 mode_tracker()
5774 \end_layout
5776 \begin_layout Standard
5777 \begin_inset listings
5778 inline false
5779 status open
5781 \begin_layout Plain Layout
5783 function mode_tracker(context, text, values, 
5784 \end_layout
5786 \begin_layout Plain Layout
5788   # optional parameters
5789 \end_layout
5791 \begin_layout Plain Layout
5793   # local vars
5794 \end_layout
5796 \begin_layout Plain Layout
5798   mode, submodes, language,
5799 \end_layout
5801 \begin_layout Plain Layout
5803   cindex, c, a, part, item, name, result, new_values, new_mode, 
5804 \end_layout
5806 \begin_layout Plain Layout
5808   delimiters, terminators)
5809 \end_layout
5811 \begin_layout Plain Layout
5814 \end_layout
5816 \end_inset
5819 \end_layout
5821 \begin_layout Standard
5822 We could be re-commencing with a valid context, so we need to setup the
5823  state according to the last context.
5824 \end_layout
5826 \begin_layout Standard
5827 \begin_inset listings
5828 inline false
5829 status open
5831 \begin_layout Plain Layout
5833   cindex = context[""] + 0;
5834 \end_layout
5836 \begin_layout Plain Layout
5838   mode = context[cindex, "mode"];
5839 \end_layout
5841 \begin_layout Plain Layout
5843   language = context[cindex, "language" ];
5844 \end_layout
5846 \end_inset
5849 \end_layout
5851 \begin_layout Standard
5852 First we construct a single large regex combining the possile sub-modes
5853  for the current mode along with the terminators for the current mode.
5854 \end_layout
5856 \begin_layout Chunk
5857 parse_chunk_args-reset-modes
5858 \end_layout
5860 \begin_layout Standard
5861 \begin_inset listings
5862 inline false
5863 status open
5865 \begin_layout Plain Layout
5867   submodes=modes[language, mode, "submodes"];
5868 \end_layout
5870 \begin_layout Plain Layout
5872   if ((language, mode, "delimiters") in modes) {
5873 \end_layout
5875 \begin_layout Plain Layout
5877     delimiters = modes[language, mode, "delimiters"];
5878 \end_layout
5880 \begin_layout Plain Layout
5882     submodes=submodes "|" delimiters;
5883 \end_layout
5885 \begin_layout Plain Layout
5887   }
5888 \end_layout
5890 \begin_layout Plain Layout
5892   if ((language, mode, "terminators") in modes) {
5893 \end_layout
5895 \begin_layout Plain Layout
5897     terminators = modes[language, mode, "terminators"];
5898 \end_layout
5900 \begin_layout Plain Layout
5902     submodes=submodes "|" terminators;
5903 \end_layout
5905 \begin_layout Plain Layout
5907   }
5908 \end_layout
5910 \end_inset
5913 \end_layout
5915 \begin_layout Chunk
5916 mode_tracker()
5917 \end_layout
5919 \begin_layout Standard
5920 \begin_inset listings
5921 inline false
5922 status open
5924 \begin_layout Plain Layout
5927 \backslash
5928 chunkref{parse_chunk_args-reset-modes}>
5929 \end_layout
5931 \end_inset
5934 \end_layout
5936 \begin_layout Standard
5937 We then iterate the text (until there is none left) looking for sub-modes
5938  or terminators in the regex.
5939 \end_layout
5941 \begin_layout Standard
5942 \begin_inset listings
5943 inline false
5944 status open
5946 \begin_layout Plain Layout
5948   while((cindex >= 0) && length(text)) {
5949 \end_layout
5951 \begin_layout Plain Layout
5953     if (match(text, "(" submodes ")", a)) {
5954 \end_layout
5956 \end_inset
5959 \end_layout
5961 \begin_layout Standard
5962 A bug that creeps in regularly during development is bad regexes of zero
5963  length which result in an infinite loop (as no text is consumed), so I
5964  catch that right away with this test.
5965 \end_layout
5967 \begin_layout Standard
5968 \begin_inset listings
5969 inline false
5970 status open
5972 \begin_layout Plain Layout
5974       if (RLENGTH<1) {
5975 \end_layout
5977 \begin_layout Plain Layout
5979         error("Internal error, matched zero length submode, should be impossible
5980  - likely regex computation error");
5981 \end_layout
5983 \begin_layout Plain Layout
5985       }
5986 \end_layout
5988 \end_inset
5991 \end_layout
5993 \begin_layout Standard
5994 \begin_inset Flex CharStyle:Code
5995 status collapsed
5997 \begin_layout Plain Layout
5998 part
5999 \end_layout
6001 \end_inset
6003  is defined as the text up to the sub-mode or terminator, and this is appended
6004  to 
6005 \begin_inset Flex CharStyle:Code
6006 status collapsed
6008 \begin_layout Plain Layout
6009 item
6010 \end_layout
6012 \end_inset
6014  --- which is the current text being gathered.
6015  If a mode has a delimiter, then item is reset each time a delimiter is
6016  found.
6017 \end_layout
6019 \begin_layout Standard
6020 \begin_inset Formula $\mathtt{\overbrace{"\overbrace{hello}^{item},\ \overbrace{there}^{item}"}^{item},\ \overbrace{he\ said.}^{item}}$
6021 \end_inset
6024 \end_layout
6026 \begin_layout Standard
6027 \begin_inset listings
6028 inline false
6029 status open
6031 \begin_layout Plain Layout
6033       part = substr(text, 1, RSTART -1);
6034 \end_layout
6036 \begin_layout Plain Layout
6038       item = item part;
6039 \end_layout
6041 \end_inset
6044 \end_layout
6046 \begin_layout Standard
6047 We must now determine what was matched.
6048  If it was a terminator, then we must restore the previous mode.
6049 \end_layout
6051 \begin_layout Standard
6052 \begin_inset listings
6053 inline false
6054 status open
6056 \begin_layout Plain Layout
6058       if (match(a[1], "^" terminators "$")) {
6059 \end_layout
6061 \begin_layout Plain Layout
6063         context[cindex, "values", ++context[cindex, "values"]] = item;
6064 \end_layout
6066 \begin_layout Plain Layout
6068         delete context[cindex];
6069 \end_layout
6071 \begin_layout Plain Layout
6073         context[""] = --cindex;
6074 \end_layout
6076 \begin_layout Plain Layout
6078         if (cindex>=0) {
6079 \end_layout
6081 \begin_layout Plain Layout
6083           mode = context[cindex, "mode"];
6084 \end_layout
6086 \begin_layout Plain Layout
6088           language = context[cindex, "language"];
6089 \end_layout
6091 \begin_layout Plain Layout
6093           =<
6094 \backslash
6095 chunkref{parse_chunk_args-reset-modes}>
6096 \end_layout
6098 \begin_layout Plain Layout
6100         }
6101 \end_layout
6103 \begin_layout Plain Layout
6105         item = item a[1];
6106 \end_layout
6108 \begin_layout Plain Layout
6110         text = substr(text, 1 + length(part) + length(a[1]));
6111 \end_layout
6113 \begin_layout Plain Layout
6115       }
6116 \end_layout
6118 \end_inset
6121 \end_layout
6123 \begin_layout Standard
6124 If a delimiter was matched, then we must store the current item in the parsed
6125  values array, and reset the item.
6126 \end_layout
6128 \begin_layout Standard
6129 \begin_inset listings
6130 inline false
6131 status open
6133 \begin_layout Plain Layout
6135       else if (match(a[1], "^" delimiters "$")) {
6136 \end_layout
6138 \begin_layout Plain Layout
6140         if (cindex==0) {
6141 \end_layout
6143 \begin_layout Plain Layout
6145           context[cindex, "values", ++context[cindex, "values"]] = item;
6146 \end_layout
6148 \begin_layout Plain Layout
6150           item = "";
6151 \end_layout
6153 \begin_layout Plain Layout
6155         } else {
6156 \end_layout
6158 \begin_layout Plain Layout
6160           item = item a[1];
6161 \end_layout
6163 \begin_layout Plain Layout
6165         }
6166 \end_layout
6168 \begin_layout Plain Layout
6170         text = substr(text, 1 + length(part) + length(a[1]));
6171 \end_layout
6173 \begin_layout Plain Layout
6175       }
6176 \end_layout
6178 \end_inset
6181 \end_layout
6183 \begin_layout Standard
6184 otherwise, if a new submode is detected (all submodes have terminators),
6185  we must create a nested parse context until we find the terminator for
6186  this mode.
6187 \end_layout
6189 \begin_layout Standard
6190 \begin_inset listings
6191 inline false
6192 status open
6194 \begin_layout Plain Layout
6196  else if ((language, a[1], "terminators") in modes) {
6197 \end_layout
6199 \begin_layout Plain Layout
6201         #check if new_mode is defined
6202 \end_layout
6204 \begin_layout Plain Layout
6206         item = item a[1];
6207 \end_layout
6209 \begin_layout Plain Layout
6211         text = substr(text, 1 + length(part) + length(a[1]));
6212 \end_layout
6214 \begin_layout Plain Layout
6216 \end_layout
6218 \begin_layout Plain Layout
6220         context[""] = ++cindex;
6221 \end_layout
6223 \begin_layout Plain Layout
6225         context[cindex, "mode"] = a[1];
6226 \end_layout
6228 \begin_layout Plain Layout
6230         context[cindex, "language"] = language;
6231 \end_layout
6233 \begin_layout Plain Layout
6235         mode = a[1];
6236 \end_layout
6238 \begin_layout Plain Layout
6240         =<
6241 \backslash
6242 chunkref{parse_chunk_args-reset-modes}>
6243 \end_layout
6245 \begin_layout Plain Layout
6247       } else {
6248 \end_layout
6250 \begin_layout Plain Layout
6252         error(sprintf("Submode '%s' set unknown mode in text: %s", a[1],
6253  text));
6254 \end_layout
6256 \begin_layout Plain Layout
6258         text = substr(text, 1 + length(part) + length(a[1]));
6259 \end_layout
6261 \begin_layout Plain Layout
6263       }
6264 \end_layout
6266 \begin_layout Plain Layout
6268     }
6269 \end_layout
6271 \end_inset
6274 \end_layout
6276 \begin_layout Standard
6277 In the final case, we parsed to the end of the string.
6278  If the string was entire, then we should have no nested mode context, but
6279  if the string was just a fragment we may have a mode context which must
6280  be preserved for the next fragment.
6281  Todo: Consideration ought to be given if sub-mode strings are split over
6282  two fragments.
6283 \begin_inset Note Note
6284 status collapsed
6286 \begin_layout Plain Layout
6287 Consideration ought to be given if sub-mode strings are split over two fragments.
6288 \end_layout
6290 \end_inset
6293 \end_layout
6295 \begin_layout Standard
6296 \begin_inset listings
6297 inline false
6298 status open
6300 \begin_layout Plain Layout
6302 else {
6303 \end_layout
6305 \begin_layout Plain Layout
6307       context[cindex, "values", ++context[cindex, "values"]] = item text;
6308 \end_layout
6310 \begin_layout Plain Layout
6312       text = "";
6313 \end_layout
6315 \begin_layout Plain Layout
6317       item = "";
6318 \end_layout
6320 \begin_layout Plain Layout
6322     }
6323 \end_layout
6325 \begin_layout Plain Layout
6327   }
6328 \end_layout
6330 \begin_layout Plain Layout
6332 \end_layout
6334 \begin_layout Plain Layout
6336   context["item"] = item;
6337 \end_layout
6339 \begin_layout Plain Layout
6341 \end_layout
6343 \begin_layout Plain Layout
6345   if (length(item)) context[cindex, "values", ++context[cindex, "values"]]
6346  = item;
6347 \end_layout
6349 \begin_layout Plain Layout
6351   return text;
6352 \end_layout
6354 \begin_layout Plain Layout
6357 \end_layout
6359 \end_inset
6362 \end_layout
6364 \begin_layout Subsection
6365 One happy chunk
6366 \end_layout
6368 \begin_layout Standard
6369 All the mode tracker chunks are referred to here:
6370 \end_layout
6372 \begin_layout Chunk
6373 mode-tracker
6374 \end_layout
6376 \begin_layout Standard
6377 \begin_inset listings
6378 inline false
6379 status open
6381 \begin_layout Plain Layout
6384 \backslash
6385 chunkref{new_mode_tracker()}>
6386 \end_layout
6388 \begin_layout Plain Layout
6391 \backslash
6392 chunkref{mode_tracker()}>
6393 \end_layout
6395 \end_inset
6398 \end_layout
6400 \begin_layout Subsection
6401 Tests
6402 \end_layout
6404 \begin_layout Standard
6405 We can test this function like this:
6406 \end_layout
6408 \begin_layout Chunk
6409 pca-test.awk
6410 \end_layout
6412 \begin_layout Standard
6413 \begin_inset listings
6414 inline false
6415 status open
6417 \begin_layout Plain Layout
6420 \backslash
6421 chunkref{error()}>
6422 \end_layout
6424 \begin_layout Plain Layout
6427 \backslash
6428 chunkref{mode-tracker}>
6429 \end_layout
6431 \begin_layout Plain Layout
6434 \backslash
6435 chunkref{parse_chunk_args()}>
6436 \end_layout
6438 \begin_layout Plain Layout
6440 BEGIN {
6441 \end_layout
6443 \begin_layout Plain Layout
6445   SUBSEP=".";
6446 \end_layout
6448 \begin_layout Plain Layout
6450   =<
6451 \backslash
6452 chunkref{mode-definitions}>
6453 \end_layout
6455 \begin_layout Plain Layout
6457 \end_layout
6459 \begin_layout Plain Layout
6461   =<
6462 \backslash
6463 chunkref{test:mode-definitions}>
6464 \end_layout
6466 \begin_layout Plain Layout
6469 \end_layout
6471 \end_inset
6474 \end_layout
6476 \begin_layout Chunk
6477 pca-test.awk:summary
6478 \end_layout
6480 \begin_layout Standard
6481 \begin_inset listings
6482 inline false
6483 status open
6485 \begin_layout Plain Layout
6487 if (e) {
6488 \end_layout
6490 \begin_layout Plain Layout
6492   printf "Failed " e
6493 \end_layout
6495 \begin_layout Plain Layout
6497   for (b in a) {
6498 \end_layout
6500 \begin_layout Plain Layout
6502     print "a[" b "] => " a[b];
6503 \end_layout
6505 \begin_layout Plain Layout
6507   }
6508 \end_layout
6510 \begin_layout Plain Layout
6512 } else {
6513 \end_layout
6515 \begin_layout Plain Layout
6517   print "Passed"
6518 \end_layout
6520 \begin_layout Plain Layout
6523 \end_layout
6525 \begin_layout Plain Layout
6527 split("", a);
6528 \end_layout
6530 \begin_layout Plain Layout
6532 e=0;
6533 \end_layout
6535 \end_inset
6538 \end_layout
6540 \begin_layout Standard
6541 which should give this output:
6542 \end_layout
6544 \begin_layout Chunk
6545 pca-test.awk-results
6546 \end_layout
6548 \begin_layout Standard
6549 \begin_inset listings
6550 inline false
6551 status open
6553 \begin_layout Plain Layout
6555 a[foo.quux.quirk] => 
6556 \end_layout
6558 \begin_layout Plain Layout
6560 a[foo.quux.a] => fleeg
6561 \end_layout
6563 \begin_layout Plain Layout
6565 a[foo.bar] => baz
6566 \end_layout
6568 \begin_layout Plain Layout
6570 a[etc] => 
6571 \end_layout
6573 \begin_layout Plain Layout
6575 a[name] => freddie
6576 \end_layout
6578 \end_inset
6581 \end_layout
6583 \begin_layout Chapter
6584 Expanding chunk arguments
6585 \end_layout
6587 \begin_layout Standard
6588 \begin_inset CommandInset label
6589 LatexCommand label
6590 name "cha:Chunk Arguments"
6592 \end_inset
6595 \begin_inset Note Note
6596 status collapsed
6598 \begin_layout Plain Layout
6599 Explain this in the documentation section too
6600 \end_layout
6602 \end_inset
6604 As an extension to many literate-programming styles, newfangle permits code
6605  chunks to take parameters and thus operate somewhat like C pre-processor
6606  macros, or like C++ templates.
6607 \end_layout
6609 \begin_layout Standard
6610 Chunk parameters are declared with a chunk argument called 
6611 \begin_inset Flex CharStyle:Code
6612 status collapsed
6614 \begin_layout Plain Layout
6615 params
6616 \end_layout
6618 \end_inset
6620 , which holds a semi-colon separated list of parameters, like this:
6621 \end_layout
6623 \begin_layout LyX-Code
6624 achunk,language=C,params=name;address
6625 \end_layout
6627 \begin_layout Standard
6628 When such a chunk is included, the arguments are expressed in round brackets
6629  as a comma separated list of optional arguments:
6630 \begin_inset Note Note
6631 status collapsed
6633 \begin_layout Plain Layout
6634 We ought to support qouting in {} like ({Jones, John}, Jones@example.com)
6635 \end_layout
6637 \end_inset
6640 \end_layout
6642 \begin_layout LyX-Code
6644 \backslash
6645 chunkref{achunk}(John Jones, jones@example.com)
6646 \end_layout
6648 \begin_layout Standard
6649 Within the body of a chunk, the parameters are referred to with: 
6650 \begin_inset Flex CharStyle:Code
6651 status collapsed
6653 \begin_layout Plain Layout
6654 ${name}
6655 \end_layout
6657 \end_inset
6659  and 
6660 \begin_inset Flex CharStyle:Code
6661 status collapsed
6663 \begin_layout Plain Layout
6664 ${address}
6665 \end_layout
6667 \end_inset
6670  There is a strong case that a LaTeX style notation should be used, like
6672 \backslash
6673 param{name} which would be expressed in the listing as =<
6674 \backslash
6675 param{name}> and be rendered as 
6676 \begin_inset listings
6677 inline true
6678 status open
6680 \begin_layout Plain Layout
6683 \backslash
6684 param{name}>
6685 \end_layout
6687 \end_inset
6690  Such notation would make me go blind, but I do intend to adopt it.
6691 \end_layout
6693 \begin_layout Standard
6694 We therefore need a function 
6695 \begin_inset Flex CharStyle:Code
6696 status collapsed
6698 \begin_layout Plain Layout
6699 expand_chunk_args
6700 \end_layout
6702 \end_inset
6704  which will take a block of text, a list of permitted parameters and the
6705  arguments which must substitute for the parameters.
6707 \end_layout
6709 \begin_layout Standard
6710 We also need to be able to parse a parameter list into an array of parameters.
6711 \end_layout
6713 \begin_layout Section
6714 Parsing argument lists
6715 \end_layout
6717 \begin_layout Standard
6718 An argument list may be as simple as in 
6719 \begin_inset Flex CharStyle:Code
6720 status collapsed
6722 \begin_layout Plain Layout
6724 \backslash
6725 chunkref{pull}(thing, otherthing)
6726 \end_layout
6728 \end_inset
6730  or as complex as:
6731 \end_layout
6733 \begin_layout LyX-Code
6735 \backslash
6736 chunkref{pull}(things[x, y], get_other_things(a, "(all)")) 
6737 \end_layout
6739 \begin_layout Standard
6740 --- which for all it's commas and quotes and parenthesis represents only
6741  two parameters: 
6742 \begin_inset Flex CharStyle:Code
6743 status collapsed
6745 \begin_layout Plain Layout
6746 things[x, y]
6747 \end_layout
6749 \end_inset
6751  and 
6752 \begin_inset Flex CharStyle:Code
6753 status collapsed
6755 \begin_layout Plain Layout
6756 get_other_things(a, "(all)")
6757 \end_layout
6759 \end_inset
6762 \end_layout
6764 \begin_layout Standard
6765 If we simply split parameter list on commas, then the comma in 
6766 \begin_inset Flex CharStyle:Code
6767 status collapsed
6769 \begin_layout Plain Layout
6770 things[x,y]
6771 \end_layout
6773 \end_inset
6775  would split into two seperate arguments: 
6776 \begin_inset Flex CharStyle:Code
6777 status collapsed
6779 \begin_layout Plain Layout
6780 things[x
6781 \end_layout
6783 \end_inset
6785  and 
6786 \begin_inset Flex CharStyle:Code
6787 status collapsed
6789 \begin_layout Plain Layout
6791 \end_layout
6793 \end_inset
6795 --- neither of which make sense on their own.
6796 \end_layout
6798 \begin_layout Standard
6799 One way to prevent this would be by refusing to split text between maching
6800  delimiters, such as 
6801 \begin_inset Flex CharStyle:Code
6802 status collapsed
6804 \begin_layout Plain Layout
6806 \end_layout
6808 \end_inset
6811 \begin_inset Flex CharStyle:Code
6812 status collapsed
6814 \begin_layout Plain Layout
6816 \end_layout
6818 \end_inset
6821 \begin_inset Flex CharStyle:Code
6822 status collapsed
6824 \begin_layout Plain Layout
6826 \end_layout
6828 \end_inset
6831 \begin_inset Flex CharStyle:Code
6832 status collapsed
6834 \begin_layout Plain Layout
6836 \end_layout
6838 \end_inset
6841 \begin_inset Flex CharStyle:Code
6842 status collapsed
6844 \begin_layout Plain Layout
6846 \end_layout
6848 \end_inset
6851 \begin_inset Flex CharStyle:Code
6852 status collapsed
6854 \begin_layout Plain Layout
6856 \end_layout
6858 \end_inset
6860  and most likely also 
6861 \begin_inset Flex CharStyle:Code
6862 status collapsed
6864 \begin_layout Plain Layout
6866 \end_layout
6868 \end_inset
6871 \begin_inset Flex CharStyle:Code
6872 status collapsed
6874 \begin_layout Plain Layout
6876 \end_layout
6878 \end_inset
6880  and 
6881 \begin_inset Flex CharStyle:Code
6882 status collapsed
6884 \begin_layout Plain Layout
6886 \end_layout
6888 \end_inset
6891 \begin_inset Flex CharStyle:Code
6892 status collapsed
6894 \begin_layout Plain Layout
6896 \end_layout
6898 \end_inset
6901  Of course this also makes it impossible to pass such mis-matched code fragments
6902  as parameters, but I think that it would be hard for readers to cope with
6903  authors who would pass such code unbalanced fragments as chunk parameters
6904 \begin_inset Foot
6905 status collapsed
6907 \begin_layout Plain Layout
6908 I know that I couldn't cope with users doing such things, and although the
6909  GPL3 license prevents me from actually forbidding anyone from trying, if
6910  they want it to work they'll have to write the code themselves and not
6911  expect any support from me.
6912 \end_layout
6914 \end_inset
6917 \end_layout
6919 \begin_layout Standard
6920 Unfortunately, the full set of matching delimiters may vary from language
6921  to language.
6922  In certain C++ template contexts, 
6923 \begin_inset Flex CharStyle:Code
6924 status collapsed
6926 \begin_layout Plain Layout
6928 \end_layout
6930 \end_inset
6932  and 
6933 \begin_inset Flex CharStyle:Code
6934 status collapsed
6936 \begin_layout Plain Layout
6938 \end_layout
6940 \end_inset
6942  would count as delimiters, and yet in other contexts they would not.
6943 \end_layout
6945 \begin_layout Standard
6946 This puts me in the unfortunate position of having to parse-somewhat all
6947  programming languages without knowing what they are!
6948 \end_layout
6950 \begin_layout Standard
6951 This is the basis of mode-tracking, by tracking parse-modes for different
6952  languages.
6953 \end_layout
6955 \begin_layout Chunk
6956 parse_chunk_args
6957 \end_layout
6959 \begin_layout Standard
6960 \begin_inset listings
6961 inline false
6962 status open
6964 \begin_layout Plain Layout
6966 function parse_chunk_args(language, text, values, mode,
6967 \end_layout
6969 \begin_layout Plain Layout
6971   # local vars
6972 \end_layout
6974 \begin_layout Plain Layout
6976   c, context, rest)
6977 \end_layout
6979 \begin_layout Plain Layout
6982 \end_layout
6984 \begin_layout Plain Layout
6986   =<
6987 \backslash
6988 chunkref{new-mode-tracker}(context, language, mode)>
6989 \end_layout
6991 \begin_layout Plain Layout
6993   rest = mode_tracker(context, text, values);
6994 \end_layout
6996 \begin_layout Plain Layout
6998   # extract values
6999 \end_layout
7001 \begin_layout Plain Layout
7003   for(c=1; c <= context[0, "values"]; c++) {
7004 \end_layout
7006 \begin_layout Plain Layout
7008     values[c] = context[0, "values", c];
7009 \end_layout
7011 \begin_layout Plain Layout
7013   }
7014 \end_layout
7016 \begin_layout Plain Layout
7018   return rest;
7019 \end_layout
7021 \begin_layout Plain Layout
7024 \end_layout
7026 \end_inset
7029 \end_layout
7031 \begin_layout Section
7032 Expanding parameters
7033 \end_layout
7035 \begin_layout Standard
7036 \begin_inset CommandInset label
7037 LatexCommand label
7038 name "Here-we-split"
7040 \end_inset
7042 Here we split the text on 
7043 \begin_inset Flex CharStyle:Code
7044 status collapsed
7046 \begin_layout Plain Layout
7048 \end_layout
7050 \end_inset
7052  which means that all parts except the first will begin with a parameter
7053  name.
7054  The split function will consume the literal 
7055 \begin_inset Flex CharStyle:Code
7056 status collapsed
7058 \begin_layout Plain Layout
7060 \end_layout
7062 \end_inset
7064  in each case.
7065 \end_layout
7067 \begin_layout Chunk
7068 expand_chunk_args()
7069 \end_layout
7071 \begin_layout Standard
7072 \begin_inset listings
7073 inline false
7074 status open
7076 \begin_layout Plain Layout
7078 function expand_chunk_args(text, params, args,  
7079 \end_layout
7081 \begin_layout Plain Layout
7083   p, text_array, next_text, v, t, l)
7084 \end_layout
7086 \begin_layout Plain Layout
7089 \end_layout
7091 \begin_layout Plain Layout
7093   if (split(text, text_array, "
7094 \backslash
7096 \backslash
7097 ${")) {
7098 \end_layout
7100 \begin_layout Plain Layout
7102     =<
7103 \backslash
7104 chunkref{substitute-chunk-args}>
7105 \end_layout
7107 \begin_layout Plain Layout
7109   }
7110 \end_layout
7112 \begin_layout Plain Layout
7114 \end_layout
7116 \begin_layout Plain Layout
7118   return text;
7119 \end_layout
7121 \begin_layout Plain Layout
7124 \end_layout
7126 \end_inset
7129 \end_layout
7131 \begin_layout Standard
7132 First, we produce an associative array of substitution values indexed by
7133  parameter names
7134 \end_layout
7136 \begin_layout Chunk
7137 substitute-chunk-args
7138 \end_layout
7140 \begin_layout Standard
7141 \begin_inset listings
7142 inline false
7143 status open
7145 \begin_layout Plain Layout
7147 for(p in params) {
7148 \end_layout
7150 \begin_layout Plain Layout
7152   v[params[p]]=args[p];
7153 \end_layout
7155 \begin_layout Plain Layout
7158 \end_layout
7160 \end_inset
7163 \end_layout
7165 \begin_layout Standard
7166 We accumulate substituted text in the variable 
7167 \begin_inset Flex CharStyle:Code
7168 status collapsed
7170 \begin_layout Plain Layout
7171 text
7172 \end_layout
7174 \end_inset
7177  As the first part of the split function is the part before the delimiter
7178  --- which is 
7179 \begin_inset Flex CharStyle:Code
7180 status collapsed
7182 \begin_layout Plain Layout
7184 \end_layout
7186 \end_inset
7188  in our case --- this part will never contain a parameter reference, so
7189  we assign this directly to the result kept in 
7190 \begin_inset Flex CharStyle:Code
7191 status collapsed
7193 \begin_layout Plain Layout
7194 $text
7195 \end_layout
7197 \end_inset
7200 \begin_inset listings
7201 inline false
7202 status open
7204 \begin_layout Plain Layout
7206 text=text_array[1];
7207 \end_layout
7209 \end_inset
7212 \end_layout
7214 \begin_layout Standard
7215 We then iterate over the remaining values in the array
7216 \begin_inset Foot
7217 status collapsed
7219 \begin_layout Plain Layout
7220 I don't know why I think that it will enumerate the array in order, but
7221  it seems to work
7222 \end_layout
7224 \end_inset
7227 \begin_inset Note Note
7228 status collapsed
7230 \begin_layout Plain Layout
7231 So fix it or porve it
7232 \end_layout
7234 \end_inset
7236 , and substitute each reference for it's argument.
7237 \end_layout
7239 \begin_layout Standard
7240 \begin_inset listings
7241 inline false
7242 status open
7244 \begin_layout Plain Layout
7246 for(t=2; t in text_array; t++) {
7247 \end_layout
7249 \begin_layout Plain Layout
7251   =<
7252 \backslash
7253 chunkref{substitute-chunk-arg}>
7254 \end_layout
7256 \begin_layout Plain Layout
7259 \end_layout
7261 \end_inset
7264 \end_layout
7266 \begin_layout Standard
7267 After the split on 
7268 \begin_inset Flex CharStyle:Code
7269 status collapsed
7271 \begin_layout Plain Layout
7273 \end_layout
7275 \end_inset
7277  a valid parameter reference will consist of valid parameter name terminated
7278  by a close-brace 
7279 \begin_inset Flex CharStyle:Code
7280 status collapsed
7282 \begin_layout Plain Layout
7284 \end_layout
7286 \end_inset
7289  A valid character name begins with the underscore or a letter, and may
7290  contain letters, digits or underscores.
7291 \end_layout
7293 \begin_layout Standard
7294 A valid looking reference that is not actually the name of a parameter will
7295  be and not substituted.
7296  This is good because there is nothing to substitute anyway, and it avoids
7297  clashes when writing code for languages where ${\SpecialChar \ldots{}
7298 } is a valid construct
7299  --- such constructs will not be interfered with unless the parameter name
7300  also matches.
7301 \end_layout
7303 \begin_layout Chunk
7304 substitute-chunk-arg
7305 \end_layout
7307 \begin_layout Standard
7308 \begin_inset listings
7309 inline false
7310 status open
7312 \begin_layout Plain Layout
7314 if (match(text_array[t], "^([a-zA-Z_][a-zA-Z0-9_]*)}", l) &&
7315 \end_layout
7317 \begin_layout Plain Layout
7319     l[1] in v) 
7320 \end_layout
7322 \begin_layout Plain Layout
7325 \end_layout
7327 \begin_layout Plain Layout
7329   text = text v[l[1]] substr(text_array[t], length(l[1])+2);
7330 \end_layout
7332 \begin_layout Plain Layout
7334 } else {
7335 \end_layout
7337 \begin_layout Plain Layout
7339   text = text "${" text_array[t];
7340 \end_layout
7342 \begin_layout Plain Layout
7345 \end_layout
7347 \end_inset
7350 \end_layout
7352 \begin_layout Chapter
7353 Recognizing Chunks
7354 \end_layout
7356 \begin_layout Standard
7357 Newfangle recognizes noweb chunks, but as we also want better LaTeX integration
7358  we will recognize any of these:
7359 \end_layout
7361 \begin_layout Itemize
7362 notangle chunks matching the pattern 
7363 \begin_inset Flex CharStyle:Code
7364 status collapsed
7366 \begin_layout Plain Layout
7368 \begin_inset space \hspace*{}
7369 \length 0in
7370 \end_inset
7372 <.*?>
7373 \begin_inset space \hspace*{}
7374 \length 0in
7375 \end_inset
7378 \end_layout
7380 \end_inset
7383 \end_layout
7385 \begin_layout Itemize
7386 a chunks beginning with 
7387 \begin_inset Flex CharStyle:Code
7388 status collapsed
7390 \begin_layout Plain Layout
7392 \backslash
7393 begin{lstlistings}
7394 \end_layout
7396 \end_inset
7398 , possibly with 
7399 \backslash
7400 Chunk{\SpecialChar \ldots{}
7401 } on the previous line
7402 \end_layout
7404 \begin_layout Itemize
7405 an older form I have used, beginning with 
7406 \begin_inset Flex CharStyle:Code
7407 status collapsed
7409 \begin_layout Plain Layout
7411 \backslash
7412 begin{Chunk}[options]
7413 \end_layout
7415 \end_inset
7417  --- also more suitable for plain LaTeX users
7418 \begin_inset Foot
7419 status collapsed
7421 \begin_layout Plain Layout
7422 Is there such a thing as plain LaTeX?
7423 \end_layout
7425 \end_inset
7428 \end_layout
7430 \begin_layout Section
7431 Chunk start
7432 \end_layout
7434 \begin_layout Standard
7435 The variable 
7436 \begin_inset Flex CharStyle:Code
7437 status collapsed
7439 \begin_layout Plain Layout
7440 chunking
7441 \end_layout
7443 \end_inset
7445  is used to signify that we are processing a code chunk and not document.
7446  In such a state, input lines will be assigned to the current chunk; otherwise
7447  they are ignored.
7448 \end_layout
7450 \begin_layout Subsection
7451 lstlistings
7452 \end_layout
7454 \begin_layout Standard
7455 Our current scheme is to recognize the new lstlisting chunks, but these
7456  may be preceded by a 
7457 \begin_inset Flex CharStyle:Code
7458 status collapsed
7460 \begin_layout Plain Layout
7462 \backslash
7463 Chunk
7464 \end_layout
7466 \end_inset
7468  command which in LyX is a more convenient way to pass the chunk name to
7469  the 
7470 \begin_inset Flex CharStyle:Code
7471 status collapsed
7473 \begin_layout Plain Layout
7475 \backslash
7476 begin{lstlistings}
7477 \end_layout
7479 \end_inset
7481  command, and a more visible way to specify other 
7482 \begin_inset Flex CharStyle:Code
7483 status collapsed
7485 \begin_layout Plain Layout
7486 lstset
7487 \end_layout
7489 \end_inset
7491  settings.
7492 \end_layout
7494 \begin_layout Standard
7495 The arguments to the 
7496 \begin_inset Flex CharStyle:Code
7497 status collapsed
7499 \begin_layout Plain Layout
7501 \backslash
7502 Chunk
7503 \end_layout
7505 \end_inset
7507  command are a name, and then a comma-seperated list of key-value pairs
7508  after the manner of 
7509 \begin_inset Flex CharStyle:Code
7510 status collapsed
7512 \begin_layout Plain Layout
7514 \backslash
7515 lstset
7516 \end_layout
7518 \end_inset
7521  (In fact within the LaTeX 
7522 \begin_inset Flex CharStyle:Code
7523 status collapsed
7525 \begin_layout Plain Layout
7527 \backslash
7528 Chunk
7529 \end_layout
7531 \end_inset
7533  macro (section 
7534 \begin_inset CommandInset ref
7535 LatexCommand ref
7536 reference "sub:The-chunk-command"
7538 \end_inset
7540 ) the text 
7541 \begin_inset Flex CharStyle:Code
7542 status collapsed
7544 \begin_layout Plain Layout
7545 name=
7546 \end_layout
7548 \end_inset
7550  is prefixed to the argument which is then literally passed to 
7551 \begin_inset Flex CharStyle:Code
7552 status collapsed
7554 \begin_layout Plain Layout
7556 \backslash
7557 lstset
7558 \end_layout
7560 \end_inset
7563 \end_layout
7565 \begin_layout Chunk
7566 recognize-chunk
7567 \end_layout
7569 \begin_layout Standard
7570 \begin_inset listings
7571 inline false
7572 status open
7574 \begin_layout Plain Layout
7577 \backslash
7579 \backslash
7580 Chunk{/ {
7581 \end_layout
7583 \begin_layout Plain Layout
7585   if (match($0, "^
7586 \backslash
7588 \backslash
7590 \backslash
7592 \backslash
7593 Chunk{ *([^ ,}]*),?(.*)}", line)) {
7594 \end_layout
7596 \begin_layout Plain Layout
7598     next_chunk_name = line[1];
7599 \end_layout
7601 \begin_layout Plain Layout
7603     get_chunk_args(line[2], next_chunk_args);
7604 \end_layout
7606 \begin_layout Plain Layout
7608   }
7609 \end_layout
7611 \begin_layout Plain Layout
7613   next;
7614 \end_layout
7616 \begin_layout Plain Layout
7619 \end_layout
7621 \end_inset
7624 \end_layout
7626 \begin_layout Standard
7627 We also make a basic attempt to parse the name out of the 
7628 \begin_inset Flex CharStyle:Code
7629 status collapsed
7631 \begin_layout Plain Layout
7633 \backslash
7634 lstlistings[name=
7635 \begin_inset space \hspace{}
7636 \length 0in
7637 \end_inset
7639 chunk-name]
7640 \end_layout
7642 \end_inset
7644  text, otherwise we fall back to the name found in the previous chunk command.
7645  This attempt is very basic and doesn't support commas or spaces or square
7646  brackets as part of the chunkname.
7647  We also recognize 
7648 \begin_inset Flex CharStyle:Code
7649 status collapsed
7651 \begin_layout Plain Layout
7653 \backslash
7654 begin{Chunk}
7655 \end_layout
7657 \end_inset
7659  which is convenient for some users
7660 \begin_inset Foot
7661 status open
7663 \begin_layout Plain Layout
7664 but not yet supported in the LaTeX macros
7665 \end_layout
7667 \end_inset
7670 \begin_inset Note Note
7671 status collapsed
7673 \begin_layout Plain Layout
7674 Add noweave support
7675 \end_layout
7677 \end_inset
7680 \end_layout
7682 \begin_layout Standard
7683 \begin_inset listings
7684 inline false
7685 status open
7687 \begin_layout Plain Layout
7690 \backslash
7692 \backslash
7693 begin{lstlisting}|^
7694 \backslash
7696 \backslash
7697 begin{Chunk}/ {
7698 \end_layout
7700 \begin_layout Plain Layout
7702   if (match($0, "}.*[[,] *name= *{? *([^], }]*)", line)) {
7703 \end_layout
7705 \begin_layout Plain Layout
7707     new_chunk(line[1]);
7708 \end_layout
7710 \begin_layout Plain Layout
7712   } else {
7713 \end_layout
7715 \begin_layout Plain Layout
7717     new_chunk(next_chunk_name, next_chunk_args);
7718 \end_layout
7720 \begin_layout Plain Layout
7722   }
7723 \end_layout
7725 \begin_layout Plain Layout
7727   chunking=1;
7728 \end_layout
7730 \begin_layout Plain Layout
7732   next;
7733 \end_layout
7735 \begin_layout Plain Layout
7738 \end_layout
7740 \end_inset
7743 \end_layout
7745 \begin_layout Subsection
7746 Noweb
7747 \end_layout
7749 \begin_layout Standard
7750 We recognize notangle style chunks too:
7751 \end_layout
7753 \begin_layout Chunk
7754 recognize-chunk
7755 \end_layout
7757 \begin_layout Standard
7758 \begin_inset listings
7759 inline false
7760 status open
7762 \begin_layout Plain Layout
7764 /^[<]<.*[>]>=/ {
7765 \end_layout
7767 \begin_layout Plain Layout
7769   if (match($0, "^[<]<(.*)[>]>= *$", line)) {
7770 \end_layout
7772 \begin_layout Plain Layout
7774     chunking=1;
7775 \end_layout
7777 \begin_layout Plain Layout
7779     notangle_mode=1;
7780 \end_layout
7782 \begin_layout Plain Layout
7784     new_chunk(line[1]);
7785 \end_layout
7787 \begin_layout Plain Layout
7789     next;
7790 \end_layout
7792 \begin_layout Plain Layout
7794   }
7795 \end_layout
7797 \begin_layout Plain Layout
7800 \end_layout
7802 \end_inset
7805 \end_layout
7807 \begin_layout Section
7808 Chunk end
7809 \end_layout
7811 \begin_layout Standard
7812 Likewise, we need to recognize when a chunk ends.
7813 \end_layout
7815 \begin_layout Subsection
7816 lstlistings
7817 \end_layout
7819 \begin_layout Standard
7820 The 
7821 \begin_inset Flex CharStyle:Code
7822 status collapsed
7824 \begin_layout Plain Layout
7826 \end_layout
7828 \end_inset
7830  in 
7831 \begin_inset Flex CharStyle:Code
7832 status collapsed
7834 \begin_layout Plain Layout
7835 [e]end{lislisting}
7836 \end_layout
7838 \end_inset
7840  is surrounded by square brackets so that when this document is processed,
7841  this chunk doesn't terminate early when the lstlistings package recognizes
7842  it's own end-string! 
7843 \begin_inset Note Greyedout
7844 status collapsed
7846 \begin_layout Plain Layout
7847 This doesn't make sense as the regex is anchored with ^, which this line
7848  does not begin with!
7849 \end_layout
7851 \end_inset
7854 \begin_inset Note Note
7855 status open
7857 \begin_layout Plain Layout
7858 No, it doesn't.
7859 \end_layout
7861 \end_inset
7864 \end_layout
7866 \begin_layout Chunk
7867 recognize-chunk
7868 \end_layout
7870 \begin_layout Standard
7871 \begin_inset listings
7872 inline false
7873 status open
7875 \begin_layout Plain Layout
7878 \backslash
7880 \backslash
7881 [e]nd{lstlisting}|^
7882 \backslash
7884 \backslash
7885 [e]nd{Chunk}/ {
7886 \end_layout
7888 \begin_layout Plain Layout
7890   chunking=0;
7891 \end_layout
7893 \begin_layout Plain Layout
7895   active_chunk="";
7896 \end_layout
7898 \begin_layout Plain Layout
7900   next;
7901 \end_layout
7903 \begin_layout Plain Layout
7906 \end_layout
7908 \end_inset
7911 \end_layout
7913 \begin_layout Subsection
7914 noweb
7915 \end_layout
7917 \begin_layout Chunk
7918 recognize-chunk
7919 \end_layout
7921 \begin_layout Standard
7922 \begin_inset listings
7923 inline false
7924 status open
7926 \begin_layout Plain Layout
7928 /^@ *$/ {
7929 \end_layout
7931 \begin_layout Plain Layout
7933   chunking=0;
7934 \end_layout
7936 \begin_layout Plain Layout
7938   active_chunk="";
7939 \end_layout
7941 \begin_layout Plain Layout
7944 \end_layout
7946 \end_inset
7949 \end_layout
7951 \begin_layout Standard
7952 All other recognizers are only of effect if we are chunking; there's no
7953  point in looking at lines if they aren't part of a chunk, so we just ignore
7954  them as efficiently as we can.
7955 \end_layout
7957 \begin_layout Chunk
7958 recognize-chunk
7959 \end_layout
7961 \begin_layout Standard
7962 \begin_inset listings
7963 inline false
7964 status open
7966 \begin_layout Plain Layout
7968 ! chunking { next; }
7969 \end_layout
7971 \end_inset
7974 \end_layout
7976 \begin_layout Section
7977 Chunk contents
7978 \end_layout
7980 \begin_layout Standard
7981 Chunk contents are any lines read while 
7982 \begin_inset Flex CharStyle:Code
7983 status collapsed
7985 \begin_layout Plain Layout
7986 chunking
7987 \end_layout
7989 \end_inset
7991  is true.
7992  Some chunk contents are special in that they refer to other chunks, and
7993  will be replaced by the contents of these chunks when the file is generated.
7994 \end_layout
7996 \begin_layout Standard
7997 \begin_inset CommandInset label
7998 LatexCommand label
7999 name "sub:ORS-chunk-text"
8001 \end_inset
8003 We add the output record separator 
8004 \begin_inset Flex CharStyle:Code
8005 status collapsed
8007 \begin_layout Plain Layout
8009 \end_layout
8011 \end_inset
8013  to the line now, because we will set 
8014 \begin_inset Flex CharStyle:Code
8015 status collapsed
8017 \begin_layout Plain Layout
8019 \end_layout
8021 \end_inset
8023  to the empty string when we generate the output
8024 \begin_inset Foot
8025 status collapsed
8027 \begin_layout Plain Layout
8028 So that we can print partial lines using 
8029 \begin_inset Flex CharStyle:Code
8030 status collapsed
8032 \begin_layout Plain Layout
8033 print
8034 \end_layout
8036 \end_inset
8038  instead of 
8039 \begin_inset Flex CharStyle:Code
8040 status collapsed
8042 \begin_layout Plain Layout
8043 printf
8044 \end_layout
8046 \end_inset
8049 \end_layout
8051 \end_inset
8054 \end_layout
8056 \begin_layout Chunk
8057 recognize-chunk
8058 \end_layout
8060 \begin_layout Standard
8061 \begin_inset listings
8062 inline false
8063 status open
8065 \begin_layout Plain Layout
8067 length(active_chunk) {
8068 \end_layout
8070 \begin_layout Plain Layout
8072   =<
8073 \backslash
8074 chunkref{process-chunk-tabs}>
8075 \end_layout
8077 \begin_layout Plain Layout
8079   =<
8080 \backslash
8081 chunkref{process-chunk}>
8082 \end_layout
8084 \begin_layout Plain Layout
8087 \end_layout
8089 \end_inset
8092 \end_layout
8094 \begin_layout Standard
8095 If a chunk just consisted of plain text, we could handle the chunk like
8096  this:
8097 \end_layout
8099 \begin_layout Chunk
8100 process-chunk-simple
8101 \end_layout
8103 \begin_layout Standard
8104 \begin_inset listings
8105 inline false
8106 status open
8108 \begin_layout Plain Layout
8110 chunk_line(active_chunk, $0 ORS);
8111 \end_layout
8113 \end_inset
8116 \end_layout
8118 \begin_layout Standard
8119 but in fact a chunk can include references to other chunks.
8120  Chunk includes are traditionally written as 
8121 \begin_inset Flex CharStyle:Code
8122 status collapsed
8124 \begin_layout Plain Layout
8125 <<chunk-name>>
8126 \end_layout
8128 \end_inset
8130 , but we support other variations.
8131 \end_layout
8133 \begin_layout Standard
8134 However, we also process tabs at this point, a tab at input can be replaced
8135  by a number of spaces defined by the 
8136 \begin_inset Flex CharStyle:Code
8137 status collapsed
8139 \begin_layout Plain Layout
8140 tabs
8141 \end_layout
8143 \end_inset
8145  variable, set by the 
8146 \begin_inset Flex CharStyle:Code
8147 status collapsed
8149 \begin_layout Plain Layout
8151 \end_layout
8153 \end_inset
8155  option.
8156  Of course this is poor tab behaviour, we should probably have the option
8157  to use proper counted tab-stops and process this on output.
8158 \end_layout
8160 \begin_layout Chunk
8161 process-chunk-tabs
8162 \end_layout
8164 \begin_layout Standard
8165 \begin_inset listings
8166 inline false
8167 status open
8169 \begin_layout Plain Layout
8171 if (length(tabs)) {
8172 \end_layout
8174 \begin_layout Plain Layout
8176   gsub("
8177 \backslash
8178 t", tabs);
8179 \end_layout
8181 \begin_layout Plain Layout
8184 \end_layout
8186 \end_inset
8189 \end_layout
8191 \begin_layout Subsection
8192 \begin_inset CommandInset label
8193 LatexCommand label
8194 name "sub:lstlistings-includes"
8196 \end_inset
8198 lstlistings
8199 \end_layout
8201 \begin_layout Standard
8202 If 
8203 \begin_inset Flex CharStyle:Code
8204 status collapsed
8206 \begin_layout Plain Layout
8208 \backslash
8209 lstset{escapeinside={=<}{>}}
8210 \end_layout
8212 \end_inset
8214  is set, then we can use 
8215 \begin_inset Flex CharStyle:Code
8216 status collapsed
8218 \begin_layout Plain Layout
8220 \backslash
8221 chunkref{
8222 \begin_inset space \hspace{}
8223 \length 0in
8224 \end_inset
8226 chunk-name}>
8227 \end_layout
8229 \end_inset
8231  in listings.
8232  The sequence 
8233 \begin_inset Flex CharStyle:Code
8234 status collapsed
8236 \begin_layout Plain Layout
8238 \end_layout
8240 \end_inset
8242  was chosen because:
8243 \end_layout
8245 \begin_layout Enumerate
8246 it is a better mnemonic than 
8247 \begin_inset Flex CharStyle:Code
8248 status collapsed
8250 \begin_layout Plain Layout
8251 <<chunk-name>>
8252 \end_layout
8254 \end_inset
8256  in that the = sign signifies equivalent or substitutability, 
8257 \end_layout
8259 \begin_layout Enumerate
8260 and because =< is not valid in C or in any language I can think of 
8261 \end_layout
8263 \begin_layout Enumerate
8264 and also because lstlistings doesn't like 
8265 \begin_inset Flex CharStyle:Code
8266 status collapsed
8268 \begin_layout Plain Layout
8270 \end_layout
8272 \end_inset
8274  as an end delimiter for the 
8275 \emph on
8276 texcl
8277 \emph default
8278  escape, so we must make do with a single 
8279 \begin_inset Flex CharStyle:Code
8280 status collapsed
8282 \begin_layout Plain Layout
8284 \end_layout
8286 \end_inset
8288 , which is better matched by 
8289 \begin_inset Flex CharStyle:Code
8290 status collapsed
8292 \begin_layout Plain Layout
8294 \end_layout
8296 \end_inset
8298  than 
8299 \begin_inset Flex CharStyle:Code
8300 status collapsed
8302 \begin_layout Plain Layout
8304 \end_layout
8306 \end_inset
8309 \end_layout
8311 \begin_layout Standard
8312 As each chunk line may contain more than one chunk include, we will split
8313  out chunk includes in an iterative fashion
8314 \begin_inset Foot
8315 status open
8317 \begin_layout Plain Layout
8318 Contrary to our use of 
8319 \begin_inset Flex CharStyle:Code
8320 status collapsed
8322 \begin_layout Plain Layout
8323 split
8324 \end_layout
8326 \end_inset
8328  when substituting parameters in chapter 
8329 \begin_inset CommandInset ref
8330 LatexCommand ref
8331 reference "Here-we-split"
8333 \end_inset
8336 \end_layout
8338 \end_inset
8341 \end_layout
8343 \begin_layout Standard
8344 First, as long as the chunk contains a 
8345 \begin_inset Flex CharStyle:Code
8346 status collapsed
8348 \begin_layout Plain Layout
8350 \backslash
8351 chunkref
8352 \end_layout
8354 \end_inset
8356  command we take as much as we can up to the first 
8357 \begin_inset Flex CharStyle:Code
8358 status collapsed
8360 \begin_layout Plain Layout
8362 \backslash
8363 chunkref
8364 \end_layout
8366 \end_inset
8368  command.
8369 \end_layout
8371 \begin_layout Chunk
8372 process-chunk
8373 \end_layout
8375 \begin_layout Standard
8376 \begin_inset listings
8377 inline false
8378 status open
8380 \begin_layout Plain Layout
8382 chunk = $0;
8383 \end_layout
8385 \begin_layout Plain Layout
8387 indent = 0;
8388 \end_layout
8390 \begin_layout Plain Layout
8392 while(match(chunk, 
8393 \end_layout
8395 \begin_layout Plain Layout
8397             "([=]<
8398 \backslash
8400 \backslash
8402 \backslash
8404 \backslash
8405 chunkref{([^}>]*)}(
8406 \backslash
8408 \backslash
8410 \backslash
8412 \backslash
8413 )|)>|<<([a-zA-Z_][-a-zA-Z0-9_]*)>>)", 
8414 \end_layout
8416 \begin_layout Plain Layout
8418             line)
8419 \backslash
8421 \end_layout
8423 \begin_layout Plain Layout
8425 ) {
8426 \end_layout
8428 \begin_layout Plain Layout
8430   chunklet = substr(chunk, 1, RSTART - 1);
8431 \end_layout
8433 \end_inset
8436 \end_layout
8438 \begin_layout Standard
8439 We keep track of the indent count, by counting the number of literal characters
8440  found.
8441  We can then preserve this indent on each output line when multi-line chunks
8442  are expanded.
8443 \end_layout
8445 \begin_layout Standard
8446 We then process this first part literal text, and set the chunk which is
8447  still to be processed to be the text after the 
8448 \begin_inset Flex CharStyle:Code
8449 status collapsed
8451 \begin_layout Plain Layout
8453 \backslash
8454 chunkref
8455 \end_layout
8457 \end_inset
8459  command, which we will process next as we continue around the loop.
8460 \end_layout
8462 \begin_layout Standard
8463 \begin_inset listings
8464 inline false
8465 status open
8467 \begin_layout Plain Layout
8469   indent += length(chunklet);
8470 \end_layout
8472 \begin_layout Plain Layout
8474   chunk_line(active_chunk, chunklet);
8475 \end_layout
8477 \begin_layout Plain Layout
8479   chunk = substr(chunk, RSTART + RLENGTH);
8480 \end_layout
8482 \end_inset
8485 \end_layout
8487 \begin_layout Standard
8488 We then consider the type of chunk command we have found, whether it is
8489  the newfangle style command beginning with 
8490 \begin_inset Flex CharStyle:Code
8491 status collapsed
8493 \begin_layout Plain Layout
8495 \end_layout
8497 \end_inset
8499  or the older notangle style beginning with 
8500 \begin_inset Flex CharStyle:Code
8501 status collapsed
8503 \begin_layout Plain Layout
8505 \end_layout
8507 \end_inset
8511 \end_layout
8513 \begin_layout Standard
8514 Newfangle chunks may have parameters contained within square brackets.
8515  These will be matched in 
8516 \begin_inset Flex CharStyle:Code
8517 status collapsed
8519 \begin_layout Plain Layout
8520 line[3]
8521 \end_layout
8523 \end_inset
8525  and are considered at this stage of processing to be part of the name of
8526  the chunk to be included.
8527 \end_layout
8529 \begin_layout Standard
8530 \begin_inset listings
8531 inline false
8532 status open
8534 \begin_layout Plain Layout
8536   if (substr(line[1], 1, 1) == "=") {
8537 \end_layout
8539 \begin_layout Plain Layout
8541     # chunk name up to }
8542 \end_layout
8544 \begin_layout Plain Layout
8546     chunk_include(active_chunk, line[2] line[3], indent);
8547 \end_layout
8549 \begin_layout Plain Layout
8551   } else if (substr(line[1], 1, 1) == "<") {
8552 \end_layout
8554 \begin_layout Plain Layout
8556     chunk_include(active_chunk, line[4], indent);
8557 \end_layout
8559 \begin_layout Plain Layout
8561   } else {
8562 \end_layout
8564 \begin_layout Plain Layout
8566     error("Unknown chunk fragment: " line[1]);
8567 \end_layout
8569 \begin_layout Plain Layout
8571   }
8572 \end_layout
8574 \end_inset
8577 \end_layout
8579 \begin_layout Standard
8580 The loop will continue until there are no more chunkref statements in the
8581  text, at which point we process the final part of the chunk.
8582 \end_layout
8584 \begin_layout Standard
8585 \begin_inset listings
8586 inline false
8587 status open
8589 \begin_layout Plain Layout
8592 \end_layout
8594 \begin_layout Plain Layout
8596 chunk_line(active_chunk, chunk);
8597 \end_layout
8599 \end_inset
8602 \end_layout
8604 \begin_layout Standard
8605 \begin_inset CommandInset label
8606 LatexCommand label
8607 name "lone-newline"
8609 \end_inset
8611 We add the newline character as a chunklet on it's own, to make it easier
8612  to detect new lines and thus manage indentation when processing the output.
8613 \end_layout
8615 \begin_layout Standard
8616 \begin_inset listings
8617 inline false
8618 status open
8620 \begin_layout Plain Layout
8622 chunk_line(active_chunk, "
8623 \backslash
8624 n");
8625 \end_layout
8627 \end_inset
8630 \end_layout
8632 \begin_layout Standard
8633 We will also permit a chunk-part number to follow in square brackets, so
8634  that 
8635 \begin_inset Flex CharStyle:Code
8636 status collapsed
8638 \begin_layout Plain Layout
8640 \backslash
8641 chunkref{chunk-name[1]}>
8642 \end_layout
8644 \end_inset
8646  will refer to the first part only.
8647  This can make it easy to include a C function prototype in a header file,
8648  if the first part of the chunk is just the function prototype without the
8649  trailing semi-colon.
8650  The header file would include the prototype with the trailing semi-colon,
8651  like this:
8652 \end_layout
8654 \begin_layout LyX-Code
8656 \backslash
8657 chunkref{chunk-name[1]}>;
8658 \end_layout
8660 \begin_layout Standard
8661 This is handled in section 
8662 \begin_inset CommandInset ref
8663 LatexCommand ref
8664 reference "sub:Chunk-parts"
8666 \end_inset
8669 \end_layout
8671 \begin_layout Standard
8672 We should perhaps introduce a notion of language specific chunk options;
8673  so that perhaps we could specify:
8674 \end_layout
8676 \begin_layout LyX-Code
8678 \backslash
8679 chunkref{chunk-name[function-declaration]}>;
8680 \end_layout
8682 \begin_layout Standard
8683 which applies a transform 
8684 \begin_inset Flex CharStyle:Code
8685 status collapsed
8687 \begin_layout Plain Layout
8688 function-declaration
8689 \end_layout
8691 \end_inset
8693  to the chunk --- which in this case would extract a function prototype
8694  from a function.
8695 \begin_inset Note Note
8696 status open
8698 \begin_layout Plain Layout
8699 So do it
8700 \end_layout
8702 \end_inset
8705 \end_layout
8707 \begin_layout Chapter
8708 Processing Options
8709 \end_layout
8711 \begin_layout Standard
8712 At the start, first we set the default options.
8713 \end_layout
8715 \begin_layout Chunk
8716 default-options
8717 \end_layout
8719 \begin_layout Standard
8720 \begin_inset listings
8721 inline false
8722 status open
8724 \begin_layout Plain Layout
8726 debug=0;
8727 \end_layout
8729 \begin_layout Plain Layout
8731 linenos=0;
8732 \end_layout
8734 \begin_layout Plain Layout
8736 notangle_mode=0;
8737 \end_layout
8739 \begin_layout Plain Layout
8741 root="*";
8742 \end_layout
8744 \begin_layout Plain Layout
8746 tabs = "";
8747 \end_layout
8749 \end_inset
8752 \end_layout
8754 \begin_layout Standard
8755 Then we use getopt the standard way, and null out ARGV afterwards in the
8756  normal AWK fashion.
8757 \end_layout
8759 \begin_layout Chunk
8760 read-options
8761 \end_layout
8763 \begin_layout Standard
8764 \begin_inset listings
8765 inline false
8766 status open
8768 \begin_layout Plain Layout
8770 Optind = 1    # skip ARGV[0]
8771 \end_layout
8773 \begin_layout Plain Layout
8775 while(getopt(ARGC, ARGV, "R:LdT:hr")!=-1) {
8776 \end_layout
8778 \begin_layout Plain Layout
8780   =<
8781 \backslash
8782 chunkref{handle-options}>
8783 \end_layout
8785 \begin_layout Plain Layout
8788 \end_layout
8790 \begin_layout Plain Layout
8792 for (i=1; i<Optind; i++) { ARGV[i]=""; }
8793 \end_layout
8795 \end_inset
8798 \end_layout
8800 \begin_layout Standard
8801 This is how we handle our options:
8802 \end_layout
8804 \begin_layout Chunk
8805 handle-options
8806 \end_layout
8808 \begin_layout Standard
8809 \begin_inset listings
8810 inline false
8811 status open
8813 \begin_layout Plain Layout
8815 if (Optopt == "R") root = Optarg;
8816 \end_layout
8818 \begin_layout Plain Layout
8820 else if (Optopt == "r") root="";
8821 \end_layout
8823 \begin_layout Plain Layout
8825 else if (Optopt == "L") linenos = 1;
8826 \end_layout
8828 \begin_layout Plain Layout
8830 else if (Optopt == "d") debug = 1;
8831 \end_layout
8833 \begin_layout Plain Layout
8835 else if (Optopt == "T") tabs = indent_string(Optarg+0);
8836 \end_layout
8838 \begin_layout Plain Layout
8840 else if (Optopt == "h") help();
8841 \end_layout
8843 \begin_layout Plain Layout
8845 else if (Optopt == "?") help();
8846 \end_layout
8848 \end_inset
8851 \end_layout
8853 \begin_layout Standard
8854 We do all of this at the beginning of the program
8855 \end_layout
8857 \begin_layout Chunk
8858 begin
8859 \end_layout
8861 \begin_layout Standard
8862 \begin_inset listings
8863 inline false
8864 status open
8866 \begin_layout Plain Layout
8868 BEGIN {
8869 \end_layout
8871 \begin_layout Plain Layout
8873   =<
8874 \backslash
8875 chunkref{constants}>
8876 \end_layout
8878 \begin_layout Plain Layout
8880   =<
8881 \backslash
8882 chunkref{mode-definitions}>
8883 \end_layout
8885 \begin_layout Plain Layout
8887   =<
8888 \backslash
8889 chunkref{default-options}>
8890 \end_layout
8892 \begin_layout Plain Layout
8894 \end_layout
8896 \begin_layout Plain Layout
8898   =<
8899 \backslash
8900 chunkref{read-options}>
8901 \end_layout
8903 \begin_layout Plain Layout
8906 \end_layout
8908 \end_inset
8911 \end_layout
8913 \begin_layout Standard
8914 And have a simple help function
8915 \end_layout
8917 \begin_layout Chunk
8918 help()
8919 \end_layout
8921 \begin_layout Standard
8922 \begin_inset listings
8923 inline false
8924 status open
8926 \begin_layout Plain Layout
8928 function help() {
8929 \end_layout
8931 \begin_layout Plain Layout
8933   print "Usage:"
8934 \end_layout
8936 \begin_layout Plain Layout
8938   print "  newfangle [-L] -R<rootname> [source.tex ...]"
8939 \end_layout
8941 \begin_layout Plain Layout
8943   print "  newfangle -r [source.tex ...]"
8944 \end_layout
8946 \begin_layout Plain Layout
8948   print "  If the filename, source.tex is not specified then stdin is used"
8949 \end_layout
8951 \begin_layout Plain Layout
8953   print
8954 \end_layout
8956 \begin_layout Plain Layout
8958   print "-L causes the C statement: #line <lineno> 
8959 \backslash
8960 "filename
8961 \backslash
8962 "" to be issued"
8963 \end_layout
8965 \begin_layout Plain Layout
8967   print "-R causes the named root to be written to stdout"
8968 \end_layout
8970 \begin_layout Plain Layout
8972   print "-r lists all roots in the file (even those used elsewhere)"
8973 \end_layout
8975 \begin_layout Plain Layout
8977   exit 1;
8978 \end_layout
8980 \begin_layout Plain Layout
8983 \end_layout
8985 \end_inset
8988 \end_layout
8990 \begin_layout Chapter
8991 Generating the output
8992 \end_layout
8994 \begin_layout Standard
8995 We generate output by calling output_chunk, or listing the chunk names.
8996 \end_layout
8998 \begin_layout Chunk
8999 generate-output
9000 \end_layout
9002 \begin_layout Standard
9003 \begin_inset listings
9004 inline false
9005 status open
9007 \begin_layout Plain Layout
9009 if (length(root)) output_chunk(root);
9010 \end_layout
9012 \begin_layout Plain Layout
9014 else output_chunk_names();
9015 \end_layout
9017 \end_inset
9020 \end_layout
9022 \begin_layout Standard
9023 We also have some other output debugging:
9024 \end_layout
9026 \begin_layout Chunk
9027 debug-output
9028 \end_layout
9030 \begin_layout Standard
9031 \begin_inset listings
9032 inline false
9033 status open
9035 \begin_layout Plain Layout
9037 if (debug) {
9038 \end_layout
9040 \begin_layout Plain Layout
9042   print "------ chunk names "
9043 \end_layout
9045 \begin_layout Plain Layout
9047   output_chunk_names();
9048 \end_layout
9050 \begin_layout Plain Layout
9052   print "====== chunks"
9053 \end_layout
9055 \begin_layout Plain Layout
9057   output_chunks();
9058 \end_layout
9060 \begin_layout Plain Layout
9062   print "++++++ debug"
9063 \end_layout
9065 \begin_layout Plain Layout
9067   for (a in chunks) {
9068 \end_layout
9070 \begin_layout Plain Layout
9072     print a "=" chunks[a];
9073 \end_layout
9075 \begin_layout Plain Layout
9077   }
9078 \end_layout
9080 \begin_layout Plain Layout
9083 \end_layout
9085 \end_inset
9088 \end_layout
9090 \begin_layout Standard
9091 We do both of these at the end.
9092  We also set 
9093 \begin_inset Flex CharStyle:Code
9094 status collapsed
9096 \begin_layout Plain Layout
9097 ORS=""
9098 \end_layout
9100 \end_inset
9102  because each chunklet is not necessarily a complete line, and we already
9103  added 
9104 \begin_inset Flex CharStyle:Code
9105 status collapsed
9107 \begin_layout Plain Layout
9109 \end_layout
9111 \end_inset
9113  to each input line in section 
9114 \begin_inset CommandInset ref
9115 LatexCommand ref
9116 reference "sub:ORS-chunk-text"
9118 \end_inset
9121 \end_layout
9123 \begin_layout Chunk
9125 \end_layout
9127 \begin_layout Standard
9128 \begin_inset listings
9129 inline false
9130 status open
9132 \begin_layout Plain Layout
9134 END {
9135 \end_layout
9137 \begin_layout Plain Layout
9139   =<
9140 \backslash
9141 chunkref{debug-output}>
9142 \end_layout
9144 \begin_layout Plain Layout
9146   ORS="";
9147 \end_layout
9149 \begin_layout Plain Layout
9151   =<
9152 \backslash
9153 chunkref{generate-output}>
9154 \end_layout
9156 \begin_layout Plain Layout
9159 \end_layout
9161 \end_inset
9164 \end_layout
9166 \begin_layout Standard
9167 We write chunk names like this.
9168  If we seem to be running in notangle compatibility mode, then we enclose
9169  the name like this 
9170 \begin_inset Flex CharStyle:Code
9171 status collapsed
9173 \begin_layout Plain Layout
9174 <<name>>
9175 \end_layout
9177 \end_inset
9179  the same way notangle does:
9180 \end_layout
9182 \begin_layout Chunk
9183 output_chunk_names()
9184 \end_layout
9186 \begin_layout Standard
9187 \begin_inset listings
9188 inline false
9189 status open
9191 \begin_layout Plain Layout
9193 function output_chunk_names(   c, prefix, suffix) 
9194 \end_layout
9196 \begin_layout Plain Layout
9199 \end_layout
9201 \begin_layout Plain Layout
9203   if (notangle_mode) {
9204 \end_layout
9206 \begin_layout Plain Layout
9208     prefix="<<";
9209 \end_layout
9211 \begin_layout Plain Layout
9213     suffix=">>";
9214 \end_layout
9216 \begin_layout Plain Layout
9218   }
9219 \end_layout
9221 \begin_layout Plain Layout
9223   for (c in chunk_names) {
9224 \end_layout
9226 \begin_layout Plain Layout
9228     print prefix c suffix "
9229 \backslash
9231 \end_layout
9233 \begin_layout Plain Layout
9235   }
9236 \end_layout
9238 \begin_layout Plain Layout
9241 \end_layout
9243 \end_inset
9246 \end_layout
9248 \begin_layout Standard
9249 This function would write out all chunks
9250 \end_layout
9252 \begin_layout Chunk
9253 output_chunks()
9254 \end_layout
9256 \begin_layout Standard
9257 \begin_inset listings
9258 inline false
9259 status open
9261 \begin_layout Plain Layout
9263 function output_chunks(  a) 
9264 \end_layout
9266 \begin_layout Plain Layout
9269 \end_layout
9271 \begin_layout Plain Layout
9273   for (a in chunk_names) {
9274 \end_layout
9276 \begin_layout Plain Layout
9278     output_chunk(chunk_names[a]);
9279 \end_layout
9281 \begin_layout Plain Layout
9283   }
9284 \end_layout
9286 \begin_layout Plain Layout
9289 \end_layout
9291 \begin_layout Plain Layout
9293 \end_layout
9295 \begin_layout Plain Layout
9297 function output_chunk(chunk) {
9298 \end_layout
9300 \begin_layout Plain Layout
9302   newline = 1;
9303 \end_layout
9305 \begin_layout Plain Layout
9307   lineno_needed = linenos;
9308 \end_layout
9310 \begin_layout Plain Layout
9312 \end_layout
9314 \begin_layout Plain Layout
9316   write_chunk(chunk);
9317 \end_layout
9319 \begin_layout Plain Layout
9322 \end_layout
9324 \begin_layout Plain Layout
9326 \end_layout
9328 \end_inset
9331 \end_layout
9333 \begin_layout Section
9334 Assembling the chunks
9335 \end_layout
9337 \begin_layout Standard
9338 \begin_inset Flex CharStyle:Code
9339 status collapsed
9341 \begin_layout Plain Layout
9342 chunk_path
9343 \end_layout
9345 \end_inset
9347  holds a string consisting of the names of all the chunks that resulted
9348  in this chunk being output.
9350 \begin_inset Note Note
9351 status collapsed
9353 \begin_layout Plain Layout
9354 Make sure it includes the line numbers too...
9356 \end_layout
9358 \end_inset
9360 It should probably also contain the source line numbers at which each inclusion
9361  also occured.
9362 \end_layout
9364 \begin_layout Chunk
9365 write_chunk()
9366 \end_layout
9368 \begin_layout Standard
9369 We first initialize the mode tracker for this chunk.
9370 \end_layout
9372 \begin_layout Standard
9373 \begin_inset listings
9374 inline false
9375 status open
9377 \begin_layout Plain Layout
9379 function write_chunk(chunk_name) {
9380 \end_layout
9382 \begin_layout Plain Layout
9384   =<
9385 \backslash
9386 chunkref{awk-delete-array}(context)>
9387 \end_layout
9389 \begin_layout Plain Layout
9391   return write_chunk_r(chunk_name, context);
9392 \end_layout
9394 \begin_layout Plain Layout
9397 \end_layout
9399 \end_inset
9402 \end_layout
9404 \begin_layout Chunk
9405 write_chunk(),emph={chunk_path}
9406 \end_layout
9408 \begin_layout Standard
9409 \begin_inset listings
9410 inline false
9411 status open
9413 \begin_layout Plain Layout
9415 function write_chunk_r(chunk_name, context, indent, tail,
9416 \end_layout
9418 \begin_layout Plain Layout
9420   # optional vars
9421 \end_layout
9423 \begin_layout Plain Layout
9425   chunk_path, chunk_args, 
9426 \end_layout
9428 \begin_layout Plain Layout
9430   # local vars
9431 \end_layout
9433 \begin_layout Plain Layout
9435   chunk_params, part, max_part, part_line, frag, max_frag, text, 
9436 \end_layout
9438 \begin_layout Plain Layout
9440   chunklet, only_part, call_chunk_args)
9441 \end_layout
9443 \begin_layout Plain Layout
9446 \end_layout
9448 \end_inset
9451 \end_layout
9453 \begin_layout Subsection
9454 \begin_inset CommandInset label
9455 LatexCommand label
9456 name "sub:Chunk-parts"
9458 \end_inset
9460 Chunk parts
9461 \end_layout
9463 \begin_layout Standard
9464 As mentioned in section 
9465 \begin_inset CommandInset ref
9466 LatexCommand ref
9467 reference "sub:lstlistings-includes"
9469 \end_inset
9471 , a chunk name may contain a part specifier in square brackets, limiting
9472  the parts that should be emitted.
9473 \end_layout
9475 \begin_layout Standard
9476 \begin_inset listings
9477 inline false
9478 status open
9480 \begin_layout Plain Layout
9482   if (match(chunk_name, "^(.*)
9483 \backslash
9485 \backslash
9486 [([0-9]*)
9487 \backslash
9489 \backslash
9490 ]$", chunk_name_parts)) {
9491 \end_layout
9493 \begin_layout Plain Layout
9495     chunk_name = chunk_name_parts[1];
9496 \end_layout
9498 \begin_layout Plain Layout
9500     only_part = chunk_name_parts[2];
9501 \end_layout
9503 \begin_layout Plain Layout
9505   }
9506 \end_layout
9508 \end_inset
9511 \end_layout
9513 \begin_layout Standard
9514 We then create a mode tracker 
9515 \end_layout
9517 \begin_layout Standard
9518 \begin_inset listings
9519 inline false
9520 status open
9522 \begin_layout Plain Layout
9524   =<
9525 \backslash
9526 chunkref{new-mode-tracker}(context, chunks[chunk_name, "language"], "")>
9527 \end_layout
9529 \end_inset
9532 \end_layout
9534 \begin_layout Standard
9535 We extract into 
9536 \begin_inset Flex CharStyle:Code
9537 status collapsed
9539 \begin_layout Plain Layout
9540 chunk_params
9541 \end_layout
9543 \end_inset
9545  the names of the parameters that this chunk accepts, whose values were
9546  (optionally) passed in 
9547 \begin_inset Flex CharStyle:Code
9548 status collapsed
9550 \begin_layout Plain Layout
9551 chunk_args
9552 \end_layout
9554 \end_inset
9557 \end_layout
9559 \begin_layout Standard
9560 \begin_inset listings
9561 inline false
9562 status open
9564 \begin_layout Plain Layout
9566   split(chunks[chunk_name, "params"], chunk_params, " *; *");
9567 \end_layout
9569 \end_inset
9572 \end_layout
9574 \begin_layout Standard
9575 To assemble a chunk, we write out each part.
9576 \end_layout
9578 \begin_layout Chunk
9579 write_chunk()
9580 \end_layout
9582 \begin_layout Standard
9583 \begin_inset listings
9584 inline false
9585 status open
9587 \begin_layout Plain Layout
9589   if (! (chunk_name in chunk_names)) {
9590 \end_layout
9592 \begin_layout Plain Layout
9594     error(sprintf(_"The root module <<%s>> was not defined.
9595 \backslash
9596 nUsed by: %s",
9597 \backslash
9599 \end_layout
9601 \begin_layout Plain Layout
9603                   chunk_name, chunk_path));
9604 \end_layout
9606 \begin_layout Plain Layout
9608   }
9609 \end_layout
9611 \begin_layout Plain Layout
9613 \end_layout
9615 \begin_layout Plain Layout
9617   max_part = chunks[chunk_name, "part"];
9618 \end_layout
9620 \begin_layout Plain Layout
9622   for(part = 1; part <= max_part; part++) {
9623 \end_layout
9625 \begin_layout Plain Layout
9627     if (! only_part || part == only_part) {
9628 \end_layout
9630 \begin_layout Plain Layout
9632       =<
9633 \backslash
9634 chunkref{write-part}>
9635 \end_layout
9637 \begin_layout Plain Layout
9639     }
9640 \end_layout
9642 \begin_layout Plain Layout
9644   }
9645 \end_layout
9647 \begin_layout Plain Layout
9649   if (! finalize_mode_tracker(context)) {
9650 \end_layout
9652 \begin_layout Plain Layout
9654     error(sprintf(_"Module %s did not close context properly.
9655 \backslash
9656 nUsed by: %s
9657 \backslash
9658 n", chunk_name, chunk_path));
9659 \end_layout
9661 \begin_layout Plain Layout
9663   }
9664 \end_layout
9666 \begin_layout Plain Layout
9669 \end_layout
9671 \end_inset
9674 \end_layout
9676 \begin_layout Standard
9677 A part can either be a chunklet of lines, or an include of another chunk.
9678 \end_layout
9680 \begin_layout Standard
9681 Chunks may also have parameters, specified in LaTeX style with braces after
9682  the chunk name --- looking like this in the document: 
9683 \begin_inset Flex CharStyle:Code
9684 status collapsed
9686 \begin_layout Plain Layout
9687 chunkname{param1, param2}
9688 \end_layout
9690 \end_inset
9693  Arguments are passed in square brackets: 
9694 \begin_inset Flex CharStyle:Code
9695 status collapsed
9697 \begin_layout Plain Layout
9699 \backslash
9700 chunkref{chunkname}[arg1, arg2]
9701 \end_layout
9703 \end_inset
9706 \end_layout
9708 \begin_layout Standard
9709 Before we process each part, we check that the source position hasn't changed
9710  unexpectedly, so that we can know if we need to output a new file-line
9711  directive.
9712 \end_layout
9714 \begin_layout Chunk
9715 write-part
9716 \end_layout
9718 \begin_layout Standard
9719 \begin_inset listings
9720 inline false
9721 status open
9723 \begin_layout Plain Layout
9726 \backslash
9727 chunkref{check-source-jump}>
9728 \end_layout
9730 \begin_layout Plain Layout
9732 \end_layout
9734 \begin_layout Plain Layout
9736 chunklet = chunks[chunk_name, "part", part];
9737 \end_layout
9739 \begin_layout Plain Layout
9741 if (chunks[chunk_name, "part", part, "type"] == part_type_chunk) {
9742 \end_layout
9744 \begin_layout Plain Layout
9746   =<
9747 \backslash
9748 chunkref{write-included-chunk}>
9749 \end_layout
9751 \begin_layout Plain Layout
9753 } else if (chunklet SUBSEP "line" in chunks) {
9754 \end_layout
9756 \begin_layout Plain Layout
9758   =<
9759 \backslash
9760 chunkref{write-chunklets}>
9761 \end_layout
9763 \begin_layout Plain Layout
9765 } else {
9766 \end_layout
9768 \begin_layout Plain Layout
9770   # empty last chunklet
9771 \end_layout
9773 \begin_layout Plain Layout
9776 \end_layout
9778 \end_inset
9781 \end_layout
9783 \begin_layout Standard
9784 To write an included chunk, we must detect any optional chunk arguments
9785  in parenthesis.
9786  Then we recurse calling 
9787 \begin_inset Flex Chunkref
9788 status collapsed
9790 \begin_layout Plain Layout
9791 write_chunk()
9792 \end_layout
9794 \end_inset
9797 \end_layout
9799 \begin_layout Chunk
9800 write-included-chunk
9801 \end_layout
9803 \begin_layout Standard
9804 \begin_inset listings
9805 inline false
9806 status open
9808 \begin_layout Plain Layout
9810 if (match(chunklet, "^([^
9811 \backslash
9813 \backslash
9814 []*)
9815 \backslash
9817 \backslash
9818 ((.*)
9819 \backslash
9821 \backslash
9822 )$", chunklet_parts)) {
9823 \end_layout
9825 \begin_layout Plain Layout
9827   chunklet = chunklet_parts[1];
9828 \end_layout
9830 \begin_layout Plain Layout
9832   parse_chunk_args("", chunklet_parts[2], call_chunk_args, "(");
9833 \end_layout
9835 \begin_layout Plain Layout
9837   for (c in call_chunk_args) {
9838 \end_layout
9840 \begin_layout Plain Layout
9842     call_chunk_args[c] = expand_chunk_args(call_chunk_args[c], chunk_params,
9843  chunk_args);
9844 \end_layout
9846 \begin_layout Plain Layout
9848   }
9849 \end_layout
9851 \begin_layout Plain Layout
9853 } else {
9854 \end_layout
9856 \begin_layout Plain Layout
9858   split("", call_chunk_args);
9859 \end_layout
9861 \begin_layout Plain Layout
9864 \end_layout
9866 \begin_layout Plain Layout
9868 write_chunk_r(chunklet, context,
9869 \end_layout
9871 \begin_layout Plain Layout
9873             chunks[chunk_name, "part", part, "indent"] indent,
9874 \end_layout
9876 \begin_layout Plain Layout
9878             chunks[chunk_name, "part", part, "tail"],
9879 \end_layout
9881 \begin_layout Plain Layout
9883             chunk_path "
9884 \backslash
9885 n         " chunk_name,
9886 \end_layout
9888 \begin_layout Plain Layout
9890             call_chunk_args);
9891 \end_layout
9893 \end_inset
9896 \end_layout
9898 \begin_layout Standard
9899 Before we output a chunklet of lines, we first emit the file and line number
9900  if we have one, and if it is safe to do so.
9902 \end_layout
9904 \begin_layout Standard
9905 Chunklets are generally broken up by includes, so the start of a chunklet
9906  is a good place to do this.
9907  Then we output each line of the chunklet.
9908 \end_layout
9910 \begin_layout Standard
9911 When it is not safe, such as in the middle of a multi-line macro definition,
9913 \begin_inset Flex CharStyle:Code
9914 status collapsed
9916 \begin_layout Plain Layout
9917 lineno_suppressed
9918 \end_layout
9920 \end_inset
9922  is set to true, and in such a case we note that we want to emit the line
9923  statement when it is next safe.
9924 \end_layout
9926 \begin_layout Chunk
9927 write-chunklets
9928 \end_layout
9930 \begin_layout Standard
9931 \begin_inset listings
9932 inline false
9933 status open
9935 \begin_layout Plain Layout
9937 max_frag = chunks[chunklet, "line"];
9938 \end_layout
9940 \begin_layout Plain Layout
9942 for(frag = 1; frag <= max_frag; frag++) {
9943 \end_layout
9945 \begin_layout Plain Layout
9947   =<
9948 \backslash
9949 chunkref{write-file-line}>
9950 \end_layout
9952 \end_inset
9955 \end_layout
9957 \begin_layout Standard
9958 We then extract the chunklet text and expand any arguments.
9959 \end_layout
9961 \begin_layout Standard
9962 \begin_inset listings
9963 inline false
9964 status open
9966 \begin_layout Plain Layout
9968 \end_layout
9970 \begin_layout Plain Layout
9972   text = chunks[chunklet, frag];
9973 \end_layout
9975 \begin_layout Plain Layout
9978 \end_layout
9980 \begin_layout Plain Layout
9982   /* check params */
9983 \end_layout
9985 \begin_layout Plain Layout
9987   text = expand_chunk_args(text, chunk_params, chunk_args);
9988 \end_layout
9990 \end_inset
9993 \end_layout
9995 \begin_layout Standard
9996 If the text is a single newline (which we keep separate - see 
9997 \begin_inset CommandInset ref
9998 LatexCommand ref
9999 reference "lone-newline"
10001 \end_inset
10003 ) then we increment the line number.
10004  In the case where this is the last line of a chunk and it is not a top-level
10005  chunk we replace the newline with an empty string --- because the chunk
10006  that included this chunk will have the newline at the end of the line that
10007  included this chunk.
10008 \end_layout
10010 \begin_layout Standard
10011 We also note by 
10012 \begin_inset Flex CharStyle:Code
10013 status collapsed
10015 \begin_layout Plain Layout
10016 newline = 1
10017 \end_layout
10019 \end_inset
10021  that we have started a new line, so that indentation can be managed with
10022  the following piece of text.
10023 \end_layout
10025 \begin_layout Standard
10026 \begin_inset listings
10027 inline false
10028 status open
10030 \begin_layout Plain Layout
10032 \end_layout
10034 \begin_layout Plain Layout
10036  if (text == "
10037 \backslash
10038 n") {
10039 \end_layout
10041 \begin_layout Plain Layout
10043     lineno++;
10044 \end_layout
10046 \begin_layout Plain Layout
10048     if (part == max_part && frag == max_frag && length(chunk_path)) {
10049 \end_layout
10051 \begin_layout Plain Layout
10053       text = "";
10054 \end_layout
10056 \begin_layout Plain Layout
10058       break;
10059 \end_layout
10061 \begin_layout Plain Layout
10063     } else {
10064 \end_layout
10066 \begin_layout Plain Layout
10068       newline = 1;
10069 \end_layout
10071 \begin_layout Plain Layout
10073     }
10074 \end_layout
10076 \end_inset
10079 \end_layout
10081 \begin_layout Standard
10082 If this text does not represent a newline, but we see that we are the first
10083  piece of text on a newline, then we prefix our text with the current indent.
10084  NOTE: 
10085 \begin_inset Flex CharStyle:Code
10086 status collapsed
10088 \begin_layout Plain Layout
10089 newline
10090 \end_layout
10092 \end_inset
10094  is a global output-state variable, but the 
10095 \begin_inset Flex CharStyle:Code
10096 status collapsed
10098 \begin_layout Plain Layout
10099 indent
10100 \end_layout
10102 \end_inset
10104  is not.
10106 \end_layout
10108 \begin_layout Standard
10109 \begin_inset listings
10110 inline false
10111 status open
10113 \begin_layout Plain Layout
10115   } else if (length(text) || length(tail)) {
10116 \end_layout
10118 \begin_layout Plain Layout
10120     if (newline) text = indent text;
10121 \end_layout
10123 \begin_layout Plain Layout
10125     newline = 0;
10126 \end_layout
10128 \begin_layout Plain Layout
10130   }
10131 \end_layout
10133 \begin_layout Plain Layout
10135 \end_layout
10137 \end_inset
10140 \end_layout
10142 \begin_layout Standard
10143 Tail will soon no longer be relevant once mode-detection is in place.
10144 \end_layout
10146 \begin_layout Standard
10147 \begin_inset listings
10148 inline false
10149 status open
10151 \begin_layout Plain Layout
10153   text = text tail;
10154 \end_layout
10156 \begin_layout Plain Layout
10158   mode_tracker(context, text);
10159 \end_layout
10161 \begin_layout Plain Layout
10163   print text;
10164 \end_layout
10166 \end_inset
10169 \end_layout
10171 \begin_layout Standard
10172 If a line ends in a backslash --- suggesting continuation --- then we supress
10173  outputting file-line as it would probably break the continued lines.
10175 \end_layout
10177 \begin_layout Standard
10178 \begin_inset listings
10179 inline false
10180 status open
10182 \begin_layout Plain Layout
10184   if (linenos) {
10185 \end_layout
10187 \begin_layout Plain Layout
10189     lineno_suppressed = substr(lastline, length(lastline)) == "
10190 \backslash
10192 \backslash
10194 \end_layout
10196 \begin_layout Plain Layout
10198   }
10199 \end_layout
10201 \begin_layout Plain Layout
10204 \end_layout
10206 \end_inset
10209 \end_layout
10211 \begin_layout Standard
10212 Of course there is no point in actually outputting the source filename and
10213  line number (file-line) if they don't say anything new! We only need to
10214  emit them if they aren't what is expected, or if we we not able to emit
10215  one when they had changed.
10216 \end_layout
10218 \begin_layout Chunk
10219 write-file-line
10220 \end_layout
10222 \begin_layout Standard
10223 \begin_inset listings
10224 inline false
10225 status open
10227 \begin_layout Plain Layout
10229 if (newline && lineno_needed && ! lineno_suppressed) {
10230 \end_layout
10232 \begin_layout Plain Layout
10234   filename = a_filename;
10235 \end_layout
10237 \begin_layout Plain Layout
10239   lineno = a_lineno;
10240 \end_layout
10242 \begin_layout Plain Layout
10244   print "#line " lineno " 
10245 \backslash
10246 "" filename "
10247 \backslash
10249 \backslash
10251 \end_layout
10253 \begin_layout Plain Layout
10255   lineno_needed = 0;
10256 \end_layout
10258 \begin_layout Plain Layout
10261 \end_layout
10263 \end_inset
10266 \end_layout
10268 \begin_layout Standard
10269 We check if a new file-line is needed by checking if the source line matches
10270  what we (or a compiler) would expect.
10272 \end_layout
10274 \begin_layout Chunk
10275 check-source-jump
10276 \end_layout
10278 \begin_layout Standard
10279 \begin_inset listings
10280 inline false
10281 status open
10283 \begin_layout Plain Layout
10285 if (linenos && (chunk_name SUBSEP "part" SUBSEP part SUBSEP "FILENAME" in
10286  chunks)) {
10287 \end_layout
10289 \begin_layout Plain Layout
10291   a_filename = chunks[chunk_name, "part", part, "FILENAME"];
10292 \end_layout
10294 \begin_layout Plain Layout
10296   a_lineno = chunks[chunk_name, "part", part, "LINENO"];
10297 \end_layout
10299 \begin_layout Plain Layout
10301   if (a_filename != filename || a_lineno != lineno) {
10302 \end_layout
10304 \begin_layout Plain Layout
10306     lineno_needed++;
10307 \end_layout
10309 \begin_layout Plain Layout
10311   }
10312 \end_layout
10314 \begin_layout Plain Layout
10317 \end_layout
10319 \end_inset
10322 \end_layout
10324 \begin_layout Chapter
10325 Storing chunks
10326 \end_layout
10328 \begin_layout Standard
10329 Awk has pretty limited data structures, so we will use two main hashes.
10330  Uninterrupted sequences of a chunk will be stored in 
10331 \begin_inset Flex CharStyle:Code
10332 status collapsed
10334 \begin_layout Plain Layout
10335 chunklets
10336 \end_layout
10338 \end_inset
10340  and the chunklets used in a chunk will be stored in 
10341 \begin_inset Flex CharStyle:Code
10342 status collapsed
10344 \begin_layout Plain Layout
10345 chunks
10346 \end_layout
10348 \end_inset
10351 \end_layout
10353 \begin_layout Chunk
10354 constants
10355 \end_layout
10357 \begin_layout Standard
10358 \begin_inset listings
10359 inline false
10360 status open
10362 \begin_layout Plain Layout
10364 part_type_chunk=1;
10365 \end_layout
10367 \begin_layout Plain Layout
10369 SUBSEP=",";
10370 \end_layout
10372 \end_inset
10375 \end_layout
10377 \begin_layout Standard
10378 The 
10379 \begin_inset Flex CharStyle:Code
10380 status collapsed
10382 \begin_layout Plain Layout
10383 params
10384 \end_layout
10386 \end_inset
10388  mentioned are not chunk parameters for parameterized chunks, as mentioned
10389  in 
10390 \begin_inset CommandInset ref
10391 LatexCommand ref
10392 reference "cha:Chunk Arguments"
10394 \end_inset
10396 , but the lstlistings style parameters used in the 
10397 \begin_inset Flex CharStyle:Code
10398 status collapsed
10400 \begin_layout Plain Layout
10402 \backslash
10403 Chunk
10404 \end_layout
10406 \end_inset
10408  command
10409 \begin_inset Foot
10410 status collapsed
10412 \begin_layout Plain Layout
10413 The 
10414 \begin_inset Flex CharStyle:Code
10415 status collapsed
10417 \begin_layout Plain Layout
10418 params
10419 \end_layout
10421 \end_inset
10423  parameter is used to hold the parameters for parameterized chunks
10424 \end_layout
10426 \end_inset
10429 \end_layout
10431 \begin_layout Chunk
10432 chunk-storage-functions
10433 \end_layout
10435 \begin_layout Standard
10436 \begin_inset listings
10437 inline false
10438 status open
10440 \begin_layout Plain Layout
10442 function new_chunk(chunk_name, params,
10443 \end_layout
10445 \begin_layout Plain Layout
10447   # local vars
10448 \end_layout
10450 \begin_layout Plain Layout
10452   p, append )
10453 \end_layout
10455 \begin_layout Plain Layout
10458 \end_layout
10460 \begin_layout Plain Layout
10462   # HACK WHILE WE CHANGE TO ( ) for PARAM CHUNKS
10463 \end_layout
10465 \begin_layout Plain Layout
10467   gsub("
10468 \backslash
10470 \backslash
10472 \backslash
10474 \backslash
10475 )$", "", chunk_name);
10476 \end_layout
10478 \begin_layout Plain Layout
10480   if (! (chunk_name in chunk_names)) {
10481 \end_layout
10483 \begin_layout Plain Layout
10485     if (debug) print "New chunk " chunk_name;
10486 \end_layout
10488 \begin_layout Plain Layout
10490     chunk_names[chunk_name];
10491 \end_layout
10493 \begin_layout Plain Layout
10495     for (p in params) {
10496 \end_layout
10498 \begin_layout Plain Layout
10500       chunks[chunk_name, p] = params[p];
10501 \end_layout
10503 \begin_layout Plain Layout
10505     }
10506 \end_layout
10508 \begin_layout Plain Layout
10510     if ("append" in params) {
10511 \end_layout
10513 \begin_layout Plain Layout
10515       append=params["append"];
10516 \end_layout
10518 \begin_layout Plain Layout
10520       if (! (append in chunk_names)) {
10521 \end_layout
10523 \begin_layout Plain Layout
10525         warning("Chunk " chunk_name " is appended to chunk " append " which
10526  is not defined yet");
10527 \end_layout
10529 \begin_layout Plain Layout
10531         new_chunk(append);
10532 \end_layout
10534 \begin_layout Plain Layout
10536       }
10537 \end_layout
10539 \begin_layout Plain Layout
10541       chunk_include(append, chunk_name);
10542 \end_layout
10544 \begin_layout Plain Layout
10546       chunk_line(append, ORS);
10547 \end_layout
10549 \begin_layout Plain Layout
10551     }
10552 \end_layout
10554 \begin_layout Plain Layout
10556   }
10557 \end_layout
10559 \begin_layout Plain Layout
10561   active_chunk = chunk_name;
10562 \end_layout
10564 \begin_layout Plain Layout
10566   prime_chunk(chunk_name);
10567 \end_layout
10569 \begin_layout Plain Layout
10572 \end_layout
10574 \end_inset
10577 \end_layout
10579 \begin_layout Standard
10580 \begin_inset listings
10581 inline false
10582 status open
10584 \begin_layout Plain Layout
10586 \end_layout
10588 \begin_layout Plain Layout
10590 function prime_chunk(chunk_name)
10591 \end_layout
10593 \begin_layout Plain Layout
10596 \end_layout
10598 \begin_layout Plain Layout
10600   chunks[chunk_name, "part", ++chunks[chunk_name, "part"] ] = 
10601 \backslash
10603 \end_layout
10605 \begin_layout Plain Layout
10607          chunk_name SUBSEP "chunklet" SUBSEP "" ++chunks[chunk_name, "chunklet"]
10609 \end_layout
10611 \begin_layout Plain Layout
10613   chunks[chunk_name, "part", chunks[chunk_name, "part"], "FILENAME"] = FILENAME;
10614 \end_layout
10616 \begin_layout Plain Layout
10618   chunks[chunk_name, "part", chunks[chunk_name, "part"], "LINENO"] = FNR
10619  + 1;
10620 \end_layout
10622 \begin_layout Plain Layout
10625 \end_layout
10627 \begin_layout Plain Layout
10629 \end_layout
10631 \begin_layout Plain Layout
10633 function chunk_line(chunk_name, line){
10634 \end_layout
10636 \begin_layout Plain Layout
10638   chunks[chunk_name, "chunklet", chunks[chunk_name, "chunklet"],
10639 \end_layout
10641 \begin_layout Plain Layout
10643          ++chunks[chunk_name, "chunklet", chunks[chunk_name, "chunklet"],
10644  "line"]  ] = line;
10645 \end_layout
10647 \begin_layout Plain Layout
10650 \end_layout
10652 \begin_layout Plain Layout
10654 \end_layout
10656 \end_inset
10659 \end_layout
10661 \begin_layout Standard
10662 Chunk include represents a 
10663 \emph on
10664 chunkref
10665 \emph default
10666  statement, and stores the requirement to include another chunk.
10667  The parameter indent represents the quanity of literal text characters
10668  that preceded this 
10669 \emph on
10670 chunkref
10671 \emph default
10672  statement and therefore by how much additional lines of the included chunk
10673  should be indented.
10674 \end_layout
10676 \begin_layout Standard
10677 \begin_inset listings
10678 inline false
10679 status open
10681 \begin_layout Plain Layout
10683 function chunk_include(chunk_name, chunk_ref, indent, tail)
10684 \end_layout
10686 \begin_layout Plain Layout
10689 \end_layout
10691 \begin_layout Plain Layout
10693   chunks[chunk_name, "part", ++chunks[chunk_name, "part"] ] = chunk_ref;
10694 \end_layout
10696 \begin_layout Plain Layout
10698   chunks[chunk_name, "part", chunks[chunk_name, "part"], "type" ] = part_type_ch
10699 unk;
10700 \end_layout
10702 \begin_layout Plain Layout
10704   chunks[chunk_name, "part", chunks[chunk_name, "part"], "indent" ] = indent_str
10705 ing(indent);
10706 \end_layout
10708 \begin_layout Plain Layout
10710   chunks[chunk_name, "part", chunks[chunk_name, "part"], "tail" ] = tail;
10711 \end_layout
10713 \begin_layout Plain Layout
10715   prime_chunk(chunk_name);
10716 \end_layout
10718 \begin_layout Plain Layout
10721 \end_layout
10723 \begin_layout Plain Layout
10725 \end_layout
10727 \end_inset
10730 \end_layout
10732 \begin_layout Standard
10733 The indent is calculated by indent_string, which may in future convert some
10734  spaces into tab characters.
10735  This function works by generating a printf padded format string, like 
10736 \begin_inset Flex CharStyle:Code
10737 status collapsed
10739 \begin_layout Plain Layout
10740 %22s
10741 \end_layout
10743 \end_inset
10745  for an indent of 22, and then printing an empty string using that format.
10746 \end_layout
10748 \begin_layout Standard
10749 \begin_inset listings
10750 inline false
10751 status open
10753 \begin_layout Plain Layout
10755 function indent_string(indent) {
10756 \end_layout
10758 \begin_layout Plain Layout
10760   return sprintf("%" indent "s", "");
10761 \end_layout
10763 \begin_layout Plain Layout
10766 \end_layout
10768 \end_inset
10771 \end_layout
10773 \begin_layout Chapter
10774 \begin_inset CommandInset label
10775 LatexCommand label
10776 name "cha:getopt"
10778 \end_inset
10780 getopt
10781 \end_layout
10783 \begin_layout Standard
10784 I use Arnold Robbins public domain getopt (1993 revision).
10785  This is probably the same one that is covered in chapter 12 of 
10786 \begin_inset Quotes eld
10787 \end_inset
10789 Edition 3 of GAWK: Effective AWK Programming: A User's Guide for GNU Awk
10790 \begin_inset Quotes erd
10791 \end_inset
10793  but as that is licensed under the GNU Free Documentation License, Version
10794  1.3, which conflicts with the GPL3, I can't use it from there (or it's accompany
10795 ing explanations), so I do my best to explain how it works here.
10796 \end_layout
10798 \begin_layout Standard
10799 The getopt.awk header is:
10800 \end_layout
10802 \begin_layout Chunk
10803 getopt.awk-header,language=awk,morestring=[b]{/},morekeywords=else
10804 \end_layout
10806 \begin_layout Standard
10807 \begin_inset listings
10808 inline false
10809 status open
10811 \begin_layout Plain Layout
10813 # getopt.awk --- do C library getopt(3) function in awk
10814 \end_layout
10816 \begin_layout Plain Layout
10819 \end_layout
10821 \begin_layout Plain Layout
10823 # Arnold Robbins, arnold@skeeve.com, Public Domain
10824 \end_layout
10826 \begin_layout Plain Layout
10829 \end_layout
10831 \begin_layout Plain Layout
10833 # Initial version: March, 1991
10834 \end_layout
10836 \begin_layout Plain Layout
10838 # Revised: May, 1993
10839 \end_layout
10841 \end_inset
10844 \end_layout
10846 \begin_layout Standard
10847 The provided explanation is:
10848 \end_layout
10850 \begin_layout Chunk
10851 getopt.awk-notes
10852 \end_layout
10854 \begin_layout Standard
10855 \begin_inset listings
10856 inline false
10857 status open
10859 \begin_layout Plain Layout
10861 # External variables:
10862 \end_layout
10864 \begin_layout Plain Layout
10866 #    Optind -- index in ARGV of first nonoption argument
10867 \end_layout
10869 \begin_layout Plain Layout
10871 #    Optarg -- string value of argument to current option
10872 \end_layout
10874 \begin_layout Plain Layout
10876 #    Opterr -- if nonzero, print our own diagnostic
10877 \end_layout
10879 \begin_layout Plain Layout
10881 #    Optopt -- current option letter
10882 \end_layout
10884 \begin_layout Plain Layout
10886 \end_layout
10888 \begin_layout Plain Layout
10890 # Returns:
10891 \end_layout
10893 \begin_layout Plain Layout
10895 #    -1     at end of options
10896 \end_layout
10898 \begin_layout Plain Layout
10900 #    ?      for unrecognized option
10901 \end_layout
10903 \begin_layout Plain Layout
10905 #    <c>    a character representing the current option
10906 \end_layout
10908 \begin_layout Plain Layout
10910 \end_layout
10912 \begin_layout Plain Layout
10914 # Private Data:
10915 \end_layout
10917 \begin_layout Plain Layout
10919 #    _opti  -- index in multi-flag option, e.g., -abc
10920 \end_layout
10922 \end_inset
10925 \end_layout
10927 \begin_layout Standard
10928 The function follows.
10929  The final two parameters, 
10930 \begin_inset Flex CharStyle:Code
10931 status collapsed
10933 \begin_layout Plain Layout
10934 thisopt
10935 \end_layout
10937 \end_inset
10939  and 
10940 \begin_inset Flex CharStyle:Code
10941 status collapsed
10943 \begin_layout Plain Layout
10945 \end_layout
10947 \end_inset
10949  are local variables and not parameters --- as indicated by the multiple
10950  spaces preceding them.
10951  Awk doesn't care, the multiple spaces are a convention to help us humans.
10952 \end_layout
10954 \begin_layout Chunk
10955 getopt.awk-getopt()
10956 \end_layout
10958 \begin_layout Standard
10959 \begin_inset listings
10960 inline false
10961 status open
10963 \begin_layout Plain Layout
10965 function getopt(argc, argv, options,    thisopt, i)
10966 \end_layout
10968 \begin_layout Plain Layout
10971 \end_layout
10973 \begin_layout Plain Layout
10975     if (length(options) == 0)    # no options given
10976 \end_layout
10978 \begin_layout Plain Layout
10980         return -1
10981 \end_layout
10983 \begin_layout Plain Layout
10985     if (argv[Optind] == "--") {  # all done
10986 \end_layout
10988 \begin_layout Plain Layout
10990         Optind++
10991 \end_layout
10993 \begin_layout Plain Layout
10995         _opti = 0
10996 \end_layout
10998 \begin_layout Plain Layout
11000         return -1
11001 \end_layout
11003 \begin_layout Plain Layout
11005     } else if (argv[Optind] !~ /^-[^: 
11006 \backslash
11008 \backslash
11010 \backslash
11012 \backslash
11014 \backslash
11016 \backslash
11017 b]/) {
11018 \end_layout
11020 \begin_layout Plain Layout
11022         _opti = 0
11023 \end_layout
11025 \begin_layout Plain Layout
11027         return -1
11028 \end_layout
11030 \begin_layout Plain Layout
11032     }
11033 \end_layout
11035 \begin_layout Plain Layout
11037     if (_opti == 0)
11038 \end_layout
11040 \begin_layout Plain Layout
11042         _opti = 2
11043 \end_layout
11045 \begin_layout Plain Layout
11047     thisopt = substr(argv[Optind], _opti, 1)
11048 \end_layout
11050 \begin_layout Plain Layout
11052     Optopt = thisopt
11053 \end_layout
11055 \begin_layout Plain Layout
11057     i = index(options, thisopt)
11058 \end_layout
11060 \begin_layout Plain Layout
11062     if (i == 0) {
11063 \end_layout
11065 \begin_layout Plain Layout
11067         if (Opterr)
11068 \end_layout
11070 \begin_layout Plain Layout
11072             printf("%c -- invalid option
11073 \backslash
11075 \end_layout
11077 \begin_layout Plain Layout
11079                                   thisopt) > "/dev/stderr"
11080 \end_layout
11082 \begin_layout Plain Layout
11084         if (_opti >= length(argv[Optind])) {
11085 \end_layout
11087 \begin_layout Plain Layout
11089             Optind++
11090 \end_layout
11092 \begin_layout Plain Layout
11094             _opti = 0
11095 \end_layout
11097 \begin_layout Plain Layout
11099         } else
11100 \end_layout
11102 \begin_layout Plain Layout
11104             _opti++
11105 \end_layout
11107 \begin_layout Plain Layout
11109         return "?"
11110 \end_layout
11112 \begin_layout Plain Layout
11114     }
11115 \end_layout
11117 \end_inset
11120 \end_layout
11122 \begin_layout Standard
11123 At this point, the option has been found and we need to know if it takes
11124  any arguments.
11125 \end_layout
11127 \begin_layout Standard
11128 \begin_inset listings
11129 inline false
11130 status open
11132 \begin_layout Plain Layout
11134     if (substr(options, i + 1, 1) == ":") {
11135 \end_layout
11137 \begin_layout Plain Layout
11139         # get option argument
11140 \end_layout
11142 \begin_layout Plain Layout
11144         if (length(substr(argv[Optind], _opti + 1)) > 0)
11145 \end_layout
11147 \begin_layout Plain Layout
11149             Optarg = substr(argv[Optind], _opti + 1)
11150 \end_layout
11152 \begin_layout Plain Layout
11154         else
11155 \end_layout
11157 \begin_layout Plain Layout
11159             Optarg = argv[++Optind]
11160 \end_layout
11162 \begin_layout Plain Layout
11164         _opti = 0
11165 \end_layout
11167 \begin_layout Plain Layout
11169     } else
11170 \end_layout
11172 \begin_layout Plain Layout
11174         Optarg = ""
11175 \end_layout
11177 \begin_layout Plain Layout
11179     if (_opti == 0 || _opti >= length(argv[Optind])) {
11180 \end_layout
11182 \begin_layout Plain Layout
11184         Optind++
11185 \end_layout
11187 \begin_layout Plain Layout
11189         _opti = 0
11190 \end_layout
11192 \begin_layout Plain Layout
11194     } else
11195 \end_layout
11197 \begin_layout Plain Layout
11199         _opti++
11200 \end_layout
11202 \begin_layout Plain Layout
11204     return thisopt
11205 \end_layout
11207 \begin_layout Plain Layout
11210 \end_layout
11212 \end_inset
11214 A test program is built in, too
11215 \end_layout
11217 \begin_layout Chunk
11218 getopt.awk-begin
11219 \end_layout
11221 \begin_layout Standard
11222 \begin_inset listings
11223 inline false
11224 status open
11226 \begin_layout Plain Layout
11228 BEGIN {
11229 \end_layout
11231 \begin_layout Plain Layout
11233     Opterr = 1    # default is to diagnose
11234 \end_layout
11236 \begin_layout Plain Layout
11238     Optind = 1    # skip ARGV[0]
11239 \end_layout
11241 \begin_layout Plain Layout
11243     # test program
11244 \end_layout
11246 \begin_layout Plain Layout
11248     if (_getopt_test) {
11249 \end_layout
11251 \begin_layout Plain Layout
11253         while ((_go_c = getopt(ARGC, ARGV, "ab:cd")) != -1)
11254 \end_layout
11256 \begin_layout Plain Layout
11258             printf("c = <%c>, optarg = <%s>
11259 \backslash
11261 \end_layout
11263 \begin_layout Plain Layout
11265                                        _go_c, Optarg)
11266 \end_layout
11268 \begin_layout Plain Layout
11270         printf("non-option arguments:
11271 \backslash
11273 \end_layout
11275 \begin_layout Plain Layout
11277         for (; Optind < ARGC; Optind++)
11278 \end_layout
11280 \begin_layout Plain Layout
11282             printf("
11283 \backslash
11284 tARGV[%d] = <%s>
11285 \backslash
11287 \end_layout
11289 \begin_layout Plain Layout
11291                                     Optind, ARGV[Optind])
11292 \end_layout
11294 \begin_layout Plain Layout
11296     }
11297 \end_layout
11299 \begin_layout Plain Layout
11302 \end_layout
11304 \end_inset
11307 \end_layout
11309 \begin_layout Standard
11310 The entire getopt.awk is made out of these chunks in order
11311 \end_layout
11313 \begin_layout Chunk
11314 getopt.awk
11315 \end_layout
11317 \begin_layout Standard
11318 \begin_inset listings
11319 inline false
11320 status open
11322 \begin_layout Plain Layout
11325 \backslash
11326 chunkref{getopt.awk-header}>
11327 \end_layout
11329 \begin_layout Plain Layout
11331 \end_layout
11333 \begin_layout Plain Layout
11336 \backslash
11337 chunkref{getopt.awk-notes}>
11338 \end_layout
11340 \begin_layout Plain Layout
11343 \backslash
11344 chunkref{getopt.awk-getopt()}>
11345 \end_layout
11347 \begin_layout Plain Layout
11350 \backslash
11351 chunkref{getopt.awk-begin}>
11352 \end_layout
11354 \end_inset
11357 \end_layout
11359 \begin_layout Standard
11360 Although we only want the header and function:
11361 \end_layout
11363 \begin_layout Chunk
11364 getopt
11365 \end_layout
11367 \begin_layout Standard
11368 \begin_inset listings
11369 inline false
11370 status open
11372 \begin_layout Plain Layout
11374 # try: locate getopt.awk for the full original file
11375 \end_layout
11377 \begin_layout Plain Layout
11379 # as part of your standard awk installation
11380 \end_layout
11382 \begin_layout Plain Layout
11385 \backslash
11386 chunkref{getopt.awk-header}>
11387 \end_layout
11389 \begin_layout Plain Layout
11391 \end_layout
11393 \begin_layout Plain Layout
11396 \backslash
11397 chunkref{getopt.awk-getopt()}>
11398 \end_layout
11400 \end_inset
11403 \end_layout
11405 \begin_layout Chapter
11406 Newfangle LaTeX source code
11407 \end_layout
11409 \begin_layout Section
11410 newfangle module
11411 \end_layout
11413 \begin_layout Standard
11414 Here we define a Lyx .module file that makes it convenient to use LyX for
11415  writing such literate programs.
11416 \end_layout
11418 \begin_layout Standard
11419 This file 
11420 \begin_inset Flex CharStyle:Code
11421 status collapsed
11423 \begin_layout Plain Layout
11424 ./newfangle.module
11425 \end_layout
11427 \end_inset
11429  can be installed in your personal 
11430 \begin_inset Flex CharStyle:Code
11431 status collapsed
11433 \begin_layout Plain Layout
11434 .lyx/layouts folder
11435 \end_layout
11437 \end_inset
11440  You will need to Tools Reconfigure so that LyX notices it.
11441  It adds a new format Chunk, which should precede every listing and contain
11442  the chunk name.
11444 \end_layout
11446 \begin_layout Chunk
11447 ./newfangle.module,language=
11448 \end_layout
11450 \begin_layout Standard
11451 \begin_inset listings
11452 inline false
11453 status open
11455 \begin_layout Plain Layout
11458 \backslash
11459 DeclareLyXModule{Newfangle Literate Listings}
11460 \end_layout
11462 \begin_layout Plain Layout
11464 #DescriptionBegin
11465 \end_layout
11467 \begin_layout Plain Layout
11469 #  Newfangle literate listings allow one to write
11470 \end_layout
11472 \begin_layout Plain Layout
11474 #   literate programs after the fashion of noweb, but without having
11475 \end_layout
11477 \begin_layout Plain Layout
11479 #   to use noweave to generate the documentation.
11480  Instead the listings
11481 \end_layout
11483 \begin_layout Plain Layout
11485 #   package is extended in conjunction with the noweb package to implement
11486 \end_layout
11488 \begin_layout Plain Layout
11490 #   to code formating directly as latex.
11491 \end_layout
11493 \begin_layout Plain Layout
11495 #  The newfangle awk script
11496 \end_layout
11498 \begin_layout Plain Layout
11500 #DescriptionEnd
11501 \end_layout
11503 \begin_layout Plain Layout
11505 \end_layout
11507 \begin_layout Plain Layout
11509 Format 11
11510 \end_layout
11512 \begin_layout Plain Layout
11514 \end_layout
11516 \begin_layout Plain Layout
11518 AddToPreamble
11519 \end_layout
11521 \begin_layout Plain Layout
11524 \backslash
11525 chunkref{./newfangle.sty}>
11526 \end_layout
11528 \begin_layout Plain Layout
11530 EndPreamble
11531 \end_layout
11533 \begin_layout Plain Layout
11535 \end_layout
11537 \begin_layout Plain Layout
11540 \backslash
11541 chunkref{chunkstyle}>
11542 \end_layout
11544 \begin_layout Plain Layout
11546 \end_layout
11548 \begin_layout Plain Layout
11551 \backslash
11552 chunkref{chunkref}>
11553 \end_layout
11555 \end_inset
11558 \end_layout
11560 \begin_layout Subsection
11561 The Chunk style
11562 \end_layout
11564 \begin_layout Standard
11565 The purpose of the 
11566 \noun on
11567 chunk
11568 \noun default
11569  style is to make it easier for LyX users to provide the name to 
11570 \begin_inset Flex CharStyle:Code
11571 status collapsed
11573 \begin_layout Plain Layout
11575 \backslash
11576 lstlistings
11577 \end_layout
11579 \end_inset
11582  Normally this requires right-clicking on the listing, choosing settings,
11583  advanced, and then typing 
11584 \begin_inset Flex CharStyle:Code
11585 status collapsed
11587 \begin_layout Plain Layout
11588 name=chunk-name
11589 \end_layout
11591 \end_inset
11594  This has the further disadvantage that the name (and other options) are
11595  not generally visible during document editing.
11596 \end_layout
11598 \begin_layout Standard
11599 The chunk style is defined as a LaTeX command, so that all text on the same
11600  line is passed to the LaTeX command 
11601 \begin_inset Flex CharStyle:Code
11602 status collapsed
11604 \begin_layout Plain Layout
11605 Chunk
11606 \end_layout
11608 \end_inset
11611  This makes it easy to parse using 
11612 \begin_inset Flex CharStyle:Code
11613 status collapsed
11615 \begin_layout Plain Layout
11616 newfangle
11617 \end_layout
11619 \end_inset
11621 , and easy to pass these options on to the listings package.
11622  The first word in a chunk section should be the chunk name, and will have
11624 \begin_inset Flex CharStyle:Code
11625 status collapsed
11627 \begin_layout Plain Layout
11628 name=
11629 \end_layout
11631 \end_inset
11633  prepended to it.
11634  Any other words are accepted arguments to 
11635 \begin_inset Flex CharStyle:Code
11636 status collapsed
11638 \begin_layout Plain Layout
11640 \backslash
11641 lstset
11642 \end_layout
11644 \end_inset
11647 \end_layout
11649 \begin_layout Standard
11650 We set PassThru to 1 because the user is actually entering raw latex.
11651 \end_layout
11653 \begin_layout Chunk
11654 chunkstyle
11655 \end_layout
11657 \begin_layout Standard
11658 \begin_inset listings
11659 inline false
11660 status open
11662 \begin_layout Plain Layout
11664 Style Chunk
11665 \end_layout
11667 \begin_layout Plain Layout
11669   LatexType             Command
11670 \end_layout
11672 \begin_layout Plain Layout
11674   LatexName             Chunk
11675 \end_layout
11677 \begin_layout Plain Layout
11679   Margin                First_Dynamic
11680 \end_layout
11682 \begin_layout Plain Layout
11684   LeftMargin            Chunk:xxx
11685 \end_layout
11687 \begin_layout Plain Layout
11689   LabelSep              xx
11690 \end_layout
11692 \begin_layout Plain Layout
11694   LabelType             Static
11695 \end_layout
11697 \begin_layout Plain Layout
11699   LabelString           "Chunk:"
11700 \end_layout
11702 \begin_layout Plain Layout
11704   Align                 Left
11705 \end_layout
11707 \begin_layout Plain Layout
11709   PassThru              1
11710 \end_layout
11712 \begin_layout Plain Layout
11714 \end_layout
11716 \end_inset
11719 \end_layout
11721 \begin_layout Standard
11722 To make the label very visible we choose a larger font coloured red.
11723 \end_layout
11725 \begin_layout Standard
11726 \begin_inset listings
11727 inline false
11728 status open
11730 \begin_layout Plain Layout
11732   LabelFont
11733 \end_layout
11735 \begin_layout Plain Layout
11737     Family              Sans
11738 \end_layout
11740 \begin_layout Plain Layout
11742     Size                Large
11743 \end_layout
11745 \begin_layout Plain Layout
11747     Series              Bold
11748 \end_layout
11750 \begin_layout Plain Layout
11752     Shape               Italic
11753 \end_layout
11755 \begin_layout Plain Layout
11757     Color               red
11758 \end_layout
11760 \begin_layout Plain Layout
11762   EndFont
11763 \end_layout
11765 \begin_layout Plain Layout
11768 \end_layout
11770 \end_inset
11773 \end_layout
11775 \begin_layout Subsection
11776 The chunkref style
11777 \end_layout
11779 \begin_layout Standard
11780 We also define the Chunkref style which can be used to express cross references
11781  to chunks.
11782 \end_layout
11784 \begin_layout Chunk
11785 chunkref
11786 \end_layout
11788 \begin_layout Standard
11789 \begin_inset listings
11790 inline false
11791 status open
11793 \begin_layout Plain Layout
11795 InsetLayout Chunkref
11796 \end_layout
11798 \begin_layout Plain Layout
11800   LyxType               charstyle
11801 \end_layout
11803 \begin_layout Plain Layout
11805   LatexType             Command
11806 \end_layout
11808 \begin_layout Plain Layout
11810   LatexName             chunkref
11811 \end_layout
11813 \begin_layout Plain Layout
11815   PassThru              1
11816 \end_layout
11818 \begin_layout Plain Layout
11820   LabelFont             
11821 \end_layout
11823 \begin_layout Plain Layout
11825     Shape               Italic
11826 \end_layout
11828 \begin_layout Plain Layout
11830     Color               red
11831 \end_layout
11833 \begin_layout Plain Layout
11835   EndFont
11836 \end_layout
11838 \begin_layout Plain Layout
11841 \end_layout
11843 \end_inset
11846 \end_layout
11848 \begin_layout Section
11849 \begin_inset CommandInset label
11850 LatexCommand label
11851 name "sec:Latex-Macros"
11853 \end_inset
11855 Latex Macros
11856 \end_layout
11858 \begin_layout Standard
11859 We require the 
11860 \noun on
11861 listings
11862 \noun default
11864 \noun on
11865 noweb
11866 \noun default
11867  and 
11868 \noun on
11869 xargs
11870 \noun default
11871  packages.
11872  As noweb defines it's own 
11873 \begin_inset Flex CharStyle:Code
11874 status collapsed
11876 \begin_layout Plain Layout
11878 \backslash
11879 code
11880 \end_layout
11882 \end_inset
11884  environment, we re-define the one that LyX logical markup module expects
11885  here.
11886 \end_layout
11888 \begin_layout Chunk
11889 ./newfangle.sty,language=tex,basicstyle=
11890 \backslash
11891 ttfamily
11892 \end_layout
11894 \begin_layout Standard
11895 \begin_inset listings
11896 inline false
11897 status open
11899 \begin_layout Plain Layout
11902 \backslash
11903 usepackage{listings}%
11904 \end_layout
11906 \begin_layout Plain Layout
11909 \backslash
11910 usepackage{noweb}%
11911 \end_layout
11913 \begin_layout Plain Layout
11916 \backslash
11917 usepackage{xargs}%
11918 \end_layout
11920 \begin_layout Plain Layout
11923 \backslash
11924 renewcommand{
11925 \backslash
11926 code}[1]{
11927 \backslash
11928 texttt{#1}}%
11929 \end_layout
11931 \end_inset
11934 \end_layout
11936 \begin_layout Standard
11937 We also define a 
11938 \begin_inset Flex CharStyle:Code
11939 status collapsed
11941 \begin_layout Plain Layout
11942 CChunk
11943 \end_layout
11945 \end_inset
11947  macro, for use as: 
11948 \begin_inset Flex CharStyle:Code
11949 status collapsed
11951 \begin_layout Plain Layout
11953 \backslash
11954 begin{CChunk}
11955 \end_layout
11957 \end_inset
11959  which will need renaming to 
11960 \begin_inset Flex CharStyle:Code
11961 status collapsed
11963 \begin_layout Plain Layout
11965 \backslash
11966 begin{Chunk}
11967 \end_layout
11969 \end_inset
11971  when I can do this without clashing with 
11972 \begin_inset Flex CharStyle:Code
11973 status collapsed
11975 \begin_layout Plain Layout
11977 \backslash
11978 Chunk
11979 \end_layout
11981 \end_inset
11984 \end_layout
11986 \begin_layout Standard
11987 \begin_inset listings
11988 inline false
11989 status open
11991 \begin_layout Plain Layout
11994 \backslash
11995 lstnewenvironment{Chunk}{
11996 \backslash
11997 relax}{
11998 \backslash
11999 relax}%
12000 \end_layout
12002 \end_inset
12005 \end_layout
12007 \begin_layout Standard
12008 We also define a suitable 
12009 \begin_inset Flex CharStyle:Code
12010 status collapsed
12012 \begin_layout Plain Layout
12014 \backslash
12015 lstset
12016 \end_layout
12018 \end_inset
12020  of parameters that suit the literate programming style after the fashion
12021  of 
12022 \noun on
12023 noweave
12024 \noun default
12026 \end_layout
12028 \begin_layout Standard
12029 \begin_inset listings
12030 inline false
12031 status open
12033 \begin_layout Plain Layout
12036 \backslash
12037 lstset{numbers=left, stepnumber=5, numbersep=5pt,
12038 \end_layout
12040 \begin_layout Plain Layout
12042         breaklines=false,basicstyle=
12043 \backslash
12044 ttfamily,
12045 \end_layout
12047 \begin_layout Plain Layout
12049         numberstyle=
12050 \backslash
12051 tiny, language=C}%
12052 \end_layout
12054 \end_inset
12057 \end_layout
12059 \begin_layout Standard
12060 We also define a notangle-like mechanism for 
12061 \emph on
12062 escaping
12063 \emph default
12064  to LaTeX from the listing, and by which we can refer to other listings.
12065  We declare the 
12066 \begin_inset Flex CharStyle:Code
12067 status collapsed
12069 \begin_layout Plain Layout
12070 =<\SpecialChar \ldots{}
12072 \end_layout
12074 \end_inset
12076  sequence to contain LaTeX code, and include another like this chunk: 
12077 \begin_inset Flex CharStyle:Code
12078 status collapsed
12080 \begin_layout Plain Layout
12082 \backslash
12083 chunkref{chunkname}>
12084 \end_layout
12086 \end_inset
12089  However, because 
12090 \begin_inset Flex CharStyle:Code
12091 status collapsed
12093 \begin_layout Plain Layout
12094 =<\SpecialChar \ldots{}
12096 \end_layout
12098 \end_inset
12100  is already defined to contain LaTeX code for this document --- this is
12101  a 
12102 \noun on
12103 newfangle
12104 \noun default
12105  document after all --- the code fragment below effectively contains the
12106  LaTeX code: 
12107 \begin_inset Flex CharStyle:Code
12108 status collapsed
12110 \begin_layout Plain Layout
12112 \end_layout
12114 \end_inset
12117  To avoid problems with document generation, I had to declare an lstlistings
12118  property: 
12119 \begin_inset Flex CharStyle:Code
12120 status collapsed
12122 \begin_layout Plain Layout
12123 escapeinside={}
12124 \end_layout
12126 \end_inset
12128  for this listing only; which in LyX was done by right-clicking the listings
12129  inset, choosing 
12130 \begin_inset Flex CharStyle:Code
12131 status collapsed
12133 \begin_layout Plain Layout
12134 settings
12135 \end_layout
12137 \end_inset
12139 \SpecialChar \menuseparator
12141 \begin_inset Flex CharStyle:Code
12142 status collapsed
12144 \begin_layout Plain Layout
12145 advanced
12146 \end_layout
12148 \end_inset
12151 \end_layout
12153 \begin_layout Standard
12154 \begin_inset Note Note
12155 status collapsed
12157 \begin_layout Plain Layout
12158 =< isn't enjoyed literally here, in a listing when the escape sequence is
12159  already defined as shown...
12160  we need to somehow escape this representation...
12161 \end_layout
12163 \end_inset
12166 \end_layout
12168 \begin_layout Standard
12169 \begin_inset listings
12170 lstparams "escapeinside={}"
12171 inline false
12172 status open
12174 \begin_layout Plain Layout
12177 \backslash
12178 lstset{escapeinside={=<}{>}}%
12179 \end_layout
12181 \end_inset
12184 \end_layout
12186 \begin_layout Standard
12187 Although our macros will contain the @ symbol, they will be included in
12188  a 
12189 \begin_inset Flex CharStyle:Code
12190 status collapsed
12192 \begin_layout Plain Layout
12194 \backslash
12195 makeatletter
12196 \end_layout
12198 \end_inset
12200  section by LyX; however we keep the commented out 
12201 \begin_inset Flex CharStyle:Code
12202 status collapsed
12204 \begin_layout Plain Layout
12206 \backslash
12207 makeatletter
12208 \end_layout
12210 \end_inset
12212  as a reminder.
12213  The listings package likes to centre the titles, but noweb titles are specially
12214  formatted and must be left aligned.
12215  The simplest way to do this turned out to be by removing the definition
12216  of 
12217 \begin_inset Flex CharStyle:Code
12218 status collapsed
12220 \begin_layout Plain Layout
12222 \backslash
12223 lst@maketitle
12224 \end_layout
12226 \end_inset
12229  This may interact badly if other listings want a regular title or caption.
12230  We remember the old maketitle in case we need it.
12231 \end_layout
12233 \begin_layout Standard
12234 \begin_inset listings
12235 inline false
12236 status open
12238 \begin_layout Plain Layout
12241 \backslash
12242 makeatletter
12243 \end_layout
12245 \begin_layout Plain Layout
12247 %somehow re-defining maketitle gives us a left-aligned title
12248 \end_layout
12250 \begin_layout Plain Layout
12252 %which is extactly what our specially formatted title needs!
12253 \end_layout
12255 \begin_layout Plain Layout
12258 \backslash
12259 global
12260 \backslash
12262 \backslash
12263 newfangle@lst@maketitle
12264 \backslash
12265 lst@maketitle%
12266 \end_layout
12268 \begin_layout Plain Layout
12271 \backslash
12272 global
12273 \backslash
12275 \backslash
12276 lst@maketitle{}%
12277 \end_layout
12279 \end_inset
12282 \end_layout
12284 \begin_layout Subsection
12285 \begin_inset CommandInset label
12286 LatexCommand label
12287 name "sub:The-chunk-command"
12289 \end_inset
12291 The chunk command
12292 \end_layout
12294 \begin_layout Standard
12295 Our chunk command accepts one argument, and calls 
12296 \begin_inset Flex CharStyle:Code
12297 status collapsed
12299 \begin_layout Plain Layout
12301 \backslash
12302 ltset
12303 \end_layout
12305 \end_inset
12308  Although 
12309 \begin_inset Flex CharStyle:Code
12310 status collapsed
12312 \begin_layout Plain Layout
12314 \backslash
12315 ltset
12316 \end_layout
12318 \end_inset
12320  will note the name, this is erased when the next 
12321 \begin_inset Flex CharStyle:Code
12322 status collapsed
12324 \begin_layout Plain Layout
12326 \backslash
12327 lstlisting
12328 \end_layout
12330 \end_inset
12332  starts, so we make a note of this in 
12333 \begin_inset Flex CharStyle:Code
12334 status collapsed
12336 \begin_layout Plain Layout
12338 \backslash
12339 lst@chunkname
12340 \end_layout
12342 \end_inset
12344  and restore in in lstlistings Init hook.
12345 \end_layout
12347 \begin_layout Standard
12348 \begin_inset listings
12349 inline false
12350 status open
12352 \begin_layout Plain Layout
12355 \backslash
12357 \backslash
12358 Chunk#1{%
12359 \end_layout
12361 \begin_layout Plain Layout
12363   
12364 \backslash
12365 lstset{title={
12366 \backslash
12367 newfanglecaption},name=#1}%
12368 \end_layout
12370 \begin_layout Plain Layout
12372   
12373 \backslash
12374 global
12375 \backslash
12376 edef
12377 \backslash
12378 lst@chunkname{
12379 \backslash
12380 lst@intname}%
12381 \end_layout
12383 \begin_layout Plain Layout
12386 \end_layout
12388 \begin_layout Plain Layout
12391 \backslash
12393 \backslash
12394 lst@chunkname{
12395 \backslash
12396 empty}%
12397 \end_layout
12399 \end_inset
12402 \end_layout
12404 \begin_layout Subsubsection
12405 Chunk parameters
12406 \end_layout
12408 \begin_layout Standard
12409 Newfangle permits parameterized chunks, and requires the paramters to be
12410  specified as listings options.
12411  The newfangle script uses this, and although we don't do anything with
12412  these in the LaTeX code right now, we need to stop the listings package
12413  complaining.
12414 \end_layout
12416 \begin_layout Standard
12417 \begin_inset listings
12418 inline false
12419 status open
12421 \begin_layout Plain Layout
12424 \backslash
12425 lst@Key{params}
12426 \backslash
12427 relax{
12428 \backslash
12430 \backslash
12431 newfangle@chunk@params{#1}}%
12432 \end_layout
12434 \end_inset
12437 \end_layout
12439 \begin_layout Standard
12440 As it is common to define a chunk which then needs appending to another
12441  chunk, and annoying to have to declare a single line chunk to manage the
12442  include, we support an 
12443 \begin_inset Flex CharStyle:Code
12444 status collapsed
12446 \begin_layout Plain Layout
12447 append=
12448 \end_layout
12450 \end_inset
12452  option.
12454 \end_layout
12456 \begin_layout Standard
12457 \begin_inset listings
12458 inline false
12459 status open
12461 \begin_layout Plain Layout
12464 \backslash
12465 lst@Key{append}
12466 \backslash
12467 relax{
12468 \backslash
12470 \backslash
12471 newfangle@chunk@append{#1}}%
12472 \end_layout
12474 \end_inset
12477 \end_layout
12479 \begin_layout Subsection
12480 The noweb styled caption
12481 \end_layout
12483 \begin_layout Standard
12484 We define a public macro 
12485 \begin_inset Flex CharStyle:Code
12486 status collapsed
12488 \begin_layout Plain Layout
12490 \backslash
12491 newfanglecaption
12492 \end_layout
12494 \end_inset
12496  which can be set as a regular title.
12497  By means of 
12498 \begin_inset Flex CharStyle:Code
12499 status collapsed
12501 \begin_layout Plain Layout
12503 \backslash
12504 protect
12505 \end_layout
12507 \end_inset
12509 , It expands to 
12510 \begin_inset Flex CharStyle:Code
12511 status collapsed
12513 \begin_layout Plain Layout
12515 \backslash
12516 newfangle@caption
12517 \end_layout
12519 \end_inset
12521  at the appriate time when the caption is emitted.
12522 \end_layout
12524 \begin_layout Standard
12525 \begin_inset listings
12526 inline false
12527 status open
12529 \begin_layout Plain Layout
12532 \backslash
12534 \backslash
12535 newfanglecaption{
12536 \backslash
12537 protect
12538 \backslash
12539 newfangle@caption}%
12540 \end_layout
12542 \end_inset
12545 \end_layout
12547 \begin_layout Standard
12548 \begin_inset Float figure
12549 placement H
12550 wide false
12551 sideways false
12552 status collapsed
12554 \begin_layout Plain Layout
12555 \begin_inset Box Boxed
12556 position "t"
12557 hor_pos "c"
12558 has_inner_box 1
12559 inner_pos "t"
12560 use_parbox 0
12561 width "100col%"
12562 special "none"
12563 height "1in"
12564 height_special "totalheight"
12565 status open
12567 \begin_layout Plain Layout
12569 \begin_inset space \qquad{}
12570 \end_inset
12573 \shape italic
12574 some-chunk
12575 \shape default
12576  19b⟩
12577 \begin_inset Formula $\equiv+$
12578 \end_inset
12581 \begin_inset space \qquad{}
12582 \end_inset
12585 \begin_inset space \qquad{}
12586 \end_inset
12589 \begin_inset space \qquad{}
12590 \end_inset
12593 \begin_inset Formula $\triangleleft$
12594 \end_inset
12597 \begin_inset space \quad{}
12598 \end_inset
12601 \begin_inset Formula $\triangleright$
12602 \end_inset
12605 \end_layout
12607 \begin_layout Plain Layout
12609 \size footnotesize
12610 In this example, the current chunk is 22c, and therefore the third chunk
12611  on page 22.
12612 \end_layout
12614 \begin_layout Plain Layout
12616 \size footnotesize
12617 It's name is 
12618 \emph on
12619 some-chunk
12620 \emph default
12623 \end_layout
12625 \begin_layout Plain Layout
12627 \size footnotesize
12628 The first chunk with this name (19b) occurs as the second chunk on page
12629  19.
12630 \end_layout
12632 \begin_layout Plain Layout
12634 \size footnotesize
12635 The previous chunk (22d) with the same name is the second chunk on page
12636  22.
12637 \end_layout
12639 \begin_layout Plain Layout
12641 \size footnotesize
12642 The next chunk (24d) is the fourth chunk on page 24.
12643 \end_layout
12645 \begin_layout Plain Layout
12646 \begin_inset Caption
12648 \begin_layout Plain Layout
12649 noweb heading
12650 \end_layout
12652 \end_inset
12655 \end_layout
12657 \end_inset
12660 \end_layout
12662 \end_inset
12664 The general noweb output format compactly identifies the current chunk,
12665  and references to the first chunk, and the previous and next chunks that
12666  have the same name.
12668 \end_layout
12670 \begin_layout Standard
12671 This means that we need to keep a counter for each chunk-name, that we use
12672  to count chunks of the same name.
12674 \end_layout
12676 \begin_layout Subsection
12677 The chunk counter
12678 \end_layout
12680 \begin_layout Standard
12681 It would be natural to have a counter for each chunk name, but TeX would
12682  soon run out of counters
12683 \begin_inset Foot
12684 status collapsed
12686 \begin_layout Plain Layout
12687 \SpecialChar \ldots{}
12688 soon 
12689 \emph on
12691 \emph default
12692  run out of counters and so I had to re-write the LaTeX macros to share
12693  a counter as described here
12694 \end_layout
12696 \end_inset
12698 , so we have one counter which we save at the end of a chunk and restore
12699  at the beginning of a chunk.
12700 \end_layout
12702 \begin_layout Standard
12703 \begin_inset listings
12704 inline false
12705 status open
12707 \begin_layout Plain Layout
12710 \backslash
12711 newcounter{newfangle@chunkcounter}%
12712 \end_layout
12714 \end_inset
12717 \end_layout
12719 \begin_layout Standard
12720 We construct the name of this variable to store the counter to be the text
12722 \begin_inset Flex CharStyle:Code
12723 status collapsed
12725 \begin_layout Plain Layout
12726 lst-chunk-
12727 \end_layout
12729 \end_inset
12731  prefixed onto the chunks own name, and store it in 
12732 \begin_inset Flex CharStyle:Code
12733 status collapsed
12735 \begin_layout Plain Layout
12737 \backslash
12738 chunkcount
12739 \end_layout
12741 \end_inset
12745 \end_layout
12747 \begin_layout Standard
12748 We save the counter like this:
12749 \end_layout
12751 \begin_layout Chunk
12752 save-counter
12753 \end_layout
12755 \begin_layout Standard
12756 \begin_inset listings
12757 inline false
12758 status open
12760 \begin_layout Plain Layout
12763 \backslash
12764 global
12765 \backslash
12766 expandafter
12767 \backslash
12768 edef
12769 \backslash
12770 csname 
12771 \backslash
12772 chunkcount
12773 \backslash
12774 endcsname{
12775 \backslash
12776 arabic{newfangle@chunkcounter}}%
12777 \end_layout
12779 \end_inset
12782 \end_layout
12784 \begin_layout Standard
12785 and restore the counter like this:
12786 \end_layout
12788 \begin_layout Chunk
12789 restore-counter
12790 \end_layout
12792 \begin_layout Standard
12793 \begin_inset listings
12794 inline false
12795 status open
12797 \begin_layout Plain Layout
12800 \backslash
12801 setcounter{newfangle@chunkcounter}{
12802 \backslash
12803 csname 
12804 \backslash
12805 chunkcount
12806 \backslash
12807 endcsname}%
12808 \end_layout
12810 \end_inset
12813 \end_layout
12815 \begin_layout Chunk
12816 ./newfangle.sty
12817 \end_layout
12819 \begin_layout Standard
12820 If there does not already exist a variable whose name is stored in 
12821 \begin_inset Flex CharStyle:Code
12822 status collapsed
12824 \begin_layout Plain Layout
12826 \backslash
12827 chunkcount
12828 \end_layout
12830 \end_inset
12832 , then we know we are the first chunk with this name, and then define a
12833  counter.
12835 \end_layout
12837 \begin_layout Standard
12838 Although chunks of the same name share a common counter, they must still
12839  be distinguished.
12840  We use is the internal name of the listing, suffixed by the counter value.
12841  So the first chunk might be 
12842 \begin_inset Flex CharStyle:Code
12843 status collapsed
12845 \begin_layout Plain Layout
12846 something-1
12847 \end_layout
12849 \end_inset
12851  and the second chunk be 
12852 \begin_inset Flex CharStyle:Code
12853 status collapsed
12855 \begin_layout Plain Layout
12856 something-2
12857 \end_layout
12859 \end_inset
12861 , etc.
12862 \end_layout
12864 \begin_layout Standard
12865 We also calculate the name of the previous chunk if we can (before we increment
12866  the chunk counter).
12867  If this is the first chunk of that name, then 
12868 \begin_inset Flex CharStyle:Code
12869 status collapsed
12871 \begin_layout Plain Layout
12873 \backslash
12874 prevchunkname
12875 \end_layout
12877 \end_inset
12879  is set to 
12880 \begin_inset Flex CharStyle:Code
12881 status collapsed
12883 \begin_layout Plain Layout
12885 \backslash
12886 relax
12887 \end_layout
12889 \end_inset
12891  which the noweb package will interpret as not existing.
12892 \end_layout
12894 \begin_layout Standard
12895 \begin_inset listings
12896 inline false
12897 status open
12899 \begin_layout Plain Layout
12902 \backslash
12904 \backslash
12905 newfangle@caption{%
12906 \end_layout
12908 \begin_layout Plain Layout
12910   
12911 \backslash
12912 edef
12913 \backslash
12914 chunkcount{lst-chunk-
12915 \backslash
12916 lst@intname}%
12917 \end_layout
12919 \begin_layout Plain Layout
12921   
12922 \backslash
12923 @ifundefined{
12924 \backslash
12925 chunkcount}{%
12926 \end_layout
12928 \begin_layout Plain Layout
12930     
12931 \backslash
12932 expandafter
12933 \backslash
12934 gdef
12935 \backslash
12936 csname 
12937 \backslash
12938 chunkcount
12939 \backslash
12940 endcsname{0}%
12941 \end_layout
12943 \begin_layout Plain Layout
12945     
12946 \backslash
12947 setcounter{newfangle@chunkcounter}{
12948 \backslash
12949 csname 
12950 \backslash
12951 chunkcount
12952 \backslash
12953 endcsname}%
12954 \end_layout
12956 \begin_layout Plain Layout
12958     
12959 \backslash
12961 \backslash
12962 prevchunkname
12963 \backslash
12964 relax%
12965 \end_layout
12967 \begin_layout Plain Layout
12969   }{%
12970 \end_layout
12972 \begin_layout Plain Layout
12974     
12975 \backslash
12976 setcounter{newfangle@chunkcounter}{
12977 \backslash
12978 csname 
12979 \backslash
12980 chunkcount
12981 \backslash
12982 endcsname}%
12983 \end_layout
12985 \begin_layout Plain Layout
12987     
12988 \backslash
12989 edef
12990 \backslash
12991 prevchunkname{
12992 \backslash
12993 lst@intname-
12994 \backslash
12995 arabic{newfangle@chunkcounter}}%
12996 \end_layout
12998 \begin_layout Plain Layout
13000   }%
13001 \end_layout
13003 \end_inset
13006 \end_layout
13008 \begin_layout Standard
13009 After incrementing the chunk counter, we then define the name of this chunk,
13010  as well as the name of the first chunk.
13011 \end_layout
13013 \begin_layout Standard
13014 \begin_inset listings
13015 inline false
13016 status open
13018 \begin_layout Plain Layout
13020   
13021 \backslash
13022 addtocounter{newfangle@chunkcounter}{1}%
13023 \end_layout
13025 \begin_layout Plain Layout
13027   
13028 \backslash
13029 global
13030 \backslash
13031 expandafter
13032 \backslash
13033 edef
13034 \backslash
13035 csname 
13036 \backslash
13037 chunkcount
13038 \backslash
13039 endcsname{
13040 \backslash
13041 arabic{newfangle@chunkcounter}}%
13042 \end_layout
13044 \begin_layout Plain Layout
13046   
13047 \backslash
13048 edef
13049 \backslash
13050 chunkname{
13051 \backslash
13052 lst@intname-
13053 \backslash
13054 arabic{newfangle@chunkcounter}}%
13055 \end_layout
13057 \begin_layout Plain Layout
13059   
13060 \backslash
13061 edef
13062 \backslash
13063 firstchunkname{
13064 \backslash
13065 lst@intname-1}%
13066 \end_layout
13068 \end_inset
13071 \end_layout
13073 \begin_layout Standard
13074 We now need to calculate the name of the next chunk.
13075  We do this by temporarily skipping the counter on by one; however there
13076  may not actually be another chunk with this name! We detect this by also
13077  defining a label for each chunk based on the chunkname.
13078  If there is a next chunkname then it will define a label with that name.
13079  As labels are persistent, we can at least tell the second time LaTeX is
13080  run.
13081  If we don't find such a defined label then we define 
13082 \begin_inset Flex CharStyle:Code
13083 status collapsed
13085 \begin_layout Plain Layout
13087 \backslash
13088 nextchunkname
13089 \end_layout
13091 \end_inset
13093  to 
13094 \begin_inset Flex CharStyle:Code
13095 status collapsed
13097 \begin_layout Plain Layout
13099 \backslash
13100 relax
13101 \end_layout
13103 \end_inset
13106 \end_layout
13108 \begin_layout Standard
13109 \begin_inset listings
13110 inline false
13111 status open
13113 \begin_layout Plain Layout
13115   
13116 \backslash
13117 addtocounter{newfangle@chunkcounter}{1}%
13118 \end_layout
13120 \begin_layout Plain Layout
13122   
13123 \backslash
13124 edef
13125 \backslash
13126 nextchunkname{
13127 \backslash
13128 lst@intname-
13129 \backslash
13130 arabic{newfangle@chunkcounter}}%
13131 \end_layout
13133 \begin_layout Plain Layout
13135   
13136 \backslash
13137 @ifundefined{r@label-
13138 \backslash
13139 nextchunkname}{
13140 \backslash
13142 \backslash
13143 nextchunkname
13144 \backslash
13145 relax}{}%
13146 \end_layout
13148 \end_inset
13151 \end_layout
13153 \begin_layout Standard
13154 The noweb package requires that we define a 
13155 \begin_inset Flex CharStyle:Code
13156 status collapsed
13158 \begin_layout Plain Layout
13160 \backslash
13161 sublabel
13162 \end_layout
13164 \end_inset
13166  for every chunk, with a unique name, which is then used to print out it's
13167  navigation hints.
13168 \end_layout
13170 \begin_layout Standard
13171 We also define a regular label for this chunk, as was mentioned above when
13172  we calculated 
13173 \begin_inset Flex CharStyle:Code
13174 status collapsed
13176 \begin_layout Plain Layout
13178 \backslash
13179 nextchunkname
13180 \end_layout
13182 \end_inset
13185  This requires LaTeX to be run at least twice after new chunk sections are
13186  added --- but noweb requried that anyway.
13187 \end_layout
13189 \begin_layout Standard
13190 \begin_inset listings
13191 inline false
13192 status open
13194 \begin_layout Plain Layout
13196   
13197 \backslash
13198 sublabel{
13199 \backslash
13200 chunkname}%
13201 \end_layout
13203 \begin_layout Plain Layout
13205 % define this label for every chunk instance, so we
13206 \end_layout
13208 \begin_layout Plain Layout
13210 % can tell when we are the last chunk of this name
13211 \end_layout
13213 \begin_layout Plain Layout
13215   
13216 \backslash
13217 label{label-
13218 \backslash
13219 chunkname}%
13220 \end_layout
13222 \end_inset
13225 \end_layout
13227 \begin_layout Standard
13228 We also try and add the chunk to the list of listings, but I'm afraid we
13229  don't do very well.
13230  We want each chunk name listing once, with all of it's references.
13231 \end_layout
13233 \begin_layout Standard
13234 \begin_inset listings
13235 inline false
13236 status open
13238 \begin_layout Plain Layout
13240   
13241 \backslash
13242 addcontentsline{lol}{lstlisting}{
13243 \backslash
13244 lst@name~[
13245 \backslash
13246 protect
13247 \backslash
13248 subpageref{
13249 \backslash
13250 chunkname}]}%
13251 \end_layout
13253 \end_inset
13256 \end_layout
13258 \begin_layout Standard
13259 We then call the noweb output macros in the same way that noweave generates
13260  them, except that we don't need to call 
13261 \begin_inset Flex CharStyle:Code
13262 status collapsed
13264 \begin_layout Plain Layout
13266 \backslash
13267 nwstartdeflinemarkup
13268 \end_layout
13270 \end_inset
13272  or 
13273 \begin_inset Flex CharStyle:Code
13274 status collapsed
13276 \begin_layout Plain Layout
13278 \backslash
13279 nwenddeflinemarkup
13280 \end_layout
13282 \end_inset
13284  -- and if we do it messes up the output somewhat.
13285 \end_layout
13287 \begin_layout Standard
13288 \begin_inset listings
13289 inline false
13290 status open
13292 \begin_layout Plain Layout
13294   
13295 \backslash
13296 nwmargintag{%
13297 \end_layout
13299 \begin_layout Plain Layout
13301     {%
13302 \end_layout
13304 \begin_layout Plain Layout
13306       
13307 \backslash
13308 nwtagstyle{}%
13309 \end_layout
13311 \begin_layout Plain Layout
13313       
13314 \backslash
13315 subpageref{
13316 \backslash
13317 chunkname}%
13318 \end_layout
13320 \begin_layout Plain Layout
13322     }%
13323 \end_layout
13325 \begin_layout Plain Layout
13327   }%
13328 \end_layout
13330 \begin_layout Plain Layout
13333 \end_layout
13335 \begin_layout Plain Layout
13337   
13338 \backslash
13339 moddef{%
13340 \end_layout
13342 \begin_layout Plain Layout
13344     {
13345 \backslash
13346 lst@name}%
13347 \end_layout
13349 \begin_layout Plain Layout
13351     {%
13352 \end_layout
13354 \begin_layout Plain Layout
13356       
13357 \backslash
13358 nwtagstyle{}
13359 \backslash
13361 \end_layout
13363 \begin_layout Plain Layout
13365       
13366 \backslash
13367 @ifundefined{newfangle@chunk@params}{}{%
13368 \end_layout
13370 \begin_layout Plain Layout
13372         (
13373 \backslash
13374 newfangle@chunk@params)%
13375 \end_layout
13377 \begin_layout Plain Layout
13379       }%
13380 \end_layout
13382 \begin_layout Plain Layout
13384       [
13385 \backslash
13386 csname 
13387 \backslash
13388 chunkcount
13389 \backslash
13390 endcsname]~%
13391 \end_layout
13393 \begin_layout Plain Layout
13395       
13396 \backslash
13397 subpageref{
13398 \backslash
13399 firstchunkname}%
13400 \end_layout
13402 \begin_layout Plain Layout
13404     }%
13405 \end_layout
13407 \begin_layout Plain Layout
13409     
13410 \backslash
13411 @ifundefined{newfangle@chunk@append}{}{%
13412 \end_layout
13414 \begin_layout Plain Layout
13416     
13417 \backslash
13418 ifx{}
13419 \backslash
13420 newfangle@chunk@append{x}
13421 \backslash
13422 else%
13423 \end_layout
13425 \begin_layout Plain Layout
13427         ,~add~to~
13428 \backslash
13429 newfangle@chunk@append%
13430 \end_layout
13432 \begin_layout Plain Layout
13434     
13435 \backslash
13437 \end_layout
13439 \begin_layout Plain Layout
13441     }%
13442 \end_layout
13444 \begin_layout Plain Layout
13447 \backslash
13448 global
13449 \backslash
13451 \backslash
13452 newfangle@chunk@append{}%
13453 \end_layout
13455 \begin_layout Plain Layout
13458 \backslash
13459 lstset{append=x}%
13460 \end_layout
13462 \begin_layout Plain Layout
13464   }%
13465 \end_layout
13467 \begin_layout Plain Layout
13470 \end_layout
13472 \begin_layout Plain Layout
13474   
13475 \backslash
13477 \backslash
13478 relax
13479 \backslash
13480 prevchunkname
13481 \backslash
13482 endmoddef
13483 \backslash
13484 else
13485 \backslash
13486 plusendmoddef
13487 \backslash
13489 \end_layout
13491 \begin_layout Plain Layout
13493 %  
13494 \backslash
13495 nwstartdeflinemarkup%
13496 \end_layout
13498 \begin_layout Plain Layout
13500   
13501 \backslash
13502 nwprevnextdefs{
13503 \backslash
13504 prevchunkname}{
13505 \backslash
13506 nextchunkname}%
13507 \end_layout
13509 \begin_layout Plain Layout
13511 %  
13512 \backslash
13513 nwenddeflinemarkup%
13514 \end_layout
13516 \begin_layout Plain Layout
13519 \end_layout
13521 \end_inset
13524 \end_layout
13526 \begin_layout Standard
13527 Originally this was developed as a 
13528 \begin_inset Flex CharStyle:Code
13529 status collapsed
13531 \begin_layout Plain Layout
13532 listings
13533 \end_layout
13535 \end_inset
13537  aspect, in the Init hook, but it was found easier to affect the title without
13538  using a hook --- 
13539 \begin_inset Flex CharStyle:Code
13540 status collapsed
13542 \begin_layout Plain Layout
13544 \backslash
13545 lst@AddToHookExe{PreSet}
13546 \end_layout
13548 \end_inset
13550  is still required to set the listings name to the name passed to the 
13551 \begin_inset Flex CharStyle:Code
13552 status collapsed
13554 \begin_layout Plain Layout
13556 \backslash
13557 Chunk
13558 \end_layout
13560 \end_inset
13562  command, though.
13563 \end_layout
13565 \begin_layout Standard
13566 \begin_inset listings
13567 inline false
13568 status open
13570 \begin_layout Plain Layout
13573 \backslash
13574 lst@BeginAspect{newfangle}
13575 \end_layout
13577 \begin_layout Plain Layout
13580 \backslash
13581 lst@Key{newfangle}{true}[t]{
13582 \backslash
13583 lstKV@SetIf{#1}{true}}
13584 \end_layout
13586 \begin_layout Plain Layout
13589 \backslash
13590 lst@AddToHookExe{PreSet}{
13591 \backslash
13592 global
13593 \backslash
13595 \backslash
13596 lst@intname
13597 \backslash
13598 lst@chunkname}
13599 \end_layout
13601 \begin_layout Plain Layout
13604 \backslash
13605 lst@AddToHook{Init}{}%
13606 \backslash
13607 newfangle@caption}
13608 \end_layout
13610 \begin_layout Plain Layout
13613 \backslash
13614 lst@EndAspect
13615 \end_layout
13617 \end_inset
13620 \end_layout
13622 \begin_layout Subsection
13623 Cross references
13624 \end_layout
13626 \begin_layout Standard
13627 We define the 
13628 \backslash
13629 chunkref command which makes it easy to generate visual references to different
13630  code chunks, e.g.
13631 \end_layout
13633 \begin_layout Standard
13634 \begin_inset Tabular
13635 <lyxtabular version="3" rows="4" columns="2">
13636 <features>
13637 <column alignment="center" valignment="top" width="0">
13638 <column alignment="center" valignment="top" width="0">
13639 <row>
13640 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
13641 \begin_inset Text
13643 \begin_layout Plain Layout
13644 Macro
13645 \end_layout
13647 \end_inset
13648 </cell>
13649 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
13650 \begin_inset Text
13652 \begin_layout Plain Layout
13653 Appearance
13654 \end_layout
13656 \end_inset
13657 </cell>
13658 </row>
13659 <row>
13660 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
13661 \begin_inset Text
13663 \begin_layout Plain Layout
13665 \backslash
13666 chunkref{preamble}
13667 \end_layout
13669 \end_inset
13670 </cell>
13671 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
13672 \begin_inset Text
13674 \begin_layout Plain Layout
13675 \begin_inset ERT
13676 status open
13678 \begin_layout Plain Layout
13681 \backslash
13682 chunkref{preamble}
13683 \end_layout
13685 \end_inset
13688 \end_layout
13690 \end_inset
13691 </cell>
13692 </row>
13693 <row>
13694 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
13695 \begin_inset Text
13697 \begin_layout Plain Layout
13699 \backslash
13700 chunkref[3]{preamble}
13701 \end_layout
13703 \end_inset
13704 </cell>
13705 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
13706 \begin_inset Text
13708 \begin_layout Plain Layout
13709 \begin_inset ERT
13710 status open
13712 \begin_layout Plain Layout
13715 \backslash
13716 chunkref[3]{preamble}
13717 \end_layout
13719 \end_inset
13722 \end_layout
13724 \end_inset
13725 </cell>
13726 </row>
13727 <row>
13728 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
13729 \begin_inset Text
13731 \begin_layout Plain Layout
13733 \backslash
13734 chunkref{preamble}[arg1, arg2]
13735 \end_layout
13737 \end_inset
13738 </cell>
13739 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
13740 \begin_inset Text
13742 \begin_layout Plain Layout
13743 \begin_inset ERT
13744 status open
13746 \begin_layout Plain Layout
13749 \backslash
13750 chunkref{preamble}[arg1, arg2]
13751 \end_layout
13753 \end_inset
13756 \end_layout
13758 \end_inset
13759 </cell>
13760 </row>
13761 </lyxtabular>
13763 \end_inset
13766 \end_layout
13768 \begin_layout Standard
13769 Chunkref can also be used within a code chunk to include another code chunk.
13770  The third optional parameter to chunkref is a comma sepatarated list of
13771  arguments, which will replace defined parameters in the chunkref.
13772 \begin_inset Note Note
13773 status open
13775 \begin_layout Plain Layout
13776 Darn it, if I have: =<
13777 \backslash
13778 chunkref{new-mode-tracker}[{chunks[chunk_name, "language"]},{mode}]> the
13779  inner braces (inside [ ]) cause _ to signify subscript even though we have
13780  lst@ReplaceIn
13781 \end_layout
13783 \end_inset
13786 \end_layout
13788 \begin_layout Standard
13789 \begin_inset listings
13790 inline false
13791 status open
13793 \begin_layout Plain Layout
13796 \backslash
13798 \backslash
13799 chunkref@args#1,{%
13800 \end_layout
13802 \begin_layout Plain Layout
13804   
13805 \backslash
13807 \backslash
13808 arg{#1}%
13809 \end_layout
13811 \begin_layout Plain Layout
13813   
13814 \backslash
13815 lst@ReplaceIn
13816 \backslash
13818 \backslash
13819 lst@filenamerpl%
13820 \end_layout
13822 \begin_layout Plain Layout
13824   
13825 \backslash
13826 arg%
13827 \end_layout
13829 \begin_layout Plain Layout
13831   
13832 \backslash
13833 @ifnextchar){
13834 \backslash
13835 relax}{, 
13836 \backslash
13837 chunkref@args}%
13838 \end_layout
13840 \begin_layout Plain Layout
13843 \end_layout
13845 \begin_layout Plain Layout
13848 \backslash
13849 newcommand
13850 \backslash
13851 chunkref[2][0]{%
13852 \end_layout
13854 \begin_layout Plain Layout
13856   
13857 \backslash
13858 @ifnextchar({
13859 \backslash
13860 chunkref@i{#1}{#2}}{
13861 \backslash
13862 chunkref@i{#1}{#2}()}%
13863 \end_layout
13865 \begin_layout Plain Layout
13868 \end_layout
13870 \begin_layout Plain Layout
13873 \backslash
13875 \backslash
13876 chunkref@i#1#2(#3){%
13877 \end_layout
13879 \begin_layout Plain Layout
13881   
13882 \backslash
13884 \backslash
13885 zero{0}%
13886 \end_layout
13888 \begin_layout Plain Layout
13890   
13891 \backslash
13893 \backslash
13894 chunk{#2}%
13895 \end_layout
13897 \begin_layout Plain Layout
13899   
13900 \backslash
13902 \backslash
13903 chunkno{#1}%
13904 \end_layout
13906 \begin_layout Plain Layout
13908   
13909 \backslash
13911 \backslash
13912 chunkargs{#3}%
13913 \end_layout
13915 \begin_layout Plain Layout
13917   
13918 \backslash
13920 \backslash
13921 chunkno
13922 \backslash
13923 zero%
13924 \end_layout
13926 \begin_layout Plain Layout
13928     
13929 \backslash
13931 \backslash
13932 chunkname{#2-1}%
13933 \end_layout
13935 \begin_layout Plain Layout
13937   
13938 \backslash
13939 else%
13940 \end_layout
13942 \begin_layout Plain Layout
13944     
13945 \backslash
13947 \backslash
13948 chunkname{#2-
13949 \backslash
13950 chunkno}%
13951 \end_layout
13953 \begin_layout Plain Layout
13955   
13956 \backslash
13958 \end_layout
13960 \begin_layout Plain Layout
13962   
13963 \backslash
13965 \backslash
13966 lst@arg
13967 \backslash
13968 chunk%
13969 \end_layout
13971 \begin_layout Plain Layout
13973   
13974 \backslash
13975 lst@ReplaceIn
13976 \backslash
13977 chunk
13978 \backslash
13979 lst@filenamerpl%
13980 \end_layout
13982 \begin_layout Plain Layout
13984   
13985 \backslash
13986 LA{%
13987 \backslash
13988 moddef{%
13989 \end_layout
13991 \begin_layout Plain Layout
13993     {
13994 \backslash
13995 chunk}%
13996 \end_layout
13998 \begin_layout Plain Layout
14000     {%
14001 \end_layout
14003 \begin_layout Plain Layout
14005       
14006 \backslash
14007 nwtagstyle{}
14008 \backslash
14010 \end_layout
14012 \begin_layout Plain Layout
14014       
14015 \backslash
14017 \backslash
14018 chunkno
14019 \backslash
14020 zero%
14021 \end_layout
14023 \begin_layout Plain Layout
14025       
14026 \backslash
14027 else%
14028 \end_layout
14030 \begin_layout Plain Layout
14032       [
14033 \backslash
14034 chunkno]%
14035 \end_layout
14037 \begin_layout Plain Layout
14039       
14040 \backslash
14042 \end_layout
14044 \begin_layout Plain Layout
14046       
14047 \backslash
14049 \backslash
14050 chunkargs
14051 \backslash
14052 empty%
14053 \end_layout
14055 \begin_layout Plain Layout
14057       
14058 \backslash
14059 else%
14060 \end_layout
14062 \begin_layout Plain Layout
14064         (
14065 \backslash
14066 chunkref@args #3,)%
14067 \end_layout
14069 \begin_layout Plain Layout
14071       
14072 \backslash
14074 \end_layout
14076 \begin_layout Plain Layout
14078       ~
14079 \backslash
14080 subpageref{
14081 \backslash
14082 chunkname}%
14083 \end_layout
14085 \begin_layout Plain Layout
14087     }%
14088 \end_layout
14090 \begin_layout Plain Layout
14092   }%
14093 \end_layout
14095 \begin_layout Plain Layout
14097   
14098 \backslash
14100 \backslash
14101 endmoddef%
14102 \end_layout
14104 \begin_layout Plain Layout
14107 \end_layout
14109 \end_inset
14112 \end_layout
14114 \begin_layout Subsection
14115 The end
14116 \end_layout
14118 \begin_layout Standard
14119 \begin_inset listings
14120 inline false
14121 status open
14123 \begin_layout Plain Layout
14126 \end_layout
14128 \begin_layout Plain Layout
14131 \backslash
14132 makeatother
14133 \end_layout
14135 \end_inset
14138 \end_layout
14140 \begin_layout Chapter
14141 Extracting newfangle
14142 \end_layout
14144 \begin_layout Section
14145 Extracting from Lyx
14146 \end_layout
14148 \begin_layout Standard
14149 To extract from LyX, you will need to configure LyX as explained in section
14151 \begin_inset CommandInset ref
14152 LatexCommand ref
14153 reference "sub:Configuring-the-build"
14155 \end_inset
14158 \end_layout
14160 \begin_layout Standard
14161 \begin_inset CommandInset label
14162 LatexCommand label
14163 name "lyx-build-script"
14165 \end_inset
14167 And this lyx-build scrap will extract newfangle for me.
14168 \end_layout
14170 \begin_layout Chunk
14171 lyx-build,language=sh
14172 \end_layout
14174 \begin_layout Standard
14175 \begin_inset listings
14176 inline false
14177 status open
14179 \begin_layout Plain Layout
14181 #! /bin/sh
14182 \end_layout
14184 \begin_layout Plain Layout
14186 set -x
14187 \end_layout
14189 \begin_layout Plain Layout
14191 \end_layout
14193 \begin_layout Plain Layout
14196 \backslash
14197 chunkref{lyx-build-helper}>
14198 \end_layout
14200 \begin_layout Plain Layout
14202 cd $PROJECT_DIR || exit 1
14203 \end_layout
14205 \begin_layout Plain Layout
14207 \end_layout
14209 \begin_layout Plain Layout
14211 /usr/local/bin/newfangle -R./newfangle $TEX_SRC > ./newfangle
14212 \end_layout
14214 \begin_layout Plain Layout
14216 /usr/local/bin/newfangle -R./newfangle.module $TEX_SRC > ./newfangle.module
14217 \end_layout
14219 \begin_layout Plain Layout
14221 \end_layout
14223 \begin_layout Plain Layout
14226 \backslash
14227 chunkref{test:helpers}>
14228 \end_layout
14230 \begin_layout Plain Layout
14232 # run tests
14233 \end_layout
14235 \begin_layout Plain Layout
14237 ./newfangle -Rpca-test.awk $TEX_SRC | awk -f - || exit 1
14238 \end_layout
14240 \begin_layout Plain Layout
14243 \backslash
14244 chunkref{test:cromulence}>
14245 \end_layout
14247 \end_inset
14250 \end_layout
14252 \begin_layout Standard
14253 With a lyx-build-helper
14254 \end_layout
14256 \begin_layout Chunk
14257 lyx-build-helper,language=sh
14258 \end_layout
14260 \begin_layout Standard
14261 \begin_inset listings
14262 inline false
14263 status open
14265 \begin_layout Plain Layout
14267 PROJECT_DIR="$LYX_r"
14268 \end_layout
14270 \begin_layout Plain Layout
14272 LYX_SRC="$PROJECT_DIR/${LYX_i%.tex}.lyx"
14273 \end_layout
14275 \begin_layout Plain Layout
14277 TEX_DIR="$LYX_p"
14278 \end_layout
14280 \begin_layout Plain Layout
14282 TEX_SRC="$TEX_DIR/$LYX_i"
14283 \end_layout
14285 \end_inset
14288 \end_layout
14290 \begin_layout Section
14291 Extracting from the command line
14292 \end_layout
14294 \begin_layout Standard
14295 First you will need the tex output, then you can extract:
14296 \end_layout
14298 \begin_layout Chunk
14299 lyx-build-manual,language=sh
14300 \end_layout
14302 \begin_layout Standard
14303 \begin_inset listings
14304 inline false
14305 status open
14307 \begin_layout Plain Layout
14309 lyx -e latex newfangle.lyx
14310 \end_layout
14312 \begin_layout Plain Layout
14314 newfangle -R./newfangle newfangle.tex > ./newfangle
14315 \end_layout
14317 \begin_layout Plain Layout
14319 newfangle -R./newfangle.module newfangle.tex > ./newfangle.module
14320 \end_layout
14322 \end_inset
14325 \end_layout
14327 \begin_layout Section
14328 Testing
14329 \end_layout
14331 \begin_layout Chunk
14332 test:helpers
14333 \end_layout
14335 \begin_layout Standard
14336 \begin_inset listings
14337 inline false
14338 status open
14340 \begin_layout Plain Layout
14342 passtest() {
14343 \end_layout
14345 \begin_layout Plain Layout
14347   if "$@"
14348 \end_layout
14350 \begin_layout Plain Layout
14352   then echo "Passed"
14353 \end_layout
14355 \begin_layout Plain Layout
14357   else echo "Failed"
14358 \end_layout
14360 \begin_layout Plain Layout
14362        return 1
14363 \end_layout
14365 \begin_layout Plain Layout
14367   fi
14368 \end_layout
14370 \begin_layout Plain Layout
14373 \end_layout
14375 \begin_layout Plain Layout
14377 \end_layout
14379 \begin_layout Plain Layout
14381 failtest() {
14382 \end_layout
14384 \begin_layout Plain Layout
14386   if ! "$@"
14387 \end_layout
14389 \begin_layout Plain Layout
14391   then echo "Passed"
14392 \end_layout
14394 \begin_layout Plain Layout
14396   else echo "Failed"
14397 \end_layout
14399 \begin_layout Plain Layout
14401        return 1
14402 \end_layout
14404 \begin_layout Plain Layout
14406   fi
14407 \end_layout
14409 \begin_layout Plain Layout
14412 \end_layout
14414 \end_inset
14417 \end_layout
14419 \begin_layout Part
14420 Tests
14421 \end_layout
14423 \begin_layout Chapter
14424 Chunk Parameters
14425 \end_layout
14427 \begin_layout Chunk
14428 tests-sub,params=THING;colour
14429 \end_layout
14431 \begin_layout Standard
14432 \begin_inset listings
14433 inline false
14434 status open
14436 \begin_layout Plain Layout
14438 I see a ${THING} of 
14439 \end_layout
14441 \begin_layout Plain Layout
14443 colour ${colour}, 
14444 \end_layout
14446 \begin_layout Plain Layout
14448 looking closer =<
14449 \backslash
14450 chunkref{tests-sub-sub}(${colour})>
14451 \end_layout
14453 \end_inset
14456 \end_layout
14458 \begin_layout Chunk
14459 tests-sub-sub,params=colour
14460 \end_layout
14462 \begin_layout Standard
14463 \begin_inset listings
14464 inline false
14465 status open
14467 \begin_layout Plain Layout
14469 a funny shade of ${colour}
14470 \end_layout
14472 \end_inset
14475 \end_layout
14477 \begin_layout Chunk
14478 tests
14479 \end_layout
14481 \begin_layout Standard
14482 \begin_inset listings
14483 inline false
14484 status open
14486 \begin_layout Plain Layout
14488 What do you see? "=<
14489 \backslash
14490 chunkref{tests-sub}(joe, red)>"
14491 \end_layout
14493 \begin_layout Plain Layout
14495 Well, fancy!
14496 \end_layout
14498 \end_inset
14501 \end_layout
14503 \begin_layout Standard
14504 Should generate output:
14505 \end_layout
14507 \begin_layout Chunk
14508 tests-result
14509 \end_layout
14511 \begin_layout Standard
14512 \begin_inset listings
14513 inline false
14514 status open
14516 \begin_layout Plain Layout
14518 What do you see? "I see a joe of 
14519 \end_layout
14521 \begin_layout Plain Layout
14523                   colour red, 
14524 \end_layout
14526 \begin_layout Plain Layout
14528                   looking closer a funny shade of red"
14529 \end_layout
14531 \begin_layout Plain Layout
14533 Well, fancy!
14534 \end_layout
14536 \begin_layout Plain Layout
14538 \end_layout
14540 \end_inset
14543 \end_layout
14545 \end_body
14546 \end_document