Fix link error
[newfangle.git] / newfangle.lyx
blob3ce432baa2e59bf165400f364b82e2fca74f3039
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 \lstset{
8 numbers=left, stepnumber=1, numbersep=5pt,
9 breaklines=false,
10 basicstyle=\footnotesize\ttfamily,
11 numberstyle=\tiny,
12 language=C,
13 columns=fullflexible,
14 numberfirstline=true}
15 \end_preamble
16 \use_default_options true
17 \begin_modules
18 logicalmkup
19 newfangle
20 \end_modules
21 \language english
22 \inputencoding auto
23 \font_roman default
24 \font_sans default
25 \font_typewriter default
26 \font_default_family default
27 \font_sc false
28 \font_osf false
29 \font_sf_scale 100
30 \font_tt_scale 100
32 \graphics default
33 \paperfontsize default
34 \spacing single
35 \use_hyperref true
36 \pdf_title "Newfangle"
37 \pdf_author "Sam Liddicott"
38 \pdf_subject "Literate Programing"
39 \pdf_keywords "notangle noweb noweave literate programming cweb"
40 \pdf_bookmarks true
41 \pdf_bookmarksnumbered false
42 \pdf_bookmarksopen false
43 \pdf_bookmarksopenlevel 1
44 \pdf_breaklinks false
45 \pdf_pdfborder false
46 \pdf_colorlinks true
47 \pdf_backref false
48 \pdf_pdfusetitle true
49 \papersize default
50 \use_geometry false
51 \use_amsmath 1
52 \use_esint 1
53 \cite_engine basic
54 \use_bibtopic false
55 \paperorientation portrait
56 \secnumdepth 3
57 \tocdepth 3
58 \paragraph_separation skip
59 \defskip medskip
60 \quotes_language english
61 \papercolumns 1
62 \papersides 1
63 \paperpagestyle default
64 \tracking_changes false
65 \output_changes false
66 \author "" 
67 \author "" 
68 \end_header
70 \begin_body
72 \begin_layout Title
73 newfangle
74 \end_layout
76 \begin_layout Author
77 Sam Liddicott
78 \end_layout
80 \begin_layout Date
81 August 2009
82 \end_layout
84 \begin_layout Chapter*
85 Introduction
86 \end_layout
88 \begin_layout Standard
90 \noun on
91 Newfangle
92 \noun default
93  is a tool for newfangled literate programming.
94  Newfangled is defined as 
95 \emph on
96 New and often needlessly novel
97 \emph default
98  by 
99 \noun on
100 TheFreeDictionary.com
101 \noun default
103 \end_layout
105 \begin_layout Standard
106 In this case, newfangled means yet another new and improved method for literate
107  programming.
108 \end_layout
110 \begin_layout Standard
112 \noun on
113 Literate Programming
114 \noun default
115  has a long history starting with the great 
116 \noun on
117 Donald Knuth
118 \noun default
119  himself, whose literate programming tools seem to make use of as many escape
120  sequences for semantic markup as TeX itself.
121 \end_layout
123 \begin_layout Standard
125 \noun on
126 Norman Ramsey
127 \noun default
128  wrote the 
129 \noun on
130 noweb
131 \noun default
132  set of tools (notangle, noweave and noroots) and helpfully reduced the
133  amount of magic character sequences to pretty much just 
134 \begin_inset Flex CharStyle:Code
135 status collapsed
137 \begin_layout Plain Layout
139 \end_layout
141 \end_inset
143  and 
144 \begin_inset Flex CharStyle:Code
145 status collapsed
147 \begin_layout Plain Layout
149 \end_layout
151 \end_inset
153 , and in doing so brought the wonders of literate programming within my
154  reach.
155 \end_layout
157 \begin_layout Standard
158 While using the LyX editor for LaTeX editing I had various troubles with
159  the noweb tools, some of which were my fault, some of which were noweb's
160  fault and some of which were LyX's fault.
161 \end_layout
163 \begin_layout Standard
165 \noun on
166 Noweb
167 \noun default
168  generally brought literate programming to the masses through removing some
169  of the complexity of the original literate programming, but this would
170  be of no advantage to me if the LyX / LaTeX combination brought more complicati
171 ons in their place.
172 \end_layout
174 \begin_layout Standard
176 \noun on
177 Newfangle
178 \noun default
179  was thus born --- as an awk replacement for notangle, adding some important
180  features, like better integration with LyX and LaTeX, multiple output format
181  conversions, and fixing notangle bugs like indentation when using -L for
182  line numbers.
183 \end_layout
185 \begin_layout Standard
186 Significantly, newfangle is just one program which replaces various programs
187  in Noweb.
188  Noweave is done away with and implemented directly as LaTeX macros, and
189  noroots is implemented as a function of the untangler 
190 \noun on
191 newfangle
192 \noun default
194 \end_layout
196 \begin_layout Standard
197 Newfangle is written in awk for portability reasons, awk being available
198  for most platforms.
199  A python conversion will probably be attempted for the benefit of LyX.
200  (Hasn't anyone implemented awk in python yet?)
201 \end_layout
203 \begin_layout Standard
204 As an extension to many literate-programming styles, Newfangle permits code
205  chunks to take parameters and thus operate somewhat like C pre-processor
206  macros, or like C++ templates.
207 \end_layout
209 \begin_layout Section*
210 Todo
211 \end_layout
213 \begin_layout Enumerate
214 ^^ is always going to be a problem, see texbytopic 1.2.2 (Work out what I
215  meant by this).
216 \end_layout
218 \begin_layout Enumerate
219 copy over up to date Makefile guide from noweb-lyx document
220 \end_layout
222 \begin_layout Enumerate
223 Make chunk-name settings only apply to chunks with that name
224 \end_layout
226 \begin_layout Enumerate
227 indent of multi-line chunks may be mode dependant (i.e.
228  not in string literals)
229 \end_layout
231 \begin_layout Enumerate
232 add support for other commands in =<...>, starting with 
233 \backslash
234 label which takes the line-number within the chunk, and maybe should also
235  take the chunk name/page
236 \end_layout
238 \begin_layout Enumerate
239 cant have listing inside a ruled box
240 \end_layout
242 \begin_layout Enumerate
243 when a parameterized chunk is included as well as the #line emission, say
244  what the paremeters were for that invocation.
245 \end_layout
247 \begin_layout Enumerate
249 \backslash
250 chunkref[3]{preamble} to include a certain chunk needs to work in newfangle.awk
251  instead of failing to be recognized at all
252 \end_layout
254 \begin_layout Enumerate
255 make in-listins labels track the chunk ref too, and make 
256 \backslash
257 chunref{[2],thing}> resolve to 41c (or d, or whatever chunk the 2nd chunk
258  of thing is
259 \end_layout
261 \begin_layout Enumerate
263 \backslash
264 chunkref in text needs a trailing space maybe, it keeps butting up to the
265  next word
266 \end_layout
268 \begin_layout Enumerate
269 because the white-space indent is output by the parent chunk, the #line
270  is that of the parent chunk.
271  White space indents must be passed to the child chunk
272 \end_layout
274 \begin_layout Chapter*
275 License
276 \end_layout
278 \begin_layout Standard
279 \begin_inset CommandInset label
280 LatexCommand label
281 name "cha:License"
283 \end_inset
285 Newfangle is licensed under the GPL 3
286 \begin_inset CommandInset citation
287 LatexCommand cite
288 key "gpl-licenses"
290 \end_inset
292  (or later).
293  This doesn't mean that you can't use or distribute newfangle with sources
294  of an incompatible license, but it means you must make the source of newfangle
295  available too.
296 \end_layout
298 \begin_layout Standard
299 As newfangle is currently written in 
300 \noun on
302 \noun default
303 , an interpreted language, this should not be too hard.
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
322 \end_layout
324 \begin_layout Plain Layout
326 Copyright (C) 2009 Sam Liddicott <sam@liddicott.com>
327 \end_layout
329 \begin_layout Plain Layout
331 \end_layout
333 \begin_layout Plain Layout
335 This program is free software: you can redistribute it and/or modify
336 \end_layout
338 \begin_layout Plain Layout
340 it under the terms of the GNU General Public License as published by
341 \end_layout
343 \begin_layout Plain Layout
345 the Free Software Foundation, either version 3 of the License, or
346 \end_layout
348 \begin_layout Plain Layout
350 (at your option) any later version.
351 \end_layout
353 \begin_layout Plain Layout
355 \end_layout
357 \begin_layout Plain Layout
359 This program is distributed in the hope that it will be useful,
360 \end_layout
362 \begin_layout Plain Layout
364 but WITHOUT ANY WARRANTY; without even the implied warranty of
365 \end_layout
367 \begin_layout Plain Layout
369 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
370   See the
371 \end_layout
373 \begin_layout Plain Layout
375 GNU General Public License for more details.
376 \end_layout
378 \begin_layout Plain Layout
380 \end_layout
382 \begin_layout Plain Layout
384 You should have received a copy of the GNU General Public License
385 \end_layout
387 \begin_layout Plain Layout
389 along with this program.
390   If not, see <http://www.gnu.org/licenses/>.
391 \end_layout
393 \begin_layout Plain Layout
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  and so-called top level roots could also be included in another root as
543  well.
545 \end_layout
547 \begin_layout Standard
548 My convention is that top level roots to be extracted begin with 
549 \begin_inset Flex CharStyle:Code
550 status collapsed
552 \begin_layout Plain Layout
554 \end_layout
556 \end_inset
558  and have the form of a filename.
559 \end_layout
561 \begin_layout Standard
562 Makefile.inc, discussed in 
563 \begin_inset CommandInset ref
564 LatexCommand ref
565 reference "cha:makefile.inc"
567 \end_inset
569 , can automatically extract all such sources.
570 \end_layout
572 \begin_layout Section
573 Extracting roots
574 \end_layout
576 \begin_layout Standard
577 notangle's 
578 \begin_inset Flex CharStyle:Code
579 status collapsed
581 \begin_layout Plain Layout
583 \end_layout
585 \end_inset
587  and 
588 \begin_inset Flex CharStyle:Code
589 status collapsed
591 \begin_layout Plain Layout
593 \end_layout
595 \end_inset
597  options are supported.
598 \end_layout
600 \begin_layout Standard
601 The standard way to extract a file would be:
602 \end_layout
604 \begin_layout LyX-Code
605 newfangle -R./Makefile.inc newfangle.tex > ./Makefile.inc
606 \end_layout
608 \begin_layout Standard
609 Unlike the 
610 \begin_inset Flex CharStyle:Code
611 status collapsed
613 \begin_layout Plain Layout
614 noroots
615 \end_layout
617 \end_inset
619  command, the 
620 \begin_inset Flex CharStyle:Code
621 status collapsed
623 \begin_layout Plain Layout
625 \end_layout
627 \end_inset
629  option does not break indenting.
630 \end_layout
632 \begin_layout Standard
633 Also, thanks to mode tracking (described in 
634 \begin_inset CommandInset ref
635 LatexCommand ref
636 reference "cha:modes"
638 \end_inset
640 ) the 
641 \begin_inset Flex CharStyle:Code
642 status collapsed
644 \begin_layout Plain Layout
646 \end_layout
648 \end_inset
650  option does not interrupt (and break) multi-line C macros either.
651 \end_layout
653 \begin_layout Standard
654 This does mean that sometimes the compiler might calculate the source line
655  wrongly when generating error messages in such cases, but there isn't any
656  other way around if multi-line macros include other chunks.
657 \end_layout
659 \begin_layout Section
660 Formatting source in LaTeX
661 \end_layout
663 \begin_layout Standard
664 The noweave replacement is a set of LaTeX macros dependant upon 
665 \emph on
666 noweb.sty
667 \emph default
668 , and which can be included with:
669 \end_layout
671 \begin_layout LyX-Code
673 \backslash
674 usepackage{newfangle.sty}
675 \end_layout
677 \begin_layout Standard
678 The LaTeX macros are shown in section 
679 \begin_inset CommandInset ref
680 LatexCommand ref
681 reference "sec:Latex-Macros"
683 \end_inset
685 , and are part of a LyX module file 
686 \begin_inset Flex CharStyle:Code
687 status collapsed
689 \begin_layout Plain Layout
690 newfangle.module
691 \end_layout
693 \end_inset
695 , which automatically includes the macros in the document pre-amble when
696  the newfangle LyX module is used.
697 \end_layout
699 \begin_layout Standard
700 Because the noweave replacement is impemented in LaTeX, there is no processing
701  stage required before running the 
702 \begin_inset Flex CharStyle:Code
703 status collapsed
705 \begin_layout Plain Layout
706 latex
707 \end_layout
709 \end_inset
711  command.
712  LaTeX may need running two or more times, so that the code chunk references
713  can be fully calculated.
714 \end_layout
716 \begin_layout Standard
717 The 
718 \begin_inset Flex CharStyle:Code
719 status collapsed
721 \begin_layout Plain Layout
722 noweb.sty
723 \end_layout
725 \end_inset
727  package is required as it is used for formatting the code chunk captions
728 \end_layout
730 \begin_layout Standard
731 The 
732 \begin_inset Flex CharStyle:Code
733 status collapsed
735 \begin_layout Plain Layout
736 listings.sty
737 \end_layout
739 \end_inset
741  package is also required, as it is used for formatting the code chunks
742  themselves.
743 \end_layout
745 \begin_layout Standard
746 The 
747 \begin_inset Flex CharStyle:Code
748 status collapsed
750 \begin_layout Plain Layout
751 xargs.sty
752 \end_layout
754 \end_inset
756  package is also required.
757 \end_layout
759 \begin_layout Chapter
760 Literate Programming with Newfangle
761 \end_layout
763 \begin_layout Standard
764 Todo.
765  Should really follow on from a part-0 explanation of what literate programming
766  is.
767 \end_layout
769 \begin_layout Chapter
770 Using Newfangle with LyX
771 \end_layout
773 \begin_layout Section
774 Setting up Lyx
775 \end_layout
777 \begin_layout Subsection
778 Installing the LyX module
779 \end_layout
781 \begin_layout Standard
782 Copy 
783 \begin_inset Flex CharStyle:Code
784 status collapsed
786 \begin_layout Plain Layout
787 newfangle.module
788 \end_layout
790 \end_inset
792  to your LyX layouts directory, which for unix users will be 
793 \begin_inset Flex CharStyle:Code
794 status collapsed
796 \begin_layout Plain Layout
797 ~/.lyx/layouts
798 \end_layout
800 \end_inset
803 \end_layout
805 \begin_layout Standard
806 You will need to reconfigure LyX by clicking Tools\SpecialChar \menuseparator
807 Reconfigure, and then
808  re-start LyX.
809 \end_layout
811 \begin_layout Subsection
812 \begin_inset CommandInset label
813 LatexCommand label
814 name "sub:Configuring-the-build"
816 \end_inset
818 Configuring the build script
819 \end_layout
821 \begin_layout Standard
822 Make sure you don't have a conversion defined for Lyx → Program
823 \end_layout
825 \begin_layout Standard
826 From the menu Tools\SpecialChar \menuseparator
827 Preferences, add a conversion from Latex(Plain) → Program
828  as:
829 \end_layout
831 \begin_layout LyX-Code
832 set -x ; newfangle -Rlyx-build $$i | 
833 \end_layout
835 \begin_layout LyX-Code
836   env LYX_b=$$b LYX_i=$$i LYX_o=$$o LYX_p=$$p LYX_r=$$r bash
837 \end_layout
839 \begin_layout Standard
840 (But don't cut-n-paste it from this document or you'll be pasting a multi-line
841  string which will break your lyx preferences file).
843 \end_layout
845 \begin_layout Standard
846 I hope that one day, LyX will set these into the environment when calling
847  the build script.
848 \end_layout
850 \begin_layout Standard
851 You may also want to consider adding options to this conversion\SpecialChar \ldots{}
853 \end_layout
855 \begin_layout LyX-Code
856 parselog=/usr/share/lyx/scripts/listerrors
857 \end_layout
859 \begin_layout Standard
860 \SpecialChar \ldots{}
861 but if you do you will lose your stderr
862 \begin_inset Foot
863 status collapsed
865 \begin_layout Plain Layout
866 There is some bash plumbing to get a copy of stderr but this footnote is
867  too small
868 \end_layout
870 \end_inset
873 \end_layout
875 \begin_layout Standard
876 Now, a shell script chunk called 
877 \begin_inset Flex CharStyle:Code
878 status collapsed
880 \begin_layout Plain Layout
881 lyx-build
882 \end_layout
884 \end_inset
886  will be extracted and run whenever you choose the Document\SpecialChar \menuseparator
887 Build Program
888  menu item.
889 \end_layout
891 \begin_layout Standard
892 The lyx-build script for this document is in section 
893 \begin_inset CommandInset ref
894 LatexCommand ref
895 reference "lyx-build-script"
897 \end_inset
899  and on a unix system will extract 
900 \begin_inset Flex CharStyle:Code
901 status collapsed
903 \begin_layout Plain Layout
904 newfangle.module
905 \end_layout
907 \end_inset
909  and the 
910 \begin_inset Flex CharStyle:Code
911 status collapsed
913 \begin_layout Plain Layout
914 newfangle
915 \end_layout
917 \end_inset
919  awk script, and run some basic tests.
921 \begin_inset Note Note
922 status collapsed
924 \begin_layout Plain Layout
925 cross-ref to test chapter when it is a chapter all on its own
926 \end_layout
928 \end_inset
931 \end_layout
933 \begin_layout Subsection
934 Preparing your Lyx document
935 \end_layout
937 \begin_layout Standard
938 It is not necessary to base your literate document on any of the original
939  LyX literate classes; so select a regular class for your document type.
940 \end_layout
942 \begin_layout Standard
943 Add the new module 
944 \emph on
945 Newfangle Literate
946 \emph default
948 \emph on
949 Listings
950 \emph default
951  and possibly also 
952 \emph on
953 Logical Markup
954 \emph default
956 \end_layout
958 \begin_layout Standard
959 In the drop-down style listbox you should notice a new style defined, called
961 \emph on
962 Chunk
963 \emph default
965 \end_layout
967 \begin_layout Standard
968 When you wish to insert a literate chunk, you enter it's plain name in the
969  Chunk style, instead of the older method that used 
970 \begin_inset Flex CharStyle:Code
971 status collapsed
973 \begin_layout Plain Layout
974 <<name>>=
975 \end_layout
977 \end_inset
979  type tags.
980  Following the chunk name, you insert a listing with: Insert\SpecialChar \menuseparator
981 Program Listing.
982 \end_layout
984 \begin_layout Standard
985 Inside the white listing box you can type (or paste using shift+ctrl+V)
986  your listing.
987  There is not need to use ctrl+enter at the end of lines as with some older
988  LyX literate techniques --- just press enter as normal.
989 \end_layout
991 \begin_layout Subsubsection
992 Customising the listing appearance
993 \end_layout
995 \begin_layout Standard
996 In the final document, the code is formatted using the 
997 \noun on
998 lstlistings
999 \noun default
1000  package.
1001  The chunk style doesn't just define the chunk name, but can also define
1002  any other chunk options supported by the lstlistings package 
1003 \begin_inset Flex CharStyle:Code
1004 status collapsed
1006 \begin_layout Plain Layout
1008 \backslash
1009 lstset
1010 \end_layout
1012 \end_inset
1014  command.
1015  In fact, what you type in the chunk style is raw latex.
1016  If you want to set the chunk language without having to right-click the
1017  listing, just add 
1018 \begin_inset Flex CharStyle:Code
1019 status collapsed
1021 \begin_layout Plain Layout
1022 ,lanuage=C
1023 \end_layout
1025 \end_inset
1027  after the chunk name.
1028  (Currently the language will affect all subsequent listings, so you may
1029  need to specify 
1030 \begin_inset Flex CharStyle:Code
1031 status collapsed
1033 \begin_layout Plain Layout
1034 ,language=
1035 \end_layout
1037 \end_inset
1039  quite a lot)
1040 \begin_inset Note Note
1041 status open
1043 \begin_layout Plain Layout
1044 so fix the bug
1045 \end_layout
1047 \end_inset
1050 \end_layout
1052 \begin_layout Standard
1053 Of course you can do this by editing the listings box advanced properties
1054  by right-clicking on the listings box, but that takes longer, and you can't
1055  see at-a-glance what the advanced settings are while editing the document;
1056  also advanced settings apply only to that box --- the chunk settings apply
1057  through the rest of the document
1058 \begin_inset Foot
1059 status collapsed
1061 \begin_layout Plain Layout
1062 It ought to apply only to subsequent chunks of the same name.
1063  I'll fix that later
1064 \end_layout
1066 \end_inset
1069 \begin_inset Note Note
1070 status collapsed
1072 \begin_layout Plain Layout
1073 So make sure they only apply to chunks of that name
1074 \end_layout
1076 \end_inset
1079 \end_layout
1081 \begin_layout Subsubsection
1082 Global customisations
1083 \end_layout
1085 \begin_layout Standard
1086 As 
1087 \emph on
1088 lstlistings
1089 \emph default
1090  is used to set the code chunks, it's 
1091 \begin_inset Flex CharStyle:Code
1092 status collapsed
1094 \begin_layout Plain Layout
1096 \backslash
1097 lstset
1098 \end_layout
1100 \end_inset
1102  command can be used in the pre-amble to set some document wide settings.
1103 \end_layout
1105 \begin_layout Standard
1106 If your source has many words with long sequences of capital letters, then
1108 \begin_inset Flex CharStyle:Code
1109 status collapsed
1111 \begin_layout Plain Layout
1112 columns=fullflexible
1113 \end_layout
1115 \end_inset
1117  may be a good idea, or the capital letters will get crowded.
1118  (I think lstlistings ought to use a slightly smaller font for captial letters
1119  so that they still fit).
1120 \end_layout
1122 \begin_layout Standard
1123 The font family 
1124 \begin_inset Flex CharStyle:Code
1125 status collapsed
1127 \begin_layout Plain Layout
1129 \backslash
1130 ttfamily
1131 \end_layout
1133 \end_inset
1135  looks more normal for code, but has no bold (an alternate typewriter font
1136  is used).
1138 \end_layout
1140 \begin_layout Standard
1141 With 
1142 \begin_inset Flex CharStyle:Code
1143 status collapsed
1145 \begin_layout Plain Layout
1147 \backslash
1148 ttfamily
1149 \end_layout
1151 \end_inset
1153 , I must also specify 
1154 \begin_inset Flex CharStyle:Code
1155 status collapsed
1157 \begin_layout Plain Layout
1158 columns=fullflexible
1159 \end_layout
1161 \end_inset
1163  or the wrong letter spacing is used.
1164 \end_layout
1166 \begin_layout Standard
1167 In my LeTeX pre-amble I usually specialise my code format with:
1168 \end_layout
1170 \begin_layout Chunk
1171 document-preamble,language=tex
1172 \end_layout
1174 \begin_layout Standard
1175 \begin_inset listings
1176 inline false
1177 status open
1179 \begin_layout Plain Layout
1182 \backslash
1183 lstset{
1184 \end_layout
1186 \begin_layout Plain Layout
1188 numbers=left, stepnumber=1, numbersep=5pt,
1189 \end_layout
1191 \begin_layout Plain Layout
1193 breaklines=false,
1194 \end_layout
1196 \begin_layout Plain Layout
1198 basicstyle=
1199 \backslash
1200 footnotesize
1201 \backslash
1202 ttfamily,
1203 \end_layout
1205 \begin_layout Plain Layout
1207 numberstyle=
1208 \backslash
1209 tiny,
1210 \end_layout
1212 \begin_layout Plain Layout
1214 language=C,
1215 \end_layout
1217 \begin_layout Plain Layout
1219 columns=fullflexible,
1220 \end_layout
1222 \begin_layout Plain Layout
1224 numberfirstline=true
1225 \end_layout
1227 \begin_layout Plain Layout
1230 \end_layout
1232 \end_inset
1235 \end_layout
1237 \begin_layout Chapter
1238 Newfangle with Makefiles
1239 \end_layout
1241 \begin_layout Standard
1242 \begin_inset CommandInset label
1243 LatexCommand label
1244 name "cha:makefile.inc"
1246 \end_inset
1249 \begin_inset Note Note
1250 status open
1252 \begin_layout Plain Layout
1253 This chapter needs revising
1254 \end_layout
1256 \end_inset
1259 \begin_inset Note Greyedout
1260 status open
1262 \begin_layout Plain Layout
1263 This chapter needs revising
1264 \end_layout
1266 \end_inset
1268 Here we describe a Makefile.inc that you can include in your own Makefiles,
1269  or glue as a recursive make to other projects.
1270 \end_layout
1272 \begin_layout Standard
1273 The Makefile.inc described here was put together for a Samba4 vfs module,
1274  but can be used in any Make project, including automake projects.
1275 \end_layout
1277 \begin_layout Section
1278 A word about makefiles formats
1279 \end_layout
1281 \begin_layout Standard
1282 Whitespace formatting is very important in a Makefile.
1283  The first character of each command line must be a TAB.
1284 \end_layout
1286 \begin_layout LyX-Code
1287 target: pre-requisite
1288 \begin_inset Newline newline
1289 \end_inset
1291    →    action
1292 \begin_inset Newline newline
1293 \end_inset
1295    →    action
1296 \end_layout
1298 \begin_layout Standard
1299 But a TAB is pretty hard to enter into most of the Lyx formats and insets
1300  I've been using.
1301  An alternative is to use a semi-colon after the pre-requisite, and a backslash
1302  at the end of each line (except the last).
1303  Then any whitespace (or none) can prefix each action.
1304 \end_layout
1306 \begin_layout LyX-Code
1307 target: pre-requisite ; 
1308 \backslash
1310 \begin_inset Newline newline
1311 \end_inset
1313 ␣␣action 
1314 \backslash
1316 \begin_inset Newline newline
1317 \end_inset
1319 ␣␣action
1320 \end_layout
1322 \begin_layout Standard
1323 This is the style that we use and it works pretty well for GNU make at least.
1324 \end_layout
1326 \begin_layout Standard
1327 We also adopt a convention that code chunks whose names beginning with ./
1328  should always be automatically extracted from the document.
1329  Code chunks whose names do not begin with ./ are for internal reference.
1330  (This doesn't prevent such chunks from being extracted directly).
1331 \end_layout
1333 \begin_layout Section
1334 Boot-strapping the extraction
1335 \end_layout
1337 \begin_layout Subsection
1338 Using a Makefile
1339 \end_layout
1341 \begin_layout Standard
1342 \begin_inset CommandInset label
1343 LatexCommand label
1344 name "sub:Bootstrap-Using-a-Makefile"
1346 \end_inset
1348 It seems convenient to have the makefile extract or update the C source
1349  files as part of it's operation.
1350  It also seems convenient to have the makefile itself extracted from this
1351  document.
1352 \end_layout
1354 \begin_layout Standard
1355 It would also be convenient to have the code to extract the makefile from
1356  this document to also be part of this document, however we have to start
1357  somewhere and this unfortunately requires us to type at least a few words
1358  by hand to start things off.
1359 \end_layout
1361 \begin_layout Standard
1362 Therefore we will have a minimal root fragment, which, when extracted, can
1363  cope with extracting the rest of the source.
1364  perhaps with this shell script, which could be called 
1365 \emph on
1366 autoboot
1367 \emph default
1369 \begin_inset Note Note
1370 status open
1372 \begin_layout Plain Layout
1373 FIX THIS CHUNK AND TEST IT
1374 \end_layout
1376 \end_inset
1379 \end_layout
1381 \begin_layout Chunk
1383 \end_layout
1385 \begin_layout Standard
1386 \begin_inset listings
1387 inline false
1388 status open
1390 \begin_layout Plain Layout
1392 #! /bin/sh
1393 \end_layout
1395 \begin_layout Plain Layout
1397 \end_layout
1399 \begin_layout Plain Layout
1401 MAKE_SRC="${1:-${NW_LYX:-../../noweb-lyx/noweb-lyx3.lyx}}"
1402 \end_layout
1404 \begin_layout Plain Layout
1406 MAKE_SRC=`dirname "$MAKE_SRC"`/`basename "$MAKE_SRC" .lyx`
1407 \end_layout
1409 \begin_layout Plain Layout
1411 NOWEB_SRC="${2:-${NOWEB_SRC:-$MAKE_SRC.lyx}}"
1412 \end_layout
1414 \begin_layout Plain Layout
1416 lyx -e latex $MAKE_SRC
1417 \end_layout
1419 \begin_layout Plain Layout
1421 \end_layout
1423 \begin_layout Plain Layout
1425 newfangle -R./Makefile.inc ${MAKE_SRC}.tex 
1426 \backslash
1428 \end_layout
1430 \begin_layout Plain Layout
1432   | sed "/NEWFANGLE_SOURCE=/s/^/#/;T;aNOWEB_SOURCE=$NEWFANGLE_SRC" 
1433 \backslash
1435 \end_layout
1437 \begin_layout Plain Layout
1439   | cpif ./Makefile.inc
1440 \end_layout
1442 \begin_layout Plain Layout
1444 \end_layout
1446 \begin_layout Plain Layout
1448 make -f ./Makefile.inc newfangle_sources
1449 \end_layout
1451 \end_inset
1454 \end_layout
1456 \begin_layout Standard
1457 The general Makefile can be invoked with 
1458 \emph on
1459 ./autoboot
1460 \emph default
1461  and can also be included into any automake file to automatically re-generate
1462  the source files.
1463 \end_layout
1465 \begin_layout Standard
1466 The 
1467 \emph on
1468 autoboot
1469 \emph default
1470  can be extracted with this command:
1471 \end_layout
1473 \begin_layout LyX-Code
1474 lyx -e latex newfangle.lyx && 
1475 \backslash
1477 \end_layout
1479 \begin_layout LyX-Code
1480 newfangle newfangle.lyx > ./autoboot
1481 \end_layout
1483 \begin_layout Standard
1484 This looks simple enough, but as mentioned, newfangle has to be had from
1485  somewhere before it can be extracted.
1486 \end_layout
1488 \begin_layout Subsection
1489 \begin_inset Note Note
1490 status collapsed
1492 \begin_layout Plain Layout
1493 MERGE THIS WITH THE SECTIONS OF THIS DOCUMENT
1494 \end_layout
1496 \end_inset
1498 \SpecialChar \ldots{}
1500 \end_layout
1502 \begin_layout Standard
1503 When the lyx-build chunk is executed, the current directory will be a temporary
1504  directory, and 
1505 \begin_inset Flex CharStyle:Code
1506 status collapsed
1508 \begin_layout Plain Layout
1509 LYX_SOURCE
1510 \end_layout
1512 \end_inset
1514  will refer to the tex file in this temporary directory.
1515  This is unfortunate as our makefile wants to run from the project directory
1516  where the Lyx file is kept.
1517 \end_layout
1519 \begin_layout Standard
1520 We can extract the project directory from $$r, and derive the probable Lyx
1521  filename from the noweb file that Lyx generated.
1522 \end_layout
1524 \begin_layout Chunk
1525 lyx-build-helper
1526 \end_layout
1528 \begin_layout Standard
1529 \begin_inset listings
1530 inline false
1531 status open
1533 \begin_layout Plain Layout
1535 PROJECT_DIR="$LYX_r"
1536 \end_layout
1538 \begin_layout Plain Layout
1540 LYX_SRC="$PROJECT_DIR/${LYX_i%.tex}.lyx"
1541 \end_layout
1543 \begin_layout Plain Layout
1545 TEX_DIR="$LYX_p"
1546 \end_layout
1548 \begin_layout Plain Layout
1550 TEX_SRC="$TEX_DIR/$LYX_i"
1551 \end_layout
1553 \end_inset
1556 \end_layout
1558 \begin_layout Standard
1559 And then we can define a lyx-build fragment similar to the autoboot fragment
1560 \end_layout
1562 \begin_layout Chunk
1563 lyx-build
1564 \end_layout
1566 \begin_layout Standard
1567 \begin_inset listings
1568 inline false
1569 status open
1571 \begin_layout Plain Layout
1573 #! /bin/sh
1574 \end_layout
1576 \begin_layout Plain Layout
1579 \backslash
1580 chunkref{lyx-build-helper}>
1581 \end_layout
1583 \begin_layout Plain Layout
1585 cd $PROJECT_DIR || exit 1
1586 \end_layout
1588 \begin_layout Plain Layout
1590 \end_layout
1592 \begin_layout Plain Layout
1594 #/usr/bin/newfangle -filter ./notanglefix-filter 
1595 \backslash
1597 \end_layout
1599 \begin_layout Plain Layout
1601 #  -R./Makefile.inc "../../noweb-lyx/noweb-lyx3.lyx" 
1602 \backslash
1604 \end_layout
1606 \begin_layout Plain Layout
1608 #  | sed '/NOWEB_SOURCE=/s/=.*/=samba4-dfs.lyx/' 
1609 \backslash
1611 \end_layout
1613 \begin_layout Plain Layout
1615 #  > ./Makefile.inc
1616 \end_layout
1618 \begin_layout Plain Layout
1621 \end_layout
1623 \begin_layout Plain Layout
1625 #make -f ./Makefile.inc newfangle_sources
1626 \end_layout
1628 \end_inset
1631 \end_layout
1633 \begin_layout Section
1634 Extracting Sources
1635 \end_layout
1637 \begin_layout Subsection
1638 Including Makefile.inc
1639 \end_layout
1641 \begin_layout Standard
1642 \begin_inset CommandInset label
1643 LatexCommand label
1644 name "sub:Keeping-extracted-files"
1646 \end_inset
1648 Makefile.inc will cope with extracting all the other source files from this
1649  document and keeping them up to date.
1651 \end_layout
1653 \begin_layout Standard
1654 It may also be included by a Makefile or Makefile.am defined in a Lyx document
1655  to automatically deal with the extraction of source files and documents.
1656 \end_layout
1658 \begin_layout Standard
1659 A makefile has two parts; variables must be defined before the targets that
1660  use them.
1661 \end_layout
1663 \begin_layout Chunk
1664 ./Makefile.inc
1665 \end_layout
1667 \begin_layout Standard
1668 \begin_inset listings
1669 inline false
1670 status open
1672 \begin_layout Plain Layout
1675 \backslash
1676 chunkref{Makefile.inc-vars}>
1677 \end_layout
1679 \begin_layout Plain Layout
1682 \backslash
1683 chunkref{Makefile.inc-targets}>
1684 \end_layout
1686 \end_inset
1689 \end_layout
1691 \begin_layout Standard
1692 We first define 
1693 \begin_inset Flex CharStyle:Code
1694 status collapsed
1696 \begin_layout Plain Layout
1697 NOWEB_SOURCE
1698 \end_layout
1700 \end_inset
1702  to hold the name of this Lyx file.
1703 \end_layout
1705 \begin_layout Chunk
1706 Makefile.inc-vars
1707 \end_layout
1709 \begin_layout Standard
1710 \begin_inset listings
1711 inline false
1712 status open
1714 \begin_layout Plain Layout
1716 LYX_SOURCE=
1717 \end_layout
1719 \begin_layout Plain Layout
1721 LITERATE_SOURCE=$(LYX_SOURCE)
1722 \end_layout
1724 \end_inset
1727 \end_layout
1729 \begin_layout Subsection
1730 Recursive use of Makefile.inc
1731 \end_layout
1733 \begin_layout Standard
1734 The makefile glue described here is used when building Samba4 vfs modules.
1735 \end_layout
1737 \begin_layout Standard
1738 If you are defining a module of an existing program you may find it easier
1739  to use a slight recursive make instead of including the makefile directly.
1740  This way there is less chance of definitions in Makefile.inc interfering
1741  with definitions in the main makefile, or with definitions in other Makefile.inc
1742  from other noweb modules.
1743 \end_layout
1745 \begin_layout Standard
1746 The glue works by adding a .PHONY target to call the recursive make, and
1747  adding this target as an additional pre-requisite to the existing targets.
1748 \end_layout
1750 \begin_layout Standard
1751 In this example, the existing build system already has a build target for
1753 \begin_inset Flex CharStyle:Code
1754 status collapsed
1756 \begin_layout Plain Layout
1757 example.o
1758 \end_layout
1760 \end_inset
1762 , so we just add another pre-requisite to that.
1763  In this case we use 
1764 \begin_inset Flex CharStyle:Code
1765 status collapsed
1767 \begin_layout Plain Layout
1768 example.tex.stamp
1769 \end_layout
1771 \end_inset
1773  as a pre-requisite, the stamp file's modified time indicating when all
1774  sources were extracted.
1775 \end_layout
1777 \begin_layout Chunk
1778 makefile-glue
1779 \end_layout
1781 \begin_layout Standard
1782 \begin_inset listings
1783 inline false
1784 status open
1786 \begin_layout Plain Layout
1788 $(example_srcdir)/example.o: $(example_srcdir)/example.tex.stamp
1789 \end_layout
1791 \end_inset
1794 \end_layout
1796 \begin_layout Standard
1797 The target for this new pre-requisite is generated by a recursive make using
1798  Makefile.inc which will make sure that the source is up to date, before
1799  it is built by the main projects makefile.
1800 \end_layout
1802 \begin_layout Chunk
1803 makefile-glue
1804 \end_layout
1806 \begin_layout Standard
1807 \begin_inset listings
1808 inline false
1809 status open
1811 \begin_layout Plain Layout
1813 $(example_srcdir)/example.tex.stamp: $(example_srcdir)/example.tex ; 
1814 \backslash
1816 \end_layout
1818 \begin_layout Plain Layout
1820         cd $(example_srcdir) && 
1821 \backslash
1823 \end_layout
1825 \begin_layout Plain Layout
1827         $(MAKE) -f Makefile.inc newfangle_sources
1828 \end_layout
1830 \end_inset
1833 \end_layout
1835 \begin_layout Standard
1836 We can do similar glue for the docs, clean and distclean targets.
1837  In this example our build system is using a double colon for these targets,
1838  so we use the same in our glue.
1839 \end_layout
1841 \begin_layout Chunk
1842 makefile-glue
1843 \end_layout
1845 \begin_layout Standard
1846 \begin_inset listings
1847 inline false
1848 status open
1850 \begin_layout Plain Layout
1852 docs:: docs_example
1853 \end_layout
1855 \begin_layout Plain Layout
1857 .PHONY: docs_example
1858 \end_layout
1860 \begin_layout Plain Layout
1862 docs_example:: ; cd $(example_srcdir) && 
1863 \backslash
1865 \end_layout
1867 \begin_layout Plain Layout
1869         $(MAKE) -f Makefile.inc docs
1870 \end_layout
1872 \begin_layout Plain Layout
1874 \end_layout
1876 \begin_layout Plain Layout
1878 clean:: clean_example
1879 \end_layout
1881 \begin_layout Plain Layout
1883 .PHONEY: clean_example
1884 \end_layout
1886 \begin_layout Plain Layout
1888 clean_example: ; cd $(example_srcdir) && 
1889 \backslash
1891 \end_layout
1893 \begin_layout Plain Layout
1895         $(MAKE) -f Makefile.inc clean
1896 \end_layout
1898 \begin_layout Plain Layout
1900 \end_layout
1902 \begin_layout Plain Layout
1904 distclean:: distclean_example
1905 \end_layout
1907 \begin_layout Plain Layout
1909 .PHONY: distclean_example
1910 \end_layout
1912 \begin_layout Plain Layout
1914 distclean_example: ; cd $(example_srcdir) && 
1915 \backslash
1917 \end_layout
1919 \begin_layout Plain Layout
1921         $(MAKE) -f Makefile.inc distclean
1922 \end_layout
1924 \end_inset
1927 \end_layout
1929 \begin_layout Standard
1930 We could do similarly for install targets to install the generated docs.
1931 \end_layout
1933 \begin_layout Subsection
1934 \begin_inset CommandInset label
1935 LatexCommand label
1936 name "sub:Converting-from-Lyx"
1938 \end_inset
1940 Converting from Lyx to LaTeX
1941 \end_layout
1943 \begin_layout Standard
1944 The first stage will always be to convert the Lyx file to a LaTeX file;
1945  this must be so not only because newfangle needs to to run on a TeX file,
1946  but also because the Lyx command 
1947 \emph on
1948 server-goto-file-line
1949 \begin_inset Foot
1950 status collapsed
1952 \begin_layout Plain Layout
1953 The Lyx command 
1954 \emph on
1955 server-goto-file-line
1956 \emph default
1957  is used to position the Lyx cursor at the compiler errors.
1958 \end_layout
1960 \end_inset
1963 \emph default
1964  insists that the line number provided is a line in the TeX file, and always
1965  reverse maps this to derive the line in the Lyx docment.
1966 \begin_inset Note Note
1967 status collapsed
1969 \begin_layout Plain Layout
1970 The tex file should probably be an automake extra dist sources or something,
1971  so that it gets produced and packaged by make dist
1972 \end_layout
1974 \end_inset
1977 \end_layout
1979 \begin_layout Standard
1980 The command [[lyx -e literate noweb-lyx.lyx]] will produce [[noweb-lyx.nw]]
1981  a tex file, so we define the noweb target to be the same as the Lyx file
1982  but with the .nw extension.
1983 \end_layout
1985 \begin_layout Chunk
1986 Makefile.inc-vars
1987 \end_layout
1989 \begin_layout Standard
1990 \begin_inset listings
1991 inline false
1992 status open
1994 \begin_layout Plain Layout
1996 TEX_SOURCE=$(LYX_SOURCE:.lyx=.tex)
1997 \end_layout
1999 \end_inset
2002 \end_layout
2004 \begin_layout Chunk
2005 Makefile.inc-targets
2006 \end_layout
2008 \begin_layout Standard
2009 \begin_inset listings
2010 inline false
2011 status open
2013 \begin_layout Plain Layout
2015 $(TEX_SOURCE): $(LYX_SOURCE) ;
2016 \backslash
2018 \end_layout
2020 \begin_layout Plain Layout
2022         lyx -e latex $<
2023 \end_layout
2025 \begin_layout Plain Layout
2027 clean_tex: ; rm -f -- $(TEX_SOURCE)
2028 \end_layout
2030 \end_inset
2033 \end_layout
2035 \begin_layout Subsection
2036 Extracting Program Source
2037 \end_layout
2039 \begin_layout Standard
2040 The program source is extracted using newfangle, which is designed to operate
2041  on a LaTeX document.
2043 \end_layout
2045 \begin_layout Chunk
2046 Makefile.inc-vars
2047 \end_layout
2049 \begin_layout Standard
2050 \begin_inset listings
2051 inline false
2052 status open
2054 \begin_layout Plain Layout
2056 NEWFANGLE_SOURCE=$(TEX_SOURCE)
2057 \end_layout
2059 \end_inset
2062 \end_layout
2064 \begin_layout Standard
2065 The Lyx document can result in any number of source documents, but not all
2066  of these will be changed each time the Lyx document is updated.
2067  We certainly don't want to update the timestamps of these files and cause
2068  the whole source tree to be recompiled just because the Lyx document was
2069  edited.
2071 \end_layout
2073 \begin_layout Standard
2074 To solve this problem we use a stamp file which is always updated each time
2075  the sources are extracted from the LaTeX document.
2076  If the stamp file is older than the LaTeX document, then we can make an
2077  attempt to re-extract the sources.
2078 \end_layout
2080 \begin_layout Chunk
2081 Makefile.inc-vars
2082 \end_layout
2084 \begin_layout Standard
2085 \begin_inset listings
2086 inline false
2087 status open
2089 \begin_layout Plain Layout
2091 NEWFANGLE_SOURCE_STAMP=$(NEWFANGLE_SOURCE).stamp
2092 \end_layout
2094 \end_inset
2097 \end_layout
2099 \begin_layout Chunk
2100 Makefile.inc-targets
2101 \end_layout
2103 \begin_layout Standard
2104 \begin_inset listings
2105 inline false
2106 status open
2108 \begin_layout Plain Layout
2110 $(NEWFANGLE_SOURCE_STAMP): $(NEWFANGLE_SOURCE) 
2111 \backslash
2113 \end_layout
2115 \begin_layout Plain Layout
2117                            $(NEWFANGLE_SOURCES) ; 
2118 \backslash
2120 \end_layout
2122 \begin_layout Plain Layout
2124         echo > $(NEWFANGLE_SOURCE_STAMP)
2125 \end_layout
2127 \begin_layout Plain Layout
2129 clean_stamp: ; rm -f $(NEWFANGLE_SOURCE_STAMP)
2130 \end_layout
2132 \begin_layout Plain Layout
2134 clean: clean_stamp
2135 \end_layout
2137 \end_inset
2140 \end_layout
2142 \begin_layout Subsection
2143 Extracting C sources
2144 \end_layout
2146 \begin_layout Standard
2147 We compute 
2148 \begin_inset Flex CharStyle:Code
2149 status collapsed
2151 \begin_layout Plain Layout
2152 NEWFANGLE_SOURCES
2153 \end_layout
2155 \end_inset
2157  to hold the names of all the C source files defined in this document.
2158  We compute this only once, by means of := in assignent.
2159  The sed deletes the any <
2160 \begin_inset space \hspace*{}
2161 \length 0in
2162 \end_inset
2164 < and >
2165 \begin_inset space \hspace*{}
2166 \length 0in
2167 \end_inset
2169 > which may surround the roots names (for noroots compatibility).
2171 \end_layout
2173 \begin_layout Standard
2174 As we use chunk names beginning with ./ to denote top level fragments that
2175  should be extracted, we filter out all fragments that do not begin with
2176  ./
2177 \end_layout
2179 \begin_layout Chunk
2180 Makefile.inc-vars
2181 \end_layout
2183 \begin_layout Standard
2184 \begin_inset listings
2185 inline false
2186 status open
2188 \begin_layout Plain Layout
2190 NEWFANGLE_PREFIX:=
2191 \backslash
2193 \backslash
2195 \end_layout
2197 \begin_layout Plain Layout
2199 NEWFANGLE_SOURCES:=$(shell 
2200 \backslash
2202 \end_layout
2204 \begin_layout Plain Layout
2206   newfangle -r $(NEWFANGLE_SOURCE) |
2207 \backslash
2209 \end_layout
2211 \begin_layout Plain Layout
2213   sed -e 's/^[<][<]//;s/[>][>]$$//;/^$(NEWFANGLE_PREFIX)/!d' 
2214 \backslash
2216 \end_layout
2218 \begin_layout Plain Layout
2220       -e 's/^$(NEWFANGLE_PREFIX)/
2221 \backslash
2223 \backslash
2224 //' )
2225 \end_layout
2227 \begin_layout Plain Layout
2230 \end_layout
2232 \end_inset
2235 \end_layout
2237 \begin_layout Chunk
2238 Makefile.inc-targets
2239 \end_layout
2241 \begin_layout Standard
2242 \begin_inset listings
2243 inline false
2244 status open
2246 \begin_layout Plain Layout
2248 .PHONY: echo_newfangle_sources
2249 \end_layout
2251 \begin_layout Plain Layout
2253 echo_newfangle_sources: ; @echo $(NEWFANGLE_SOURCES)
2254 \end_layout
2256 \end_inset
2259 \end_layout
2261 \begin_layout Standard
2262 We define a convenient target called 
2263 \begin_inset Flex CharStyle:Code
2264 status collapsed
2266 \begin_layout Plain Layout
2267 newfangle_sources
2268 \end_layout
2270 \end_inset
2272  to re-extract the source if the LaTeX file has been updated.
2273 \end_layout
2275 \begin_layout Chunk
2276 Makefile.inc-targets
2277 \end_layout
2279 \begin_layout Standard
2280 \begin_inset listings
2281 inline false
2282 status open
2284 \begin_layout Plain Layout
2286 .PHONY: newfangle_sources
2287 \end_layout
2289 \begin_layout Plain Layout
2291 newfangle_sources: $(NEWFANGLE_SOURCE_STAMP)
2292 \end_layout
2294 \end_inset
2297 \end_layout
2299 \begin_layout Standard
2300 And also a convenient target to remove extracted sources.
2301 \end_layout
2303 \begin_layout Chunk
2304 Makefile.inc-targets
2305 \end_layout
2307 \begin_layout Standard
2308 \begin_inset listings
2309 inline false
2310 status open
2312 \begin_layout Plain Layout
2314 .PHONY: clean_newfangle_sources
2315 \end_layout
2317 \begin_layout Plain Layout
2319 clean_newfangle_sources: ; 
2320 \backslash
2322 \end_layout
2324 \begin_layout Plain Layout
2326         rm -f -- $(NEWFANGLE_SOURCE_STAMP) $(NEWFANGLE_SOURCES)
2327 \end_layout
2329 \end_inset
2332 \end_layout
2334 \begin_layout Standard
2335 This 
2336 \begin_inset Flex CharStyle:Code
2337 status collapsed
2339 \begin_layout Plain Layout
2340 if_extension
2341 \end_layout
2343 \end_inset
2345  macro takes 4 arguments: the filename (1), some extensions to match (2)
2346  and a some shell command to return if the filename matches the exentions
2347  (3), or not (4).
2348 \end_layout
2350 \begin_layout Chunk
2351 Makefile.inc-vars
2352 \end_layout
2354 \begin_layout Standard
2355 \begin_inset listings
2356 inline false
2357 status open
2359 \begin_layout Plain Layout
2361 if_extension=$(if $(findstring $(suffix $(1)),$(2)),$(3),$(4))
2362 \end_layout
2364 \end_inset
2367 \end_layout
2369 \begin_layout Standard
2370 For some source files like C files, we want to output the line number and
2371  filename of the original LaTeX document from which the source came.
2372 \end_layout
2374 \begin_layout Standard
2375 To make this easier we define the file extensions for which we want to do
2376  this.
2377 \end_layout
2379 \begin_layout Chunk
2380 Makefile.inc-vars
2381 \end_layout
2383 \begin_layout Standard
2384 \begin_inset listings
2385 inline false
2386 status open
2388 \begin_layout Plain Layout
2390 C_EXTENSIONS=.c .h
2391 \end_layout
2393 \end_inset
2396 \end_layout
2398 \begin_layout Standard
2399 We can then use the if_extensions macro to define a macro which expands
2400  out to the 
2401 \begin_inset Flex CharStyle:Code
2402 status collapsed
2404 \begin_layout Plain Layout
2406 \end_layout
2408 \end_inset
2410  option if newfangle is being invoked in a C source file, so that C compile
2411  errors will refer to the line number in the Lyx document.
2413 \end_layout
2415 \begin_layout Chunk
2416 Makefile.inc-vars
2417 \end_layout
2419 \begin_layout Standard
2420 \begin_inset listings
2421 inline false
2422 status open
2424 \begin_layout Plain Layout
2426 TABS=8
2427 \end_layout
2429 \begin_layout Plain Layout
2431 nf_line=-L -T$(TABS)
2432 \end_layout
2434 \begin_layout Plain Layout
2436 newfangle=newfangle 
2437 \backslash
2439 \end_layout
2441 \begin_layout Plain Layout
2443   $(call if_extension,$(2),$(C_EXTENSIONS),$(nf_line)) 
2444 \backslash
2446 \end_layout
2448 \begin_layout Plain Layout
2450     -R"$(2)" $(1)
2451 \end_layout
2453 \end_inset
2456 \end_layout
2458 \begin_layout Standard
2459 We can use a similar trick to define an 
2460 \emph on
2461 indent
2462 \emph default
2463  macro which takes just the filename as an argument and can return a pipeline
2464  stage calling the indent command.
2465  Indent can be turned off with 
2466 \begin_inset Flex CharStyle:Code
2467 status collapsed
2469 \begin_layout Plain Layout
2470 make newfangle_sources indent=
2471 \end_layout
2473 \end_inset
2476 \end_layout
2478 \begin_layout Chunk
2479 Makefile.inc-vars
2480 \end_layout
2482 \begin_layout Standard
2483 \begin_inset listings
2484 inline false
2485 status open
2487 \begin_layout Plain Layout
2489 indent_options=-npro -kr -i8 -ts8 -sob -l80 -ss -ncs
2490 \end_layout
2492 \begin_layout Plain Layout
2494 indent=$(call if_extension,$(1),$(C_EXTENSIONS),
2495 \backslash
2497 \end_layout
2499 \begin_layout Plain Layout
2501               | indent $(indent_options))
2502 \end_layout
2504 \end_inset
2507 \end_layout
2509 \begin_layout Standard
2510 We now define the pattern for extracting a file.
2511  The files are written using noweb's 
2512 \emph on
2513 cpif
2514 \begin_inset Foot
2515 status collapsed
2517 \begin_layout Plain Layout
2519 \emph on
2520 So you still need noweb installed in order to use cpif
2521 \end_layout
2523 \end_inset
2526 \begin_inset Note Note
2527 status collapsed
2529 \begin_layout Plain Layout
2531 \emph on
2532 Write an awk version
2533 \end_layout
2535 \end_inset
2538 \emph default
2539  so that the file timestamp will not be touched if the contents haven't
2540  changed.
2541  This avoids the need to rebuild the entire project because of a typographical
2542  change in the documentation, or if only a few C source files have changed.
2543 \end_layout
2545 \begin_layout Chunk
2546 Makefile.inc-vars
2547 \end_layout
2549 \begin_layout Standard
2550 \begin_inset listings
2551 inline false
2552 status open
2554 \begin_layout Plain Layout
2556 newfangle_extract=@mkdir -p $(dir $(1)) && 
2557 \backslash
2559 \end_layout
2561 \begin_layout Plain Layout
2563   $(call newfangle,$(2),$(1)) > "$(1).tmp" && 
2564 \backslash
2566 \end_layout
2568 \begin_layout Plain Layout
2570   cat "$(1).tmp" $(indent) | cpif "$(1)" 
2571 \backslash
2573 \end_layout
2575 \begin_layout Plain Layout
2577   && rm -- "$(1).tmp" || 
2578 \backslash
2580 \end_layout
2582 \begin_layout Plain Layout
2584   (echo error newfangling $(1) from $(2) ; exit 1)
2585 \end_layout
2587 \end_inset
2590 \end_layout
2592 \begin_layout Standard
2593 We define a target which will extract or update all sources.
2594  To do this we first defined a makefile template that can do this for any
2595  source file in the LaTeX document.
2596 \end_layout
2598 \begin_layout Chunk
2599 Makefile.inc-vars
2600 \end_layout
2602 \begin_layout Standard
2603 \begin_inset listings
2604 inline false
2605 status open
2607 \begin_layout Plain Layout
2609 define NEWFANGLE_template
2610 \end_layout
2612 \begin_layout Plain Layout
2614   $(1): $(2); 
2615 \backslash
2617 \end_layout
2619 \begin_layout Plain Layout
2621     $$(call newfangle_extract,$(1),$(2))
2622 \end_layout
2624 \begin_layout Plain Layout
2626   NEWFANGLE_TARGETS+=$(1)
2627 \end_layout
2629 \begin_layout Plain Layout
2631 endef
2632 \end_layout
2634 \end_inset
2637 \end_layout
2639 \begin_layout Standard
2640 We then enumerate the discovered 
2641 \begin_inset Flex CharStyle:Code
2642 status collapsed
2644 \begin_layout Plain Layout
2645 NEWTANGLE_SOURCES
2646 \end_layout
2648 \end_inset
2650  to generate a makefile rule for each one using the makefile template we
2651  defined above.
2652 \end_layout
2654 \begin_layout Chunk
2655 Makefile.inc-targets
2656 \end_layout
2658 \begin_layout Standard
2659 \begin_inset listings
2660 inline false
2661 status open
2663 \begin_layout Plain Layout
2665 $(foreach source,$(NEWFANGLE_SOURCES),
2666 \backslash
2668 \end_layout
2670 \begin_layout Plain Layout
2672   $(eval $(call NEWFANGLE_template,$(source),$(NEWFANGLE_SOURCE))) 
2673 \backslash
2675 \end_layout
2677 \begin_layout Plain Layout
2680 \end_layout
2682 \end_inset
2685 \end_layout
2687 \begin_layout Standard
2688 These will all be built with NEWFANGLE_SOURCE_STAMP.
2689 \end_layout
2691 \begin_layout Standard
2692 We also remove the generated sources on a 
2693 \emph on
2694 make distclean
2695 \emph default
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 _distclean: clean_newfangle_sources
2711 \end_layout
2713 \end_inset
2716 \end_layout
2718 \begin_layout Subsection
2719 Extracting Documentation
2720 \end_layout
2722 \begin_layout Standard
2723 We then identify the intermediate stages of the documentation and their
2724  build and clean targets.
2725 \end_layout
2727 \begin_layout Subsubsection
2728 Running pdflatex
2729 \end_layout
2731 \begin_layout Standard
2732 We produce a pdf file from the tex file.
2733 \end_layout
2735 \begin_layout Chunk
2736 Makefile.inc-vars
2737 \end_layout
2739 \begin_layout Standard
2740 \begin_inset listings
2741 inline false
2742 status open
2744 \begin_layout Plain Layout
2746 NEWFANGLE_PDF=$(TEX_SOURCE:.tex=.pdf)
2747 \end_layout
2749 \end_inset
2752 \end_layout
2754 \begin_layout Standard
2755 We run pdflatex twice to be sure that the contents and aux files are up
2756  to date.
2757  We certainly are required to run pdflatex twice if these files do not exist!
2758 \end_layout
2760 \begin_layout Chunk
2761 Makefile.inc-targets
2762 \end_layout
2764 \begin_layout Standard
2765 \begin_inset listings
2766 inline false
2767 status open
2769 \begin_layout Plain Layout
2771 $(NEWFANGLE_PDF): $(TEX_SOURCE); pdflatex $< && pdflatex $<
2772 \end_layout
2774 \begin_layout Plain Layout
2776 clean_pdf: ; rm -f -- $(NEWFANGLE_PDF) 
2777 \backslash
2779 \end_layout
2781 \begin_layout Plain Layout
2783                       $(TEX_SOURCE:.tex=.toc) 
2784 \backslash
2786 \end_layout
2788 \begin_layout Plain Layout
2790                       $(TEX_SOURCE:.tex=.log) 
2791 \backslash
2793 \end_layout
2795 \begin_layout Plain Layout
2797                       $(TEX_SOURCE:.tex=.aux)
2798 \end_layout
2800 \end_inset
2803 \end_layout
2805 \begin_layout Subsubsection
2806 The docs as a whole
2807 \end_layout
2809 \begin_layout Standard
2810 Currently we only build pdf as a final format, but NEWFANGLE_DOCS may later
2811  hold other output formats.
2812 \end_layout
2814 \begin_layout Chunk
2815 Makefile.inc-vars
2816 \end_layout
2818 \begin_layout Standard
2819 \begin_inset listings
2820 inline false
2821 status open
2823 \begin_layout Plain Layout
2825 NEWFANGLE_DOCS=$(NEWFANGLE_PDF)
2826 \end_layout
2828 \end_inset
2831 \end_layout
2833 \begin_layout Standard
2834 We also define newfangle_docs as a convenient phony target<
2835 \end_layout
2837 \begin_layout Chunk
2838 Makefile.inc-targets
2839 \end_layout
2841 \begin_layout Standard
2842 \begin_inset listings
2843 inline false
2844 status open
2846 \begin_layout Plain Layout
2848 .PHONY: newfangle_docs
2849 \end_layout
2851 \begin_layout Plain Layout
2853 newfangle_docs: $(NEWFANGLE_DOCS)
2854 \end_layout
2856 \begin_layout Plain Layout
2858 docs: newfangle_docs
2859 \end_layout
2861 \end_inset
2864 \end_layout
2866 \begin_layout Standard
2867 And define a convenient clean_noweb_docs which we add to the regular clean
2868  target
2869 \end_layout
2871 \begin_layout Chunk
2872 Makefile.inc-targets
2873 \end_layout
2875 \begin_layout Standard
2876 \begin_inset listings
2877 inline false
2878 status open
2880 \begin_layout Plain Layout
2882 .PHONEY: clean_newfangle_docs
2883 \end_layout
2885 \begin_layout Plain Layout
2887 clean_newfangle_docs: clean_tex clean_pdf
2888 \end_layout
2890 \begin_layout Plain Layout
2892 clean: clean_newfangle_docs
2893 \end_layout
2895 \begin_layout Plain Layout
2897 \end_layout
2899 \begin_layout Plain Layout
2901 distclean_newfangle_docs: clean_tex clean_newfangle_docs
2902 \end_layout
2904 \begin_layout Plain Layout
2906 distclean: clean distclean_newfangle_docs
2907 \end_layout
2909 \end_inset
2912 \end_layout
2914 \begin_layout Subsection
2915 Other helpers
2916 \end_layout
2918 \begin_layout Standard
2919 If Makefile.inc is included into Makefile, then extracted files can be updated
2920  with this command:
2921 \end_layout
2923 \begin_layout LyX-Code
2924 make newfangle_sources
2925 \end_layout
2927 \begin_layout Standard
2928 otherwise, with:
2929 \end_layout
2931 \begin_layout LyX-Code
2932 make -f Makefile.inc newfangle_sources
2933 \end_layout
2935 \begin_layout Part
2936 Source Code
2937 \end_layout
2939 \begin_layout Chapter
2940 Newfangle awk source code
2941 \end_layout
2943 \begin_layout Standard
2944 We use the copyright notice from chapter 
2945 \begin_inset CommandInset ref
2946 LatexCommand ref
2947 reference "cha:License"
2949 \end_inset
2952 \end_layout
2954 \begin_layout Chunk
2955 ./newfangle,language=awk,morestring=[b]{/},morekeywords=else
2956 \end_layout
2958 \begin_layout Standard
2959 \begin_inset listings
2960 inline false
2961 status open
2963 \begin_layout Plain Layout
2965 #! /usr/bin/awk -f
2966 \end_layout
2968 \begin_layout Plain Layout
2970 # =<
2971 \backslash
2972 chunkref{gpl3-copyright}>
2973 \end_layout
2975 \begin_layout Plain Layout
2977 \end_layout
2979 \end_inset
2982 \end_layout
2984 \begin_layout Standard
2985 We also use code from Arnold Robbins public domain getopt (1993 revision)
2986  defined in chapter 
2987 \begin_inset CommandInset ref
2988 LatexCommand ref
2989 reference "cha:getopt"
2991 \end_inset
2993 , and naturally want to attribute this appropriately.
2994 \end_layout
2996 \begin_layout Standard
2997 \begin_inset listings
2998 inline false
2999 status open
3001 \begin_layout Plain Layout
3003 \end_layout
3005 \begin_layout Plain Layout
3007 # NOTE: Arnold Robbins public domain getopt for awk is also used:
3008 \end_layout
3010 \begin_layout Plain Layout
3013 \backslash
3014 chunkref{getopt.awk-header}>
3015 \end_layout
3017 \begin_layout Plain Layout
3019 \end_layout
3021 \begin_layout Plain Layout
3024 \backslash
3025 chunkref{getopt.awk-getopt()}>
3026 \end_layout
3028 \begin_layout Plain Layout
3030 \end_layout
3032 \end_inset
3035 \end_layout
3037 \begin_layout Standard
3038 And include the following chunks
3039 \end_layout
3041 \begin_layout Chunk
3042 ./newfangle
3043 \end_layout
3045 \begin_layout Standard
3046 \begin_inset listings
3047 inline false
3048 status open
3050 \begin_layout Plain Layout
3053 \backslash
3054 chunkref{helper-functions}>
3055 \end_layout
3057 \begin_layout Plain Layout
3060 \backslash
3061 chunkref{mode-tracker}>
3062 \end_layout
3064 \begin_layout Plain Layout
3067 \backslash
3068 chunkref{parse_chunk_args}>
3069 \end_layout
3071 \begin_layout Plain Layout
3074 \backslash
3075 chunkref{chunk-storage-functions}>
3076 \end_layout
3078 \begin_layout Plain Layout
3081 \backslash
3082 chunkref{output_chunk_names()}>
3083 \end_layout
3085 \begin_layout Plain Layout
3088 \backslash
3089 chunkref{output_chunks()}>
3090 \end_layout
3092 \begin_layout Plain Layout
3095 \backslash
3096 chunkref{write_chunk()}>
3097 \end_layout
3099 \begin_layout Plain Layout
3102 \backslash
3103 chunkref{expand_chunk_args()}>
3104 \end_layout
3106 \begin_layout Plain Layout
3109 \backslash
3110 chunkref{begin}>
3111 \end_layout
3113 \begin_layout Plain Layout
3116 \backslash
3117 chunkref{recognize-chunk}>
3118 \end_layout
3120 \begin_layout Plain Layout
3123 \backslash
3124 chunkref{end}>
3125 \end_layout
3127 \end_inset
3130 \end_layout
3132 \begin_layout Section
3133 AWK tricks
3134 \end_layout
3136 \begin_layout Standard
3137 The portable way to erase an array in awk is to split the empty string,
3138  like this:
3139 \end_layout
3141 \begin_layout Chunk
3142 awk-delete-array,params=ARRAY
3143 \end_layout
3145 \begin_layout Standard
3146 \begin_inset listings
3147 inline false
3148 status open
3150 \begin_layout Plain Layout
3152 split("", ${ARRAY});
3153 \end_layout
3155 \end_inset
3158 \end_layout
3160 \begin_layout Chunk
3161 dump-array,params=ARRAY
3162 \end_layout
3164 \begin_layout Standard
3165 \begin_inset listings
3166 inline false
3167 status open
3169 \begin_layout Plain Layout
3171 print "
3172 \backslash
3173 nDump: ${ARRAY}
3174 \backslash
3175 n--------
3176 \backslash
3177 n" > "/dev/stderr";
3178 \end_layout
3180 \begin_layout Plain Layout
3182 for (_x in ${ARRAY}) {
3183 \end_layout
3185 \begin_layout Plain Layout
3187   print _x "=" ${ARRAY}[_x] "
3188 \backslash
3189 n" > "/dev/stderr";
3190 \end_layout
3192 \begin_layout Plain Layout
3195 \end_layout
3197 \begin_layout Plain Layout
3199 print "========
3200 \backslash
3201 n" > "/dev/stderr";
3202 \end_layout
3204 \end_inset
3207 \end_layout
3209 \begin_layout Chunk
3210 ,params=
3211 \end_layout
3213 \begin_layout Section
3214 Catching errors
3215 \end_layout
3217 \begin_layout Standard
3218 Fatal errors are issued with the error function:
3219 \end_layout
3221 \begin_layout Chunk
3222 error(),append=helper-functions
3223 \end_layout
3225 \begin_layout Standard
3226 \begin_inset listings
3227 inline false
3228 status open
3230 \begin_layout Plain Layout
3232 function error(message)
3233 \end_layout
3235 \begin_layout Plain Layout
3238 \end_layout
3240 \begin_layout Plain Layout
3242   print "ERROR: " FILENAME ":" FNR " " message > "/dev/stderr";
3243 \end_layout
3245 \begin_layout Plain Layout
3247   exit 1;
3248 \end_layout
3250 \begin_layout Plain Layout
3253 \end_layout
3255 \end_inset
3258 \end_layout
3260 \begin_layout Standard
3261 \begin_inset listings
3262 inline false
3263 status open
3265 \begin_layout Plain Layout
3267 function warning(message)
3268 \end_layout
3270 \begin_layout Plain Layout
3273 \end_layout
3275 \begin_layout Plain Layout
3277   print "WARNING: " FILENAME ":" FNR " " message > "/dev/stderr";
3278 \end_layout
3280 \begin_layout Plain Layout
3282   warnings++;
3283 \end_layout
3285 \begin_layout Plain Layout
3288 \end_layout
3290 \end_inset
3293 \end_layout
3295 \begin_layout Chapter
3296 lstlistings
3297 \end_layout
3299 \begin_layout Standard
3300 LaTeX arguments to lstlistings macros are a comma seperated list of key-value
3301  pairs.
3302  Values containing commas are enclosed in 
3303 \begin_inset Flex CharStyle:Code
3304 status collapsed
3306 \begin_layout Plain Layout
3308 \end_layout
3310 \end_inset
3312  braces 
3313 \begin_inset Flex CharStyle:Code
3314 status collapsed
3316 \begin_layout Plain Layout
3318 \end_layout
3320 \end_inset
3322 , which is to be expected for LaTeX.
3323 \end_layout
3325 \begin_layout Standard
3326 A sample expressions is:
3327 \end_layout
3329 \begin_layout LyX-Code
3330 name=thomas, params={a, b}, something, something-else
3331 \end_layout
3333 \begin_layout Standard
3334 but we see that this is just a simpler form of this expression:
3335 \end_layout
3337 \begin_layout LyX-Code
3338 name=freddie, foo={bar=baz, quux={quirk, a=fleeg}}, etc
3339 \end_layout
3341 \begin_layout Standard
3342 We may consider that we need a function that can parse such LaTeX expressions
3343  and assign the values to an 
3344 \noun on
3346 \noun default
3347  associated array, perhaps using a recursive parser into a multi-dimensional
3348  hash
3349 \begin_inset Foot
3350 status collapsed
3352 \begin_layout Plain Layout
3353 as AWK doesn't have nested-hash support
3354 \end_layout
3356 \end_inset
3358 , resulting in:
3359 \end_layout
3361 \begin_layout Standard
3362 \begin_inset Tabular
3363 <lyxtabular version="3" rows="6" columns="2">
3364 <features>
3365 <column alignment="left" valignment="top" width="0">
3366 <column alignment="left" valignment="top" width="0">
3367 <row>
3368 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
3369 \begin_inset Text
3371 \begin_layout Plain Layout
3373 \end_layout
3375 \end_inset
3376 </cell>
3377 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
3378 \begin_inset Text
3380 \begin_layout Plain Layout
3381 value
3382 \end_layout
3384 \end_inset
3385 </cell>
3386 </row>
3387 <row>
3388 <cell alignment="left" valignment="top" topline="true" leftline="true" usebox="none">
3389 \begin_inset Text
3391 \begin_layout Plain Layout
3392 a[name]
3393 \end_layout
3395 \end_inset
3396 </cell>
3397 <cell alignment="left" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
3398 \begin_inset Text
3400 \begin_layout Plain Layout
3401 freddie
3402 \end_layout
3404 \end_inset
3405 </cell>
3406 </row>
3407 <row>
3408 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
3409 \begin_inset Text
3411 \begin_layout Plain Layout
3412 a[foo, bar]
3413 \end_layout
3415 \end_inset
3416 </cell>
3417 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
3418 \begin_inset Text
3420 \begin_layout Plain Layout
3422 \end_layout
3424 \end_inset
3425 </cell>
3426 </row>
3427 <row>
3428 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
3429 \begin_inset Text
3431 \begin_layout Plain Layout
3432 a[foo, quux, quirk]
3433 \end_layout
3435 \end_inset
3436 </cell>
3437 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
3438 \begin_inset Text
3440 \begin_layout Plain Layout
3442 \end_layout
3444 \end_inset
3445 </cell>
3446 </row>
3447 <row>
3448 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
3449 \begin_inset Text
3451 \begin_layout Plain Layout
3452 a[foo, quux, a]
3453 \end_layout
3455 \end_inset
3456 </cell>
3457 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
3458 \begin_inset Text
3460 \begin_layout Plain Layout
3461 fleeg
3462 \end_layout
3464 \end_inset
3465 </cell>
3466 </row>
3467 <row>
3468 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
3469 \begin_inset Text
3471 \begin_layout Plain Layout
3472 a[etc]
3473 \end_layout
3475 \end_inset
3476 </cell>
3477 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
3478 \begin_inset Text
3480 \begin_layout Plain Layout
3482 \end_layout
3484 \end_inset
3485 </cell>
3486 </row>
3487 </lyxtabular>
3489 \end_inset
3492 \end_layout
3494 \begin_layout Standard
3495 Oon reflection it seems that sometimes such nesting is not desirable, as
3496  the braces are also used to delimit values that contain commas --- we may
3497  consider that
3498 \end_layout
3500 \begin_layout LyX-Code
3501 name={williamson, freddie}
3502 \end_layout
3504 \begin_layout Standard
3505 should assign 
3506 \begin_inset Flex CharStyle:Code
3507 status collapsed
3509 \begin_layout Plain Layout
3510 williamson, freddie
3511 \end_layout
3513 \end_inset
3515  to 
3516 \begin_inset Flex CharStyle:Code
3517 status collapsed
3519 \begin_layout Plain Layout
3520 name
3521 \end_layout
3523 \end_inset
3526 \end_layout
3528 \begin_layout Standard
3529 In fact we are not so interested in the detail so as to be bothered by this,
3530  which turns out to be a good thing for two reasons.
3531  Firstly LaTeX has a malleable parser with no strict syntax, and secondly
3532  whether or not 
3533 \begin_inset Flex CharStyle:Code
3534 status collapsed
3536 \begin_layout Plain Layout
3537 williamson
3538 \end_layout
3540 \end_inset
3542  and 
3543 \begin_inset Flex CharStyle:Code
3544 status collapsed
3546 \begin_layout Plain Layout
3547 freddie
3548 \end_layout
3550 \end_inset
3552  should count as two items will be context dependant anyway.
3553 \end_layout
3555 \begin_layout Standard
3556 We need to parse this latex for only one reason; which is that we are extending
3557  lstlistings to add some additional arguments which will be used to express
3558  chunk parameters and other chunk options.
3559 \end_layout
3561 \begin_layout Section
3562 Additional lstlstings parameters
3563 \end_layout
3565 \begin_layout Standard
3566 Further on we define a 
3567 \begin_inset Flex CharStyle:Code
3568 status collapsed
3570 \begin_layout Plain Layout
3572 \backslash
3573 Chunk
3574 \end_layout
3576 \end_inset
3578  LaTeX macro whose arguments will consist of a the chunk name, optionally
3579  followed by a comma and then a comma separated list of arguments.
3580  In fact we will just need to prefix 
3581 \begin_inset Flex CharStyle:Code
3582 status collapsed
3584 \begin_layout Plain Layout
3585 name=
3586 \end_layout
3588 \end_inset
3590  to the arguments to in order to create valid lstlistings arguments.
3592 \end_layout
3594 \begin_layout Standard
3595 There will be other arguments supported too; 
3596 \end_layout
3598 \begin_layout Description
3599 params As an extension to many literate-programming styles, newfangle permits
3600  code chunks to take parameters and thus operate somewhat like C pre-processor
3601  macros, or like C++ templates.
3602  Chunk parameters are declared with a chunk argument called 
3603 \begin_inset Flex CharStyle:Code
3604 status collapsed
3606 \begin_layout Plain Layout
3607 params
3608 \end_layout
3610 \end_inset
3612 , which holds a semi-colon separated list of parameters, like this:
3613 \end_layout
3615 \begin_layout LyX-Code
3616 achunk,language=C,params=name;address
3617 \end_layout
3619 \begin_layout Description
3620 addto a named chunk that this chunk is to be included into.
3621  This saves the effort of having to declare another listing of the named
3622  chunk merely to include this one.
3623 \end_layout
3625 \begin_layout Standard
3626 Function 
3627 \begin_inset Flex Chunkref
3628 status collapsed
3630 \begin_layout Plain Layout
3631 get_chunk_args()
3632 \end_layout
3634 \end_inset
3636  will accept two paramters, 
3637 \begin_inset Flex CharStyle:Code
3638 status collapsed
3640 \begin_layout Plain Layout
3641 text
3642 \end_layout
3644 \end_inset
3646  being the text to parse, and 
3647 \begin_inset Flex CharStyle:Code
3648 status collapsed
3650 \begin_layout Plain Layout
3651 values
3652 \end_layout
3654 \end_inset
3656  being an array to receive the parsed values as described above.
3657  The optional parameter 
3658 \begin_inset Flex CharStyle:Code
3659 status collapsed
3661 \begin_layout Plain Layout
3662 path
3663 \end_layout
3665 \end_inset
3667  is used during recursion to build up the multi-dimensional array path.
3668 \end_layout
3670 \begin_layout Chunk
3671 ./newfangle
3672 \end_layout
3674 \begin_layout Standard
3675 \begin_inset listings
3676 inline false
3677 status open
3679 \begin_layout Plain Layout
3682 \backslash
3683 chunkref{get_chunk_args()}>
3684 \end_layout
3686 \end_inset
3689 \end_layout
3691 \begin_layout Chunk
3692 get_chunk_args()
3693 \end_layout
3695 \begin_layout Standard
3696 \begin_inset listings
3697 inline false
3698 status open
3700 \begin_layout Plain Layout
3702 function get_chunk_args(text, values,
3703 \end_layout
3705 \begin_layout Plain Layout
3707   # optional parameters
3708 \end_layout
3710 \begin_layout Plain Layout
3712   path, # hierarchical precursors
3713 \end_layout
3715 \begin_layout Plain Layout
3717   # local vars
3718 \end_layout
3720 \begin_layout Plain Layout
3722   a, name)
3723 \end_layout
3725 \end_inset
3728 \end_layout
3730 \begin_layout Standard
3731 The strategy is to parse the name, and then look for a value.
3732  If the value begins with a brace 
3733 \begin_inset Flex CharStyle:Code
3734 status collapsed
3736 \begin_layout Plain Layout
3738 \end_layout
3740 \end_inset
3742 , then we recurse and consume as much of the text as necessary, returning
3743  the remaining text when we encounter a leading close-brace 
3744 \begin_inset Flex CharStyle:Code
3745 status collapsed
3747 \begin_layout Plain Layout
3749 \end_layout
3751 \end_inset
3754  This being the strategy --- and executed in a loop --- we realise that
3755  we must first look for the closing brace (perhaps preceded by white space)
3756  in order to terminate the recursion, and returning remaining text.
3757 \end_layout
3759 \begin_layout Standard
3760 \begin_inset listings
3761 inline false
3762 status open
3764 \begin_layout Plain Layout
3767 \end_layout
3769 \begin_layout Plain Layout
3771   split("", next_chunk_args);
3772 \end_layout
3774 \begin_layout Plain Layout
3776   while(length(text)) {
3777 \end_layout
3779 \begin_layout Plain Layout
3781     if (match(text, "^ *}(.*)", a)) {
3782 \end_layout
3784 \begin_layout Plain Layout
3786       return a[1];
3787 \end_layout
3789 \begin_layout Plain Layout
3791     }
3792 \end_layout
3794 \begin_layout Plain Layout
3796     =<
3797 \backslash
3798 chunkref{parse-chunk-args}>
3799 \end_layout
3801 \begin_layout Plain Layout
3803   }
3804 \end_layout
3806 \begin_layout Plain Layout
3808   return text;
3809 \end_layout
3811 \begin_layout Plain Layout
3814 \end_layout
3816 \end_inset
3819 \end_layout
3821 \begin_layout Standard
3822 \begin_inset Note Note
3823 status collapsed
3825 \begin_layout Plain Layout
3826 Use BNF package here
3827 \end_layout
3829 \end_inset
3831 We can see that the text could be inspected with this regex:
3832 \end_layout
3834 \begin_layout Chunk
3835 parse-chunk-args
3836 \end_layout
3838 \begin_layout Standard
3839 \begin_inset listings
3840 inline false
3841 status open
3843 \begin_layout Plain Layout
3845 if (! match(text, " *([^,=]*[^,= ]) *(([,=]) *(([^,}]*) *,* *(.*))|)$", a))
3847 \end_layout
3849 \begin_layout Plain Layout
3851   return text;
3852 \end_layout
3854 \begin_layout Plain Layout
3857 \end_layout
3859 \end_inset
3862 \end_layout
3864 \begin_layout Standard
3865 and that 
3866 \begin_inset Flex CharStyle:Code
3867 status collapsed
3869 \begin_layout Plain Layout
3871 \end_layout
3873 \end_inset
3875  will have the following values:
3876 \end_layout
3878 \begin_layout Standard
3879 \begin_inset Tabular
3880 <lyxtabular version="3" rows="7" columns="2">
3881 <features>
3882 <column alignment="center" valignment="top" width="0">
3883 <column alignment="left" valignment="top" width="0">
3884 <row>
3885 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
3886 \begin_inset Text
3888 \begin_layout Plain Layout
3889 a[n]
3890 \end_layout
3892 \end_inset
3893 </cell>
3894 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
3895 \begin_inset Text
3897 \begin_layout Plain Layout
3898 assigned text
3899 \end_layout
3901 \end_inset
3902 </cell>
3903 </row>
3904 <row>
3905 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
3906 \begin_inset Text
3908 \begin_layout Plain Layout
3910 \end_layout
3912 \end_inset
3913 </cell>
3914 <cell alignment="left" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
3915 \begin_inset Text
3917 \begin_layout Plain Layout
3918 freddie
3919 \end_layout
3921 \end_inset
3922 </cell>
3923 </row>
3924 <row>
3925 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
3926 \begin_inset Text
3928 \begin_layout Plain Layout
3930 \end_layout
3932 \end_inset
3933 </cell>
3934 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
3935 \begin_inset Text
3937 \begin_layout Plain Layout
3938 =freddie, foo={bar=baz, quux={quirk, a=fleeg}}, etc
3939 \end_layout
3941 \end_inset
3942 </cell>
3943 </row>
3944 <row>
3945 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
3946 \begin_inset Text
3948 \begin_layout Plain Layout
3950 \end_layout
3952 \end_inset
3953 </cell>
3954 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
3955 \begin_inset Text
3957 \begin_layout Plain Layout
3959 \end_layout
3961 \end_inset
3962 </cell>
3963 </row>
3964 <row>
3965 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
3966 \begin_inset Text
3968 \begin_layout Plain Layout
3970 \end_layout
3972 \end_inset
3973 </cell>
3974 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
3975 \begin_inset Text
3977 \begin_layout Plain Layout
3978 freddie, foo={bar=baz, quux={quirk, a=fleeg}}, etc
3979 \end_layout
3981 \end_inset
3982 </cell>
3983 </row>
3984 <row>
3985 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
3986 \begin_inset Text
3988 \begin_layout Plain Layout
3990 \end_layout
3992 \end_inset
3993 </cell>
3994 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
3995 \begin_inset Text
3997 \begin_layout Plain Layout
3998 freddie
3999 \end_layout
4001 \end_inset
4002 </cell>
4003 </row>
4004 <row>
4005 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
4006 \begin_inset Text
4008 \begin_layout Plain Layout
4010 \end_layout
4012 \end_inset
4013 </cell>
4014 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
4015 \begin_inset Text
4017 \begin_layout Plain Layout
4018 , foo={bar=baz, quux={quirk, a=fleeg}}, etc
4019 \end_layout
4021 \end_inset
4022 </cell>
4023 </row>
4024 </lyxtabular>
4026 \end_inset
4029 \end_layout
4031 \begin_layout Standard
4032 a[3] will be either 
4033 \begin_inset Flex CharStyle:Code
4034 status collapsed
4036 \begin_layout Plain Layout
4038 \end_layout
4040 \end_inset
4042  or 
4043 \begin_inset Flex CharStyle:Code
4044 status collapsed
4046 \begin_layout Plain Layout
4048 \end_layout
4050 \end_inset
4052  and signify whether the option named in 
4053 \begin_inset Flex CharStyle:Code
4054 status collapsed
4056 \begin_layout Plain Layout
4057 a[1]
4058 \end_layout
4060 \end_inset
4062  has a value or not (respectively).
4063 \end_layout
4065 \begin_layout Standard
4066 If the option does have a value, then if the expression 
4067 \begin_inset Flex CharStyle:Code
4068 status collapsed
4070 \begin_layout Plain Layout
4071 substr(a[4],1,1)
4072 \end_layout
4074 \end_inset
4076  returns a brace 
4077 \begin_inset Flex CharStyle:Code
4078 status collapsed
4080 \begin_layout Plain Layout
4082 \end_layout
4084 \end_inset
4086  it will signify that we need to recurse:
4087 \end_layout
4089 \begin_layout Standard
4090 \begin_inset listings
4091 inline false
4092 status open
4094 \begin_layout Plain Layout
4096 name=a[1];
4097 \end_layout
4099 \begin_layout Plain Layout
4101 if (a[3] == "=") {
4102 \end_layout
4104 \begin_layout Plain Layout
4106   if (substr(a[4],1,1) == "{") {
4107 \end_layout
4109 \begin_layout Plain Layout
4111     text = get_chunk_args(substr(a[4],2), values, path name SUBSEP);
4112 \end_layout
4114 \begin_layout Plain Layout
4116   } else {
4117 \end_layout
4119 \begin_layout Plain Layout
4121     values[path name]=a[5];
4122 \end_layout
4124 \begin_layout Plain Layout
4126     text = a[6];
4127 \end_layout
4129 \begin_layout Plain Layout
4131   }
4132 \end_layout
4134 \begin_layout Plain Layout
4136 } else {
4137 \end_layout
4139 \begin_layout Plain Layout
4141   values[path name]="";
4142 \end_layout
4144 \begin_layout Plain Layout
4146   text = a[2];
4147 \end_layout
4149 \begin_layout Plain Layout
4152 \end_layout
4154 \end_inset
4157 \end_layout
4159 \begin_layout Standard
4160 We can test this function like this:
4161 \end_layout
4163 \begin_layout Chunk
4164 gca-test.awk
4165 \end_layout
4167 \begin_layout Standard
4168 \begin_inset listings
4169 inline false
4170 status open
4172 \begin_layout Plain Layout
4175 \backslash
4176 chunkref{get_chunk_args()}>
4177 \end_layout
4179 \begin_layout Plain Layout
4181 BEGIN {
4182 \end_layout
4184 \begin_layout Plain Layout
4186   SUBSEP=".";
4187 \end_layout
4189 \begin_layout Plain Layout
4191 \end_layout
4193 \begin_layout Plain Layout
4195   print get_chunk_args("name=freddie, foo={bar=baz, quux={quirk, a=fleeg}},
4196  etc", a);
4197 \end_layout
4199 \begin_layout Plain Layout
4201   for (b in a) {
4202 \end_layout
4204 \begin_layout Plain Layout
4206     print "a[" b "] => " a[b];
4207 \end_layout
4209 \begin_layout Plain Layout
4211   }
4212 \end_layout
4214 \begin_layout Plain Layout
4217 \end_layout
4219 \end_inset
4222 \end_layout
4224 \begin_layout Standard
4225 which should give this output:
4226 \end_layout
4228 \begin_layout Chunk
4229 gca-test.awk-results
4230 \end_layout
4232 \begin_layout Standard
4233 \begin_inset listings
4234 inline false
4235 status open
4237 \begin_layout Plain Layout
4239 a[foo.quux.quirk] => 
4240 \end_layout
4242 \begin_layout Plain Layout
4244 a[foo.quux.a] => fleeg
4245 \end_layout
4247 \begin_layout Plain Layout
4249 a[foo.bar] => baz
4250 \end_layout
4252 \begin_layout Plain Layout
4254 a[etc] => 
4255 \end_layout
4257 \begin_layout Plain Layout
4259 a[name] => freddie
4260 \end_layout
4262 \end_inset
4265 \end_layout
4267 \begin_layout Section
4268 Parsing chunk arguments
4269 \end_layout
4271 \begin_layout Standard
4272 \begin_inset CommandInset label
4273 LatexCommand label
4274 name "cha:Chunk Arguments"
4276 \end_inset
4279 \end_layout
4281 \begin_layout Standard
4282 Arguments to paramterized chunks are expressed in round brackets as a comma
4283  separated list of optional arguments.
4284  For example, a chunk that is defined with:
4285 \end_layout
4287 \begin_layout LyX-Code
4289 \backslash
4290 Chunk{achunk, params=name ; address}
4291 \end_layout
4293 \begin_layout Standard
4294 could be invoked as:
4295 \end_layout
4297 \begin_layout LyX-Code
4299 \backslash
4300 chunkref{achunk}(John Jones, jones@example.com)
4301 \end_layout
4303 \begin_layout Standard
4304 An argument list may be as simple as in 
4305 \begin_inset Flex CharStyle:Code
4306 status collapsed
4308 \begin_layout Plain Layout
4310 \backslash
4311 chunkref{pull}(thing, otherthing)
4312 \end_layout
4314 \end_inset
4316  or as complex as:
4317 \end_layout
4319 \begin_layout LyX-Code
4321 \backslash
4322 chunkref{pull}(things[x, y], get_other_things(a, "(all)")) 
4323 \end_layout
4325 \begin_layout Standard
4326 --- which for all it's commas and quotes and parenthesis represents only
4327  two parameters: 
4328 \begin_inset Flex CharStyle:Code
4329 status collapsed
4331 \begin_layout Plain Layout
4332 things[x, y]
4333 \end_layout
4335 \end_inset
4337  and 
4338 \begin_inset Flex CharStyle:Code
4339 status collapsed
4341 \begin_layout Plain Layout
4342 get_other_things(a, "(all)")
4343 \end_layout
4345 \end_inset
4348 \end_layout
4350 \begin_layout Standard
4351 If we simply split parameter list on commas, then the comma in 
4352 \begin_inset Flex CharStyle:Code
4353 status collapsed
4355 \begin_layout Plain Layout
4356 things[x,y]
4357 \end_layout
4359 \end_inset
4361  would split into two seperate arguments: 
4362 \begin_inset Flex CharStyle:Code
4363 status collapsed
4365 \begin_layout Plain Layout
4366 things[x
4367 \end_layout
4369 \end_inset
4371  and 
4372 \begin_inset Flex CharStyle:Code
4373 status collapsed
4375 \begin_layout Plain Layout
4377 \end_layout
4379 \end_inset
4381 --- neither of which make sense on their own.
4382 \end_layout
4384 \begin_layout Standard
4385 One way to prevent this would be by refusing to split text between matching
4386  delimiters, such as 
4387 \begin_inset Flex CharStyle:Code
4388 status collapsed
4390 \begin_layout Plain Layout
4392 \end_layout
4394 \end_inset
4397 \begin_inset Flex CharStyle:Code
4398 status collapsed
4400 \begin_layout Plain Layout
4402 \end_layout
4404 \end_inset
4407 \begin_inset Flex CharStyle:Code
4408 status collapsed
4410 \begin_layout Plain Layout
4412 \end_layout
4414 \end_inset
4417 \begin_inset Flex CharStyle:Code
4418 status collapsed
4420 \begin_layout Plain Layout
4422 \end_layout
4424 \end_inset
4427 \begin_inset Flex CharStyle:Code
4428 status collapsed
4430 \begin_layout Plain Layout
4432 \end_layout
4434 \end_inset
4437 \begin_inset Flex CharStyle:Code
4438 status collapsed
4440 \begin_layout Plain Layout
4442 \end_layout
4444 \end_inset
4446  and most likely also 
4447 \begin_inset Flex CharStyle:Code
4448 status collapsed
4450 \begin_layout Plain Layout
4452 \end_layout
4454 \end_inset
4457 \begin_inset Flex CharStyle:Code
4458 status collapsed
4460 \begin_layout Plain Layout
4462 \end_layout
4464 \end_inset
4466  and 
4467 \begin_inset Flex CharStyle:Code
4468 status collapsed
4470 \begin_layout Plain Layout
4472 \end_layout
4474 \end_inset
4477 \begin_inset Flex CharStyle:Code
4478 status collapsed
4480 \begin_layout Plain Layout
4482 \end_layout
4484 \end_inset
4487  Of course this also makes it impossible to pass such mis-matched code fragments
4488  as parameters, but I think that it would be hard for readers to cope with
4489  authors who would pass such code unbalanced fragments as chunk parameters
4490 \begin_inset Foot
4491 status collapsed
4493 \begin_layout Plain Layout
4494 I know that I couldn't cope with users doing such things, and although the
4495  GPL3 license prevents me from actually forbidding anyone from trying, if
4496  they want it to work they'll have to write the code themselves and not
4497  expect any support from me.
4498 \end_layout
4500 \end_inset
4503 \end_layout
4505 \begin_layout Standard
4506 Unfortunately, the full set of matching delimiters may vary from language
4507  to language.
4508  In certain C++ template contexts, 
4509 \begin_inset Flex CharStyle:Code
4510 status collapsed
4512 \begin_layout Plain Layout
4514 \end_layout
4516 \end_inset
4518  and 
4519 \begin_inset Flex CharStyle:Code
4520 status collapsed
4522 \begin_layout Plain Layout
4524 \end_layout
4526 \end_inset
4528  would count as delimiters, and yet in other contexts they would not.
4529 \end_layout
4531 \begin_layout Standard
4532 This puts me in the unfortunate position of having to parse-somewhat all
4533  programming languages without knowing what they are!
4534 \end_layout
4536 \begin_layout Standard
4537 However, if this universal mode-tracking is possible, then parsing the arguments
4538  would be trivial.
4539  Such a mode tracker is described in chapter 
4540 \begin_inset CommandInset ref
4541 LatexCommand ref
4542 reference "cha:modes"
4544 \end_inset
4546  and used here with simplicity.
4547 \end_layout
4549 \begin_layout Chunk
4550 parse_chunk_args
4551 \end_layout
4553 \begin_layout Standard
4554 \begin_inset listings
4555 inline false
4556 status open
4558 \begin_layout Plain Layout
4560 function parse_chunk_args(language, text, values, mode,
4561 \end_layout
4563 \begin_layout Plain Layout
4565   # local vars
4566 \end_layout
4568 \begin_layout Plain Layout
4570   c, context, rest)
4571 \end_layout
4573 \begin_layout Plain Layout
4576 \end_layout
4578 \begin_layout Plain Layout
4580   =<
4581 \backslash
4582 chunkref{new-mode-tracker}(context, language, mode)>
4583 \end_layout
4585 \begin_layout Plain Layout
4587   rest = mode_tracker(context, text, values);
4588 \end_layout
4590 \begin_layout Plain Layout
4592   # extract values
4593 \end_layout
4595 \begin_layout Plain Layout
4597   for(c=1; c <= context[0, "values"]; c++) {
4598 \end_layout
4600 \begin_layout Plain Layout
4602     values[c] = context[0, "values", c];
4603 \end_layout
4605 \begin_layout Plain Layout
4607   }
4608 \end_layout
4610 \begin_layout Plain Layout
4612   return rest;
4613 \end_layout
4615 \begin_layout Plain Layout
4618 \end_layout
4620 \end_inset
4623 \end_layout
4625 \begin_layout Section
4626 Expanding parameters in the text
4627 \end_layout
4629 \begin_layout Standard
4630 Within the body of the chunk, the parameters are referred to with: 
4631 \begin_inset Flex CharStyle:Code
4632 status collapsed
4634 \begin_layout Plain Layout
4635 ${name}
4636 \end_layout
4638 \end_inset
4640  and 
4641 \begin_inset Flex CharStyle:Code
4642 status collapsed
4644 \begin_layout Plain Layout
4645 ${address}
4646 \end_layout
4648 \end_inset
4651  There is a strong case that a LaTeX style notation should be used, like
4653 \backslash
4654 param{name} which would be expressed in the listing as =<
4655 \backslash
4656 param{name}> and be rendered as 
4657 \begin_inset listings
4658 inline true
4659 status open
4661 \begin_layout Plain Layout
4664 \backslash
4665 param{name}>
4666 \end_layout
4668 \end_inset
4671  Such notation would make me go blind, but I do intend to adopt it
4672 \begin_inset Foot
4673 status collapsed
4675 \begin_layout Plain Layout
4676 Probably when LyX's listings inset can recognize and render it, so that
4677  I no longer have to type =<\SpecialChar \ldots{}
4679 \end_layout
4681 \end_inset
4684 \end_layout
4686 \begin_layout Standard
4687 We therefore need a function 
4688 \begin_inset Flex CharStyle:Code
4689 status collapsed
4691 \begin_layout Plain Layout
4692 expand_chunk_args
4693 \end_layout
4695 \end_inset
4697  which will take a block of text, a list of permitted parameters, and the
4698  arguments which must substitute for the parameters.
4700 \end_layout
4702 \begin_layout Standard
4703 \begin_inset CommandInset label
4704 LatexCommand label
4705 name "Here-we-split"
4707 \end_inset
4709 Here we split the text on 
4710 \begin_inset Flex CharStyle:Code
4711 status collapsed
4713 \begin_layout Plain Layout
4715 \end_layout
4717 \end_inset
4719  which means that all parts except the first will begin with a parameter
4720  name which will be terminated by 
4721 \begin_inset Flex CharStyle:Code
4722 status collapsed
4724 \begin_layout Plain Layout
4726 \end_layout
4728 \end_inset
4731  The split function will consume the literal 
4732 \begin_inset Flex CharStyle:Code
4733 status collapsed
4735 \begin_layout Plain Layout
4737 \end_layout
4739 \end_inset
4741  in each case.
4742 \end_layout
4744 \begin_layout Chunk
4745 expand_chunk_args()
4746 \end_layout
4748 \begin_layout Standard
4749 \begin_inset listings
4750 inline false
4751 status open
4753 \begin_layout Plain Layout
4755 function expand_chunk_args(text, params, args,  
4756 \end_layout
4758 \begin_layout Plain Layout
4760   p, text_array, next_text, v, t, l)
4761 \end_layout
4763 \begin_layout Plain Layout
4766 \end_layout
4768 \begin_layout Plain Layout
4770   if (split(text, text_array, "
4771 \backslash
4773 \backslash
4774 ${")) {
4775 \end_layout
4777 \begin_layout Plain Layout
4779     =<
4780 \backslash
4781 chunkref{substitute-chunk-args}>
4782 \end_layout
4784 \begin_layout Plain Layout
4786   }
4787 \end_layout
4789 \begin_layout Plain Layout
4791 \end_layout
4793 \begin_layout Plain Layout
4795   return text;
4796 \end_layout
4798 \begin_layout Plain Layout
4801 \end_layout
4803 \end_inset
4806 \end_layout
4808 \begin_layout Standard
4809 First, we produce an associative array of substitution values indexed by
4810  parameter names.
4811  This will serve as a cache, allowing us to look up the replacement values
4812  as we extract each name.
4813 \end_layout
4815 \begin_layout Chunk
4816 substitute-chunk-args
4817 \end_layout
4819 \begin_layout Standard
4820 \begin_inset listings
4821 inline false
4822 status open
4824 \begin_layout Plain Layout
4826 for(p in params) {
4827 \end_layout
4829 \begin_layout Plain Layout
4831   v[params[p]]=args[p];
4832 \end_layout
4834 \begin_layout Plain Layout
4837 \end_layout
4839 \end_inset
4842 \end_layout
4844 \begin_layout Standard
4845 We accumulate substituted text in the variable 
4846 \begin_inset Flex CharStyle:Code
4847 status collapsed
4849 \begin_layout Plain Layout
4850 text
4851 \end_layout
4853 \end_inset
4856  As the first part of the split function is the part before the delimiter
4857  --- which is 
4858 \begin_inset Flex CharStyle:Code
4859 status collapsed
4861 \begin_layout Plain Layout
4863 \end_layout
4865 \end_inset
4867  in our case --- this part will never contain a parameter reference, so
4868  we assign this directly to the result kept in 
4869 \begin_inset Flex CharStyle:Code
4870 status collapsed
4872 \begin_layout Plain Layout
4873 $text
4874 \end_layout
4876 \end_inset
4879 \begin_inset listings
4880 inline false
4881 status open
4883 \begin_layout Plain Layout
4885 text=text_array[1];
4886 \end_layout
4888 \end_inset
4891 \end_layout
4893 \begin_layout Standard
4894 We then iterate over the remaining values in the array
4895 \begin_inset Foot
4896 status collapsed
4898 \begin_layout Plain Layout
4899 I don't know why I think that it will enumerate the array in order, but
4900  it seems to work
4901 \end_layout
4903 \end_inset
4906 \begin_inset Note Note
4907 status collapsed
4909 \begin_layout Plain Layout
4910 So fix it or porve it
4911 \end_layout
4913 \end_inset
4915 , and substitute each reference for it's argument.
4916 \end_layout
4918 \begin_layout Standard
4919 \begin_inset listings
4920 inline false
4921 status open
4923 \begin_layout Plain Layout
4925 for(t=2; t in text_array; t++) {
4926 \end_layout
4928 \begin_layout Plain Layout
4930   =<
4931 \backslash
4932 chunkref{substitute-chunk-arg}>
4933 \end_layout
4935 \begin_layout Plain Layout
4938 \end_layout
4940 \end_inset
4943 \end_layout
4945 \begin_layout Standard
4946 After the split on 
4947 \begin_inset Flex CharStyle:Code
4948 status collapsed
4950 \begin_layout Plain Layout
4952 \end_layout
4954 \end_inset
4956  a valid parameter reference will consist of valid parameter name terminated
4957  by a close-brace 
4958 \begin_inset Flex CharStyle:Code
4959 status collapsed
4961 \begin_layout Plain Layout
4963 \end_layout
4965 \end_inset
4968  A valid character name begins with the underscore or a letter, and may
4969  contain letters, digits or underscores.
4970 \end_layout
4972 \begin_layout Standard
4973 A valid looking reference that is not actually the name of a parameter will
4974  be and not substituted.
4975  This is good because there is nothing to substitute anyway, and it avoids
4976  clashes when writing code for languages where ${\SpecialChar \ldots{}
4977 } is a valid construct
4978  --- such constructs will not be interfered with unless the parameter name
4979  also matches.
4980 \end_layout
4982 \begin_layout Chunk
4983 substitute-chunk-arg
4984 \end_layout
4986 \begin_layout Standard
4987 \begin_inset listings
4988 inline false
4989 status open
4991 \begin_layout Plain Layout
4993 if (match(text_array[t], "^([a-zA-Z_][a-zA-Z0-9_]*)}", l) &&
4994 \end_layout
4996 \begin_layout Plain Layout
4998     l[1] in v) 
4999 \end_layout
5001 \begin_layout Plain Layout
5004 \end_layout
5006 \begin_layout Plain Layout
5008   text = text v[l[1]] substr(text_array[t], length(l[1])+2);
5009 \end_layout
5011 \begin_layout Plain Layout
5013 } else {
5014 \end_layout
5016 \begin_layout Plain Layout
5018   text = text "${" text_array[t];
5019 \end_layout
5021 \begin_layout Plain Layout
5024 \end_layout
5026 \end_inset
5029 \end_layout
5031 \begin_layout Chapter
5032 Language Modes & Quoting
5033 \end_layout
5035 \begin_layout Standard
5036 \begin_inset CommandInset label
5037 LatexCommand label
5038 name "cha:modes"
5040 \end_inset
5043 \end_layout
5045 \begin_layout Section
5046 Modes
5047 \end_layout
5049 \begin_layout Standard
5050 lstlistings and newfangle both recognize source languages, and perform some
5051  basic parsing.
5052  lstlistings can detect strings and comments within a language definition
5053  and perform suitable rendering, such as italics for comments, and visible-space
5054 s within strings.
5055 \end_layout
5057 \begin_layout Standard
5058 Newfangle similarly can recognize strings, and comments, etc, within a language,
5059  so that any chunks included with 
5060 \begin_inset Flex CharStyle:Code
5061 status collapsed
5063 \begin_layout Plain Layout
5065 \backslash
5066 chunkref
5067 \end_layout
5069 \end_inset
5071  can be suitably escape or quoted.
5072 \end_layout
5074 \begin_layout Subsection
5075 Modes to keep code together
5076 \end_layout
5078 \begin_layout Standard
5079 As an example, in the C language there are a few parse modes, affecting
5080  the interpretation of characters.
5081 \end_layout
5083 \begin_layout Standard
5084 One parse mode is the strings mode.
5085  The string mode is commenced by an un-escaped quotation mark 
5086 \begin_inset Flex CharStyle:Code
5087 status collapsed
5089 \begin_layout Plain Layout
5091 \end_layout
5093 \end_inset
5095  and terminated by the same.
5096  Within the string mode, only one additional mode can be commenced, it is
5097  the backslash mode 
5098 \begin_inset Flex CharStyle:Code
5099 status collapsed
5101 \begin_layout Plain Layout
5103 \backslash
5105 \end_layout
5107 \end_inset
5109 , which is always terminated by the folloing character.
5110 \end_layout
5112 \begin_layout Standard
5113 Other modes are 
5114 \begin_inset Flex CharStyle:Code
5115 status collapsed
5117 \begin_layout Plain Layout
5119 \end_layout
5121 \end_inset
5123  which is terminated by a 
5124 \begin_inset Flex CharStyle:Code
5125 status collapsed
5127 \begin_layout Plain Layout
5129 \end_layout
5131 \end_inset
5133  (unless it occurs in a string).
5134 \end_layout
5136 \begin_layout Standard
5137 Consider this line of C code:
5138 \end_layout
5140 \begin_layout Standard
5141 \begin_inset Formula $\mathtt{things\underbrace{[\mathtt{x,\ y}]}_{1.\ [\ mode},\ get\_other\_things\underbrace{(\mathtt{a,\overbrace{"\mathtt{(all)}"}})}_{2.\ (\ mode}^{3.\ "\ mode}}$
5142 \end_inset
5145 \end_layout
5147 \begin_layout Standard
5148 Mode nesting prevents the close parenthesis in quote mode (part 3) from
5149  terminating the parenthesis mode (part 2).
5150 \end_layout
5152 \begin_layout Standard
5153 Each language has a set of modes, the default mode being the null mode.
5154  Each mode can lead to other modes.
5155 \end_layout
5157 \begin_layout Subsection
5158 Modes to included chunks
5159 \end_layout
5161 \begin_layout Standard
5162 For instance, consider this chunk with 
5163 \begin_inset Flex CharStyle:Code
5164 status collapsed
5166 \begin_layout Plain Layout
5167 language=perl
5168 \end_layout
5170 \end_inset
5173 \end_layout
5175 \begin_layout Chunk
5176 example-perl,language=perl
5177 \end_layout
5179 \begin_layout Standard
5180 \begin_inset listings
5181 inline false
5182 status open
5184 \begin_layout Plain Layout
5186 print "hello world $0
5187 \backslash
5189 \end_layout
5191 \end_inset
5194 \end_layout
5196 \begin_layout Standard
5197 If it were included in a chunk with 
5198 \begin_inset Flex CharStyle:Code
5199 status collapsed
5201 \begin_layout Plain Layout
5202 language=sh
5203 \end_layout
5205 \end_inset
5207 , like this:
5208 \end_layout
5210 \begin_layout Chunk
5211 example-sh,language=sh
5212 \end_layout
5214 \begin_layout Standard
5215 \begin_inset listings
5216 inline false
5217 status open
5219 \begin_layout Plain Layout
5221 perl -e "=<
5222 \backslash
5223 chunkref{example-perl}>"
5224 \end_layout
5226 \end_inset
5229 \end_layout
5231 \begin_layout Standard
5232 newfangle would need to generate output like this if it were to work: 
5233 \end_layout
5235 \begin_layout LyX-Code
5236 perl -e "print 
5237 \backslash
5238 "hello world $0
5239 \backslash
5241 \backslash
5243 \backslash
5244 ";" 
5245 \end_layout
5247 \begin_layout Standard
5248 See that the double quote 
5249 \begin_inset Flex CharStyle:Code
5250 status collapsed
5252 \begin_layout Plain Layout
5254 \end_layout
5256 \end_inset
5258 , and 
5259 \begin_inset Flex CharStyle:Code
5260 status collapsed
5262 \begin_layout Plain Layout
5264 \end_layout
5266 \end_inset
5268  in the regex have been quoted with a back-slash to protect them from shell
5269  interpretation.
5270 \end_layout
5272 \begin_layout Standard
5273 If that were then included in a chunk with 
5274 \begin_inset Flex CharStyle:Code
5275 status collapsed
5277 \begin_layout Plain Layout
5278 language=make
5279 \end_layout
5281 \end_inset
5283 , like this:
5284 \end_layout
5286 \begin_layout Chunk
5287 example-makefile,language=make
5288 \end_layout
5290 \begin_layout Standard
5291 \begin_inset listings
5292 inline false
5293 status open
5295 \begin_layout Plain Layout
5297 target: pre-req
5298 \end_layout
5300 \begin_layout Plain Layout
5302                 =<
5303 \backslash
5304 chunkref{example-sh}>
5305 \end_layout
5307 \end_inset
5310 \end_layout
5312 \begin_layout Standard
5313 We would need the output to look like this --- note the $$:
5314 \end_layout
5316 \begin_layout LyX-Code
5317 target: pre-req
5318 \end_layout
5320 \begin_layout LyX-Code
5321         perl -pe "s/
5322 \backslash
5324 \backslash
5325 $$/'/;"
5326 \end_layout
5328 \begin_layout Standard
5329 In order to make this work, we need to define a mode-tracker supporting
5330  each language, that can detect the various quoting modes, and provide a
5331  transformation that must be applied to any included text so that included
5332  text will be interpreted correctly after any interpolation that it may
5333  be subject to at run-time.
5334 \end_layout
5336 \begin_layout Standard
5337 For example, the sed transformation for text to be inserted into sh double-quote
5338 d strings would be something like:
5339 \end_layout
5341 \begin_layout LyX-Code
5343 \backslash
5345 \backslash
5347 \backslash
5349 \backslash
5351 \backslash
5353 \backslash
5354 /g;s/$/
5355 \backslash
5357 \backslash
5358 $/g;s/"/
5359 \backslash
5361 \backslash
5362 "/g;
5363 \end_layout
5365 \begin_layout Standard
5366 which protects 
5367 \begin_inset Flex CharStyle:Code
5368 status collapsed
5370 \begin_layout Plain Layout
5372 \backslash
5373  $ "
5374 \end_layout
5376 \end_inset
5379 \end_layout
5381 \begin_layout Standard
5382 \begin_inset Note Note
5383 status collapsed
5385 \begin_layout Plain Layout
5386 I don't think this example is true
5387 \end_layout
5389 \end_inset
5391 The mode tracker must also track nested mode-changes, as in this 
5392 \begin_inset Flex CharStyle:Code
5393 status collapsed
5395 \begin_layout Plain Layout
5397 \end_layout
5399 \end_inset
5401  example.
5402 \end_layout
5404 \begin_layout LyX-Code
5405 echo "hello `id \SpecialChar \ldots{}
5407 \end_layout
5409 \begin_layout LyX-Code
5410 \begin_inset ERT
5411 status open
5413 \begin_layout Plain Layout
5416 \backslash
5417 noindent
5418 \backslash
5419 hphantom{echo "hello `id}
5420 \end_layout
5422 \end_inset
5425 \end_layout
5427 \begin_layout Standard
5428 Any characters inserted at the point marked ↑ would need to be escaped,
5429  including 
5430 \begin_inset Flex CharStyle:Code
5431 status collapsed
5433 \begin_layout Plain Layout
5434 ` | *
5435 \end_layout
5437 \end_inset
5439  among others.
5440  First it would need escaping for the back-ticks `, and then for the double-quot
5441 es ".
5442 \end_layout
5444 \begin_layout Standard
5445 Escaping need not occur if the format and mode of the included chunk matches
5446  that of the including chunk.
5447 \end_layout
5449 \begin_layout Standard
5450 As each chunk is output a new mode tracker for that language is initialized
5451  in it's normal state.
5452  As text is output for that chunk the output mode is tracked.
5453  When a new chunk is included, a transformation appropriate to that mode
5454  is selected and pushed onto a stack of transformations.
5455  Any text to be output is first passed through this stack of transformations.
5456 \end_layout
5458 \begin_layout Standard
5459 It remains to consider if the chunk-include function should return it's
5460  generated text so that the caller can apply any transformations (and formatting
5461 ), or if it should apply the stack of transformations itself.
5462 \end_layout
5464 \begin_layout Standard
5465 Note that the transformed text should have the property of not being able
5466  to change the mode in the current chunk.
5467 \end_layout
5469 \begin_layout Standard
5470 \begin_inset Note Note
5471 status open
5473 \begin_layout Plain Layout
5474 Note chunk parameters should probably also be transformed
5475 \end_layout
5477 \end_inset
5480 \end_layout
5482 \begin_layout Section
5483 Language Mode Definitions
5484 \end_layout
5486 \begin_layout Standard
5487 All modes are stored in a single multi-dimensional hash.
5488  The first index is the language, and the second index is the mode-identifier.
5489  The third indexes are terminators, and optionally, submodes, and delimiters.
5490 \end_layout
5492 \begin_layout Standard
5493 A useful set of mode definitions for a nameless general C-type language
5494  is shown here.
5495  (Don't be confused by the double backslash escaping needed in awk.
5496  One set of escaping is for the string, and the second set of escaping is
5497  for the regex).
5499 \begin_inset Note Note
5500 status open
5502 \begin_layout Plain Layout
5503 TODO: Add =<
5504 \backslash
5505 mode{}> command which will allow us to signify that a string is regex and
5506  thus newfangle will quote it for us.
5507 \end_layout
5509 \end_inset
5512 \end_layout
5514 \begin_layout Standard
5515 Submodes are entered by the characters 
5516 \begin_inset Flex CharStyle:Code
5517 status collapsed
5519 \begin_layout Plain Layout
5521 \backslash
5523 \end_layout
5525 \end_inset
5528 \begin_inset Flex CharStyle:Code
5529 status collapsed
5531 \begin_layout Plain Layout
5533 \end_layout
5535 \end_inset
5538 \begin_inset Flex CharStyle:Code
5539 status collapsed
5541 \begin_layout Plain Layout
5543 \end_layout
5545 \end_inset
5548 \begin_inset Flex CharStyle:Code
5549 status collapsed
5551 \begin_layout Plain Layout
5553 \end_layout
5555 \end_inset
5558 \begin_inset Flex CharStyle:Code
5559 status collapsed
5561 \begin_layout Plain Layout
5563 \end_layout
5565 \end_inset
5568 \begin_inset Flex CharStyle:Code
5569 status collapsed
5571 \begin_layout Plain Layout
5573 \end_layout
5575 \end_inset
5578 \begin_inset Flex CharStyle:Code
5579 status collapsed
5581 \begin_layout Plain Layout
5583 \end_layout
5585 \end_inset
5588 \end_layout
5590 \begin_layout Chunk
5591 common-mode-definitions,params=language
5592 \end_layout
5594 \begin_layout Standard
5595 \begin_inset listings
5596 inline false
5597 status open
5599 \begin_layout Plain Layout
5601 modes[${language}, "",  "submodes" ]="
5602 \backslash
5604 \backslash
5606 \backslash
5608 \backslash
5610 \backslash
5611 "|'|{|
5612 \backslash
5614 \backslash
5616 \backslash
5618 \backslash
5620 \end_layout
5622 \end_inset
5625 \end_layout
5627 \begin_layout Standard
5628 In the default mode, a comma surrounded by un-important white space is a
5629  delimiter of language items.
5630 \end_layout
5632 \begin_layout Standard
5633 \begin_inset listings
5634 inline false
5635 status open
5637 \begin_layout Plain Layout
5639 modes[${language}, "",  "delimiters"]=" *, *";
5640 \end_layout
5642 \end_inset
5645 \end_layout
5647 \begin_layout Standard
5648 and should pass this test:
5649 \end_layout
5651 \begin_layout Standard
5652 \begin_inset Note Note
5653 status open
5655 \begin_layout Plain Layout
5656 Why do the tests run in 
5657 \begin_inset Quotes eld
5658 \end_inset
5661 \begin_inset Quotes erd
5662 \end_inset
5664  mode and not 
5665 \begin_inset Quotes eld
5666 \end_inset
5669 \begin_inset Quotes erd
5670 \end_inset
5672  mode
5673 \end_layout
5675 \end_inset
5678 \end_layout
5680 \begin_layout Chunk
5681 test:mode-definitions
5682 \end_layout
5684 \begin_layout Standard
5685 \begin_inset listings
5686 inline false
5687 status open
5689 \begin_layout Plain Layout
5691 parse_chunk_args("c-like", "1,2,3", a, "");
5692 \end_layout
5694 \begin_layout Plain Layout
5696 if (a[1] != "1") e++;
5697 \end_layout
5699 \begin_layout Plain Layout
5701 if (a[2] != "2") e++;
5702 \end_layout
5704 \begin_layout Plain Layout
5706 if (a[3] != "3") e++;
5707 \end_layout
5709 \begin_layout Plain Layout
5711 if (length(a) != 3) e++;
5712 \end_layout
5714 \begin_layout Plain Layout
5717 \backslash
5718 chunkref{pca-test.awk:summary}>
5719 \end_layout
5721 \begin_layout Plain Layout
5723 \end_layout
5725 \begin_layout Plain Layout
5727 parse_chunk_args("c-like", "joe, red", a, "");
5728 \end_layout
5730 \begin_layout Plain Layout
5732 if (a[1] != "joe") e++;
5733 \end_layout
5735 \begin_layout Plain Layout
5737 if (a[2] != "red") e++;
5738 \end_layout
5740 \begin_layout Plain Layout
5742 if (length(a) != 2) e++;
5743 \end_layout
5745 \begin_layout Plain Layout
5748 \backslash
5749 chunkref{pca-test.awk:summary}>
5750 \end_layout
5752 \begin_layout Plain Layout
5754 \end_layout
5756 \begin_layout Plain Layout
5758 parse_chunk_args("c-like", "${colour}", a, "");
5759 \end_layout
5761 \begin_layout Plain Layout
5763 if (a[1] != "${colour}") e++;
5764 \end_layout
5766 \begin_layout Plain Layout
5768 if (length(a) != 1) e++;
5769 \end_layout
5771 \begin_layout Plain Layout
5774 \backslash
5775 chunkref{pca-test.awk:summary}>
5776 \end_layout
5778 \end_inset
5781 \end_layout
5783 \begin_layout Standard
5784 Nested modes are identified by a backslash, a double or single quote, various
5785  bracket styles or a /* comment.
5786 \end_layout
5788 \begin_layout Standard
5789 For each of these sub-modes modes we must also identify at a mode terminator,
5790  and any sub-modes or delimiters that may be entered
5791 \begin_inset Foot
5792 status collapsed
5794 \begin_layout Plain Layout
5795 Because we are using the sub-mode characters as the mode identifier it means
5796  we can't currently have a mode character dependant on it's context; i.e.
5798 \begin_inset Flex CharStyle:Code
5799 status collapsed
5801 \begin_layout Plain Layout
5803 \end_layout
5805 \end_inset
5807  can't behave differently when it is inside 
5808 \begin_inset Flex CharStyle:Code
5809 status collapsed
5811 \begin_layout Plain Layout
5813 \end_layout
5815 \end_inset
5818 \end_layout
5820 \end_inset
5823 \end_layout
5825 \begin_layout Subsection
5826 Backslash
5827 \end_layout
5829 \begin_layout Standard
5830 The backslash mode has no submodes or delimiters, and is terminated by any
5831  character.
5832  Note that we are not so much interested in evaluating or interpolating
5833  content as we are in delineating content.
5834  It is no matter that a double backslash (
5835 \begin_inset Flex CharStyle:Code
5836 status collapsed
5838 \begin_layout Plain Layout
5840 \backslash
5842 \backslash
5844 \end_layout
5846 \end_inset
5848 ) may represent a single backslash while a backslash-newline may represent
5849  white space, but it does matter that the newline in a backslash newline
5850  should not be able to terminate a C pre-processor statement; and so the
5851  newline will be consumed by the backslash however it is to be interpreted.
5852 \end_layout
5854 \begin_layout Chunk
5855 common-mode-definitions
5856 \end_layout
5858 \begin_layout Standard
5859 \begin_inset listings
5860 inline false
5861 status open
5863 \begin_layout Plain Layout
5865 modes[${language}, "
5866 \backslash
5868 \backslash
5869 ", "terminators"]=".";
5870 \end_layout
5872 \end_inset
5875 \end_layout
5877 \begin_layout Subsection
5878 Strings
5879 \end_layout
5881 \begin_layout Standard
5882 Common languages support two kinds of strings quoting, double quotes and
5883  single quotes.
5884 \end_layout
5886 \begin_layout Chunk
5887 mode:common-string,params=language;quote
5888 \end_layout
5890 \begin_layout Standard
5891 In a string we have one special mode, which is the backslash.
5892  This may escape an embedded quote and prevent us thinking that it should
5893  terminate the string.
5895 \end_layout
5897 \begin_layout Standard
5898 \begin_inset listings
5899 inline false
5900 status open
5902 \begin_layout Plain Layout
5904 modes[${language}, ${quote}, "submodes" ]="
5905 \backslash
5907 \backslash
5909 \backslash
5911 \backslash
5913 \end_layout
5915 \end_inset
5918 \end_layout
5920 \begin_layout Standard
5921 Otherwise, the string will be terminated by the same character that commenced
5922  it.
5923 \end_layout
5925 \begin_layout Standard
5926 \begin_inset listings
5927 inline false
5928 status open
5930 \begin_layout Plain Layout
5932 modes[${language}, ${quote}, "terminators"]=${quote};
5933 \end_layout
5935 \end_inset
5938 \end_layout
5940 \begin_layout Standard
5941 In C type languages, certain escape sequences exist in strings.
5942  We need to define mechanism to enclode any chunks included in this mode
5943  using those escape sequences.
5944  These are expressed in two parts, s meaning search, and r meaning replace.
5945 \end_layout
5947 \begin_layout Standard
5948 The first substitution is to replace a backslash with a double backslash.
5949  We do this first as other substitutions may introduce a backslash which
5950  we would not then want to escape again here.
5951 \end_layout
5953 \begin_layout Standard
5954 Note: Backslashes need double-escaping in the search pattern but not in
5955  the replacement string, hence we are replacing a literal 
5956 \backslash
5957  with a literal 
5958 \backslash
5960 \backslash
5962 \end_layout
5964 \begin_layout Standard
5965 \begin_inset listings
5966 inline false
5967 status open
5969 \begin_layout Plain Layout
5971 escapes[${language}, ${quote}, ++escapes[${language}, ${quote}], "s"]="
5972 \backslash
5974 \backslash
5976 \backslash
5978 \backslash
5980 \end_layout
5982 \begin_layout Plain Layout
5984 escapes[${language}, ${quote},   escapes[${language}, ${quote}], "r"]="
5985 \backslash
5987 \backslash
5989 \backslash
5991 \backslash
5993 \end_layout
5995 \end_inset
5998 \end_layout
6000 \begin_layout Standard
6001 If the quote character occurs in the text, it should be preceded by a backslash,
6002  otherwise it would terminate the string unexpectedly.
6003 \end_layout
6005 \begin_layout Standard
6006 \begin_inset listings
6007 inline false
6008 status open
6010 \begin_layout Plain Layout
6012 escapes[${language}, ${quote}, ++escapes[${language}, ${quote}], "s"]=${quote};
6013 \end_layout
6015 \begin_layout Plain Layout
6017 escapes[${language}, ${quote},   escapes[${language}, ${quote}], "r"]="
6018 \backslash
6020 \backslash
6021 " ${quote};
6022 \end_layout
6024 \end_inset
6027 \end_layout
6029 \begin_layout Standard
6030 Any newlines in the string, must be replaced by 
6031 \begin_inset Flex CharStyle:Code
6032 status collapsed
6034 \begin_layout Plain Layout
6036 \backslash
6038 \end_layout
6040 \end_inset
6043 \end_layout
6045 \begin_layout Standard
6046 \begin_inset listings
6047 inline false
6048 status open
6050 \begin_layout Plain Layout
6052 escapes[${language}, ${quote}, ++escapes[${language}, ${quote}], "s"]="
6053 \backslash
6055 \end_layout
6057 \begin_layout Plain Layout
6059 escapes[${language}, ${quote},   escapes[${language}, ${quote}], "r"]="
6060 \backslash
6062 \backslash
6064 \end_layout
6066 \end_inset
6069 \end_layout
6071 \begin_layout Standard
6072 For the common modes, we define this string handling for double and single
6073  quotes.
6074 \end_layout
6076 \begin_layout Chunk
6077 common-mode-definitions,params=language
6078 \end_layout
6080 \begin_layout Standard
6081 \begin_inset listings
6082 inline false
6083 status open
6085 \begin_layout Plain Layout
6088 \backslash
6089 chunkref{mode:common-string}(${language}, "
6090 \backslash
6091 textbackslash{}"")>
6092 \end_layout
6094 \begin_layout Plain Layout
6097 \backslash
6098 chunkref{mode:common-string}(${language}, "'")>
6099 \end_layout
6101 \end_inset
6104 \end_layout
6106 \begin_layout Standard
6107 Working strings should pass this test:
6108 \end_layout
6110 \begin_layout Chunk
6111 test:mode-definitions
6112 \end_layout
6114 \begin_layout Standard
6115 \begin_inset listings
6116 inline false
6117 status open
6119 \begin_layout Plain Layout
6121 parse_chunk_args("c-like", "say 
6122 \backslash
6123 "I said, 
6124 \backslash
6126 \backslash
6128 \backslash
6129 "Hello, how are you
6130 \backslash
6132 \backslash
6134 \backslash
6136 \backslash
6137 ", for me", a, "");
6138 \end_layout
6140 \begin_layout Plain Layout
6142 if (a[1] != "say 
6143 \backslash
6144 "I said, 
6145 \backslash
6147 \backslash
6149 \backslash
6150 "Hello, how are you
6151 \backslash
6153 \backslash
6155 \backslash
6157 \backslash
6158 "") e++;
6159 \end_layout
6161 \begin_layout Plain Layout
6163 if (a[2] != "for me") e++;
6164 \end_layout
6166 \begin_layout Plain Layout
6168 if (length(a) != 2) e++;
6169 \end_layout
6171 \begin_layout Plain Layout
6174 \backslash
6175 chunkref{pca-test.awk:summary}>
6176 \end_layout
6178 \end_inset
6181 \end_layout
6183 \begin_layout Subsection
6184 Parentheses, Braces and Brackets
6185 \end_layout
6187 \begin_layout Standard
6188 Where quotes are closed by the same character, parentheses, brackets and
6189  braces are closed by an alternate character.
6190 \end_layout
6192 \begin_layout Chunk
6193 mode:common-brackets,params=language;open;close
6194 \end_layout
6196 \begin_layout Standard
6197 \begin_inset listings
6198 inline false
6199 status open
6201 \begin_layout Plain Layout
6203 modes[${language}, ${open},  "submodes" ]="
6204 \backslash
6206 \backslash
6208 \backslash
6210 \backslash
6212 \backslash
6213 "|{|
6214 \backslash
6216 \backslash
6218 \backslash
6220 \backslash
6221 [|'|/
6222 \backslash
6224 \backslash
6226 \end_layout
6228 \begin_layout Plain Layout
6230 modes[${language}, ${open},  "delimiters"]=" *, *";
6231 \end_layout
6233 \begin_layout Plain Layout
6235 modes[${language}, ${open},  "terminators"]=${close};
6236 \end_layout
6238 \end_inset
6241 \end_layout
6243 \begin_layout Standard
6244 Note that the open is NOT a regex but the close token IS.
6246 \begin_inset Note Note
6247 status open
6249 \begin_layout Plain Layout
6250 When we can quote regex we won't have to put the slashes in here
6251 \end_layout
6253 \end_inset
6256 \end_layout
6258 \begin_layout Chunk
6259 common-mode-definitions,params=language
6260 \end_layout
6262 \begin_layout Standard
6263 \begin_inset listings
6264 inline false
6265 status open
6267 \begin_layout Plain Layout
6270 \backslash
6271 chunkref{mode:common-brackets}(${language}, "{", "}")>
6272 \end_layout
6274 \begin_layout Plain Layout
6277 \backslash
6278 chunkref{mode:common-brackets}(${language}, "[", "
6279 \backslash
6280 textbackslash{}
6281 \backslash
6282 textbackslash{}]")>
6283 \end_layout
6285 \begin_layout Plain Layout
6288 \backslash
6289 chunkref{mode:common-brackets}(${language}, "(", "
6290 \backslash
6291 textbackslash{}
6292 \backslash
6293 textbackslash{})")>
6294 \end_layout
6296 \end_inset
6299 \end_layout
6301 \begin_layout Subsection
6302 Customizing Standard Modes
6303 \end_layout
6305 \begin_layout Chunk
6306 mode:add-submode,params=language;mode;submode
6307 \end_layout
6309 \begin_layout Standard
6310 \begin_inset listings
6311 inline false
6312 status open
6314 \begin_layout Plain Layout
6316 modes[${language}, ${mode}, "submodes"] = modes[${language}, ${mode}, "submodes"
6317 ] "|" ${submode};
6318 \end_layout
6320 \end_inset
6323 \end_layout
6325 \begin_layout Chunk
6326 mode:add-escapes,params=language;mode;search;replace
6327 \end_layout
6329 \begin_layout Standard
6330 \begin_inset listings
6331 inline false
6332 status open
6334 \begin_layout Plain Layout
6336 escapes[${language}, ${mode}, ++escapes[${language}, ${mode}], "s"]=${search};
6337 \end_layout
6339 \begin_layout Plain Layout
6341 escapes[${language}, ${mode},   escapes[${language}, ${mode}], "r"]=${replace};
6342 \end_layout
6344 \end_inset
6347 \end_layout
6349 \begin_layout Subsection
6350 Comments
6351 \end_layout
6353 \begin_layout Standard
6354 We can define 
6355 \begin_inset Flex CharStyle:Code
6356 status collapsed
6358 \begin_layout Plain Layout
6359 /* comment */
6360 \end_layout
6362 \end_inset
6364  style comments and 
6365 \begin_inset Flex CharStyle:Code
6366 status collapsed
6368 \begin_layout Plain Layout
6369 //comment
6370 \end_layout
6372 \end_inset
6374  style comments to be added to any language:
6375 \end_layout
6377 \begin_layout Chunk
6378 mode:multi-line-comments,params=language
6379 \end_layout
6381 \begin_layout Standard
6382 \begin_inset listings
6383 inline false
6384 status open
6386 \begin_layout Plain Layout
6389 \backslash
6390 chunkref{mode:add-submode}(${language}, "", "/
6391 \backslash
6392 textbackslash{}
6393 \backslash
6394 textbackslash{}*")>
6395 \end_layout
6397 \begin_layout Plain Layout
6399 modes[${language}, "/*", "terminators"]="
6400 \backslash
6402 \backslash
6403 */";
6404 \end_layout
6406 \end_inset
6409 \end_layout
6411 \begin_layout Chunk
6412 mode:single-line-slash-comments,params=language
6413 \end_layout
6415 \begin_layout Standard
6416 \begin_inset listings
6417 inline false
6418 status open
6420 \begin_layout Plain Layout
6423 \backslash
6424 chunkref{mode:add-submode}(${language}, "", "//")>
6425 \end_layout
6427 \begin_layout Plain Layout
6429 modes[${language}, "//", "terminators"]="
6430 \backslash
6432 \end_layout
6434 \begin_layout Plain Layout
6437 \backslash
6438 chunkref{mode:add-escapes}(${language}, "//", "
6439 \backslash
6440 textbackslash{}n", "
6441 \backslash
6442 textbackslash{}n//")>
6443 \end_layout
6445 \end_inset
6448 \end_layout
6450 \begin_layout Standard
6451 We can also define 
6452 \begin_inset Flex CharStyle:Code
6453 status collapsed
6455 \begin_layout Plain Layout
6456 # comment
6457 \end_layout
6459 \end_inset
6461  style comments (as used in awk and shell scripts) in a similar manner.
6462 \end_layout
6464 \begin_layout Chunk
6465 mode:add-hash-comments,params=language
6466 \begin_inset Note Note
6467 status open
6469 \begin_layout Plain Layout
6470 I'm having to use 
6471 \backslash
6472 # for hash and 
6473 \backslash
6474 textbackslash{} for 
6475 \backslash
6476  and have hacky work-arounds in the parser for now
6477 \end_layout
6479 \end_inset
6482 \end_layout
6484 \begin_layout Standard
6485 \begin_inset listings
6486 inline false
6487 status open
6489 \begin_layout Plain Layout
6492 \backslash
6493 chunkref{mode:add-submode}(${language}, "", "
6494 \backslash
6495 #")>
6496 \end_layout
6498 \begin_layout Plain Layout
6500 modes[${language}, "#", "terminators"]="
6501 \backslash
6503 \end_layout
6505 \begin_layout Plain Layout
6508 \backslash
6509 chunkref{mode:add-escapes}(${language}, "
6510 \backslash
6511 #", "
6512 \backslash
6513 textbackslash{}n", "
6514 \backslash
6515 textbackslash{}n
6516 \backslash
6517 #")>
6518 \end_layout
6520 \end_inset
6523 \end_layout
6525 \begin_layout Standard
6526 In C, the 
6527 \begin_inset Flex CharStyle:Code
6528 status collapsed
6530 \begin_layout Plain Layout
6532 \end_layout
6534 \end_inset
6536  denotes pre-processor directives which can be multi-line 
6537 \end_layout
6539 \begin_layout Chunk
6540 mode:add-hash-defines,params=language
6541 \end_layout
6543 \begin_layout Standard
6544 \begin_inset listings
6545 inline false
6546 status open
6548 \begin_layout Plain Layout
6551 \backslash
6552 chunkref{mode:add-submode}(${language}, "", "
6553 \backslash
6554 #")>
6555 \end_layout
6557 \begin_layout Plain Layout
6559 modes[${language}, "#", "submodes" ]="
6560 \backslash
6562 \backslash
6564 \backslash
6566 \backslash
6568 \end_layout
6570 \begin_layout Plain Layout
6572 modes[${language}, "#", "terminators"]="
6573 \backslash
6575 \end_layout
6577 \begin_layout Plain Layout
6580 \backslash
6581 chunkref{mode:add-escapes}(${language}, "
6582 \backslash
6583 #", "
6584 \backslash
6585 textbackslash{}n", "
6586 \backslash
6587 textbackslash{}
6588 \backslash
6589 textbackslash{}
6590 \backslash
6591 textbackslash{}
6592 \backslash
6593 textbackslash{}
6594 \backslash
6595 textbackslash{}n")>
6596 \end_layout
6598 \end_inset
6601 \end_layout
6603 \begin_layout Chunk
6604 mode:quote-dollar-escape,params=language;quote
6605 \end_layout
6607 \begin_layout Standard
6608 \begin_inset listings
6609 inline false
6610 status open
6612 \begin_layout Plain Layout
6614 escapes[${language}, ${quote}, ++escapes[${language}, ${quote}], "s"]="
6615 \backslash
6617 \backslash
6619 \end_layout
6621 \begin_layout Plain Layout
6623 escapes[${language}, ${quote},   escapes[${language}, ${quote}], "r"]="
6624 \backslash
6626 \backslash
6628 \end_layout
6630 \end_inset
6633 \end_layout
6635 \begin_layout Standard
6636 We can add these definitions to various languages
6637 \end_layout
6639 \begin_layout Chunk
6640 mode-definitions
6641 \end_layout
6643 \begin_layout Standard
6644 \begin_inset listings
6645 inline false
6646 status open
6648 \begin_layout Plain Layout
6651 \backslash
6652 chunkref{common-mode-definitions}("c-like")>
6653 \end_layout
6655 \begin_layout Plain Layout
6657 \end_layout
6659 \begin_layout Plain Layout
6662 \backslash
6663 chunkref{common-mode-definitions}("c")>
6664 \end_layout
6666 \begin_layout Plain Layout
6669 \backslash
6670 chunkref{mode:multi-line-comments}("c")>
6671 \end_layout
6673 \begin_layout Plain Layout
6676 \backslash
6677 chunkref{mode:single-line-slash-comments}("c")>
6678 \end_layout
6680 \begin_layout Plain Layout
6683 \backslash
6684 chunkref{mode:add-hash-defines}("c")>
6685 \end_layout
6687 \begin_layout Plain Layout
6689 \end_layout
6691 \begin_layout Plain Layout
6694 \backslash
6695 chunkref{common-mode-definitions}("awk")>
6696 \end_layout
6698 \begin_layout Plain Layout
6701 \backslash
6702 chunkref{mode:add-hash-comments}("awk")>
6703 \end_layout
6705 \begin_layout Plain Layout
6708 \backslash
6709 chunkref{mode:add-naked-regex}("awk")>
6710 \end_layout
6712 \end_inset
6715 \end_layout
6717 \begin_layout Standard
6718 The awk definitions should allow a comment block like this:
6719 \end_layout
6721 \begin_layout Chunk
6722 test:comment-quote,language=awk
6723 \end_layout
6725 \begin_layout Standard
6726 \begin_inset listings
6727 inline false
6728 status open
6730 \begin_layout Plain Layout
6732 # Comment: =<
6733 \backslash
6734 chunkref{test:comment-text}>
6735 \end_layout
6737 \end_inset
6740 \end_layout
6742 \begin_layout Chunk
6743 test:comment-text,language=
6744 \end_layout
6746 \begin_layout Standard
6747 \begin_inset listings
6748 inline false
6749 status open
6751 \begin_layout Plain Layout
6753 Now is the time for
6754 \end_layout
6756 \begin_layout Plain Layout
6758 the quick brown fox to bring lemonade
6759 \end_layout
6761 \begin_layout Plain Layout
6763 to the party
6764 \end_layout
6766 \end_inset
6769 \end_layout
6771 \begin_layout Standard
6772 to come out like this:
6773 \end_layout
6775 \begin_layout Chunk
6776 test:comment-quote:result
6777 \end_layout
6779 \begin_layout Standard
6780 \begin_inset listings
6781 inline false
6782 status open
6784 \begin_layout Plain Layout
6786 # Comment: Now is the time for
6787 \end_layout
6789 \begin_layout Plain Layout
6791 #the quick brown fox to bring lemonade
6792 \end_layout
6794 \begin_layout Plain Layout
6796 #to the party
6797 \end_layout
6799 \end_inset
6802 \end_layout
6804 \begin_layout Standard
6805 The C definition for such a block should have it come out like this:
6806 \end_layout
6808 \begin_layout Chunk
6809 test:comment-quote:C-result
6810 \end_layout
6812 \begin_layout Standard
6813 \begin_inset listings
6814 inline false
6815 status open
6817 \begin_layout Plain Layout
6819 # Comment: Now is the time for
6820 \backslash
6822 \end_layout
6824 \begin_layout Plain Layout
6826 the quick brown fox to bring lemonade
6827 \backslash
6829 \end_layout
6831 \begin_layout Plain Layout
6833 to the party
6834 \end_layout
6836 \end_inset
6839 \end_layout
6841 \begin_layout Subsection
6842 Regex
6843 \end_layout
6845 \begin_layout Standard
6846 This pattern is in-complete, but meant to detect naked regular expressions
6847  in awk and perl; e.g.
6849 \begin_inset Flex CharStyle:Code
6850 status collapsed
6852 \begin_layout Plain Layout
6853 /.*$/
6854 \end_layout
6856 \end_inset
6858 , however required capabilities are not present.
6859 \end_layout
6861 \begin_layout Standard
6862 Current it only detects regexes anchored with 
6863 \begin_inset Flex CharStyle:Code
6864 status collapsed
6866 \begin_layout Plain Layout
6868 \end_layout
6870 \end_inset
6872  as used in newfangle.
6873 \end_layout
6875 \begin_layout Standard
6876 For full regex support, modes need to be named not after their starting
6877  character, but some other more fully qualified name.
6878 \end_layout
6880 \begin_layout Chunk
6881 mode:add-naked-regex,params=language
6882 \end_layout
6884 \begin_layout Standard
6885 \begin_inset listings
6886 inline false
6887 status open
6889 \begin_layout Plain Layout
6892 \backslash
6893 chunkref{mode:add-submode}(${language}, "", "/
6894 \backslash
6895 textbackslash{}
6896 \backslash
6897 textbackslash{}
6898 \backslash
6899 ^")>
6900 \end_layout
6902 \begin_layout Plain Layout
6904 modes[${language}, "/^", "terminators"]="/";
6905 \end_layout
6907 \end_inset
6910 \end_layout
6912 \begin_layout Subsection
6913 Perl
6914 \end_layout
6916 \begin_layout Chunk
6917 mode-definitions
6918 \end_layout
6920 \begin_layout Standard
6921 \begin_inset listings
6922 inline false
6923 status open
6925 \begin_layout Plain Layout
6928 \backslash
6929 chunkref{common-mode-definitions}("perl")>
6930 \end_layout
6932 \begin_layout Plain Layout
6935 \backslash
6936 chunkref{mode:multi-line-comments}("perl")>
6937 \end_layout
6939 \begin_layout Plain Layout
6942 \backslash
6943 chunkref{mode:add-hash-comments}("perl")>
6944 \end_layout
6946 \end_inset
6949 \end_layout
6951 \begin_layout Standard
6952 Still need to add add s/, submod /, terminate both with //
6953 \end_layout
6955 \begin_layout Subsection
6957 \end_layout
6959 \begin_layout Chunk
6960 mode-definitions
6961 \end_layout
6963 \begin_layout Standard
6964 \begin_inset listings
6965 inline false
6966 status open
6968 \begin_layout Plain Layout
6971 \backslash
6972 chunkref{common-mode-definitions}("sh")>
6973 \end_layout
6975 \begin_layout Plain Layout
6978 \backslash
6979 chunkref{mode:common-string}("sh", "
6980 \backslash
6981 textbackslash{}"")>
6982 \end_layout
6984 \begin_layout Plain Layout
6987 \backslash
6988 chunkref{mode:common-string}("sh", "'")>
6989 \end_layout
6991 \begin_layout Plain Layout
6994 \backslash
6995 chunkref{mode:add-hash-comments}("sh")>
6996 \end_layout
6998 \begin_layout Plain Layout
7001 \backslash
7002 chunkref{mode:quote-dollar-escape}("sh", "
7003 \backslash
7004 "")>
7005 \end_layout
7007 \end_inset
7010 \end_layout
7012 \begin_layout Section
7013 Some tests
7014 \end_layout
7016 \begin_layout Standard
7017 Also, the parser must return any spare text at the end that has not been
7018  processed due to a mode terminator being found.
7019 \end_layout
7021 \begin_layout Chunk
7022 test:mode-definitions
7023 \end_layout
7025 \begin_layout Standard
7026 \begin_inset listings
7027 inline false
7028 status open
7030 \begin_layout Plain Layout
7032 rest = parse_chunk_args("c-like", "1, 2, 3) spare", a, "(");
7033 \end_layout
7035 \begin_layout Plain Layout
7037 if (a[1] != 1) e++;
7038 \end_layout
7040 \begin_layout Plain Layout
7042 if (a[2] != 2) e++;
7043 \end_layout
7045 \begin_layout Plain Layout
7047 if (a[3] != 3) e++;
7048 \end_layout
7050 \begin_layout Plain Layout
7052 if (length(a) != 3) e++;
7053 \end_layout
7055 \begin_layout Plain Layout
7057 if (rest != " spare") e++;
7058 \end_layout
7060 \begin_layout Plain Layout
7063 \backslash
7064 chunkref{pca-test.awk:summary}>
7065 \end_layout
7067 \end_inset
7070 \end_layout
7072 \begin_layout Standard
7073 We must also be able to parse the example given earlier.
7074 \end_layout
7076 \begin_layout Chunk
7077 test:mode-definitions
7078 \end_layout
7080 \begin_layout Standard
7081 \begin_inset listings
7082 inline false
7083 status open
7085 \begin_layout Plain Layout
7087 parse_chunk_args("c-like", "things[x, y], get_other_things(a, 
7088 \backslash
7089 "(all)
7090 \backslash
7091 "), 99", a, "(");
7092 \end_layout
7094 \begin_layout Plain Layout
7096 if (a[1] != "things[x, y]") e++;
7097 \end_layout
7099 \begin_layout Plain Layout
7101 if (a[2] != "get_other_things(a, 
7102 \backslash
7103 "(all)
7104 \backslash
7105 ")") e++;
7106 \end_layout
7108 \begin_layout Plain Layout
7110 if (a[3] != "99") e++;
7111 \end_layout
7113 \begin_layout Plain Layout
7115 if (length(a) != 3) e++;
7116 \end_layout
7118 \begin_layout Plain Layout
7121 \backslash
7122 chunkref{pca-test.awk:summary}>
7123 \end_layout
7125 \end_inset
7128 \end_layout
7130 \begin_layout Section
7131 A non-recursive mode tracker
7132 \end_layout
7134 \begin_layout Subsection
7135 Constructor
7136 \end_layout
7138 \begin_layout Standard
7139 The mode tracker holds its state in a stack based on a hash.
7140  This function, when passed an empty hash will intialize it.
7141 \end_layout
7143 \begin_layout Chunk
7144 new_mode_tracker()
7145 \end_layout
7147 \begin_layout Standard
7148 \begin_inset listings
7149 inline false
7150 status open
7152 \begin_layout Plain Layout
7154 function new_mode_tracker(context, language, mode) {
7155 \end_layout
7157 \begin_layout Plain Layout
7159   context[""] = 0;
7160 \end_layout
7162 \begin_layout Plain Layout
7164   context[0, "language"] = language;
7165 \end_layout
7167 \begin_layout Plain Layout
7169   context[0, "mode"] = mode;
7170 \end_layout
7172 \begin_layout Plain Layout
7175 \end_layout
7177 \end_inset
7180 \end_layout
7182 \begin_layout Standard
7183 Because awk functions cannot return an array, we must create the array first
7184  and pass it in, so we have a newfangle macro to do this:
7185 \end_layout
7187 \begin_layout Chunk
7188 new-mode-tracker,language=awk,params=context;language;mode
7189 \end_layout
7191 \begin_layout Standard
7192 \begin_inset listings
7193 inline false
7194 status open
7196 \begin_layout Plain Layout
7199 \backslash
7200 chunkref{awk-delete-array}(${context})>
7201 \end_layout
7203 \begin_layout Plain Layout
7205 new_mode_tracker(${context}, ${language}, ${mode});
7206 \end_layout
7208 \end_inset
7211 \end_layout
7213 \begin_layout Subsection
7214 Management
7215 \end_layout
7217 \begin_layout Standard
7218 And for tracking modes, we dispatch to a mode-tracker action based on the
7219  current language
7220 \end_layout
7222 \begin_layout Chunk
7223 mode_tracker,language=awk
7224 \end_layout
7226 \begin_layout Standard
7227 \begin_inset listings
7228 inline false
7229 status open
7231 \begin_layout Plain Layout
7233 function push_mode_tracker(context, language, mode,
7234 \end_layout
7236 \begin_layout Plain Layout
7238   # local vars
7239 \end_layout
7241 \begin_layout Plain Layout
7243   top)
7244 \end_layout
7246 \begin_layout Plain Layout
7249 \end_layout
7251 \begin_layout Plain Layout
7253   if (! ("" in context)) {
7254 \end_layout
7256 \begin_layout Plain Layout
7258     =<
7259 \backslash
7260 chunkref{new-mode-tracker}(context, language, mode)>
7261 \end_layout
7263 \begin_layout Plain Layout
7265   } else {
7266 \end_layout
7268 \begin_layout Plain Layout
7270     top = context[""];
7271 \end_layout
7273 \begin_layout Plain Layout
7275     if (context[top, "language"] == language && mode=="") mode = context[top,
7276  "mode"];
7277 \end_layout
7279 \begin_layout Plain Layout
7281     top++;
7282 \end_layout
7284 \begin_layout Plain Layout
7286     context[top, "language"] = language;
7287 \end_layout
7289 \begin_layout Plain Layout
7291     context[top, "mode"] = mode;
7292 \end_layout
7294 \begin_layout Plain Layout
7296     context[""] = top;
7297 \end_layout
7299 \begin_layout Plain Layout
7301   }
7302 \end_layout
7304 \begin_layout Plain Layout
7307 \end_layout
7309 \end_inset
7312 \end_layout
7314 \begin_layout Standard
7315 \begin_inset listings
7316 inline false
7317 status open
7319 \begin_layout Plain Layout
7321 function dump_mode_tracker(context,  
7322 \end_layout
7324 \begin_layout Plain Layout
7326   c, d)
7327 \end_layout
7329 \begin_layout Plain Layout
7332 \end_layout
7334 \begin_layout Plain Layout
7336   for(c=0; c <= context[""]; c++) {
7337 \end_layout
7339 \begin_layout Plain Layout
7341     printf(" %2d   %s:%s
7342 \backslash
7343 n", c, context[c, "language"], context[c, "mode"]) > "/dev/stderr";
7344 \end_layout
7346 \begin_layout Plain Layout
7348     for(d=1; ( (c, "values", d) in context); d++) {
7349 \end_layout
7351 \begin_layout Plain Layout
7353       printf("   %2d %s
7354 \backslash
7355 n", d, context[c, "values", d]) > "/dev/stderr";
7356 \end_layout
7358 \begin_layout Plain Layout
7360     }
7361 \end_layout
7363 \begin_layout Plain Layout
7365   }
7366 \end_layout
7368 \begin_layout Plain Layout
7371 \end_layout
7373 \end_inset
7376 \end_layout
7378 \begin_layout Standard
7379 \begin_inset listings
7380 inline false
7381 status open
7383 \begin_layout Plain Layout
7385 function finalize_mode_tracker(context)
7386 \end_layout
7388 \begin_layout Plain Layout
7391 \end_layout
7393 \begin_layout Plain Layout
7395   if ( ("" in context) && context[""] != 0) return 0;
7396 \end_layout
7398 \begin_layout Plain Layout
7400   return 1;
7401 \end_layout
7403 \begin_layout Plain Layout
7406 \end_layout
7408 \end_inset
7411 \end_layout
7413 \begin_layout Standard
7414 This implies that any chunk must be syntactically whole; for instance, this
7415  is fine:
7416 \end_layout
7418 \begin_layout Chunk
7419 test:whole-chunk
7420 \end_layout
7422 \begin_layout Standard
7423 \begin_inset listings
7424 inline false
7425 status open
7427 \begin_layout Plain Layout
7429 if (1) {
7430 \end_layout
7432 \begin_layout Plain Layout
7434   =<
7435 \backslash
7436 chunkref{test:say-hello}>
7437 \end_layout
7439 \begin_layout Plain Layout
7442 \end_layout
7444 \end_inset
7447 \end_layout
7449 \begin_layout Chunk
7450 test:say-hello
7451 \end_layout
7453 \begin_layout Standard
7454 \begin_inset listings
7455 inline false
7456 status open
7458 \begin_layout Plain Layout
7460 print "hello";
7461 \end_layout
7463 \end_inset
7466 \end_layout
7468 \begin_layout Standard
7469 But this is not fine; the chunk 
7470 \begin_inset Flex Chunkref
7471 status collapsed
7473 \begin_layout Plain Layout
7474 test:hidden-else
7475 \end_layout
7477 \end_inset
7479  is not properly cromulent.
7480 \end_layout
7482 \begin_layout Chunk
7483 test:partial-chunk
7484 \end_layout
7486 \begin_layout Standard
7487 \begin_inset listings
7488 inline false
7489 status open
7491 \begin_layout Plain Layout
7493 if (1) {
7494 \end_layout
7496 \begin_layout Plain Layout
7498   =<
7499 \backslash
7500 chunkref{test:hidden-else}>
7501 \end_layout
7503 \begin_layout Plain Layout
7506 \end_layout
7508 \end_inset
7511 \end_layout
7513 \begin_layout Chunk
7514 test:hidden-else
7515 \end_layout
7517 \begin_layout Standard
7518 \begin_inset listings
7519 inline false
7520 status open
7522 \begin_layout Plain Layout
7524   print "I'm fine";
7525 \end_layout
7527 \begin_layout Plain Layout
7529 } else {
7530 \end_layout
7532 \begin_layout Plain Layout
7534   print "I'm not";
7535 \end_layout
7537 \end_inset
7540 \end_layout
7542 \begin_layout Standard
7543 These tests will check for correct behaviour:
7544 \end_layout
7546 \begin_layout Chunk
7547 test:cromulence
7548 \end_layout
7550 \begin_layout Standard
7551 \begin_inset listings
7552 inline false
7553 status open
7555 \begin_layout Plain Layout
7557 echo Cromulence test
7558 \end_layout
7560 \begin_layout Plain Layout
7562 passtest $NEWFANGLE -Rtest:whole-chunk $TEX_SRC &>/dev/null || ( echo "Whole
7563  chunk failed" && exit 1 )
7564 \end_layout
7566 \begin_layout Plain Layout
7568 failtest $NEWFANGLE -Rtest:partial-chunk $TEX_SRC &>/dev/null || ( echo
7569  "Partial chunk failed" && exit 1 )
7570 \end_layout
7572 \end_inset
7575 \end_layout
7577 \begin_layout Subsection
7578 Tracker
7579 \end_layout
7581 \begin_layout Standard
7582 We must avoid recursion as a language construct because we intend to employ
7583  mode-tracking to track language mode of emitted code, and the code is emitted
7584  from a function which is itself recursive, so instead we implement psuedo-recur
7585 sion using our own stack based on a hash.
7586 \end_layout
7588 \begin_layout Chunk
7589 mode_tracker()
7590 \end_layout
7592 \begin_layout Standard
7593 \begin_inset listings
7594 inline false
7595 status open
7597 \begin_layout Plain Layout
7599 function mode_tracker(context, text, values, 
7600 \end_layout
7602 \begin_layout Plain Layout
7604   # optional parameters
7605 \end_layout
7607 \begin_layout Plain Layout
7609   # local vars
7610 \end_layout
7612 \begin_layout Plain Layout
7614   mode, submodes, language,
7615 \end_layout
7617 \begin_layout Plain Layout
7619   cindex, c, a, part, item, name, result, new_values, new_mode, 
7620 \end_layout
7622 \begin_layout Plain Layout
7624   delimiters, terminators)
7625 \end_layout
7627 \begin_layout Plain Layout
7630 \end_layout
7632 \end_inset
7635 \end_layout
7637 \begin_layout Standard
7638 We could be re-commencing with a valid context, so we need to setup the
7639  state according to the last context.
7640 \end_layout
7642 \begin_layout Standard
7643 \begin_inset listings
7644 inline false
7645 status open
7647 \begin_layout Plain Layout
7649   cindex = context[""] + 0;
7650 \end_layout
7652 \begin_layout Plain Layout
7654   mode = context[cindex, "mode"];
7655 \end_layout
7657 \begin_layout Plain Layout
7659   language = context[cindex, "language" ];
7660 \end_layout
7662 \end_inset
7665 \end_layout
7667 \begin_layout Standard
7668 First we construct a single large regex combining the possible sub-modes
7669  for the current mode along with the terminators for the current mode.
7670 \end_layout
7672 \begin_layout Chunk
7673 parse_chunk_args-reset-modes
7674 \end_layout
7676 \begin_layout Standard
7677 \begin_inset listings
7678 inline false
7679 status open
7681 \begin_layout Plain Layout
7683   submodes=modes[language, mode, "submodes"];
7684 \end_layout
7686 \begin_layout Plain Layout
7688 \end_layout
7690 \begin_layout Plain Layout
7692   if ((language, mode, "delimiters") in modes) {
7693 \end_layout
7695 \begin_layout Plain Layout
7697     delimiters = modes[language, mode, "delimiters"];
7698 \end_layout
7700 \begin_layout Plain Layout
7702     if (length(submodes)>0) submodes = submodes "|";
7703 \end_layout
7705 \begin_layout Plain Layout
7707     submodes=submodes delimiters;
7708 \end_layout
7710 \begin_layout Plain Layout
7712   } else delimiters="";
7713 \end_layout
7715 \begin_layout Plain Layout
7717   if ((language, mode, "terminators") in modes) {
7718 \end_layout
7720 \begin_layout Plain Layout
7722     terminators = modes[language, mode, "terminators"];
7723 \end_layout
7725 \begin_layout Plain Layout
7727     if (length(submodes)>0) submodes = submodes "|";
7728 \end_layout
7730 \begin_layout Plain Layout
7732     submodes=submodes terminators;
7733 \end_layout
7735 \begin_layout Plain Layout
7737   } else terminators="";
7738 \end_layout
7740 \end_inset
7743 \end_layout
7745 \begin_layout Standard
7746 If we don't find anything to match on --- probably because the language
7747  is not supported --- then we return the entire text without matching anything.
7748 \end_layout
7750 \begin_layout Standard
7751 \begin_inset listings
7752 inline false
7753 status open
7755 \begin_layout Plain Layout
7757   if (! length(submodes)) return text; 
7758 \end_layout
7760 \end_inset
7763 \end_layout
7765 \begin_layout Chunk
7766 mode_tracker()
7767 \end_layout
7769 \begin_layout Standard
7770 \begin_inset listings
7771 inline false
7772 status open
7774 \begin_layout Plain Layout
7777 \backslash
7778 chunkref{parse_chunk_args-reset-modes}>
7779 \end_layout
7781 \end_inset
7784 \end_layout
7786 \begin_layout Standard
7787 We then iterate the text (until there is none left) looking for sub-modes
7788  or terminators in the regex.
7789 \end_layout
7791 \begin_layout Standard
7792 \begin_inset listings
7793 inline false
7794 status open
7796 \begin_layout Plain Layout
7798   while((cindex >= 0) && length(text)) {
7799 \end_layout
7801 \begin_layout Plain Layout
7803     if (match(text, "(" submodes ")", a)) {
7804 \end_layout
7806 \end_inset
7809 \end_layout
7811 \begin_layout Standard
7812 A bug that creeps in regularly during development is bad regexes of zero
7813  length which result in an infinite loop (as no text is consumed), so I
7814  catch that right away with this test.
7815 \end_layout
7817 \begin_layout Standard
7818 \begin_inset listings
7819 inline false
7820 status open
7822 \begin_layout Plain Layout
7824       if (RLENGTH<1) {
7825 \end_layout
7827 \begin_layout Plain Layout
7829         error(sprintf("Internal error, matched zero length submode, should
7830  be impossible - likely regex computation error
7831 \backslash
7832 n" 
7833 \backslash
7835 \end_layout
7837 \begin_layout Plain Layout
7839                 "Language=%s
7840 \backslash
7841 nmode=%s
7842 \backslash
7843 nmatch=%s
7844 \backslash
7845 n", language, mode, submodes));
7846 \end_layout
7848 \begin_layout Plain Layout
7850       }
7851 \end_layout
7853 \end_inset
7856 \end_layout
7858 \begin_layout Standard
7859 \begin_inset Flex CharStyle:Code
7860 status collapsed
7862 \begin_layout Plain Layout
7863 part
7864 \end_layout
7866 \end_inset
7868  is defined as the text up to the sub-mode or terminator, and this is appended
7869  to 
7870 \begin_inset Flex CharStyle:Code
7871 status collapsed
7873 \begin_layout Plain Layout
7874 item
7875 \end_layout
7877 \end_inset
7879  --- which is the current text being gathered.
7880  If a mode has a delimiter, then item is reset each time a delimiter is
7881  found.
7882 \end_layout
7884 \begin_layout Standard
7885 \begin_inset Formula $\mathtt{\overbrace{"\overbrace{hello}^{item},\ \overbrace{there}^{item}"}^{item},\ \overbrace{he\ said.}^{item}}$
7886 \end_inset
7889 \end_layout
7891 \begin_layout Standard
7892 \begin_inset listings
7893 inline false
7894 status open
7896 \begin_layout Plain Layout
7898       part = substr(text, 1, RSTART -1);
7899 \end_layout
7901 \begin_layout Plain Layout
7903       item = item part;
7904 \end_layout
7906 \end_inset
7909 \end_layout
7911 \begin_layout Standard
7912 We must now determine what was matched.
7913  If it was a terminator, then we must restore the previous mode.
7914 \end_layout
7916 \begin_layout Standard
7917 \begin_inset listings
7918 inline false
7919 status open
7921 \begin_layout Plain Layout
7923       if (match(a[1], "^" terminators "$")) {
7924 \end_layout
7926 \begin_layout Plain Layout
7928 #printf("%2d EXIT  MODE [%s] by [%s] [%s]
7929 \backslash
7930 n", cindex, mode, a[1], text) > "/dev/stderr"
7931 \end_layout
7933 \begin_layout Plain Layout
7935         context[cindex, "values", ++context[cindex, "values"]] = item;
7936 \end_layout
7938 \begin_layout Plain Layout
7940         delete context[cindex];
7941 \end_layout
7943 \begin_layout Plain Layout
7945         context[""] = --cindex;
7946 \end_layout
7948 \begin_layout Plain Layout
7950         if (cindex>=0) {
7951 \end_layout
7953 \begin_layout Plain Layout
7955           mode = context[cindex, "mode"];
7956 \end_layout
7958 \begin_layout Plain Layout
7960           language = context[cindex, "language"];
7961 \end_layout
7963 \begin_layout Plain Layout
7965           =<
7966 \backslash
7967 chunkref{parse_chunk_args-reset-modes}>
7968 \end_layout
7970 \begin_layout Plain Layout
7972         }
7973 \end_layout
7975 \begin_layout Plain Layout
7977         item = item a[1];
7978 \end_layout
7980 \begin_layout Plain Layout
7982         text = substr(text, 1 + length(part) + length(a[1]));
7983 \end_layout
7985 \begin_layout Plain Layout
7987       }
7988 \end_layout
7990 \end_inset
7993 \end_layout
7995 \begin_layout Standard
7996 If a delimiter was matched, then we must store the current item in the parsed
7997  values array, and reset the item.
7998 \end_layout
8000 \begin_layout Standard
8001 \begin_inset listings
8002 inline false
8003 status open
8005 \begin_layout Plain Layout
8007       else if (match(a[1], "^" delimiters "$")) {
8008 \end_layout
8010 \begin_layout Plain Layout
8012         if (cindex==0) {
8013 \end_layout
8015 \begin_layout Plain Layout
8017           context[cindex, "values", ++context[cindex, "values"]] = item;
8018 \end_layout
8020 \begin_layout Plain Layout
8022           item = "";
8023 \end_layout
8025 \begin_layout Plain Layout
8027         } else {
8028 \end_layout
8030 \begin_layout Plain Layout
8032           item = item a[1];
8033 \end_layout
8035 \begin_layout Plain Layout
8037         }
8038 \end_layout
8040 \begin_layout Plain Layout
8042         text = substr(text, 1 + length(part) + length(a[1]));
8043 \end_layout
8045 \begin_layout Plain Layout
8047       }
8048 \end_layout
8050 \end_inset
8053 \end_layout
8055 \begin_layout Standard
8056 otherwise, if a new submode is detected (all submodes have terminators),
8057  we must create a nested parse context until we find the terminator for
8058  this mode.
8059 \end_layout
8061 \begin_layout Standard
8062 \begin_inset listings
8063 inline false
8064 status open
8066 \begin_layout Plain Layout
8068  else if ((language, a[1], "terminators") in modes) {
8069 \end_layout
8071 \begin_layout Plain Layout
8073         #check if new_mode is defined
8074 \end_layout
8076 \begin_layout Plain Layout
8078         item = item a[1];
8079 \end_layout
8081 \begin_layout Plain Layout
8083 #printf("%2d ENTER MODE [%s] in [%s]
8084 \backslash
8085 n", cindex, a[1], text) > "/dev/stderr"
8086 \end_layout
8088 \begin_layout Plain Layout
8090         text = substr(text, 1 + length(part) + length(a[1]));
8091 \end_layout
8093 \begin_layout Plain Layout
8095         context[""] = ++cindex;
8096 \end_layout
8098 \begin_layout Plain Layout
8100         context[cindex, "mode"] = a[1];
8101 \end_layout
8103 \begin_layout Plain Layout
8105         context[cindex, "language"] = language;
8106 \end_layout
8108 \begin_layout Plain Layout
8110         mode = a[1];
8111 \end_layout
8113 \begin_layout Plain Layout
8115         =<
8116 \backslash
8117 chunkref{parse_chunk_args-reset-modes}>
8118 \end_layout
8120 \begin_layout Plain Layout
8122       } else {
8123 \end_layout
8125 \begin_layout Plain Layout
8127         error(sprintf("Submode '%s' set unknown mode in text: %s
8128 \backslash
8129 nLanguage %s Mode %s
8130 \backslash
8131 n", a[1], text, language, mode));
8132 \end_layout
8134 \begin_layout Plain Layout
8136         text = substr(text, 1 + length(part) + length(a[1]));
8137 \end_layout
8139 \begin_layout Plain Layout
8141       }
8142 \end_layout
8144 \begin_layout Plain Layout
8146     }
8147 \end_layout
8149 \end_inset
8152 \end_layout
8154 \begin_layout Standard
8155 In the final case, we parsed to the end of the string.
8156  If the string was entire, then we should have no nested mode context, but
8157  if the string was just a fragment we may have a mode context which must
8158  be preserved for the next fragment.
8159  Todo: Consideration ought to be given if sub-mode strings are split over
8160  two fragments.
8161 \begin_inset Note Note
8162 status collapsed
8164 \begin_layout Plain Layout
8165 Consideration ought to be given if sub-mode strings are split over two fragments.
8166 \end_layout
8168 \end_inset
8171 \end_layout
8173 \begin_layout Standard
8174 \begin_inset listings
8175 inline false
8176 status open
8178 \begin_layout Plain Layout
8180 else {
8181 \end_layout
8183 \begin_layout Plain Layout
8185       context[cindex, "values", ++context[cindex, "values"]] = item text;
8186 \end_layout
8188 \begin_layout Plain Layout
8190       text = "";
8191 \end_layout
8193 \begin_layout Plain Layout
8195       item = "";
8196 \end_layout
8198 \begin_layout Plain Layout
8200     }
8201 \end_layout
8203 \begin_layout Plain Layout
8205   }
8206 \end_layout
8208 \begin_layout Plain Layout
8210 \end_layout
8212 \begin_layout Plain Layout
8214   context["item"] = item;
8215 \end_layout
8217 \begin_layout Plain Layout
8219 \end_layout
8221 \begin_layout Plain Layout
8223   if (length(item)) context[cindex, "values", ++context[cindex, "values"]]
8224  = item;
8225 \end_layout
8227 \begin_layout Plain Layout
8229   return text;
8230 \end_layout
8232 \begin_layout Plain Layout
8235 \end_layout
8237 \end_inset
8240 \end_layout
8242 \begin_layout Subsubsection
8243 One happy chunk
8244 \end_layout
8246 \begin_layout Standard
8247 All the mode tracker chunks are referred to here:
8248 \end_layout
8250 \begin_layout Chunk
8251 mode-tracker
8252 \end_layout
8254 \begin_layout Standard
8255 \begin_inset listings
8256 inline false
8257 status open
8259 \begin_layout Plain Layout
8262 \backslash
8263 chunkref{new_mode_tracker()}>
8264 \end_layout
8266 \begin_layout Plain Layout
8269 \backslash
8270 chunkref{mode_tracker()}>
8271 \end_layout
8273 \end_inset
8276 \end_layout
8278 \begin_layout Subsubsection
8279 Tests
8280 \end_layout
8282 \begin_layout Standard
8283 We can test this function like this:
8284 \end_layout
8286 \begin_layout Chunk
8287 pca-test.awk,language=awk
8288 \end_layout
8290 \begin_layout Standard
8291 \begin_inset listings
8292 inline false
8293 status open
8295 \begin_layout Plain Layout
8298 \backslash
8299 chunkref{error()}>
8300 \end_layout
8302 \begin_layout Plain Layout
8305 \backslash
8306 chunkref{mode-tracker}>
8307 \end_layout
8309 \begin_layout Plain Layout
8312 \backslash
8313 chunkref{parse_chunk_args()}>
8314 \end_layout
8316 \begin_layout Plain Layout
8318 BEGIN {
8319 \end_layout
8321 \begin_layout Plain Layout
8323   SUBSEP=".";
8324 \end_layout
8326 \begin_layout Plain Layout
8328   =<
8329 \backslash
8330 chunkref{mode-definitions}>
8331 \end_layout
8333 \begin_layout Plain Layout
8335 \end_layout
8337 \begin_layout Plain Layout
8339   =<
8340 \backslash
8341 chunkref{test:mode-definitions}>
8342 \end_layout
8344 \begin_layout Plain Layout
8347 \end_layout
8349 \end_inset
8352 \end_layout
8354 \begin_layout Chunk
8355 pca-test.awk:summary,language=awk
8356 \end_layout
8358 \begin_layout Standard
8359 \begin_inset listings
8360 inline false
8361 status open
8363 \begin_layout Plain Layout
8365 if (e) {
8366 \end_layout
8368 \begin_layout Plain Layout
8370   printf "Failed " e
8371 \end_layout
8373 \begin_layout Plain Layout
8375   for (b in a) {
8376 \end_layout
8378 \begin_layout Plain Layout
8380     print "a[" b "] => " a[b];
8381 \end_layout
8383 \begin_layout Plain Layout
8385   }
8386 \end_layout
8388 \begin_layout Plain Layout
8390 } else {
8391 \end_layout
8393 \begin_layout Plain Layout
8395   print "Passed"
8396 \end_layout
8398 \begin_layout Plain Layout
8401 \end_layout
8403 \begin_layout Plain Layout
8405 split("", a);
8406 \end_layout
8408 \begin_layout Plain Layout
8410 e=0;
8411 \end_layout
8413 \end_inset
8416 \end_layout
8418 \begin_layout Standard
8419 which should give this output:
8420 \end_layout
8422 \begin_layout Chunk
8423 pca-test.awk-results,language=
8424 \end_layout
8426 \begin_layout Standard
8427 \begin_inset listings
8428 inline false
8429 status open
8431 \begin_layout Plain Layout
8433 a[foo.quux.quirk] => 
8434 \end_layout
8436 \begin_layout Plain Layout
8438 a[foo.quux.a] => fleeg
8439 \end_layout
8441 \begin_layout Plain Layout
8443 a[foo.bar] => baz
8444 \end_layout
8446 \begin_layout Plain Layout
8448 a[etc] => 
8449 \end_layout
8451 \begin_layout Plain Layout
8453 a[name] => freddie
8454 \end_layout
8456 \end_inset
8459 \end_layout
8461 \begin_layout Section
8462 Escaping and Quoting
8463 \end_layout
8465 \begin_layout Standard
8466 Each nested mode can optionally define a set of transforms to be applied
8467  to any text that is included from another language.
8468 \end_layout
8470 \begin_layout Standard
8471 This code can perform transforms
8472 \end_layout
8474 \begin_layout Chunk
8475 mode_tracker,language=awk
8476 \end_layout
8478 \begin_layout Standard
8479 \begin_inset listings
8480 inline false
8481 status open
8483 \begin_layout Plain Layout
8485 function transform_escape(s, r, text,
8486 \end_layout
8488 \begin_layout Plain Layout
8490     # optional
8491 \end_layout
8493 \begin_layout Plain Layout
8495     max, 
8496 \end_layout
8498 \begin_layout Plain Layout
8500         # local vars
8501 \end_layout
8503 \begin_layout Plain Layout
8505         c)
8506 \end_layout
8508 \begin_layout Plain Layout
8511 \end_layout
8513 \begin_layout Plain Layout
8515   for(c=1; c <= max && (c in s); c++) {
8516 \end_layout
8518 \begin_layout Plain Layout
8520     gsub(s[c], r[c], text);
8521 \end_layout
8523 \begin_layout Plain Layout
8525   }
8526 \end_layout
8528 \begin_layout Plain Layout
8530   return text;
8531 \end_layout
8533 \begin_layout Plain Layout
8536 \end_layout
8538 \end_inset
8541 \end_layout
8543 \begin_layout Standard
8544 This function must append from index 
8545 \begin_inset Flex CharStyle:Code
8546 status collapsed
8548 \begin_layout Plain Layout
8550 \end_layout
8552 \end_inset
8554  onwards, and escape transforms from the supplied context, and return c
8555  + number of new transforms.
8556 \end_layout
8558 \begin_layout Standard
8559 \begin_inset listings
8560 inline false
8561 status open
8563 \begin_layout Plain Layout
8565 function mode_escaper(context, s, r, src,
8566 \end_layout
8568 \begin_layout Plain Layout
8570   c, cp, cpl)
8571 \end_layout
8573 \begin_layout Plain Layout
8576 \end_layout
8578 \begin_layout Plain Layout
8580         for(c = context[""]; c >= 0; c--) {
8581 \end_layout
8583 \begin_layout Plain Layout
8585                 if ( (context[c, "language"], context[c, "mode"]) in escapes) {
8586 \end_layout
8588 \begin_layout Plain Layout
8590                         cpl = escapes[context[c, "language"], context[c, "mode"]];
8591 \end_layout
8593 \begin_layout Plain Layout
8595                         for (cp = 1; cp <= cpl; cp ++) {
8596 \end_layout
8598 \begin_layout Plain Layout
8600                                 ++src;
8601 \end_layout
8603 \begin_layout Plain Layout
8605                                 s[src] = escapes[context[c, "language"], context[c, "mode"], cp, "s"];
8606 \end_layout
8608 \begin_layout Plain Layout
8610                                 r[src] = escapes[context[c, "language"], context[c, "mode"], cp, "r"];
8611 \end_layout
8613 \begin_layout Plain Layout
8615                         }
8616 \end_layout
8618 \begin_layout Plain Layout
8620                 }
8621 \end_layout
8623 \begin_layout Plain Layout
8625         }
8626 \end_layout
8628 \begin_layout Plain Layout
8630         return src;
8631 \end_layout
8633 \begin_layout Plain Layout
8636 \end_layout
8638 \begin_layout Plain Layout
8640 function dump_escaper(c, s, r, cc) {
8641 \end_layout
8643 \begin_layout Plain Layout
8645   for(cc=1; cc<=c; cc++) {
8646 \end_layout
8648 \begin_layout Plain Layout
8650     printf("%2d s[%s] r[%s]
8651 \backslash
8652 n", cc, s[cc], r[cc]) > "/dev/stderr"
8653 \end_layout
8655 \begin_layout Plain Layout
8657   }
8658 \end_layout
8660 \begin_layout Plain Layout
8663 \end_layout
8665 \end_inset
8668 \end_layout
8670 \begin_layout Chunk
8671 test:escapes,language=sh
8672 \end_layout
8674 \begin_layout Standard
8675 \begin_inset listings
8676 inline false
8677 status open
8679 \begin_layout Plain Layout
8681 echo escapes test
8682 \end_layout
8684 \begin_layout Plain Layout
8686 passtest $NEWFANGLE -Rtest:comment-quote $TEX_SRC &>/dev/null || ( echo
8687  "Comment-quote failed" && exit 1 )
8688 \end_layout
8690 \end_inset
8693 \end_layout
8695 \begin_layout Chapter
8696 Recognizing Chunks
8697 \end_layout
8699 \begin_layout Standard
8700 Newfangle recognizes noweb chunks, but as we also want better LaTeX integration
8701  we will recognize any of these:
8702 \end_layout
8704 \begin_layout Itemize
8705 notangle chunks matching the pattern 
8706 \begin_inset Flex CharStyle:Code
8707 status collapsed
8709 \begin_layout Plain Layout
8711 \begin_inset space \hspace*{}
8712 \length 0in
8713 \end_inset
8715 <.*?>
8716 \begin_inset space \hspace*{}
8717 \length 0in
8718 \end_inset
8721 \end_layout
8723 \end_inset
8726 \end_layout
8728 \begin_layout Itemize
8729 a chunks beginning with 
8730 \begin_inset Flex CharStyle:Code
8731 status collapsed
8733 \begin_layout Plain Layout
8735 \backslash
8736 begin{lstlistings}
8737 \end_layout
8739 \end_inset
8741 , possibly with 
8742 \backslash
8743 Chunk{\SpecialChar \ldots{}
8744 } on the previous line
8745 \end_layout
8747 \begin_layout Itemize
8748 an older form I have used, beginning with 
8749 \begin_inset Flex CharStyle:Code
8750 status collapsed
8752 \begin_layout Plain Layout
8754 \backslash
8755 begin{Chunk}[options]
8756 \end_layout
8758 \end_inset
8760  --- also more suitable for plain LaTeX users
8761 \begin_inset Foot
8762 status collapsed
8764 \begin_layout Plain Layout
8765 Is there such a thing as plain LaTeX?
8766 \end_layout
8768 \end_inset
8771 \end_layout
8773 \begin_layout Section
8774 Chunk start
8775 \end_layout
8777 \begin_layout Standard
8778 The variable 
8779 \begin_inset Flex CharStyle:Code
8780 status collapsed
8782 \begin_layout Plain Layout
8783 chunking
8784 \end_layout
8786 \end_inset
8788  is used to signify that we are processing a code chunk and not document.
8789  In such a state, input lines will be assigned to the current chunk; otherwise
8790  they are ignored.
8791 \end_layout
8793 \begin_layout Subsection
8794 lstlistings
8795 \end_layout
8797 \begin_layout Standard
8798 Our current scheme is to recognize the new lstlisting chunks, but these
8799  may be preceded by a 
8800 \begin_inset Flex CharStyle:Code
8801 status collapsed
8803 \begin_layout Plain Layout
8805 \backslash
8806 Chunk
8807 \end_layout
8809 \end_inset
8811  command which in LyX is a more convenient way to pass the chunk name to
8812  the 
8813 \begin_inset Flex CharStyle:Code
8814 status collapsed
8816 \begin_layout Plain Layout
8818 \backslash
8819 begin{lstlistings}
8820 \end_layout
8822 \end_inset
8824  command, and a more visible way to specify other 
8825 \begin_inset Flex CharStyle:Code
8826 status collapsed
8828 \begin_layout Plain Layout
8829 lstset
8830 \end_layout
8832 \end_inset
8834  settings.
8835 \end_layout
8837 \begin_layout Standard
8838 The arguments to the 
8839 \begin_inset Flex CharStyle:Code
8840 status collapsed
8842 \begin_layout Plain Layout
8844 \backslash
8845 Chunk
8846 \end_layout
8848 \end_inset
8850  command are a name, and then a comma-seperated list of key-value pairs
8851  after the manner of 
8852 \begin_inset Flex CharStyle:Code
8853 status collapsed
8855 \begin_layout Plain Layout
8857 \backslash
8858 lstset
8859 \end_layout
8861 \end_inset
8864  (In fact within the LaTeX 
8865 \begin_inset Flex CharStyle:Code
8866 status collapsed
8868 \begin_layout Plain Layout
8870 \backslash
8871 Chunk
8872 \end_layout
8874 \end_inset
8876  macro (section 
8877 \begin_inset CommandInset ref
8878 LatexCommand ref
8879 reference "sub:The-chunk-command"
8881 \end_inset
8883 ) the text 
8884 \begin_inset Flex CharStyle:Code
8885 status collapsed
8887 \begin_layout Plain Layout
8888 name=
8889 \end_layout
8891 \end_inset
8893  is prefixed to the argument which is then literally passed to 
8894 \begin_inset Flex CharStyle:Code
8895 status collapsed
8897 \begin_layout Plain Layout
8899 \backslash
8900 lstset
8901 \end_layout
8903 \end_inset
8906 \end_layout
8908 \begin_layout Chunk
8909 recognize-chunk,language=awk
8910 \end_layout
8912 \begin_layout Standard
8913 \begin_inset listings
8914 inline false
8915 status open
8917 \begin_layout Plain Layout
8920 \backslash
8922 \backslash
8923 Chunk{/ {
8924 \end_layout
8926 \begin_layout Plain Layout
8928   if (match($0, "^
8929 \backslash
8931 \backslash
8933 \backslash
8935 \backslash
8936 Chunk{ *([^ ,}]*),?(.*)}", line)) {
8937 \end_layout
8939 \begin_layout Plain Layout
8941     next_chunk_name = line[1];
8942 \end_layout
8944 \begin_layout Plain Layout
8946     get_chunk_args(line[2], next_chunk_args);
8947 \end_layout
8949 \begin_layout Plain Layout
8951   }
8952 \end_layout
8954 \begin_layout Plain Layout
8956   next;
8957 \end_layout
8959 \begin_layout Plain Layout
8962 \end_layout
8964 \end_inset
8967 \end_layout
8969 \begin_layout Standard
8970 We also make a basic attempt to parse the name out of the 
8971 \begin_inset Flex CharStyle:Code
8972 status collapsed
8974 \begin_layout Plain Layout
8976 \backslash
8977 lstlistings[name=
8978 \begin_inset space \hspace{}
8979 \length 0in
8980 \end_inset
8982 chunk-name]
8983 \end_layout
8985 \end_inset
8987  text, otherwise we fall back to the name found in the previous chunk command.
8988  This attempt is very basic and doesn't support commas or spaces or square
8989  brackets as part of the chunkname.
8990  We also recognize 
8991 \begin_inset Flex CharStyle:Code
8992 status collapsed
8994 \begin_layout Plain Layout
8996 \backslash
8997 begin{Chunk}
8998 \end_layout
9000 \end_inset
9002  which is convenient for some users
9003 \begin_inset Foot
9004 status open
9006 \begin_layout Plain Layout
9007 but not yet supported in the LaTeX macros
9008 \end_layout
9010 \end_inset
9013 \begin_inset Note Note
9014 status collapsed
9016 \begin_layout Plain Layout
9017 Add noweave support
9018 \end_layout
9020 \end_inset
9023 \end_layout
9025 \begin_layout Standard
9026 \begin_inset listings
9027 inline false
9028 status open
9030 \begin_layout Plain Layout
9033 \backslash
9035 \backslash
9036 begin{lstlisting}|^
9037 \backslash
9039 \backslash
9040 begin{Chunk}/ {
9041 \end_layout
9043 \begin_layout Plain Layout
9045   if (match($0, "}.*[[,] *name= *{? *([^], }]*)", line)) {
9046 \end_layout
9048 \begin_layout Plain Layout
9050     new_chunk(line[1]);
9051 \end_layout
9053 \begin_layout Plain Layout
9055   } else {
9056 \end_layout
9058 \begin_layout Plain Layout
9060     new_chunk(next_chunk_name, next_chunk_args);
9061 \end_layout
9063 \begin_layout Plain Layout
9065   }
9066 \end_layout
9068 \begin_layout Plain Layout
9070   chunking=1;
9071 \end_layout
9073 \begin_layout Plain Layout
9075   next;
9076 \end_layout
9078 \begin_layout Plain Layout
9081 \end_layout
9083 \end_inset
9086 \end_layout
9088 \begin_layout Subsection
9089 Noweb
9090 \end_layout
9092 \begin_layout Standard
9093 We recognize notangle style chunks too:
9094 \end_layout
9096 \begin_layout Chunk
9097 recognize-chunk,language=awk
9098 \end_layout
9100 \begin_layout Standard
9101 \begin_inset listings
9102 inline false
9103 status open
9105 \begin_layout Plain Layout
9107 /^[<]<.*[>]>=/ {
9108 \end_layout
9110 \begin_layout Plain Layout
9112   if (match($0, "^[<]<(.*)[>]>= *$", line)) {
9113 \end_layout
9115 \begin_layout Plain Layout
9117     chunking=1;
9118 \end_layout
9120 \begin_layout Plain Layout
9122     notangle_mode=1;
9123 \end_layout
9125 \begin_layout Plain Layout
9127     new_chunk(line[1]);
9128 \end_layout
9130 \begin_layout Plain Layout
9132     next;
9133 \end_layout
9135 \begin_layout Plain Layout
9137   }
9138 \end_layout
9140 \begin_layout Plain Layout
9143 \end_layout
9145 \end_inset
9148 \end_layout
9150 \begin_layout Section
9151 Chunk end
9152 \end_layout
9154 \begin_layout Standard
9155 Likewise, we need to recognize when a chunk ends.
9156 \end_layout
9158 \begin_layout Subsection
9159 lstlistings
9160 \end_layout
9162 \begin_layout Standard
9163 The 
9164 \begin_inset Flex CharStyle:Code
9165 status collapsed
9167 \begin_layout Plain Layout
9169 \end_layout
9171 \end_inset
9173  in 
9174 \begin_inset Flex CharStyle:Code
9175 status collapsed
9177 \begin_layout Plain Layout
9178 [e]end{lislisting}
9179 \end_layout
9181 \end_inset
9183  is surrounded by square brackets so that when this document is processed,
9184  this chunk doesn't terminate early when the lstlistings package recognizes
9185  it's own end-string! 
9186 \begin_inset Note Greyedout
9187 status collapsed
9189 \begin_layout Plain Layout
9190 This doesn't make sense as the regex is anchored with ^, which this line
9191  does not begin with!
9192 \end_layout
9194 \end_inset
9197 \begin_inset Note Note
9198 status open
9200 \begin_layout Plain Layout
9201 No, it doesn't.
9202 \end_layout
9204 \end_inset
9207 \end_layout
9209 \begin_layout Chunk
9210 recognize-chunk
9211 \end_layout
9213 \begin_layout Standard
9214 \begin_inset listings
9215 inline false
9216 status open
9218 \begin_layout Plain Layout
9221 \backslash
9223 \backslash
9224 [e]nd{lstlisting}|^
9225 \backslash
9227 \backslash
9228 [e]nd{Chunk}/ {
9229 \end_layout
9231 \begin_layout Plain Layout
9233   chunking=0;
9234 \end_layout
9236 \begin_layout Plain Layout
9238   active_chunk="";
9239 \end_layout
9241 \begin_layout Plain Layout
9243   next;
9244 \end_layout
9246 \begin_layout Plain Layout
9249 \end_layout
9251 \end_inset
9254 \end_layout
9256 \begin_layout Subsection
9257 noweb
9258 \end_layout
9260 \begin_layout Chunk
9261 recognize-chunk
9262 \end_layout
9264 \begin_layout Standard
9265 \begin_inset listings
9266 inline false
9267 status open
9269 \begin_layout Plain Layout
9271 /^@ *$/ {
9272 \end_layout
9274 \begin_layout Plain Layout
9276   chunking=0;
9277 \end_layout
9279 \begin_layout Plain Layout
9281   active_chunk="";
9282 \end_layout
9284 \begin_layout Plain Layout
9287 \end_layout
9289 \end_inset
9292 \end_layout
9294 \begin_layout Standard
9295 All other recognizers are only of effect if we are chunking; there's no
9296  point in looking at lines if they aren't part of a chunk, so we just ignore
9297  them as efficiently as we can.
9298 \end_layout
9300 \begin_layout Chunk
9301 recognize-chunk
9302 \end_layout
9304 \begin_layout Standard
9305 \begin_inset listings
9306 inline false
9307 status open
9309 \begin_layout Plain Layout
9311 ! chunking { next; }
9312 \end_layout
9314 \end_inset
9317 \end_layout
9319 \begin_layout Section
9320 Chunk contents
9321 \end_layout
9323 \begin_layout Standard
9324 Chunk contents are any lines read while 
9325 \begin_inset Flex CharStyle:Code
9326 status collapsed
9328 \begin_layout Plain Layout
9329 chunking
9330 \end_layout
9332 \end_inset
9334  is true.
9335  Some chunk contents are special in that they refer to other chunks, and
9336  will be replaced by the contents of these chunks when the file is generated.
9337 \end_layout
9339 \begin_layout Standard
9340 \begin_inset CommandInset label
9341 LatexCommand label
9342 name "sub:ORS-chunk-text"
9344 \end_inset
9346 We add the output record separator 
9347 \begin_inset Flex CharStyle:Code
9348 status collapsed
9350 \begin_layout Plain Layout
9352 \end_layout
9354 \end_inset
9356  to the line now, because we will set 
9357 \begin_inset Flex CharStyle:Code
9358 status collapsed
9360 \begin_layout Plain Layout
9362 \end_layout
9364 \end_inset
9366  to the empty string when we generate the output
9367 \begin_inset Foot
9368 status collapsed
9370 \begin_layout Plain Layout
9371 So that we can print partial lines using 
9372 \begin_inset Flex CharStyle:Code
9373 status collapsed
9375 \begin_layout Plain Layout
9376 print
9377 \end_layout
9379 \end_inset
9381  instead of 
9382 \begin_inset Flex CharStyle:Code
9383 status collapsed
9385 \begin_layout Plain Layout
9386 printf
9387 \end_layout
9389 \end_inset
9392 \end_layout
9394 \end_inset
9397 \end_layout
9399 \begin_layout Chunk
9400 recognize-chunk
9401 \end_layout
9403 \begin_layout Standard
9404 \begin_inset listings
9405 inline false
9406 status open
9408 \begin_layout Plain Layout
9410 length(active_chunk) {
9411 \end_layout
9413 \begin_layout Plain Layout
9415   =<
9416 \backslash
9417 chunkref{process-chunk-tabs}>
9418 \end_layout
9420 \begin_layout Plain Layout
9422   =<
9423 \backslash
9424 chunkref{process-chunk}>
9425 \end_layout
9427 \begin_layout Plain Layout
9430 \end_layout
9432 \end_inset
9435 \end_layout
9437 \begin_layout Standard
9438 If a chunk just consisted of plain text, we could handle the chunk like
9439  this:
9440 \end_layout
9442 \begin_layout Chunk
9443 process-chunk-simple
9444 \end_layout
9446 \begin_layout Standard
9447 \begin_inset listings
9448 inline false
9449 status open
9451 \begin_layout Plain Layout
9453 chunk_line(active_chunk, $0 ORS);
9454 \end_layout
9456 \end_inset
9459 \end_layout
9461 \begin_layout Standard
9462 but in fact a chunk can include references to other chunks.
9463  Chunk includes are traditionally written as 
9464 \begin_inset Flex CharStyle:Code
9465 status collapsed
9467 \begin_layout Plain Layout
9468 <<chunk-name>>
9469 \end_layout
9471 \end_inset
9473 , but we support other variations.
9474 \end_layout
9476 \begin_layout Standard
9477 However, we also process tabs at this point, a tab at input can be replaced
9478  by a number of spaces defined by the 
9479 \begin_inset Flex CharStyle:Code
9480 status collapsed
9482 \begin_layout Plain Layout
9483 tabs
9484 \end_layout
9486 \end_inset
9488  variable, set by the 
9489 \begin_inset Flex CharStyle:Code
9490 status collapsed
9492 \begin_layout Plain Layout
9494 \end_layout
9496 \end_inset
9498  option.
9499  Of course this is poor tab behaviour, we should probably have the option
9500  to use proper counted tab-stops and process this on output.
9501 \end_layout
9503 \begin_layout Chunk
9504 process-chunk-tabs
9505 \end_layout
9507 \begin_layout Standard
9508 \begin_inset listings
9509 inline false
9510 status open
9512 \begin_layout Plain Layout
9514 if (length(tabs)) {
9515 \end_layout
9517 \begin_layout Plain Layout
9519   gsub("
9520 \backslash
9521 t", tabs);
9522 \end_layout
9524 \begin_layout Plain Layout
9527 \end_layout
9529 \end_inset
9532 \end_layout
9534 \begin_layout Subsection
9535 \begin_inset CommandInset label
9536 LatexCommand label
9537 name "sub:lstlistings-includes"
9539 \end_inset
9541 lstlistings
9542 \end_layout
9544 \begin_layout Standard
9545 If 
9546 \begin_inset Flex CharStyle:Code
9547 status collapsed
9549 \begin_layout Plain Layout
9551 \backslash
9552 lstset{escapeinside={=<}{>}}
9553 \end_layout
9555 \end_inset
9557  is set, then we can use 
9558 \begin_inset Flex CharStyle:Code
9559 status collapsed
9561 \begin_layout Plain Layout
9563 \backslash
9564 chunkref{
9565 \begin_inset space \hspace{}
9566 \length 0in
9567 \end_inset
9569 chunk-name}>
9570 \end_layout
9572 \end_inset
9574  in listings.
9575  The sequence 
9576 \begin_inset Flex CharStyle:Code
9577 status collapsed
9579 \begin_layout Plain Layout
9581 \end_layout
9583 \end_inset
9585  was chosen because:
9586 \end_layout
9588 \begin_layout Enumerate
9589 it is a better mnemonic than 
9590 \begin_inset Flex CharStyle:Code
9591 status collapsed
9593 \begin_layout Plain Layout
9594 <<chunk-name>>
9595 \end_layout
9597 \end_inset
9599  in that the = sign signifies equivalent or substitutability, 
9600 \end_layout
9602 \begin_layout Enumerate
9603 and because =< is not valid in C or in any language I can think of 
9604 \end_layout
9606 \begin_layout Enumerate
9607 and also because lstlistings doesn't like 
9608 \begin_inset Flex CharStyle:Code
9609 status collapsed
9611 \begin_layout Plain Layout
9613 \end_layout
9615 \end_inset
9617  as an end delimiter for the 
9618 \emph on
9619 texcl
9620 \emph default
9621  escape, so we must make do with a single 
9622 \begin_inset Flex CharStyle:Code
9623 status collapsed
9625 \begin_layout Plain Layout
9627 \end_layout
9629 \end_inset
9631 , which is better matched by 
9632 \begin_inset Flex CharStyle:Code
9633 status collapsed
9635 \begin_layout Plain Layout
9637 \end_layout
9639 \end_inset
9641  than 
9642 \begin_inset Flex CharStyle:Code
9643 status collapsed
9645 \begin_layout Plain Layout
9647 \end_layout
9649 \end_inset
9652 \end_layout
9654 \begin_layout Standard
9655 Unfortunately 
9656 \begin_inset Note Note
9657 status open
9659 \begin_layout Plain Layout
9660 fix this then
9661 \end_layout
9663 \end_inset
9665  the 
9666 \begin_inset Flex CharStyle:Code
9667 status collapsed
9669 \begin_layout Plain Layout
9670 =<\SpecialChar \ldots{}
9672 \end_layout
9674 \end_inset
9676  that we use re-enters a LaTeX parsing mode in which some characters are
9677  special, e.g.
9679 \begin_inset Flex CharStyle:Code
9680 status collapsed
9682 \begin_layout Plain Layout
9684 \backslash
9686 \end_layout
9688 \end_inset
9690 , and so these cause trouble if used in arguments to 
9691 \begin_inset Flex CharStyle:Code
9692 status collapsed
9694 \begin_layout Plain Layout
9696 \backslash
9697 chunkref
9698 \end_layout
9700 \end_inset
9703  At some point I must fix the LaTeX command 
9704 \begin_inset Flex CharStyle:Code
9705 status collapsed
9707 \begin_layout Plain Layout
9709 \backslash
9710 chunkref
9711 \end_layout
9713 \end_inset
9715  so that it can accept these literally, but until then, when writing chunkref
9716  argumemts that need these characters, I must use the forms 
9717 \begin_inset Flex CharStyle:Code
9718 status collapsed
9720 \begin_layout Plain Layout
9722 \backslash
9723 textbackslash{}
9724 \end_layout
9726 \end_inset
9728  and 
9729 \begin_inset Flex CharStyle:Code
9730 status collapsed
9732 \begin_layout Plain Layout
9734 \backslash
9736 \end_layout
9738 \end_inset
9740 ; so I also define a hacky chunk 
9741 \begin_inset Flex CharStyle:Code
9742 status collapsed
9744 \begin_layout Plain Layout
9745 delatex
9746 \end_layout
9748 \end_inset
9750  whose purpose it is to remove these from any arguments parsed by newfangle,
9751  and used further on.
9752 \end_layout
9754 \begin_layout Chunk
9755 delatex,params=text
9756 \end_layout
9758 \begin_layout Standard
9759 \begin_inset listings
9760 inline false
9761 status open
9763 \begin_layout Plain Layout
9765 # FILTHY HACK
9766 \end_layout
9768 \begin_layout Plain Layout
9770 gsub("
9771 \backslash
9773 \backslash
9775 \backslash
9777 \backslash
9778 #", "#", ${text});
9779 \end_layout
9781 \begin_layout Plain Layout
9783 gsub("
9784 \backslash
9786 \backslash
9788 \backslash
9790 \backslash
9791 textbackslash{}", "
9792 \backslash
9794 \backslash
9795 ", ${text});
9796 \end_layout
9798 \begin_layout Plain Layout
9800 gsub("
9801 \backslash
9803 \backslash
9805 \backslash
9807 \backslash
9809 \backslash
9811 \backslash
9812 ^", "^", ${text});
9813 \end_layout
9815 \end_inset
9818 \end_layout
9820 \begin_layout Standard
9821 As each chunk line may contain more than one chunk include, we will split
9822  out chunk includes in an iterative fashion
9823 \begin_inset Foot
9824 status collapsed
9826 \begin_layout Plain Layout
9827 Contrary to our use of 
9828 \begin_inset Flex CharStyle:Code
9829 status collapsed
9831 \begin_layout Plain Layout
9832 split
9833 \end_layout
9835 \end_inset
9837  when substituting parameters in chapter 
9838 \begin_inset CommandInset ref
9839 LatexCommand ref
9840 reference "Here-we-split"
9842 \end_inset
9845 \end_layout
9847 \end_inset
9850 \end_layout
9852 \begin_layout Standard
9853 First, as long as the chunk contains a 
9854 \begin_inset Flex CharStyle:Code
9855 status collapsed
9857 \begin_layout Plain Layout
9859 \backslash
9860 chunkref
9861 \end_layout
9863 \end_inset
9865  command we take as much as we can up to the first 
9866 \begin_inset Flex CharStyle:Code
9867 status collapsed
9869 \begin_layout Plain Layout
9871 \backslash
9872 chunkref
9873 \end_layout
9875 \end_inset
9877  command.
9878 \end_layout
9880 \begin_layout Chunk
9881 process-chunk
9882 \end_layout
9884 \begin_layout Standard
9885 \begin_inset listings
9886 inline false
9887 status open
9889 \begin_layout Plain Layout
9891 chunk = $0;
9892 \end_layout
9894 \begin_layout Plain Layout
9896 indent = 0;
9897 \end_layout
9899 \begin_layout Plain Layout
9901 while(match(chunk, 
9902 \end_layout
9904 \begin_layout Plain Layout
9906             "([=]<
9907 \backslash
9909 \backslash
9911 \backslash
9913 \backslash
9914 chunkref{([^}>]*)}(
9915 \backslash
9917 \backslash
9919 \backslash
9921 \backslash
9922 )|)>|<<([a-zA-Z_][-a-zA-Z0-9_]*)>>)", 
9923 \end_layout
9925 \begin_layout Plain Layout
9927             line)
9928 \backslash
9930 \end_layout
9932 \begin_layout Plain Layout
9934 ) {
9935 \end_layout
9937 \begin_layout Plain Layout
9939   chunklet = substr(chunk, 1, RSTART - 1);
9940 \end_layout
9942 \end_inset
9945 \end_layout
9947 \begin_layout Standard
9948 We keep track of the indent count, by counting the number of literal characters
9949  found.
9950  We can then preserve this indent on each output line when multi-line chunks
9951  are expanded.
9952 \end_layout
9954 \begin_layout Standard
9955 We then process this first part literal text, and set the chunk which is
9956  still to be processed to be the text after the 
9957 \begin_inset Flex CharStyle:Code
9958 status collapsed
9960 \begin_layout Plain Layout
9962 \backslash
9963 chunkref
9964 \end_layout
9966 \end_inset
9968  command, which we will process next as we continue around the loop.
9969 \end_layout
9971 \begin_layout Standard
9972 \begin_inset listings
9973 inline false
9974 status open
9976 \begin_layout Plain Layout
9978   indent += length(chunklet);
9979 \end_layout
9981 \begin_layout Plain Layout
9983   chunk_line(active_chunk, chunklet);
9984 \end_layout
9986 \begin_layout Plain Layout
9988   chunk = substr(chunk, RSTART + RLENGTH);
9989 \end_layout
9991 \end_inset
9994 \end_layout
9996 \begin_layout Standard
9997 We then consider the type of chunk command we have found, whether it is
9998  the newfangle style command beginning with 
9999 \begin_inset Flex CharStyle:Code
10000 status collapsed
10002 \begin_layout Plain Layout
10004 \end_layout
10006 \end_inset
10008  or the older notangle style beginning with 
10009 \begin_inset Flex CharStyle:Code
10010 status collapsed
10012 \begin_layout Plain Layout
10014 \end_layout
10016 \end_inset
10020 \end_layout
10022 \begin_layout Standard
10023 Newfangle chunks may have parameters contained within square brackets.
10024  These will be matched in 
10025 \begin_inset Flex CharStyle:Code
10026 status collapsed
10028 \begin_layout Plain Layout
10029 line[3]
10030 \end_layout
10032 \end_inset
10034  and are considered at this stage of processing to be part of the name of
10035  the chunk to be included.
10036 \end_layout
10038 \begin_layout Standard
10039 \begin_inset listings
10040 inline false
10041 status open
10043 \begin_layout Plain Layout
10045   if (substr(line[1], 1, 1) == "=") {
10046 \end_layout
10048 \begin_layout Plain Layout
10050     # chunk name up to }
10051 \end_layout
10053 \begin_layout Plain Layout
10055         =<
10056 \backslash
10057 chunkref{delatex}(line[3])>
10058 \end_layout
10060 \begin_layout Plain Layout
10062     chunk_include(active_chunk, line[2] line[3], indent);
10063 \end_layout
10065 \begin_layout Plain Layout
10067   } else if (substr(line[1], 1, 1) == "<") {
10068 \end_layout
10070 \begin_layout Plain Layout
10072     chunk_include(active_chunk, line[4], indent);
10073 \end_layout
10075 \begin_layout Plain Layout
10077   } else {
10078 \end_layout
10080 \begin_layout Plain Layout
10082     error("Unknown chunk fragment: " line[1]);
10083 \end_layout
10085 \begin_layout Plain Layout
10087   }
10088 \end_layout
10090 \end_inset
10093 \end_layout
10095 \begin_layout Standard
10096 The loop will continue until there are no more chunkref statements in the
10097  text, at which point we process the final part of the chunk.
10098 \end_layout
10100 \begin_layout Standard
10101 \begin_inset listings
10102 inline false
10103 status open
10105 \begin_layout Plain Layout
10108 \end_layout
10110 \begin_layout Plain Layout
10112 chunk_line(active_chunk, chunk);
10113 \end_layout
10115 \end_inset
10118 \end_layout
10120 \begin_layout Standard
10121 \begin_inset CommandInset label
10122 LatexCommand label
10123 name "lone-newline"
10125 \end_inset
10127 We add the newline character as a chunklet on it's own, to make it easier
10128  to detect new lines and thus manage indentation when processing the output.
10129 \end_layout
10131 \begin_layout Standard
10132 \begin_inset listings
10133 inline false
10134 status open
10136 \begin_layout Plain Layout
10138 chunk_line(active_chunk, "
10139 \backslash
10140 n");
10141 \end_layout
10143 \end_inset
10146 \end_layout
10148 \begin_layout Standard
10149 We will also permit a chunk-part number to follow in square brackets, so
10150  that 
10151 \begin_inset Flex CharStyle:Code
10152 status collapsed
10154 \begin_layout Plain Layout
10156 \backslash
10157 chunkref{chunk-name[1]}>
10158 \end_layout
10160 \end_inset
10162  will refer to the first part only.
10163  This can make it easy to include a C function prototype in a header file,
10164  if the first part of the chunk is just the function prototype without the
10165  trailing semi-colon.
10166  The header file would include the prototype with the trailing semi-colon,
10167  like this:
10168 \end_layout
10170 \begin_layout LyX-Code
10172 \backslash
10173 chunkref{chunk-name[1]}>;
10174 \end_layout
10176 \begin_layout Standard
10177 This is handled in section 
10178 \begin_inset CommandInset ref
10179 LatexCommand ref
10180 reference "sub:Chunk-parts"
10182 \end_inset
10185 \end_layout
10187 \begin_layout Standard
10188 We should perhaps introduce a notion of language specific chunk options;
10189  so that perhaps we could specify:
10190 \end_layout
10192 \begin_layout LyX-Code
10194 \backslash
10195 chunkref{chunk-name[function-declaration]}>;
10196 \end_layout
10198 \begin_layout Standard
10199 which applies a transform 
10200 \begin_inset Flex CharStyle:Code
10201 status collapsed
10203 \begin_layout Plain Layout
10204 function-declaration
10205 \end_layout
10207 \end_inset
10209  to the chunk --- which in this case would extract a function prototype
10210  from a function.
10211 \begin_inset Note Note
10212 status open
10214 \begin_layout Plain Layout
10215 So do it
10216 \end_layout
10218 \end_inset
10221 \end_layout
10223 \begin_layout Chapter
10224 Processing Options
10225 \end_layout
10227 \begin_layout Standard
10228 At the start, first we set the default options.
10229 \end_layout
10231 \begin_layout Chunk
10232 default-options
10233 \end_layout
10235 \begin_layout Standard
10236 \begin_inset listings
10237 inline false
10238 status open
10240 \begin_layout Plain Layout
10242 debug=0;
10243 \end_layout
10245 \begin_layout Plain Layout
10247 linenos=0;
10248 \end_layout
10250 \begin_layout Plain Layout
10252 notangle_mode=0;
10253 \end_layout
10255 \begin_layout Plain Layout
10257 root="*";
10258 \end_layout
10260 \begin_layout Plain Layout
10262 tabs = "";
10263 \end_layout
10265 \end_inset
10268 \end_layout
10270 \begin_layout Standard
10271 Then we use getopt the standard way, and null out ARGV afterwards in the
10272  normal AWK fashion.
10273 \end_layout
10275 \begin_layout Chunk
10276 read-options
10277 \end_layout
10279 \begin_layout Standard
10280 \begin_inset listings
10281 inline false
10282 status open
10284 \begin_layout Plain Layout
10286 Optind = 1    # skip ARGV[0]
10287 \end_layout
10289 \begin_layout Plain Layout
10291 while(getopt(ARGC, ARGV, "R:LdT:hr")!=-1) {
10292 \end_layout
10294 \begin_layout Plain Layout
10296   =<
10297 \backslash
10298 chunkref{handle-options}>
10299 \end_layout
10301 \begin_layout Plain Layout
10304 \end_layout
10306 \begin_layout Plain Layout
10308 for (i=1; i<Optind; i++) { ARGV[i]=""; }
10309 \end_layout
10311 \end_inset
10314 \end_layout
10316 \begin_layout Standard
10317 This is how we handle our options:
10318 \end_layout
10320 \begin_layout Chunk
10321 handle-options
10322 \end_layout
10324 \begin_layout Standard
10325 \begin_inset listings
10326 inline false
10327 status open
10329 \begin_layout Plain Layout
10331 if (Optopt == "R") root = Optarg;
10332 \end_layout
10334 \begin_layout Plain Layout
10336 else if (Optopt == "r") root="";
10337 \end_layout
10339 \begin_layout Plain Layout
10341 else if (Optopt == "L") linenos = 1;
10342 \end_layout
10344 \begin_layout Plain Layout
10346 else if (Optopt == "d") debug = 1;
10347 \end_layout
10349 \begin_layout Plain Layout
10351 else if (Optopt == "T") tabs = indent_string(Optarg+0);
10352 \end_layout
10354 \begin_layout Plain Layout
10356 else if (Optopt == "h") help();
10357 \end_layout
10359 \begin_layout Plain Layout
10361 else if (Optopt == "?") help();
10362 \end_layout
10364 \end_inset
10367 \end_layout
10369 \begin_layout Standard
10370 We do all of this at the beginning of the program
10371 \end_layout
10373 \begin_layout Chunk
10374 begin
10375 \end_layout
10377 \begin_layout Standard
10378 \begin_inset listings
10379 inline false
10380 status open
10382 \begin_layout Plain Layout
10384 BEGIN {
10385 \end_layout
10387 \begin_layout Plain Layout
10389   =<
10390 \backslash
10391 chunkref{constants}>
10392 \end_layout
10394 \begin_layout Plain Layout
10396   =<
10397 \backslash
10398 chunkref{mode-definitions}>
10399 \end_layout
10401 \begin_layout Plain Layout
10403   =<
10404 \backslash
10405 chunkref{default-options}>
10406 \end_layout
10408 \begin_layout Plain Layout
10410 \end_layout
10412 \begin_layout Plain Layout
10414   =<
10415 \backslash
10416 chunkref{read-options}>
10417 \end_layout
10419 \begin_layout Plain Layout
10422 \end_layout
10424 \end_inset
10427 \end_layout
10429 \begin_layout Standard
10430 And have a simple help function
10431 \end_layout
10433 \begin_layout Chunk
10434 help()
10435 \end_layout
10437 \begin_layout Standard
10438 \begin_inset listings
10439 inline false
10440 status open
10442 \begin_layout Plain Layout
10444 function help() {
10445 \end_layout
10447 \begin_layout Plain Layout
10449   print "Usage:"
10450 \end_layout
10452 \begin_layout Plain Layout
10454   print "  newfangle [-L] -R<rootname> [source.tex ...]"
10455 \end_layout
10457 \begin_layout Plain Layout
10459   print "  newfangle -r [source.tex ...]"
10460 \end_layout
10462 \begin_layout Plain Layout
10464   print "  If the filename, source.tex is not specified then stdin is used"
10465 \end_layout
10467 \begin_layout Plain Layout
10469   print
10470 \end_layout
10472 \begin_layout Plain Layout
10474   print "-L causes the C statement: #line <lineno> 
10475 \backslash
10476 "filename
10477 \backslash
10478 "" to be issued"
10479 \end_layout
10481 \begin_layout Plain Layout
10483   print "-R causes the named root to be written to stdout"
10484 \end_layout
10486 \begin_layout Plain Layout
10488   print "-r lists all roots in the file (even those used elsewhere)"
10489 \end_layout
10491 \begin_layout Plain Layout
10493   exit 1;
10494 \end_layout
10496 \begin_layout Plain Layout
10499 \end_layout
10501 \end_inset
10504 \end_layout
10506 \begin_layout Chapter
10507 Generating the output
10508 \end_layout
10510 \begin_layout Standard
10511 We generate output by calling output_chunk, or listing the chunk names.
10512 \end_layout
10514 \begin_layout Chunk
10515 generate-output
10516 \end_layout
10518 \begin_layout Standard
10519 \begin_inset listings
10520 inline false
10521 status open
10523 \begin_layout Plain Layout
10525 if (length(root)) output_chunk(root);
10526 \end_layout
10528 \begin_layout Plain Layout
10530 else output_chunk_names();
10531 \end_layout
10533 \end_inset
10536 \end_layout
10538 \begin_layout Standard
10539 We also have some other output debugging:
10540 \end_layout
10542 \begin_layout Chunk
10543 debug-output
10544 \end_layout
10546 \begin_layout Standard
10547 \begin_inset listings
10548 inline false
10549 status open
10551 \begin_layout Plain Layout
10553 if (debug) {
10554 \end_layout
10556 \begin_layout Plain Layout
10558   print "------ chunk names "
10559 \end_layout
10561 \begin_layout Plain Layout
10563   output_chunk_names();
10564 \end_layout
10566 \begin_layout Plain Layout
10568   print "====== chunks"
10569 \end_layout
10571 \begin_layout Plain Layout
10573   output_chunks();
10574 \end_layout
10576 \begin_layout Plain Layout
10578   print "++++++ debug"
10579 \end_layout
10581 \begin_layout Plain Layout
10583   for (a in chunks) {
10584 \end_layout
10586 \begin_layout Plain Layout
10588     print a "=" chunks[a];
10589 \end_layout
10591 \begin_layout Plain Layout
10593   }
10594 \end_layout
10596 \begin_layout Plain Layout
10599 \end_layout
10601 \end_inset
10604 \end_layout
10606 \begin_layout Standard
10607 We do both of these at the end.
10608  We also set 
10609 \begin_inset Flex CharStyle:Code
10610 status collapsed
10612 \begin_layout Plain Layout
10613 ORS=""
10614 \end_layout
10616 \end_inset
10618  because each chunklet is not necessarily a complete line, and we already
10619  added 
10620 \begin_inset Flex CharStyle:Code
10621 status collapsed
10623 \begin_layout Plain Layout
10625 \end_layout
10627 \end_inset
10629  to each input line in section 
10630 \begin_inset CommandInset ref
10631 LatexCommand ref
10632 reference "sub:ORS-chunk-text"
10634 \end_inset
10637 \end_layout
10639 \begin_layout Chunk
10641 \end_layout
10643 \begin_layout Standard
10644 \begin_inset listings
10645 inline false
10646 status open
10648 \begin_layout Plain Layout
10650 END {
10651 \end_layout
10653 \begin_layout Plain Layout
10655   =<
10656 \backslash
10657 chunkref{debug-output}>
10658 \end_layout
10660 \begin_layout Plain Layout
10662   ORS="";
10663 \end_layout
10665 \begin_layout Plain Layout
10667   =<
10668 \backslash
10669 chunkref{generate-output}>
10670 \end_layout
10672 \begin_layout Plain Layout
10675 \end_layout
10677 \end_inset
10680 \end_layout
10682 \begin_layout Standard
10683 We write chunk names like this.
10684  If we seem to be running in notangle compatibility mode, then we enclose
10685  the name like this 
10686 \begin_inset Flex CharStyle:Code
10687 status collapsed
10689 \begin_layout Plain Layout
10690 <<name>>
10691 \end_layout
10693 \end_inset
10695  the same way notangle does:
10696 \end_layout
10698 \begin_layout Chunk
10699 output_chunk_names()
10700 \end_layout
10702 \begin_layout Standard
10703 \begin_inset listings
10704 inline false
10705 status open
10707 \begin_layout Plain Layout
10709 function output_chunk_names(   c, prefix, suffix) 
10710 \end_layout
10712 \begin_layout Plain Layout
10715 \end_layout
10717 \begin_layout Plain Layout
10719   if (notangle_mode) {
10720 \end_layout
10722 \begin_layout Plain Layout
10724     prefix="<<";
10725 \end_layout
10727 \begin_layout Plain Layout
10729     suffix=">>";
10730 \end_layout
10732 \begin_layout Plain Layout
10734   }
10735 \end_layout
10737 \begin_layout Plain Layout
10739   for (c in chunk_names) {
10740 \end_layout
10742 \begin_layout Plain Layout
10744     print prefix c suffix "
10745 \backslash
10747 \end_layout
10749 \begin_layout Plain Layout
10751   }
10752 \end_layout
10754 \begin_layout Plain Layout
10757 \end_layout
10759 \end_inset
10762 \end_layout
10764 \begin_layout Standard
10765 This function would write out all chunks
10766 \end_layout
10768 \begin_layout Chunk
10769 output_chunks()
10770 \end_layout
10772 \begin_layout Standard
10773 \begin_inset listings
10774 inline false
10775 status open
10777 \begin_layout Plain Layout
10779 function output_chunks(  a) 
10780 \end_layout
10782 \begin_layout Plain Layout
10785 \end_layout
10787 \begin_layout Plain Layout
10789   for (a in chunk_names) {
10790 \end_layout
10792 \begin_layout Plain Layout
10794     output_chunk(chunk_names[a]);
10795 \end_layout
10797 \begin_layout Plain Layout
10799   }
10800 \end_layout
10802 \begin_layout Plain Layout
10805 \end_layout
10807 \begin_layout Plain Layout
10809 \end_layout
10811 \begin_layout Plain Layout
10813 function output_chunk(chunk) {
10814 \end_layout
10816 \begin_layout Plain Layout
10818   newline = 1;
10819 \end_layout
10821 \begin_layout Plain Layout
10823   lineno_needed = linenos;
10824 \end_layout
10826 \begin_layout Plain Layout
10828 \end_layout
10830 \begin_layout Plain Layout
10832   write_chunk(chunk);
10833 \end_layout
10835 \begin_layout Plain Layout
10838 \end_layout
10840 \begin_layout Plain Layout
10842 \end_layout
10844 \end_inset
10847 \end_layout
10849 \begin_layout Section
10850 Assembling the chunks
10851 \end_layout
10853 \begin_layout Standard
10854 \begin_inset Flex CharStyle:Code
10855 status collapsed
10857 \begin_layout Plain Layout
10858 chunk_path
10859 \end_layout
10861 \end_inset
10863  holds a string consisting of the names of all the chunks that resulted
10864  in this chunk being output.
10866 \begin_inset Note Note
10867 status collapsed
10869 \begin_layout Plain Layout
10870 Make sure it includes the line numbers too...
10872 \end_layout
10874 \end_inset
10876 It should probably also contain the source line numbers at which each inclusion
10877  also occured.
10878 \end_layout
10880 \begin_layout Chunk
10881 write_chunk()
10882 \end_layout
10884 \begin_layout Standard
10885 We first initialize the mode tracker for this chunk.
10886 \end_layout
10888 \begin_layout Standard
10889 \begin_inset listings
10890 inline false
10891 status open
10893 \begin_layout Plain Layout
10895 function write_chunk(chunk_name) {
10896 \end_layout
10898 \begin_layout Plain Layout
10900   =<
10901 \backslash
10902 chunkref{awk-delete-array}(context)>
10903 \end_layout
10905 \begin_layout Plain Layout
10907   return write_chunk_r(chunk_name, context);
10908 \end_layout
10910 \begin_layout Plain Layout
10913 \end_layout
10915 \end_inset
10918 \end_layout
10920 \begin_layout Chunk
10921 write_chunk(),emph={chunk_path}
10922 \end_layout
10924 \begin_layout Standard
10925 \begin_inset listings
10926 inline false
10927 status open
10929 \begin_layout Plain Layout
10931 function write_chunk_r(chunk_name, context, indent, tail,
10932 \end_layout
10934 \begin_layout Plain Layout
10936   # optional vars
10937 \end_layout
10939 \begin_layout Plain Layout
10941   chunk_path, chunk_args, 
10942 \end_layout
10944 \begin_layout Plain Layout
10946   s, r, src, new_src, 
10947 \end_layout
10949 \begin_layout Plain Layout
10951   # local vars
10952 \end_layout
10954 \begin_layout Plain Layout
10956   chunk_params, part, max_part, part_line, frag, max_frag, text, 
10957 \end_layout
10959 \begin_layout Plain Layout
10961   chunklet, only_part, call_chunk_args, new_context)
10962 \end_layout
10964 \begin_layout Plain Layout
10967 \end_layout
10969 \end_inset
10972 \end_layout
10974 \begin_layout Subsection
10975 \begin_inset CommandInset label
10976 LatexCommand label
10977 name "sub:Chunk-parts"
10979 \end_inset
10981 Chunk parts
10982 \end_layout
10984 \begin_layout Standard
10985 As mentioned in section 
10986 \begin_inset CommandInset ref
10987 LatexCommand ref
10988 reference "sub:lstlistings-includes"
10990 \end_inset
10992 , a chunk name may contain a part specifier in square brackets, limiting
10993  the parts that should be emitted.
10994 \end_layout
10996 \begin_layout Standard
10997 \begin_inset listings
10998 inline false
10999 status open
11001 \begin_layout Plain Layout
11003   if (match(chunk_name, "^(.*)
11004 \backslash
11006 \backslash
11007 [([0-9]*)
11008 \backslash
11010 \backslash
11011 ]$", chunk_name_parts)) {
11012 \end_layout
11014 \begin_layout Plain Layout
11016     chunk_name = chunk_name_parts[1];
11017 \end_layout
11019 \begin_layout Plain Layout
11021     only_part = chunk_name_parts[2];
11022 \end_layout
11024 \begin_layout Plain Layout
11026   }
11027 \end_layout
11029 \end_inset
11032 \end_layout
11034 \begin_layout Standard
11035 We then create a mode tracker 
11036 \end_layout
11038 \begin_layout Standard
11039 \begin_inset listings
11040 inline false
11041 status open
11043 \begin_layout Plain Layout
11045   =<
11046 \backslash
11047 chunkref{new-mode-tracker}(context, chunks[chunk_name, "language"], "")>
11048 \end_layout
11050 \end_inset
11053 \end_layout
11055 \begin_layout Standard
11056 We extract into 
11057 \begin_inset Flex CharStyle:Code
11058 status collapsed
11060 \begin_layout Plain Layout
11061 chunk_params
11062 \end_layout
11064 \end_inset
11066  the names of the parameters that this chunk accepts, whose values were
11067  (optionally) passed in 
11068 \begin_inset Flex CharStyle:Code
11069 status collapsed
11071 \begin_layout Plain Layout
11072 chunk_args
11073 \end_layout
11075 \end_inset
11078 \end_layout
11080 \begin_layout Standard
11081 \begin_inset listings
11082 inline false
11083 status open
11085 \begin_layout Plain Layout
11087   split(chunks[chunk_name, "params"], chunk_params, " *; *");
11088 \end_layout
11090 \end_inset
11093 \end_layout
11095 \begin_layout Standard
11096 To assemble a chunk, we write out each part.
11097 \end_layout
11099 \begin_layout Chunk
11100 write_chunk()
11101 \end_layout
11103 \begin_layout Standard
11104 \begin_inset listings
11105 inline false
11106 status open
11108 \begin_layout Plain Layout
11110   if (! (chunk_name in chunk_names)) {
11111 \end_layout
11113 \begin_layout Plain Layout
11115     error(sprintf(_"The root module <<%s>> was not defined.
11116 \backslash
11117 nUsed by: %s",
11118 \backslash
11120 \end_layout
11122 \begin_layout Plain Layout
11124                   chunk_name, chunk_path));
11125 \end_layout
11127 \begin_layout Plain Layout
11129   }
11130 \end_layout
11132 \begin_layout Plain Layout
11134 \end_layout
11136 \begin_layout Plain Layout
11138   max_part = chunks[chunk_name, "part"];
11139 \end_layout
11141 \begin_layout Plain Layout
11143   for(part = 1; part <= max_part; part++) {
11144 \end_layout
11146 \begin_layout Plain Layout
11148     if (! only_part || part == only_part) {
11149 \end_layout
11151 \begin_layout Plain Layout
11153       =<
11154 \backslash
11155 chunkref{write-part}>
11156 \end_layout
11158 \begin_layout Plain Layout
11160     }
11161 \end_layout
11163 \begin_layout Plain Layout
11165   }
11166 \end_layout
11168 \begin_layout Plain Layout
11170   if (! finalize_mode_tracker(context)) {
11171 \end_layout
11173 \begin_layout Plain Layout
11175     dump_mode_tracker(context);
11176 \end_layout
11178 \begin_layout Plain Layout
11180     error(sprintf(_"Module %s did not close context properly.
11181 \backslash
11182 nUsed by: %s
11183 \backslash
11184 n", chunk_name, chunk_path));
11185 \end_layout
11187 \begin_layout Plain Layout
11189   }
11190 \end_layout
11192 \begin_layout Plain Layout
11195 \end_layout
11197 \end_inset
11200 \end_layout
11202 \begin_layout Standard
11203 A part can either be a chunklet of lines, or an include of another chunk.
11204 \end_layout
11206 \begin_layout Standard
11207 Chunks may also have parameters, specified in LaTeX style with braces after
11208  the chunk name --- looking like this in the document: 
11209 \begin_inset Flex CharStyle:Code
11210 status collapsed
11212 \begin_layout Plain Layout
11213 chunkname{param1, param2}
11214 \end_layout
11216 \end_inset
11219  Arguments are passed in square brackets: 
11220 \begin_inset Flex CharStyle:Code
11221 status collapsed
11223 \begin_layout Plain Layout
11225 \backslash
11226 chunkref{chunkname}[arg1, arg2]
11227 \end_layout
11229 \end_inset
11232 \end_layout
11234 \begin_layout Standard
11235 Before we process each part, we check that the source position hasn't changed
11236  unexpectedly, so that we can know if we need to output a new file-line
11237  directive.
11238 \end_layout
11240 \begin_layout Chunk
11241 write-part
11242 \end_layout
11244 \begin_layout Standard
11245 \begin_inset listings
11246 inline false
11247 status open
11249 \begin_layout Plain Layout
11252 \backslash
11253 chunkref{check-source-jump}>
11254 \end_layout
11256 \begin_layout Plain Layout
11258 \end_layout
11260 \begin_layout Plain Layout
11262 chunklet = chunks[chunk_name, "part", part];
11263 \end_layout
11265 \begin_layout Plain Layout
11267 if (chunks[chunk_name, "part", part, "type"] == part_type_chunk) {
11268 \end_layout
11270 \begin_layout Plain Layout
11272   =<
11273 \backslash
11274 chunkref{write-included-chunk}>
11275 \end_layout
11277 \begin_layout Plain Layout
11279 } else if (chunklet SUBSEP "line" in chunks) {
11280 \end_layout
11282 \begin_layout Plain Layout
11284   =<
11285 \backslash
11286 chunkref{write-chunklets}>
11287 \end_layout
11289 \begin_layout Plain Layout
11291 } else {
11292 \end_layout
11294 \begin_layout Plain Layout
11296   # empty last chunklet
11297 \end_layout
11299 \begin_layout Plain Layout
11302 \end_layout
11304 \end_inset
11307 \end_layout
11309 \begin_layout Standard
11310 To write an included chunk, we must detect any optional chunk arguments
11311  in parenthesis.
11312  Then we recurse calling 
11313 \begin_inset Flex Chunkref
11314 status collapsed
11316 \begin_layout Plain Layout
11317 write_chunk()
11318 \end_layout
11320 \end_inset
11323 \end_layout
11325 \begin_layout Chunk
11326 write-included-chunk
11327 \end_layout
11329 \begin_layout Standard
11330 \begin_inset listings
11331 inline false
11332 status open
11334 \begin_layout Plain Layout
11336 if (match(chunklet, "^([^
11337 \backslash
11339 \backslash
11341 \backslash
11343 \backslash
11344 (]*)
11345 \backslash
11347 \backslash
11348 ((.*)
11349 \backslash
11351 \backslash
11352 )$", chunklet_parts)) {
11353 \end_layout
11355 \begin_layout Plain Layout
11357   chunklet = chunklet_parts[1];
11358 \end_layout
11360 \begin_layout Plain Layout
11362   parse_chunk_args("c-like", chunklet_parts[2], call_chunk_args, "(");
11363 \end_layout
11365 \begin_layout Plain Layout
11367   for (c in call_chunk_args) {
11368 \end_layout
11370 \begin_layout Plain Layout
11372     call_chunk_args[c] = expand_chunk_args(call_chunk_args[c], chunk_params,
11373  chunk_args);
11374 \end_layout
11376 \begin_layout Plain Layout
11378   }
11379 \end_layout
11381 \begin_layout Plain Layout
11383 } else {
11384 \end_layout
11386 \begin_layout Plain Layout
11388   split("", call_chunk_args);
11389 \end_layout
11391 \begin_layout Plain Layout
11394 \end_layout
11396 \begin_layout Plain Layout
11398 # update the transforms arrays
11399 \end_layout
11401 \begin_layout Plain Layout
11403 new_src = mode_escaper(context, s, r, src);
11404 \end_layout
11406 \begin_layout Plain Layout
11409 \backslash
11410 chunkref{awk-delete-array}(new_context)>
11411 \end_layout
11413 \begin_layout Plain Layout
11415 write_chunk_r(chunklet, new_context,
11416 \end_layout
11418 \begin_layout Plain Layout
11420             chunks[chunk_name, "part", part, "indent"] indent,
11421 \end_layout
11423 \begin_layout Plain Layout
11425             chunks[chunk_name, "part", part, "tail"],
11426 \end_layout
11428 \begin_layout Plain Layout
11430             chunk_path "
11431 \backslash
11432 n         " chunk_name,
11433 \end_layout
11435 \begin_layout Plain Layout
11437             call_chunk_args,
11438 \end_layout
11440 \begin_layout Plain Layout
11442                         s, r, new_src);
11443 \end_layout
11445 \end_inset
11448 \end_layout
11450 \begin_layout Standard
11451 Before we output a chunklet of lines, we first emit the file and line number
11452  if we have one, and if it is safe to do so.
11454 \end_layout
11456 \begin_layout Standard
11457 Chunklets are generally broken up by includes, so the start of a chunklet
11458  is a good place to do this.
11459  Then we output each line of the chunklet.
11460 \end_layout
11462 \begin_layout Standard
11463 When it is not safe, such as in the middle of a multi-line macro definition,
11465 \begin_inset Flex CharStyle:Code
11466 status collapsed
11468 \begin_layout Plain Layout
11469 lineno_suppressed
11470 \end_layout
11472 \end_inset
11474  is set to true, and in such a case we note that we want to emit the line
11475  statement when it is next safe.
11476 \end_layout
11478 \begin_layout Chunk
11479 write-chunklets
11480 \end_layout
11482 \begin_layout Standard
11483 \begin_inset listings
11484 inline false
11485 status open
11487 \begin_layout Plain Layout
11489 max_frag = chunks[chunklet, "line"];
11490 \end_layout
11492 \begin_layout Plain Layout
11494 for(frag = 1; frag <= max_frag; frag++) {
11495 \end_layout
11497 \begin_layout Plain Layout
11499   =<
11500 \backslash
11501 chunkref{write-file-line}>
11502 \end_layout
11504 \end_inset
11507 \end_layout
11509 \begin_layout Standard
11510 We then extract the chunklet text and expand any arguments.
11511 \end_layout
11513 \begin_layout Standard
11514 \begin_inset listings
11515 inline false
11516 status open
11518 \begin_layout Plain Layout
11520 \end_layout
11522 \begin_layout Plain Layout
11524   text = chunks[chunklet, frag];
11525 \end_layout
11527 \begin_layout Plain Layout
11530 \end_layout
11532 \begin_layout Plain Layout
11534   /* check params */
11535 \end_layout
11537 \begin_layout Plain Layout
11539   text = expand_chunk_args(text, chunk_params, chunk_args);
11540 \end_layout
11542 \end_inset
11545 \end_layout
11547 \begin_layout Standard
11548 If the text is a single newline (which we keep separate - see 
11549 \begin_inset CommandInset ref
11550 LatexCommand ref
11551 reference "lone-newline"
11553 \end_inset
11555 ) then we increment the line number.
11556  In the case where this is the last line of a chunk and it is not a top-level
11557  chunk we replace the newline with an empty string --- because the chunk
11558  that included this chunk will have the newline at the end of the line that
11559  included this chunk.
11560 \end_layout
11562 \begin_layout Standard
11563 We also note by 
11564 \begin_inset Flex CharStyle:Code
11565 status collapsed
11567 \begin_layout Plain Layout
11568 newline = 1
11569 \end_layout
11571 \end_inset
11573  that we have started a new line, so that indentation can be managed with
11574  the following piece of text.
11575 \end_layout
11577 \begin_layout Standard
11578 \begin_inset listings
11579 inline false
11580 status open
11582 \begin_layout Plain Layout
11584 \end_layout
11586 \begin_layout Plain Layout
11588  if (text == "
11589 \backslash
11590 n") {
11591 \end_layout
11593 \begin_layout Plain Layout
11595     lineno++;
11596 \end_layout
11598 \begin_layout Plain Layout
11600     if (part == max_part && frag == max_frag && length(chunk_path)) {
11601 \end_layout
11603 \begin_layout Plain Layout
11605       text = "";
11606 \end_layout
11608 \begin_layout Plain Layout
11610       break;
11611 \end_layout
11613 \begin_layout Plain Layout
11615     } else {
11616 \end_layout
11618 \begin_layout Plain Layout
11620       newline = 1;
11621 \end_layout
11623 \begin_layout Plain Layout
11625     }
11626 \end_layout
11628 \end_inset
11631 \end_layout
11633 \begin_layout Standard
11634 If this text does not represent a newline, but we see that we are the first
11635  piece of text on a newline, then we prefix our text with the current indent.
11636  NOTE: 
11637 \begin_inset Flex CharStyle:Code
11638 status collapsed
11640 \begin_layout Plain Layout
11641 newline
11642 \end_layout
11644 \end_inset
11646  is a global output-state variable, but the 
11647 \begin_inset Flex CharStyle:Code
11648 status collapsed
11650 \begin_layout Plain Layout
11651 indent
11652 \end_layout
11654 \end_inset
11656  is not.
11658 \end_layout
11660 \begin_layout Standard
11661 \begin_inset listings
11662 inline false
11663 status open
11665 \begin_layout Plain Layout
11667   } else if (length(text) || length(tail)) {
11668 \end_layout
11670 \begin_layout Plain Layout
11672     if (newline) text = indent text;
11673 \end_layout
11675 \begin_layout Plain Layout
11677     newline = 0;
11678 \end_layout
11680 \begin_layout Plain Layout
11682   }
11683 \end_layout
11685 \begin_layout Plain Layout
11687 \end_layout
11689 \end_inset
11692 \end_layout
11694 \begin_layout Standard
11695 Tail will soon no longer be relevant once mode-detection is in place.
11696 \end_layout
11698 \begin_layout Standard
11699 \begin_inset listings
11700 inline false
11701 status open
11703 \begin_layout Plain Layout
11705   text = text tail;
11706 \end_layout
11708 \begin_layout Plain Layout
11710   mode_tracker(context, text);
11711 \end_layout
11713 \begin_layout Plain Layout
11715   print transform_escape(s, r, text, src);
11716 \end_layout
11718 \end_inset
11721 \end_layout
11723 \begin_layout Standard
11724 If a line ends in a backslash --- suggesting continuation --- then we supress
11725  outputting file-line as it would probably break the continued lines.
11727 \end_layout
11729 \begin_layout Standard
11730 \begin_inset listings
11731 inline false
11732 status open
11734 \begin_layout Plain Layout
11736   if (linenos) {
11737 \end_layout
11739 \begin_layout Plain Layout
11741     lineno_suppressed = substr(lastline, length(lastline)) == "
11742 \backslash
11744 \backslash
11746 \end_layout
11748 \begin_layout Plain Layout
11750   }
11751 \end_layout
11753 \begin_layout Plain Layout
11756 \end_layout
11758 \end_inset
11761 \end_layout
11763 \begin_layout Standard
11764 Of course there is no point in actually outputting the source filename and
11765  line number (file-line) if they don't say anything new! We only need to
11766  emit them if they aren't what is expected, or if we we not able to emit
11767  one when they had changed.
11768 \end_layout
11770 \begin_layout Chunk
11771 write-file-line
11772 \end_layout
11774 \begin_layout Standard
11775 \begin_inset listings
11776 inline false
11777 status open
11779 \begin_layout Plain Layout
11781 if (newline && lineno_needed && ! lineno_suppressed) {
11782 \end_layout
11784 \begin_layout Plain Layout
11786   filename = a_filename;
11787 \end_layout
11789 \begin_layout Plain Layout
11791   lineno = a_lineno;
11792 \end_layout
11794 \begin_layout Plain Layout
11796   print "#line " lineno " 
11797 \backslash
11798 "" filename "
11799 \backslash
11801 \backslash
11803 \end_layout
11805 \begin_layout Plain Layout
11807   lineno_needed = 0;
11808 \end_layout
11810 \begin_layout Plain Layout
11813 \end_layout
11815 \end_inset
11818 \end_layout
11820 \begin_layout Standard
11821 We check if a new file-line is needed by checking if the source line matches
11822  what we (or a compiler) would expect.
11824 \end_layout
11826 \begin_layout Chunk
11827 check-source-jump
11828 \end_layout
11830 \begin_layout Standard
11831 \begin_inset listings
11832 inline false
11833 status open
11835 \begin_layout Plain Layout
11837 if (linenos && (chunk_name SUBSEP "part" SUBSEP part SUBSEP "FILENAME" in
11838  chunks)) {
11839 \end_layout
11841 \begin_layout Plain Layout
11843   a_filename = chunks[chunk_name, "part", part, "FILENAME"];
11844 \end_layout
11846 \begin_layout Plain Layout
11848   a_lineno = chunks[chunk_name, "part", part, "LINENO"];
11849 \end_layout
11851 \begin_layout Plain Layout
11853   if (a_filename != filename || a_lineno != lineno) {
11854 \end_layout
11856 \begin_layout Plain Layout
11858     lineno_needed++;
11859 \end_layout
11861 \begin_layout Plain Layout
11863   }
11864 \end_layout
11866 \begin_layout Plain Layout
11869 \end_layout
11871 \end_inset
11874 \end_layout
11876 \begin_layout Chapter
11877 Storing chunks
11878 \end_layout
11880 \begin_layout Standard
11881 Awk has pretty limited data structures, so we will use two main hashes.
11882  Uninterrupted sequences of a chunk will be stored in 
11883 \begin_inset Flex CharStyle:Code
11884 status collapsed
11886 \begin_layout Plain Layout
11887 chunklets
11888 \end_layout
11890 \end_inset
11892  and the chunklets used in a chunk will be stored in 
11893 \begin_inset Flex CharStyle:Code
11894 status collapsed
11896 \begin_layout Plain Layout
11897 chunks
11898 \end_layout
11900 \end_inset
11903 \end_layout
11905 \begin_layout Chunk
11906 constants
11907 \end_layout
11909 \begin_layout Standard
11910 \begin_inset listings
11911 inline false
11912 status open
11914 \begin_layout Plain Layout
11916 part_type_chunk=1;
11917 \end_layout
11919 \begin_layout Plain Layout
11921 SUBSEP=",";
11922 \end_layout
11924 \end_inset
11927 \end_layout
11929 \begin_layout Standard
11930 The 
11931 \begin_inset Flex CharStyle:Code
11932 status collapsed
11934 \begin_layout Plain Layout
11935 params
11936 \end_layout
11938 \end_inset
11940  mentioned are not chunk parameters for parameterized chunks, as mentioned
11941  in 
11942 \begin_inset CommandInset ref
11943 LatexCommand ref
11944 reference "cha:Chunk Arguments"
11946 \end_inset
11948 , but the lstlistings style parameters used in the 
11949 \begin_inset Flex CharStyle:Code
11950 status collapsed
11952 \begin_layout Plain Layout
11954 \backslash
11955 Chunk
11956 \end_layout
11958 \end_inset
11960  command
11961 \begin_inset Foot
11962 status collapsed
11964 \begin_layout Plain Layout
11965 The 
11966 \begin_inset Flex CharStyle:Code
11967 status collapsed
11969 \begin_layout Plain Layout
11970 params
11971 \end_layout
11973 \end_inset
11975  parameter is used to hold the parameters for parameterized chunks
11976 \end_layout
11978 \end_inset
11981 \end_layout
11983 \begin_layout Chunk
11984 chunk-storage-functions
11985 \end_layout
11987 \begin_layout Standard
11988 \begin_inset listings
11989 inline false
11990 status open
11992 \begin_layout Plain Layout
11994 function new_chunk(chunk_name, params,
11995 \end_layout
11997 \begin_layout Plain Layout
11999   # local vars
12000 \end_layout
12002 \begin_layout Plain Layout
12004   p, append )
12005 \end_layout
12007 \begin_layout Plain Layout
12010 \end_layout
12012 \begin_layout Plain Layout
12014   # HACK WHILE WE CHANGE TO ( ) for PARAM CHUNKS
12015 \end_layout
12017 \begin_layout Plain Layout
12019   gsub("
12020 \backslash
12022 \backslash
12024 \backslash
12026 \backslash
12027 )$", "", chunk_name);
12028 \end_layout
12030 \begin_layout Plain Layout
12032   if (! (chunk_name in chunk_names)) {
12033 \end_layout
12035 \begin_layout Plain Layout
12037     if (debug) print "New chunk " chunk_name;
12038 \end_layout
12040 \begin_layout Plain Layout
12042     chunk_names[chunk_name];
12043 \end_layout
12045 \begin_layout Plain Layout
12047     for (p in params) {
12048 \end_layout
12050 \begin_layout Plain Layout
12052       chunks[chunk_name, p] = params[p];
12053 \end_layout
12055 \begin_layout Plain Layout
12057     }
12058 \end_layout
12060 \begin_layout Plain Layout
12062     if ("append" in params) {
12063 \end_layout
12065 \begin_layout Plain Layout
12067       append=params["append"];
12068 \end_layout
12070 \begin_layout Plain Layout
12072       if (! (append in chunk_names)) {
12073 \end_layout
12075 \begin_layout Plain Layout
12077         warning("Chunk " chunk_name " is appended to chunk " append " which
12078  is not defined yet");
12079 \end_layout
12081 \begin_layout Plain Layout
12083         new_chunk(append);
12084 \end_layout
12086 \begin_layout Plain Layout
12088       }
12089 \end_layout
12091 \begin_layout Plain Layout
12093       chunk_include(append, chunk_name);
12094 \end_layout
12096 \begin_layout Plain Layout
12098       chunk_line(append, ORS);
12099 \end_layout
12101 \begin_layout Plain Layout
12103     }
12104 \end_layout
12106 \begin_layout Plain Layout
12108   }
12109 \end_layout
12111 \begin_layout Plain Layout
12113   active_chunk = chunk_name;
12114 \end_layout
12116 \begin_layout Plain Layout
12118   prime_chunk(chunk_name);
12119 \end_layout
12121 \begin_layout Plain Layout
12124 \end_layout
12126 \end_inset
12129 \end_layout
12131 \begin_layout Standard
12132 \begin_inset listings
12133 inline false
12134 status open
12136 \begin_layout Plain Layout
12138 \end_layout
12140 \begin_layout Plain Layout
12142 function prime_chunk(chunk_name)
12143 \end_layout
12145 \begin_layout Plain Layout
12148 \end_layout
12150 \begin_layout Plain Layout
12152   chunks[chunk_name, "part", ++chunks[chunk_name, "part"] ] = 
12153 \backslash
12155 \end_layout
12157 \begin_layout Plain Layout
12159          chunk_name SUBSEP "chunklet" SUBSEP "" ++chunks[chunk_name, "chunklet"]
12161 \end_layout
12163 \begin_layout Plain Layout
12165   chunks[chunk_name, "part", chunks[chunk_name, "part"], "FILENAME"] = FILENAME;
12166 \end_layout
12168 \begin_layout Plain Layout
12170   chunks[chunk_name, "part", chunks[chunk_name, "part"], "LINENO"] = FNR
12171  + 1;
12172 \end_layout
12174 \begin_layout Plain Layout
12177 \end_layout
12179 \begin_layout Plain Layout
12181 \end_layout
12183 \begin_layout Plain Layout
12185 function chunk_line(chunk_name, line){
12186 \end_layout
12188 \begin_layout Plain Layout
12190   chunks[chunk_name, "chunklet", chunks[chunk_name, "chunklet"],
12191 \end_layout
12193 \begin_layout Plain Layout
12195          ++chunks[chunk_name, "chunklet", chunks[chunk_name, "chunklet"],
12196  "line"]  ] = line;
12197 \end_layout
12199 \begin_layout Plain Layout
12202 \end_layout
12204 \begin_layout Plain Layout
12206 \end_layout
12208 \end_inset
12211 \end_layout
12213 \begin_layout Standard
12214 Chunk include represents a 
12215 \emph on
12216 chunkref
12217 \emph default
12218  statement, and stores the requirement to include another chunk.
12219  The parameter indent represents the quanity of literal text characters
12220  that preceded this 
12221 \emph on
12222 chunkref
12223 \emph default
12224  statement and therefore by how much additional lines of the included chunk
12225  should be indented.
12226 \end_layout
12228 \begin_layout Standard
12229 \begin_inset listings
12230 inline false
12231 status open
12233 \begin_layout Plain Layout
12235 function chunk_include(chunk_name, chunk_ref, indent, tail)
12236 \end_layout
12238 \begin_layout Plain Layout
12241 \end_layout
12243 \begin_layout Plain Layout
12245   chunks[chunk_name, "part", ++chunks[chunk_name, "part"] ] = chunk_ref;
12246 \end_layout
12248 \begin_layout Plain Layout
12250   chunks[chunk_name, "part", chunks[chunk_name, "part"], "type" ] = part_type_ch
12251 unk;
12252 \end_layout
12254 \begin_layout Plain Layout
12256   chunks[chunk_name, "part", chunks[chunk_name, "part"], "indent" ] = indent_str
12257 ing(indent);
12258 \end_layout
12260 \begin_layout Plain Layout
12262   chunks[chunk_name, "part", chunks[chunk_name, "part"], "tail" ] = tail;
12263 \end_layout
12265 \begin_layout Plain Layout
12267   prime_chunk(chunk_name);
12268 \end_layout
12270 \begin_layout Plain Layout
12273 \end_layout
12275 \begin_layout Plain Layout
12277 \end_layout
12279 \end_inset
12282 \end_layout
12284 \begin_layout Standard
12285 The indent is calculated by indent_string, which may in future convert some
12286  spaces into tab characters.
12287  This function works by generating a printf padded format string, like 
12288 \begin_inset Flex CharStyle:Code
12289 status collapsed
12291 \begin_layout Plain Layout
12292 %22s
12293 \end_layout
12295 \end_inset
12297  for an indent of 22, and then printing an empty string using that format.
12298 \end_layout
12300 \begin_layout Standard
12301 \begin_inset listings
12302 inline false
12303 status open
12305 \begin_layout Plain Layout
12307 function indent_string(indent) {
12308 \end_layout
12310 \begin_layout Plain Layout
12312   return sprintf("%" indent "s", "");
12313 \end_layout
12315 \begin_layout Plain Layout
12318 \end_layout
12320 \end_inset
12323 \end_layout
12325 \begin_layout Chapter
12326 \begin_inset CommandInset label
12327 LatexCommand label
12328 name "cha:getopt"
12330 \end_inset
12332 getopt
12333 \end_layout
12335 \begin_layout Standard
12336 I use Arnold Robbins public domain getopt (1993 revision).
12337  This is probably the same one that is covered in chapter 12 of 
12338 \begin_inset Quotes eld
12339 \end_inset
12341 Edition 3 of GAWK: Effective AWK Programming: A User's Guide for GNU Awk
12342 \begin_inset Quotes erd
12343 \end_inset
12345  but as that is licensed under the GNU Free Documentation License, Version
12346  1.3, which conflicts with the GPL3, I can't use it from there (or it's accompany
12347 ing explanations), so I do my best to explain how it works here.
12348 \end_layout
12350 \begin_layout Standard
12351 The getopt.awk header is:
12352 \end_layout
12354 \begin_layout Chunk
12355 getopt.awk-header,language=awk,morestring=[b]{/},morekeywords=else
12356 \end_layout
12358 \begin_layout Standard
12359 \begin_inset listings
12360 inline false
12361 status open
12363 \begin_layout Plain Layout
12365 # getopt.awk --- do C library getopt(3) function in awk
12366 \end_layout
12368 \begin_layout Plain Layout
12371 \end_layout
12373 \begin_layout Plain Layout
12375 # Arnold Robbins, arnold@skeeve.com, Public Domain
12376 \end_layout
12378 \begin_layout Plain Layout
12381 \end_layout
12383 \begin_layout Plain Layout
12385 # Initial version: March, 1991
12386 \end_layout
12388 \begin_layout Plain Layout
12390 # Revised: May, 1993
12391 \end_layout
12393 \begin_layout Plain Layout
12395 \end_layout
12397 \end_inset
12400 \end_layout
12402 \begin_layout Standard
12403 The provided explanation is:
12404 \end_layout
12406 \begin_layout Chunk
12407 getopt.awk-notes
12408 \end_layout
12410 \begin_layout Standard
12411 \begin_inset listings
12412 inline false
12413 status open
12415 \begin_layout Plain Layout
12417 # External variables:
12418 \end_layout
12420 \begin_layout Plain Layout
12422 #    Optind -- index in ARGV of first nonoption argument
12423 \end_layout
12425 \begin_layout Plain Layout
12427 #    Optarg -- string value of argument to current option
12428 \end_layout
12430 \begin_layout Plain Layout
12432 #    Opterr -- if nonzero, print our own diagnostic
12433 \end_layout
12435 \begin_layout Plain Layout
12437 #    Optopt -- current option letter
12438 \end_layout
12440 \begin_layout Plain Layout
12442 \end_layout
12444 \begin_layout Plain Layout
12446 # Returns:
12447 \end_layout
12449 \begin_layout Plain Layout
12451 #    -1     at end of options
12452 \end_layout
12454 \begin_layout Plain Layout
12456 #    ?      for unrecognized option
12457 \end_layout
12459 \begin_layout Plain Layout
12461 #    <c>    a character representing the current option
12462 \end_layout
12464 \begin_layout Plain Layout
12466 \end_layout
12468 \begin_layout Plain Layout
12470 # Private Data:
12471 \end_layout
12473 \begin_layout Plain Layout
12475 #    _opti  -- index in multi-flag option, e.g., -abc
12476 \end_layout
12478 \begin_layout Plain Layout
12480 \end_layout
12482 \end_inset
12485 \end_layout
12487 \begin_layout Standard
12488 The function follows.
12489  The final two parameters, 
12490 \begin_inset Flex CharStyle:Code
12491 status collapsed
12493 \begin_layout Plain Layout
12494 thisopt
12495 \end_layout
12497 \end_inset
12499  and 
12500 \begin_inset Flex CharStyle:Code
12501 status collapsed
12503 \begin_layout Plain Layout
12505 \end_layout
12507 \end_inset
12509  are local variables and not parameters --- as indicated by the multiple
12510  spaces preceding them.
12511  Awk doesn't care, the multiple spaces are a convention to help us humans.
12512 \end_layout
12514 \begin_layout Chunk
12515 getopt.awk-getopt()
12516 \end_layout
12518 \begin_layout Standard
12519 \begin_inset listings
12520 inline false
12521 status open
12523 \begin_layout Plain Layout
12525 function getopt(argc, argv, options,    thisopt, i)
12526 \end_layout
12528 \begin_layout Plain Layout
12531 \end_layout
12533 \begin_layout Plain Layout
12535     if (length(options) == 0)    # no options given
12536 \end_layout
12538 \begin_layout Plain Layout
12540         return -1
12541 \end_layout
12543 \begin_layout Plain Layout
12545     if (argv[Optind] == "--") {  # all done
12546 \end_layout
12548 \begin_layout Plain Layout
12550         Optind++
12551 \end_layout
12553 \begin_layout Plain Layout
12555         _opti = 0
12556 \end_layout
12558 \begin_layout Plain Layout
12560         return -1
12561 \end_layout
12563 \begin_layout Plain Layout
12565     } else if (argv[Optind] !~ /^-[^: 
12566 \backslash
12568 \backslash
12570 \backslash
12572 \backslash
12574 \backslash
12576 \backslash
12577 b]/) {
12578 \end_layout
12580 \begin_layout Plain Layout
12582         _opti = 0
12583 \end_layout
12585 \begin_layout Plain Layout
12587         return -1
12588 \end_layout
12590 \begin_layout Plain Layout
12592     }
12593 \end_layout
12595 \begin_layout Plain Layout
12597     if (_opti == 0)
12598 \end_layout
12600 \begin_layout Plain Layout
12602         _opti = 2
12603 \end_layout
12605 \begin_layout Plain Layout
12607     thisopt = substr(argv[Optind], _opti, 1)
12608 \end_layout
12610 \begin_layout Plain Layout
12612     Optopt = thisopt
12613 \end_layout
12615 \begin_layout Plain Layout
12617     i = index(options, thisopt)
12618 \end_layout
12620 \begin_layout Plain Layout
12622     if (i == 0) {
12623 \end_layout
12625 \begin_layout Plain Layout
12627         if (Opterr)
12628 \end_layout
12630 \begin_layout Plain Layout
12632             printf("%c -- invalid option
12633 \backslash
12635 \end_layout
12637 \begin_layout Plain Layout
12639                                   thisopt) > "/dev/stderr"
12640 \end_layout
12642 \begin_layout Plain Layout
12644         if (_opti >= length(argv[Optind])) {
12645 \end_layout
12647 \begin_layout Plain Layout
12649             Optind++
12650 \end_layout
12652 \begin_layout Plain Layout
12654             _opti = 0
12655 \end_layout
12657 \begin_layout Plain Layout
12659         } else
12660 \end_layout
12662 \begin_layout Plain Layout
12664             _opti++
12665 \end_layout
12667 \begin_layout Plain Layout
12669         return "?"
12670 \end_layout
12672 \begin_layout Plain Layout
12674     }
12675 \end_layout
12677 \end_inset
12680 \end_layout
12682 \begin_layout Standard
12683 At this point, the option has been found and we need to know if it takes
12684  any arguments.
12685 \end_layout
12687 \begin_layout Standard
12688 \begin_inset listings
12689 inline false
12690 status open
12692 \begin_layout Plain Layout
12694     if (substr(options, i + 1, 1) == ":") {
12695 \end_layout
12697 \begin_layout Plain Layout
12699         # get option argument
12700 \end_layout
12702 \begin_layout Plain Layout
12704         if (length(substr(argv[Optind], _opti + 1)) > 0)
12705 \end_layout
12707 \begin_layout Plain Layout
12709             Optarg = substr(argv[Optind], _opti + 1)
12710 \end_layout
12712 \begin_layout Plain Layout
12714         else
12715 \end_layout
12717 \begin_layout Plain Layout
12719             Optarg = argv[++Optind]
12720 \end_layout
12722 \begin_layout Plain Layout
12724         _opti = 0
12725 \end_layout
12727 \begin_layout Plain Layout
12729     } else
12730 \end_layout
12732 \begin_layout Plain Layout
12734         Optarg = ""
12735 \end_layout
12737 \begin_layout Plain Layout
12739     if (_opti == 0 || _opti >= length(argv[Optind])) {
12740 \end_layout
12742 \begin_layout Plain Layout
12744         Optind++
12745 \end_layout
12747 \begin_layout Plain Layout
12749         _opti = 0
12750 \end_layout
12752 \begin_layout Plain Layout
12754     } else
12755 \end_layout
12757 \begin_layout Plain Layout
12759         _opti++
12760 \end_layout
12762 \begin_layout Plain Layout
12764     return thisopt
12765 \end_layout
12767 \begin_layout Plain Layout
12770 \end_layout
12772 \end_inset
12774 A test program is built in, too
12775 \end_layout
12777 \begin_layout Chunk
12778 getopt.awk-begin
12779 \end_layout
12781 \begin_layout Standard
12782 \begin_inset listings
12783 inline false
12784 status open
12786 \begin_layout Plain Layout
12788 BEGIN {
12789 \end_layout
12791 \begin_layout Plain Layout
12793     Opterr = 1    # default is to diagnose
12794 \end_layout
12796 \begin_layout Plain Layout
12798     Optind = 1    # skip ARGV[0]
12799 \end_layout
12801 \begin_layout Plain Layout
12803     # test program
12804 \end_layout
12806 \begin_layout Plain Layout
12808     if (_getopt_test) {
12809 \end_layout
12811 \begin_layout Plain Layout
12813         while ((_go_c = getopt(ARGC, ARGV, "ab:cd")) != -1)
12814 \end_layout
12816 \begin_layout Plain Layout
12818             printf("c = <%c>, optarg = <%s>
12819 \backslash
12821 \end_layout
12823 \begin_layout Plain Layout
12825                                        _go_c, Optarg)
12826 \end_layout
12828 \begin_layout Plain Layout
12830         printf("non-option arguments:
12831 \backslash
12833 \end_layout
12835 \begin_layout Plain Layout
12837         for (; Optind < ARGC; Optind++)
12838 \end_layout
12840 \begin_layout Plain Layout
12842             printf("
12843 \backslash
12844 tARGV[%d] = <%s>
12845 \backslash
12847 \end_layout
12849 \begin_layout Plain Layout
12851                                     Optind, ARGV[Optind])
12852 \end_layout
12854 \begin_layout Plain Layout
12856     }
12857 \end_layout
12859 \begin_layout Plain Layout
12862 \end_layout
12864 \end_inset
12867 \end_layout
12869 \begin_layout Standard
12870 The entire getopt.awk is made out of these chunks in order
12871 \end_layout
12873 \begin_layout Chunk
12874 getopt.awk
12875 \end_layout
12877 \begin_layout Standard
12878 \begin_inset listings
12879 inline false
12880 status open
12882 \begin_layout Plain Layout
12885 \backslash
12886 chunkref{getopt.awk-header}>
12887 \end_layout
12889 \begin_layout Plain Layout
12891 \end_layout
12893 \begin_layout Plain Layout
12896 \backslash
12897 chunkref{getopt.awk-notes}>
12898 \end_layout
12900 \begin_layout Plain Layout
12903 \backslash
12904 chunkref{getopt.awk-getopt()}>
12905 \end_layout
12907 \begin_layout Plain Layout
12910 \backslash
12911 chunkref{getopt.awk-begin}>
12912 \end_layout
12914 \end_inset
12917 \end_layout
12919 \begin_layout Standard
12920 Although we only want the header and function:
12921 \end_layout
12923 \begin_layout Chunk
12924 getopt
12925 \end_layout
12927 \begin_layout Standard
12928 \begin_inset listings
12929 inline false
12930 status open
12932 \begin_layout Plain Layout
12934 # try: locate getopt.awk for the full original file
12935 \end_layout
12937 \begin_layout Plain Layout
12939 # as part of your standard awk installation
12940 \end_layout
12942 \begin_layout Plain Layout
12945 \backslash
12946 chunkref{getopt.awk-header}>
12947 \end_layout
12949 \begin_layout Plain Layout
12951 \end_layout
12953 \begin_layout Plain Layout
12956 \backslash
12957 chunkref{getopt.awk-getopt()}>
12958 \end_layout
12960 \end_inset
12963 \end_layout
12965 \begin_layout Chapter
12966 Newfangle LaTeX source code
12967 \end_layout
12969 \begin_layout Section
12970 newfangle module
12971 \end_layout
12973 \begin_layout Standard
12974 Here we define a Lyx .module file that makes it convenient to use LyX for
12975  writing such literate programs.
12976 \end_layout
12978 \begin_layout Standard
12979 This file 
12980 \begin_inset Flex CharStyle:Code
12981 status collapsed
12983 \begin_layout Plain Layout
12984 ./newfangle.module
12985 \end_layout
12987 \end_inset
12989  can be installed in your personal 
12990 \begin_inset Flex CharStyle:Code
12991 status collapsed
12993 \begin_layout Plain Layout
12994 .lyx/layouts folder
12995 \end_layout
12997 \end_inset
13000  You will need to Tools Reconfigure so that LyX notices it.
13001  It adds a new format Chunk, which should precede every listing and contain
13002  the chunk name.
13004 \end_layout
13006 \begin_layout Chunk
13007 ./newfangle.module,language=
13008 \end_layout
13010 \begin_layout Standard
13011 \begin_inset listings
13012 inline false
13013 status open
13015 \begin_layout Plain Layout
13018 \backslash
13019 DeclareLyXModule{Newfangle Literate Listings}
13020 \end_layout
13022 \begin_layout Plain Layout
13024 #DescriptionBegin
13025 \end_layout
13027 \begin_layout Plain Layout
13029 #  Newfangle literate listings allow one to write
13030 \end_layout
13032 \begin_layout Plain Layout
13034 #   literate programs after the fashion of noweb, but without having
13035 \end_layout
13037 \begin_layout Plain Layout
13039 #   to use noweave to generate the documentation.
13040  Instead the listings
13041 \end_layout
13043 \begin_layout Plain Layout
13045 #   package is extended in conjunction with the noweb package to implement
13046 \end_layout
13048 \begin_layout Plain Layout
13050 #   to code formating directly as latex.
13051 \end_layout
13053 \begin_layout Plain Layout
13055 #  The newfangle awk script
13056 \end_layout
13058 \begin_layout Plain Layout
13060 #DescriptionEnd
13061 \end_layout
13063 \begin_layout Plain Layout
13065 \end_layout
13067 \begin_layout Plain Layout
13069 Format 11
13070 \end_layout
13072 \begin_layout Plain Layout
13074 \end_layout
13076 \begin_layout Plain Layout
13078 AddToPreamble
13079 \end_layout
13081 \begin_layout Plain Layout
13084 \backslash
13085 chunkref{./newfangle.sty}>
13086 \end_layout
13088 \begin_layout Plain Layout
13090 EndPreamble
13091 \end_layout
13093 \begin_layout Plain Layout
13095 \end_layout
13097 \begin_layout Plain Layout
13100 \backslash
13101 chunkref{chunkstyle}>
13102 \end_layout
13104 \begin_layout Plain Layout
13106 \end_layout
13108 \begin_layout Plain Layout
13111 \backslash
13112 chunkref{chunkref}>
13113 \end_layout
13115 \end_inset
13118 \end_layout
13120 \begin_layout Subsection
13121 The Chunk style
13122 \end_layout
13124 \begin_layout Standard
13125 The purpose of the 
13126 \noun on
13127 chunk
13128 \noun default
13129  style is to make it easier for LyX users to provide the name to 
13130 \begin_inset Flex CharStyle:Code
13131 status collapsed
13133 \begin_layout Plain Layout
13135 \backslash
13136 lstlistings
13137 \end_layout
13139 \end_inset
13142  Normally this requires right-clicking on the listing, choosing settings,
13143  advanced, and then typing 
13144 \begin_inset Flex CharStyle:Code
13145 status collapsed
13147 \begin_layout Plain Layout
13148 name=chunk-name
13149 \end_layout
13151 \end_inset
13154  This has the further disadvantage that the name (and other options) are
13155  not generally visible during document editing.
13156 \end_layout
13158 \begin_layout Standard
13159 The chunk style is defined as a LaTeX command, so that all text on the same
13160  line is passed to the LaTeX command 
13161 \begin_inset Flex CharStyle:Code
13162 status collapsed
13164 \begin_layout Plain Layout
13165 Chunk
13166 \end_layout
13168 \end_inset
13171  This makes it easy to parse using 
13172 \begin_inset Flex CharStyle:Code
13173 status collapsed
13175 \begin_layout Plain Layout
13176 newfangle
13177 \end_layout
13179 \end_inset
13181 , and easy to pass these options on to the listings package.
13182  The first word in a chunk section should be the chunk name, and will have
13184 \begin_inset Flex CharStyle:Code
13185 status collapsed
13187 \begin_layout Plain Layout
13188 name=
13189 \end_layout
13191 \end_inset
13193  prepended to it.
13194  Any other words are accepted arguments to 
13195 \begin_inset Flex CharStyle:Code
13196 status collapsed
13198 \begin_layout Plain Layout
13200 \backslash
13201 lstset
13202 \end_layout
13204 \end_inset
13207 \end_layout
13209 \begin_layout Standard
13210 We set PassThru to 1 because the user is actually entering raw latex.
13211 \end_layout
13213 \begin_layout Chunk
13214 chunkstyle
13215 \end_layout
13217 \begin_layout Standard
13218 \begin_inset listings
13219 inline false
13220 status open
13222 \begin_layout Plain Layout
13224 Style Chunk
13225 \end_layout
13227 \begin_layout Plain Layout
13229   LatexType             Command
13230 \end_layout
13232 \begin_layout Plain Layout
13234   LatexName             Chunk
13235 \end_layout
13237 \begin_layout Plain Layout
13239   Margin                First_Dynamic
13240 \end_layout
13242 \begin_layout Plain Layout
13244   LeftMargin            Chunk:xxx
13245 \end_layout
13247 \begin_layout Plain Layout
13249   LabelSep              xx
13250 \end_layout
13252 \begin_layout Plain Layout
13254   LabelType             Static
13255 \end_layout
13257 \begin_layout Plain Layout
13259   LabelString           "Chunk:"
13260 \end_layout
13262 \begin_layout Plain Layout
13264   Align                 Left
13265 \end_layout
13267 \begin_layout Plain Layout
13269   PassThru              1
13270 \end_layout
13272 \begin_layout Plain Layout
13274 \end_layout
13276 \end_inset
13279 \end_layout
13281 \begin_layout Standard
13282 To make the label very visible we choose a larger font coloured red.
13283 \end_layout
13285 \begin_layout Standard
13286 \begin_inset listings
13287 inline false
13288 status open
13290 \begin_layout Plain Layout
13292   LabelFont
13293 \end_layout
13295 \begin_layout Plain Layout
13297     Family              Sans
13298 \end_layout
13300 \begin_layout Plain Layout
13302     Size                Large
13303 \end_layout
13305 \begin_layout Plain Layout
13307     Series              Bold
13308 \end_layout
13310 \begin_layout Plain Layout
13312     Shape               Italic
13313 \end_layout
13315 \begin_layout Plain Layout
13317     Color               red
13318 \end_layout
13320 \begin_layout Plain Layout
13322   EndFont
13323 \end_layout
13325 \begin_layout Plain Layout
13328 \end_layout
13330 \end_inset
13333 \end_layout
13335 \begin_layout Subsection
13336 The chunkref style
13337 \end_layout
13339 \begin_layout Standard
13340 We also define the Chunkref style which can be used to express cross references
13341  to chunks.
13342 \end_layout
13344 \begin_layout Chunk
13345 chunkref
13346 \end_layout
13348 \begin_layout Standard
13349 \begin_inset listings
13350 inline false
13351 status open
13353 \begin_layout Plain Layout
13355 InsetLayout Chunkref
13356 \end_layout
13358 \begin_layout Plain Layout
13360   LyxType               charstyle
13361 \end_layout
13363 \begin_layout Plain Layout
13365   LatexType             Command
13366 \end_layout
13368 \begin_layout Plain Layout
13370   LatexName             chunkref
13371 \end_layout
13373 \begin_layout Plain Layout
13375   PassThru              1
13376 \end_layout
13378 \begin_layout Plain Layout
13380   LabelFont             
13381 \end_layout
13383 \begin_layout Plain Layout
13385     Shape               Italic
13386 \end_layout
13388 \begin_layout Plain Layout
13390     Color               red
13391 \end_layout
13393 \begin_layout Plain Layout
13395   EndFont
13396 \end_layout
13398 \begin_layout Plain Layout
13401 \end_layout
13403 \end_inset
13406 \end_layout
13408 \begin_layout Section
13409 \begin_inset CommandInset label
13410 LatexCommand label
13411 name "sec:Latex-Macros"
13413 \end_inset
13415 Latex Macros
13416 \end_layout
13418 \begin_layout Standard
13419 We require the 
13420 \noun on
13421 listings
13422 \noun default
13424 \noun on
13425 noweb
13426 \noun default
13427  and 
13428 \noun on
13429 xargs
13430 \noun default
13431  packages.
13432  As noweb defines it's own 
13433 \begin_inset Flex CharStyle:Code
13434 status collapsed
13436 \begin_layout Plain Layout
13438 \backslash
13439 code
13440 \end_layout
13442 \end_inset
13444  environment, we re-define the one that LyX logical markup module expects
13445  here.
13446 \end_layout
13448 \begin_layout Chunk
13449 ./newfangle.sty,language=tex,basicstyle=
13450 \backslash
13451 ttfamily
13452 \end_layout
13454 \begin_layout Standard
13455 \begin_inset listings
13456 inline false
13457 status open
13459 \begin_layout Plain Layout
13462 \backslash
13463 usepackage{listings}%
13464 \end_layout
13466 \begin_layout Plain Layout
13469 \backslash
13470 usepackage{noweb}%
13471 \end_layout
13473 \begin_layout Plain Layout
13476 \backslash
13477 usepackage{xargs}%
13478 \end_layout
13480 \begin_layout Plain Layout
13483 \backslash
13484 renewcommand{
13485 \backslash
13486 code}[1]{
13487 \backslash
13488 texttt{#1}}%
13489 \end_layout
13491 \end_inset
13494 \end_layout
13496 \begin_layout Standard
13497 We also define a 
13498 \begin_inset Flex CharStyle:Code
13499 status collapsed
13501 \begin_layout Plain Layout
13502 CChunk
13503 \end_layout
13505 \end_inset
13507  macro, for use as: 
13508 \begin_inset Flex CharStyle:Code
13509 status collapsed
13511 \begin_layout Plain Layout
13513 \backslash
13514 begin{CChunk}
13515 \end_layout
13517 \end_inset
13519  which will need renaming to 
13520 \begin_inset Flex CharStyle:Code
13521 status collapsed
13523 \begin_layout Plain Layout
13525 \backslash
13526 begin{Chunk}
13527 \end_layout
13529 \end_inset
13531  when I can do this without clashing with 
13532 \begin_inset Flex CharStyle:Code
13533 status collapsed
13535 \begin_layout Plain Layout
13537 \backslash
13538 Chunk
13539 \end_layout
13541 \end_inset
13544 \end_layout
13546 \begin_layout Standard
13547 \begin_inset listings
13548 inline false
13549 status open
13551 \begin_layout Plain Layout
13554 \backslash
13555 lstnewenvironment{Chunk}{
13556 \backslash
13557 relax}{
13558 \backslash
13559 relax}%
13560 \end_layout
13562 \end_inset
13565 \end_layout
13567 \begin_layout Standard
13568 We also define a suitable 
13569 \begin_inset Flex CharStyle:Code
13570 status collapsed
13572 \begin_layout Plain Layout
13574 \backslash
13575 lstset
13576 \end_layout
13578 \end_inset
13580  of parameters that suit the literate programming style after the fashion
13581  of 
13582 \noun on
13583 noweave
13584 \noun default
13586 \end_layout
13588 \begin_layout Standard
13589 \begin_inset listings
13590 inline false
13591 status open
13593 \begin_layout Plain Layout
13596 \backslash
13597 lstset{numbers=left, stepnumber=5, numbersep=5pt,
13598 \end_layout
13600 \begin_layout Plain Layout
13602         breaklines=false,basicstyle=
13603 \backslash
13604 ttfamily,
13605 \end_layout
13607 \begin_layout Plain Layout
13609         numberstyle=
13610 \backslash
13611 tiny, language=C}%
13612 \end_layout
13614 \end_inset
13617 \end_layout
13619 \begin_layout Standard
13620 We also define a notangle-like mechanism for 
13621 \emph on
13622 escaping
13623 \emph default
13624  to LaTeX from the listing, and by which we can refer to other listings.
13625  We declare the 
13626 \begin_inset Flex CharStyle:Code
13627 status collapsed
13629 \begin_layout Plain Layout
13630 =<\SpecialChar \ldots{}
13632 \end_layout
13634 \end_inset
13636  sequence to contain LaTeX code, and include another like this chunk: 
13637 \begin_inset Flex CharStyle:Code
13638 status collapsed
13640 \begin_layout Plain Layout
13642 \backslash
13643 chunkref{chunkname}>
13644 \end_layout
13646 \end_inset
13649  However, because 
13650 \begin_inset Flex CharStyle:Code
13651 status collapsed
13653 \begin_layout Plain Layout
13654 =<\SpecialChar \ldots{}
13656 \end_layout
13658 \end_inset
13660  is already defined to contain LaTeX code for this document --- this is
13661  a 
13662 \noun on
13663 newfangle
13664 \noun default
13665  document after all --- the code fragment below effectively contains the
13666  LaTeX code: 
13667 \begin_inset Flex CharStyle:Code
13668 status collapsed
13670 \begin_layout Plain Layout
13672 \end_layout
13674 \end_inset
13677  To avoid problems with document generation, I had to declare an lstlistings
13678  property: 
13679 \begin_inset Flex CharStyle:Code
13680 status collapsed
13682 \begin_layout Plain Layout
13683 escapeinside={}
13684 \end_layout
13686 \end_inset
13688  for this listing only; which in LyX was done by right-clicking the listings
13689  inset, choosing 
13690 \begin_inset Flex CharStyle:Code
13691 status collapsed
13693 \begin_layout Plain Layout
13694 settings
13695 \end_layout
13697 \end_inset
13699 \SpecialChar \menuseparator
13701 \begin_inset Flex CharStyle:Code
13702 status collapsed
13704 \begin_layout Plain Layout
13705 advanced
13706 \end_layout
13708 \end_inset
13711 \end_layout
13713 \begin_layout Standard
13714 \begin_inset Note Note
13715 status collapsed
13717 \begin_layout Plain Layout
13718 =< isn't enjoyed literally here, in a listing when the escape sequence is
13719  already defined as shown...
13720  we need to somehow escape this representation...
13721 \end_layout
13723 \end_inset
13726 \end_layout
13728 \begin_layout Standard
13729 \begin_inset listings
13730 lstparams "escapeinside={}"
13731 inline false
13732 status open
13734 \begin_layout Plain Layout
13737 \backslash
13738 lstset{escapeinside={=<}{>}}%
13739 \end_layout
13741 \end_inset
13744 \end_layout
13746 \begin_layout Standard
13747 Although our macros will contain the @ symbol, they will be included in
13748  a 
13749 \begin_inset Flex CharStyle:Code
13750 status collapsed
13752 \begin_layout Plain Layout
13754 \backslash
13755 makeatletter
13756 \end_layout
13758 \end_inset
13760  section by LyX; however we keep the commented out 
13761 \begin_inset Flex CharStyle:Code
13762 status collapsed
13764 \begin_layout Plain Layout
13766 \backslash
13767 makeatletter
13768 \end_layout
13770 \end_inset
13772  as a reminder.
13773  The listings package likes to centre the titles, but noweb titles are specially
13774  formatted and must be left aligned.
13775  The simplest way to do this turned out to be by removing the definition
13776  of 
13777 \begin_inset Flex CharStyle:Code
13778 status collapsed
13780 \begin_layout Plain Layout
13782 \backslash
13783 lst@maketitle
13784 \end_layout
13786 \end_inset
13789  This may interact badly if other listings want a regular title or caption.
13790  We remember the old maketitle in case we need it.
13791 \end_layout
13793 \begin_layout Standard
13794 \begin_inset listings
13795 inline false
13796 status open
13798 \begin_layout Plain Layout
13801 \backslash
13802 makeatletter
13803 \end_layout
13805 \begin_layout Plain Layout
13807 %somehow re-defining maketitle gives us a left-aligned title
13808 \end_layout
13810 \begin_layout Plain Layout
13812 %which is extactly what our specially formatted title needs!
13813 \end_layout
13815 \begin_layout Plain Layout
13818 \backslash
13819 global
13820 \backslash
13822 \backslash
13823 newfangle@lst@maketitle
13824 \backslash
13825 lst@maketitle%
13826 \end_layout
13828 \begin_layout Plain Layout
13831 \backslash
13832 global
13833 \backslash
13835 \backslash
13836 lst@maketitle{}%
13837 \end_layout
13839 \end_inset
13842 \end_layout
13844 \begin_layout Subsection
13845 \begin_inset CommandInset label
13846 LatexCommand label
13847 name "sub:The-chunk-command"
13849 \end_inset
13851 The chunk command
13852 \end_layout
13854 \begin_layout Standard
13855 Our chunk command accepts one argument, and calls 
13856 \begin_inset Flex CharStyle:Code
13857 status collapsed
13859 \begin_layout Plain Layout
13861 \backslash
13862 ltset
13863 \end_layout
13865 \end_inset
13868  Although 
13869 \begin_inset Flex CharStyle:Code
13870 status collapsed
13872 \begin_layout Plain Layout
13874 \backslash
13875 ltset
13876 \end_layout
13878 \end_inset
13880  will note the name, this is erased when the next 
13881 \begin_inset Flex CharStyle:Code
13882 status collapsed
13884 \begin_layout Plain Layout
13886 \backslash
13887 lstlisting
13888 \end_layout
13890 \end_inset
13892  starts, so we make a note of this in 
13893 \begin_inset Flex CharStyle:Code
13894 status collapsed
13896 \begin_layout Plain Layout
13898 \backslash
13899 lst@chunkname
13900 \end_layout
13902 \end_inset
13904  and restore in in lstlistings Init hook.
13905 \end_layout
13907 \begin_layout Standard
13908 \begin_inset listings
13909 inline false
13910 status open
13912 \begin_layout Plain Layout
13915 \backslash
13917 \backslash
13918 Chunk#1{%
13919 \end_layout
13921 \begin_layout Plain Layout
13923   
13924 \backslash
13925 lstset{title={
13926 \backslash
13927 newfanglecaption},name=#1}%
13928 \end_layout
13930 \begin_layout Plain Layout
13932   
13933 \backslash
13934 global
13935 \backslash
13936 edef
13937 \backslash
13938 lst@chunkname{
13939 \backslash
13940 lst@intname}%
13941 \end_layout
13943 \begin_layout Plain Layout
13946 \end_layout
13948 \begin_layout Plain Layout
13951 \backslash
13953 \backslash
13954 lst@chunkname{
13955 \backslash
13956 empty}%
13957 \end_layout
13959 \end_inset
13962 \end_layout
13964 \begin_layout Subsubsection
13965 Chunk parameters
13966 \end_layout
13968 \begin_layout Standard
13969 Newfangle permits parameterized chunks, and requires the paramters to be
13970  specified as listings options.
13971  The newfangle script uses this, and although we don't do anything with
13972  these in the LaTeX code right now, we need to stop the listings package
13973  complaining.
13974 \end_layout
13976 \begin_layout Standard
13977 \begin_inset listings
13978 inline false
13979 status open
13981 \begin_layout Plain Layout
13984 \backslash
13985 lst@Key{params}
13986 \backslash
13987 relax{
13988 \backslash
13990 \backslash
13991 newfangle@chunk@params{#1}}%
13992 \end_layout
13994 \end_inset
13997 \end_layout
13999 \begin_layout Standard
14000 As it is common to define a chunk which then needs appending to another
14001  chunk, and annoying to have to declare a single line chunk to manage the
14002  include, we support an 
14003 \begin_inset Flex CharStyle:Code
14004 status collapsed
14006 \begin_layout Plain Layout
14007 append=
14008 \end_layout
14010 \end_inset
14012  option.
14014 \end_layout
14016 \begin_layout Standard
14017 \begin_inset listings
14018 inline false
14019 status open
14021 \begin_layout Plain Layout
14024 \backslash
14025 lst@Key{append}
14026 \backslash
14027 relax{
14028 \backslash
14030 \backslash
14031 newfangle@chunk@append{#1}}%
14032 \end_layout
14034 \end_inset
14037 \end_layout
14039 \begin_layout Subsection
14040 The noweb styled caption
14041 \end_layout
14043 \begin_layout Standard
14044 We define a public macro 
14045 \begin_inset Flex CharStyle:Code
14046 status collapsed
14048 \begin_layout Plain Layout
14050 \backslash
14051 newfanglecaption
14052 \end_layout
14054 \end_inset
14056  which can be set as a regular title.
14057  By means of 
14058 \begin_inset Flex CharStyle:Code
14059 status collapsed
14061 \begin_layout Plain Layout
14063 \backslash
14064 protect
14065 \end_layout
14067 \end_inset
14069 , It expands to 
14070 \begin_inset Flex CharStyle:Code
14071 status collapsed
14073 \begin_layout Plain Layout
14075 \backslash
14076 newfangle@caption
14077 \end_layout
14079 \end_inset
14081  at the appriate time when the caption is emitted.
14082 \end_layout
14084 \begin_layout Standard
14085 \begin_inset listings
14086 inline false
14087 status open
14089 \begin_layout Plain Layout
14092 \backslash
14094 \backslash
14095 newfanglecaption{
14096 \backslash
14097 protect
14098 \backslash
14099 newfangle@caption}%
14100 \end_layout
14102 \end_inset
14105 \end_layout
14107 \begin_layout Standard
14108 \begin_inset Float figure
14109 placement H
14110 wide false
14111 sideways false
14112 status collapsed
14114 \begin_layout Plain Layout
14115 \begin_inset Box Boxed
14116 position "t"
14117 hor_pos "c"
14118 has_inner_box 1
14119 inner_pos "t"
14120 use_parbox 0
14121 width "100col%"
14122 special "none"
14123 height "1in"
14124 height_special "totalheight"
14125 status open
14127 \begin_layout Plain Layout
14129 \begin_inset space \qquad{}
14130 \end_inset
14133 \shape italic
14134 some-chunk
14135 \shape default
14136  19b⟩
14137 \begin_inset Formula $\equiv+$
14138 \end_inset
14141 \begin_inset space \qquad{}
14142 \end_inset
14145 \begin_inset space \qquad{}
14146 \end_inset
14149 \begin_inset space \qquad{}
14150 \end_inset
14153 \begin_inset Formula $\triangleleft$
14154 \end_inset
14157 \begin_inset space \quad{}
14158 \end_inset
14161 \begin_inset Formula $\triangleright$
14162 \end_inset
14165 \end_layout
14167 \begin_layout Plain Layout
14169 \size footnotesize
14170 In this example, the current chunk is 22c, and therefore the third chunk
14171  on page 22.
14172 \end_layout
14174 \begin_layout Plain Layout
14176 \size footnotesize
14177 It's name is 
14178 \emph on
14179 some-chunk
14180 \emph default
14183 \end_layout
14185 \begin_layout Plain Layout
14187 \size footnotesize
14188 The first chunk with this name (19b) occurs as the second chunk on page
14189  19.
14190 \end_layout
14192 \begin_layout Plain Layout
14194 \size footnotesize
14195 The previous chunk (22d) with the same name is the second chunk on page
14196  22.
14197 \end_layout
14199 \begin_layout Plain Layout
14201 \size footnotesize
14202 The next chunk (24d) is the fourth chunk on page 24.
14203 \end_layout
14205 \begin_layout Plain Layout
14206 \begin_inset Caption
14208 \begin_layout Plain Layout
14209 noweb heading
14210 \end_layout
14212 \end_inset
14215 \end_layout
14217 \end_inset
14220 \end_layout
14222 \end_inset
14224 The general noweb output format compactly identifies the current chunk,
14225  and references to the first chunk, and the previous and next chunks that
14226  have the same name.
14228 \end_layout
14230 \begin_layout Standard
14231 This means that we need to keep a counter for each chunk-name, that we use
14232  to count chunks of the same name.
14234 \end_layout
14236 \begin_layout Subsection
14237 The chunk counter
14238 \end_layout
14240 \begin_layout Standard
14241 It would be natural to have a counter for each chunk name, but TeX would
14242  soon run out of counters
14243 \begin_inset Foot
14244 status collapsed
14246 \begin_layout Plain Layout
14247 \SpecialChar \ldots{}
14248 soon 
14249 \emph on
14251 \emph default
14252  run out of counters and so I had to re-write the LaTeX macros to share
14253  a counter as described here
14254 \end_layout
14256 \end_inset
14258 , so we have one counter which we save at the end of a chunk and restore
14259  at the beginning of a chunk.
14260 \end_layout
14262 \begin_layout Standard
14263 \begin_inset listings
14264 inline false
14265 status open
14267 \begin_layout Plain Layout
14270 \backslash
14271 newcounter{newfangle@chunkcounter}%
14272 \end_layout
14274 \end_inset
14277 \end_layout
14279 \begin_layout Standard
14280 We construct the name of this variable to store the counter to be the text
14282 \begin_inset Flex CharStyle:Code
14283 status collapsed
14285 \begin_layout Plain Layout
14286 lst-chunk-
14287 \end_layout
14289 \end_inset
14291  prefixed onto the chunks own name, and store it in 
14292 \begin_inset Flex CharStyle:Code
14293 status collapsed
14295 \begin_layout Plain Layout
14297 \backslash
14298 chunkcount
14299 \end_layout
14301 \end_inset
14305 \end_layout
14307 \begin_layout Standard
14308 We save the counter like this:
14309 \end_layout
14311 \begin_layout Chunk
14312 save-counter
14313 \end_layout
14315 \begin_layout Standard
14316 \begin_inset listings
14317 inline false
14318 status open
14320 \begin_layout Plain Layout
14323 \backslash
14324 global
14325 \backslash
14326 expandafter
14327 \backslash
14328 edef
14329 \backslash
14330 csname 
14331 \backslash
14332 chunkcount
14333 \backslash
14334 endcsname{
14335 \backslash
14336 arabic{newfangle@chunkcounter}}%
14337 \end_layout
14339 \end_inset
14342 \end_layout
14344 \begin_layout Standard
14345 and restore the counter like this:
14346 \end_layout
14348 \begin_layout Chunk
14349 restore-counter
14350 \end_layout
14352 \begin_layout Standard
14353 \begin_inset listings
14354 inline false
14355 status open
14357 \begin_layout Plain Layout
14360 \backslash
14361 setcounter{newfangle@chunkcounter}{
14362 \backslash
14363 csname 
14364 \backslash
14365 chunkcount
14366 \backslash
14367 endcsname}%
14368 \end_layout
14370 \end_inset
14373 \end_layout
14375 \begin_layout Chunk
14376 ./newfangle.sty
14377 \end_layout
14379 \begin_layout Standard
14380 If there does not already exist a variable whose name is stored in 
14381 \begin_inset Flex CharStyle:Code
14382 status collapsed
14384 \begin_layout Plain Layout
14386 \backslash
14387 chunkcount
14388 \end_layout
14390 \end_inset
14392 , then we know we are the first chunk with this name, and then define a
14393  counter.
14395 \end_layout
14397 \begin_layout Standard
14398 Although chunks of the same name share a common counter, they must still
14399  be distinguished.
14400  We use is the internal name of the listing, suffixed by the counter value.
14401  So the first chunk might be 
14402 \begin_inset Flex CharStyle:Code
14403 status collapsed
14405 \begin_layout Plain Layout
14406 something-1
14407 \end_layout
14409 \end_inset
14411  and the second chunk be 
14412 \begin_inset Flex CharStyle:Code
14413 status collapsed
14415 \begin_layout Plain Layout
14416 something-2
14417 \end_layout
14419 \end_inset
14421 , etc.
14422 \end_layout
14424 \begin_layout Standard
14425 We also calculate the name of the previous chunk if we can (before we increment
14426  the chunk counter).
14427  If this is the first chunk of that name, then 
14428 \begin_inset Flex CharStyle:Code
14429 status collapsed
14431 \begin_layout Plain Layout
14433 \backslash
14434 prevchunkname
14435 \end_layout
14437 \end_inset
14439  is set to 
14440 \begin_inset Flex CharStyle:Code
14441 status collapsed
14443 \begin_layout Plain Layout
14445 \backslash
14446 relax
14447 \end_layout
14449 \end_inset
14451  which the noweb package will interpret as not existing.
14452 \end_layout
14454 \begin_layout Standard
14455 \begin_inset listings
14456 inline false
14457 status open
14459 \begin_layout Plain Layout
14462 \backslash
14464 \backslash
14465 newfangle@caption{%
14466 \end_layout
14468 \begin_layout Plain Layout
14470   
14471 \backslash
14472 edef
14473 \backslash
14474 chunkcount{lst-chunk-
14475 \backslash
14476 lst@intname}%
14477 \end_layout
14479 \begin_layout Plain Layout
14481   
14482 \backslash
14483 @ifundefined{
14484 \backslash
14485 chunkcount}{%
14486 \end_layout
14488 \begin_layout Plain Layout
14490     
14491 \backslash
14492 expandafter
14493 \backslash
14494 gdef
14495 \backslash
14496 csname 
14497 \backslash
14498 chunkcount
14499 \backslash
14500 endcsname{0}%
14501 \end_layout
14503 \begin_layout Plain Layout
14505     
14506 \backslash
14507 setcounter{newfangle@chunkcounter}{
14508 \backslash
14509 csname 
14510 \backslash
14511 chunkcount
14512 \backslash
14513 endcsname}%
14514 \end_layout
14516 \begin_layout Plain Layout
14518     
14519 \backslash
14521 \backslash
14522 prevchunkname
14523 \backslash
14524 relax%
14525 \end_layout
14527 \begin_layout Plain Layout
14529   }{%
14530 \end_layout
14532 \begin_layout Plain Layout
14534     
14535 \backslash
14536 setcounter{newfangle@chunkcounter}{
14537 \backslash
14538 csname 
14539 \backslash
14540 chunkcount
14541 \backslash
14542 endcsname}%
14543 \end_layout
14545 \begin_layout Plain Layout
14547     
14548 \backslash
14549 edef
14550 \backslash
14551 prevchunkname{
14552 \backslash
14553 lst@intname-
14554 \backslash
14555 arabic{newfangle@chunkcounter}}%
14556 \end_layout
14558 \begin_layout Plain Layout
14560   }%
14561 \end_layout
14563 \end_inset
14566 \end_layout
14568 \begin_layout Standard
14569 After incrementing the chunk counter, we then define the name of this chunk,
14570  as well as the name of the first chunk.
14571 \end_layout
14573 \begin_layout Standard
14574 \begin_inset listings
14575 inline false
14576 status open
14578 \begin_layout Plain Layout
14580   
14581 \backslash
14582 addtocounter{newfangle@chunkcounter}{1}%
14583 \end_layout
14585 \begin_layout Plain Layout
14587   
14588 \backslash
14589 global
14590 \backslash
14591 expandafter
14592 \backslash
14593 edef
14594 \backslash
14595 csname 
14596 \backslash
14597 chunkcount
14598 \backslash
14599 endcsname{
14600 \backslash
14601 arabic{newfangle@chunkcounter}}%
14602 \end_layout
14604 \begin_layout Plain Layout
14606   
14607 \backslash
14608 edef
14609 \backslash
14610 chunkname{
14611 \backslash
14612 lst@intname-
14613 \backslash
14614 arabic{newfangle@chunkcounter}}%
14615 \end_layout
14617 \begin_layout Plain Layout
14619   
14620 \backslash
14621 edef
14622 \backslash
14623 firstchunkname{
14624 \backslash
14625 lst@intname-1}%
14626 \end_layout
14628 \end_inset
14631 \end_layout
14633 \begin_layout Standard
14634 We now need to calculate the name of the next chunk.
14635  We do this by temporarily skipping the counter on by one; however there
14636  may not actually be another chunk with this name! We detect this by also
14637  defining a label for each chunk based on the chunkname.
14638  If there is a next chunkname then it will define a label with that name.
14639  As labels are persistent, we can at least tell the second time LaTeX is
14640  run.
14641  If we don't find such a defined label then we define 
14642 \begin_inset Flex CharStyle:Code
14643 status collapsed
14645 \begin_layout Plain Layout
14647 \backslash
14648 nextchunkname
14649 \end_layout
14651 \end_inset
14653  to 
14654 \begin_inset Flex CharStyle:Code
14655 status collapsed
14657 \begin_layout Plain Layout
14659 \backslash
14660 relax
14661 \end_layout
14663 \end_inset
14666 \end_layout
14668 \begin_layout Standard
14669 \begin_inset listings
14670 inline false
14671 status open
14673 \begin_layout Plain Layout
14675   
14676 \backslash
14677 addtocounter{newfangle@chunkcounter}{1}%
14678 \end_layout
14680 \begin_layout Plain Layout
14682   
14683 \backslash
14684 edef
14685 \backslash
14686 nextchunkname{
14687 \backslash
14688 lst@intname-
14689 \backslash
14690 arabic{newfangle@chunkcounter}}%
14691 \end_layout
14693 \begin_layout Plain Layout
14695   
14696 \backslash
14697 @ifundefined{r@label-
14698 \backslash
14699 nextchunkname}{
14700 \backslash
14702 \backslash
14703 nextchunkname
14704 \backslash
14705 relax}{}%
14706 \end_layout
14708 \end_inset
14711 \end_layout
14713 \begin_layout Standard
14714 The noweb package requires that we define a 
14715 \begin_inset Flex CharStyle:Code
14716 status collapsed
14718 \begin_layout Plain Layout
14720 \backslash
14721 sublabel
14722 \end_layout
14724 \end_inset
14726  for every chunk, with a unique name, which is then used to print out it's
14727  navigation hints.
14728 \end_layout
14730 \begin_layout Standard
14731 We also define a regular label for this chunk, as was mentioned above when
14732  we calculated 
14733 \begin_inset Flex CharStyle:Code
14734 status collapsed
14736 \begin_layout Plain Layout
14738 \backslash
14739 nextchunkname
14740 \end_layout
14742 \end_inset
14745  This requires LaTeX to be run at least twice after new chunk sections are
14746  added --- but noweb requried that anyway.
14747 \end_layout
14749 \begin_layout Standard
14750 \begin_inset listings
14751 inline false
14752 status open
14754 \begin_layout Plain Layout
14756   
14757 \backslash
14758 sublabel{
14759 \backslash
14760 chunkname}%
14761 \end_layout
14763 \begin_layout Plain Layout
14765 % define this label for every chunk instance, so we
14766 \end_layout
14768 \begin_layout Plain Layout
14770 % can tell when we are the last chunk of this name
14771 \end_layout
14773 \begin_layout Plain Layout
14775   
14776 \backslash
14777 label{label-
14778 \backslash
14779 chunkname}%
14780 \end_layout
14782 \end_inset
14785 \end_layout
14787 \begin_layout Standard
14788 We also try and add the chunk to the list of listings, but I'm afraid we
14789  don't do very well.
14790  We want each chunk name listing once, with all of it's references.
14791 \end_layout
14793 \begin_layout Standard
14794 \begin_inset listings
14795 inline false
14796 status open
14798 \begin_layout Plain Layout
14800   
14801 \backslash
14802 addcontentsline{lol}{lstlisting}{
14803 \backslash
14804 lst@name~[
14805 \backslash
14806 protect
14807 \backslash
14808 subpageref{
14809 \backslash
14810 chunkname}]}%
14811 \end_layout
14813 \end_inset
14816 \end_layout
14818 \begin_layout Standard
14819 We then call the noweb output macros in the same way that noweave generates
14820  them, except that we don't need to call 
14821 \begin_inset Flex CharStyle:Code
14822 status collapsed
14824 \begin_layout Plain Layout
14826 \backslash
14827 nwstartdeflinemarkup
14828 \end_layout
14830 \end_inset
14832  or 
14833 \begin_inset Flex CharStyle:Code
14834 status collapsed
14836 \begin_layout Plain Layout
14838 \backslash
14839 nwenddeflinemarkup
14840 \end_layout
14842 \end_inset
14844  -- and if we do it messes up the output somewhat.
14845 \end_layout
14847 \begin_layout Standard
14848 \begin_inset listings
14849 inline false
14850 status open
14852 \begin_layout Plain Layout
14854   
14855 \backslash
14856 nwmargintag{%
14857 \end_layout
14859 \begin_layout Plain Layout
14861     {%
14862 \end_layout
14864 \begin_layout Plain Layout
14866       
14867 \backslash
14868 nwtagstyle{}%
14869 \end_layout
14871 \begin_layout Plain Layout
14873       
14874 \backslash
14875 subpageref{
14876 \backslash
14877 chunkname}%
14878 \end_layout
14880 \begin_layout Plain Layout
14882     }%
14883 \end_layout
14885 \begin_layout Plain Layout
14887   }%
14888 \end_layout
14890 \begin_layout Plain Layout
14893 \end_layout
14895 \begin_layout Plain Layout
14897   
14898 \backslash
14899 moddef{%
14900 \end_layout
14902 \begin_layout Plain Layout
14904     {
14905 \backslash
14906 lst@name}%
14907 \end_layout
14909 \begin_layout Plain Layout
14911     {%
14912 \end_layout
14914 \begin_layout Plain Layout
14916       
14917 \backslash
14918 nwtagstyle{}
14919 \backslash
14921 \end_layout
14923 \begin_layout Plain Layout
14925       
14926 \backslash
14927 @ifundefined{newfangle@chunk@params}{}{%
14928 \end_layout
14930 \begin_layout Plain Layout
14932         (
14933 \backslash
14934 newfangle@chunk@params)%
14935 \end_layout
14937 \begin_layout Plain Layout
14939       }%
14940 \end_layout
14942 \begin_layout Plain Layout
14944       [
14945 \backslash
14946 csname 
14947 \backslash
14948 chunkcount
14949 \backslash
14950 endcsname]~%
14951 \end_layout
14953 \begin_layout Plain Layout
14955       
14956 \backslash
14957 subpageref{
14958 \backslash
14959 firstchunkname}%
14960 \end_layout
14962 \begin_layout Plain Layout
14964     }%
14965 \end_layout
14967 \begin_layout Plain Layout
14969     
14970 \backslash
14971 @ifundefined{newfangle@chunk@append}{}{%
14972 \end_layout
14974 \begin_layout Plain Layout
14976     
14977 \backslash
14978 ifx{}
14979 \backslash
14980 newfangle@chunk@append{x}
14981 \backslash
14982 else%
14983 \end_layout
14985 \begin_layout Plain Layout
14987         ,~add~to~
14988 \backslash
14989 newfangle@chunk@append%
14990 \end_layout
14992 \begin_layout Plain Layout
14994     
14995 \backslash
14997 \end_layout
14999 \begin_layout Plain Layout
15001     }%
15002 \end_layout
15004 \begin_layout Plain Layout
15007 \backslash
15008 global
15009 \backslash
15011 \backslash
15012 newfangle@chunk@append{}%
15013 \end_layout
15015 \begin_layout Plain Layout
15018 \backslash
15019 lstset{append=x}%
15020 \end_layout
15022 \begin_layout Plain Layout
15024   }%
15025 \end_layout
15027 \begin_layout Plain Layout
15030 \end_layout
15032 \begin_layout Plain Layout
15034   
15035 \backslash
15037 \backslash
15038 relax
15039 \backslash
15040 prevchunkname
15041 \backslash
15042 endmoddef
15043 \backslash
15044 else
15045 \backslash
15046 plusendmoddef
15047 \backslash
15049 \end_layout
15051 \begin_layout Plain Layout
15053 %  
15054 \backslash
15055 nwstartdeflinemarkup%
15056 \end_layout
15058 \begin_layout Plain Layout
15060   
15061 \backslash
15062 nwprevnextdefs{
15063 \backslash
15064 prevchunkname}{
15065 \backslash
15066 nextchunkname}%
15067 \end_layout
15069 \begin_layout Plain Layout
15071 %  
15072 \backslash
15073 nwenddeflinemarkup%
15074 \end_layout
15076 \begin_layout Plain Layout
15079 \end_layout
15081 \end_inset
15084 \end_layout
15086 \begin_layout Standard
15087 Originally this was developed as a 
15088 \begin_inset Flex CharStyle:Code
15089 status collapsed
15091 \begin_layout Plain Layout
15092 listings
15093 \end_layout
15095 \end_inset
15097  aspect, in the Init hook, but it was found easier to affect the title without
15098  using a hook --- 
15099 \begin_inset Flex CharStyle:Code
15100 status collapsed
15102 \begin_layout Plain Layout
15104 \backslash
15105 lst@AddToHookExe{PreSet}
15106 \end_layout
15108 \end_inset
15110  is still required to set the listings name to the name passed to the 
15111 \begin_inset Flex CharStyle:Code
15112 status collapsed
15114 \begin_layout Plain Layout
15116 \backslash
15117 Chunk
15118 \end_layout
15120 \end_inset
15122  command, though.
15123 \end_layout
15125 \begin_layout Standard
15126 \begin_inset listings
15127 inline false
15128 status open
15130 \begin_layout Plain Layout
15133 \backslash
15134 lst@BeginAspect{newfangle}
15135 \end_layout
15137 \begin_layout Plain Layout
15140 \backslash
15141 lst@Key{newfangle}{true}[t]{
15142 \backslash
15143 lstKV@SetIf{#1}{true}}
15144 \end_layout
15146 \begin_layout Plain Layout
15149 \backslash
15150 lst@AddToHookExe{PreSet}{
15151 \backslash
15152 global
15153 \backslash
15155 \backslash
15156 lst@intname
15157 \backslash
15158 lst@chunkname}
15159 \end_layout
15161 \begin_layout Plain Layout
15164 \backslash
15165 lst@AddToHook{Init}{}%
15166 \backslash
15167 newfangle@caption}
15168 \end_layout
15170 \begin_layout Plain Layout
15173 \backslash
15174 lst@EndAspect
15175 \end_layout
15177 \end_inset
15180 \end_layout
15182 \begin_layout Subsection
15183 Cross references
15184 \end_layout
15186 \begin_layout Standard
15187 We define the 
15188 \backslash
15189 chunkref command which makes it easy to generate visual references to different
15190  code chunks, e.g.
15191 \end_layout
15193 \begin_layout Standard
15194 \begin_inset Tabular
15195 <lyxtabular version="3" rows="4" columns="2">
15196 <features>
15197 <column alignment="center" valignment="top" width="0">
15198 <column alignment="center" valignment="top" width="0">
15199 <row>
15200 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
15201 \begin_inset Text
15203 \begin_layout Plain Layout
15204 Macro
15205 \end_layout
15207 \end_inset
15208 </cell>
15209 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
15210 \begin_inset Text
15212 \begin_layout Plain Layout
15213 Appearance
15214 \end_layout
15216 \end_inset
15217 </cell>
15218 </row>
15219 <row>
15220 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
15221 \begin_inset Text
15223 \begin_layout Plain Layout
15225 \backslash
15226 chunkref{preamble}
15227 \end_layout
15229 \end_inset
15230 </cell>
15231 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
15232 \begin_inset Text
15234 \begin_layout Plain Layout
15235 \begin_inset ERT
15236 status open
15238 \begin_layout Plain Layout
15241 \backslash
15242 chunkref{preamble}
15243 \end_layout
15245 \end_inset
15248 \end_layout
15250 \end_inset
15251 </cell>
15252 </row>
15253 <row>
15254 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
15255 \begin_inset Text
15257 \begin_layout Plain Layout
15259 \backslash
15260 chunkref[3]{preamble}
15261 \end_layout
15263 \end_inset
15264 </cell>
15265 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
15266 \begin_inset Text
15268 \begin_layout Plain Layout
15269 \begin_inset ERT
15270 status open
15272 \begin_layout Plain Layout
15275 \backslash
15276 chunkref[3]{preamble}
15277 \end_layout
15279 \end_inset
15282 \end_layout
15284 \end_inset
15285 </cell>
15286 </row>
15287 <row>
15288 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
15289 \begin_inset Text
15291 \begin_layout Plain Layout
15293 \backslash
15294 chunkref{preamble}[arg1, arg2]
15295 \end_layout
15297 \end_inset
15298 </cell>
15299 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
15300 \begin_inset Text
15302 \begin_layout Plain Layout
15303 \begin_inset ERT
15304 status open
15306 \begin_layout Plain Layout
15309 \backslash
15310 chunkref{preamble}[arg1, arg2]
15311 \end_layout
15313 \end_inset
15316 \end_layout
15318 \end_inset
15319 </cell>
15320 </row>
15321 </lyxtabular>
15323 \end_inset
15326 \end_layout
15328 \begin_layout Standard
15329 Chunkref can also be used within a code chunk to include another code chunk.
15330  The third optional parameter to chunkref is a comma sepatarated list of
15331  arguments, which will replace defined parameters in the chunkref.
15332 \begin_inset Note Note
15333 status open
15335 \begin_layout Plain Layout
15336 Darn it, if I have: =<
15337 \backslash
15338 chunkref{new-mode-tracker}[{chunks[chunk_name, "language"]},{mode}]> the
15339  inner braces (inside [ ]) cause _ to signify subscript even though we have
15340  lst@ReplaceIn
15341 \end_layout
15343 \end_inset
15346 \end_layout
15348 \begin_layout Standard
15349 \begin_inset listings
15350 inline false
15351 status open
15353 \begin_layout Plain Layout
15356 \backslash
15358 \backslash
15359 chunkref@args#1,{%
15360 \end_layout
15362 \begin_layout Plain Layout
15364   
15365 \backslash
15367 \backslash
15368 arg{#1}%
15369 \end_layout
15371 \begin_layout Plain Layout
15373   
15374 \backslash
15375 lst@ReplaceIn
15376 \backslash
15378 \backslash
15379 lst@filenamerpl%
15380 \end_layout
15382 \begin_layout Plain Layout
15384   
15385 \backslash
15386 arg%
15387 \end_layout
15389 \begin_layout Plain Layout
15391   
15392 \backslash
15393 @ifnextchar){
15394 \backslash
15395 relax}{, 
15396 \backslash
15397 chunkref@args}%
15398 \end_layout
15400 \begin_layout Plain Layout
15403 \end_layout
15405 \begin_layout Plain Layout
15408 \backslash
15409 newcommand
15410 \backslash
15411 chunkref[2][0]{%
15412 \end_layout
15414 \begin_layout Plain Layout
15416   
15417 \backslash
15418 @ifnextchar({
15419 \backslash
15420 chunkref@i{#1}{#2}}{
15421 \backslash
15422 chunkref@i{#1}{#2}()}%
15423 \end_layout
15425 \begin_layout Plain Layout
15428 \end_layout
15430 \begin_layout Plain Layout
15433 \backslash
15435 \backslash
15436 chunkref@i#1#2(#3){%
15437 \end_layout
15439 \begin_layout Plain Layout
15441   
15442 \backslash
15444 \backslash
15445 zero{0}%
15446 \end_layout
15448 \begin_layout Plain Layout
15450   
15451 \backslash
15453 \backslash
15454 chunk{#2}%
15455 \end_layout
15457 \begin_layout Plain Layout
15459   
15460 \backslash
15462 \backslash
15463 chunkno{#1}%
15464 \end_layout
15466 \begin_layout Plain Layout
15468   
15469 \backslash
15471 \backslash
15472 chunkargs{#3}%
15473 \end_layout
15475 \begin_layout Plain Layout
15477   
15478 \backslash
15480 \backslash
15481 chunkno
15482 \backslash
15483 zero%
15484 \end_layout
15486 \begin_layout Plain Layout
15488     
15489 \backslash
15491 \backslash
15492 chunkname{#2-1}%
15493 \end_layout
15495 \begin_layout Plain Layout
15497   
15498 \backslash
15499 else%
15500 \end_layout
15502 \begin_layout Plain Layout
15504     
15505 \backslash
15507 \backslash
15508 chunkname{#2-
15509 \backslash
15510 chunkno}%
15511 \end_layout
15513 \begin_layout Plain Layout
15515   
15516 \backslash
15518 \end_layout
15520 \begin_layout Plain Layout
15522   
15523 \backslash
15525 \backslash
15526 lst@arg
15527 \backslash
15528 chunk%
15529 \end_layout
15531 \begin_layout Plain Layout
15533   
15534 \backslash
15535 lst@ReplaceIn
15536 \backslash
15537 chunk
15538 \backslash
15539 lst@filenamerpl%
15540 \end_layout
15542 \begin_layout Plain Layout
15544   
15545 \backslash
15546 LA{%
15547 \backslash
15548 moddef{%
15549 \end_layout
15551 \begin_layout Plain Layout
15553     {
15554 \backslash
15555 chunk}%
15556 \end_layout
15558 \begin_layout Plain Layout
15560     {%
15561 \end_layout
15563 \begin_layout Plain Layout
15565       
15566 \backslash
15567 nwtagstyle{}
15568 \backslash
15570 \end_layout
15572 \begin_layout Plain Layout
15574       
15575 \backslash
15577 \backslash
15578 chunkno
15579 \backslash
15580 zero%
15581 \end_layout
15583 \begin_layout Plain Layout
15585       
15586 \backslash
15587 else%
15588 \end_layout
15590 \begin_layout Plain Layout
15592       [
15593 \backslash
15594 chunkno]%
15595 \end_layout
15597 \begin_layout Plain Layout
15599       
15600 \backslash
15602 \end_layout
15604 \begin_layout Plain Layout
15606       
15607 \backslash
15609 \backslash
15610 chunkargs
15611 \backslash
15612 empty%
15613 \end_layout
15615 \begin_layout Plain Layout
15617       
15618 \backslash
15619 else%
15620 \end_layout
15622 \begin_layout Plain Layout
15624         (
15625 \backslash
15626 chunkref@args #3,)%
15627 \end_layout
15629 \begin_layout Plain Layout
15631       
15632 \backslash
15634 \end_layout
15636 \begin_layout Plain Layout
15638       ~
15639 \backslash
15640 subpageref{
15641 \backslash
15642 chunkname}%
15643 \end_layout
15645 \begin_layout Plain Layout
15647     }%
15648 \end_layout
15650 \begin_layout Plain Layout
15652   }%
15653 \end_layout
15655 \begin_layout Plain Layout
15657   
15658 \backslash
15660 \backslash
15661 endmoddef%
15662 \end_layout
15664 \begin_layout Plain Layout
15667 \end_layout
15669 \end_inset
15672 \end_layout
15674 \begin_layout Subsection
15675 The end
15676 \end_layout
15678 \begin_layout Standard
15679 \begin_inset listings
15680 inline false
15681 status open
15683 \begin_layout Plain Layout
15686 \end_layout
15688 \begin_layout Plain Layout
15691 \backslash
15692 makeatother
15693 \end_layout
15695 \end_inset
15698 \end_layout
15700 \begin_layout Chapter
15701 Extracting newfangle
15702 \end_layout
15704 \begin_layout Section
15705 Extracting from Lyx
15706 \end_layout
15708 \begin_layout Standard
15709 To extract from LyX, you will need to configure LyX as explained in section
15711 \begin_inset CommandInset ref
15712 LatexCommand ref
15713 reference "sub:Configuring-the-build"
15715 \end_inset
15718 \end_layout
15720 \begin_layout Standard
15721 \begin_inset CommandInset label
15722 LatexCommand label
15723 name "lyx-build-script"
15725 \end_inset
15727 And this lyx-build scrap will extract newfangle for me.
15728 \end_layout
15730 \begin_layout Chunk
15731 lyx-build,language=sh
15732 \end_layout
15734 \begin_layout Standard
15735 \begin_inset listings
15736 inline false
15737 status open
15739 \begin_layout Plain Layout
15741 #! /bin/sh
15742 \end_layout
15744 \begin_layout Plain Layout
15746 set -x
15747 \end_layout
15749 \begin_layout Plain Layout
15751 \end_layout
15753 \begin_layout Plain Layout
15756 \backslash
15757 chunkref{lyx-build-helper}>
15758 \end_layout
15760 \begin_layout Plain Layout
15762 cd $PROJECT_DIR || exit 1
15763 \end_layout
15765 \begin_layout Plain Layout
15767 \end_layout
15769 \begin_layout Plain Layout
15771 /usr/local/bin/newfangle -R./newfangle $TEX_SRC > ./newfangle
15772 \end_layout
15774 \begin_layout Plain Layout
15776 /usr/local/bin/newfangle -R./newfangle.module $TEX_SRC > ./newfangle.module
15777 \end_layout
15779 \begin_layout Plain Layout
15781 \end_layout
15783 \begin_layout Plain Layout
15786 \backslash
15787 chunkref{test:helpers}>
15788 \end_layout
15790 \begin_layout Plain Layout
15792 export NEWFANGLE=./newfangle
15793 \end_layout
15795 \begin_layout Plain Layout
15797 export TMP=${TMP:-/tmp}
15798 \end_layout
15800 \begin_layout Plain Layout
15803 \backslash
15804 chunkref{test:run-tests}>
15805 \end_layout
15807 \begin_layout Plain Layout
15809 # Now check that we can extract a newfangle that also passes the tests!
15810 \end_layout
15812 \begin_layout Plain Layout
15814 $NEWFANGLE -R./newfangle $TEX_SRC > ./new-newfangle
15815 \end_layout
15817 \begin_layout Plain Layout
15819 export NEWFANGLE=./new-newfangle
15820 \end_layout
15822 \begin_layout Plain Layout
15825 \backslash
15826 chunkref{test:run-tests}>
15827 \end_layout
15829 \end_inset
15832 \end_layout
15834 \begin_layout Chunk
15835 test:run-tests
15836 \end_layout
15838 \begin_layout Standard
15839 \begin_inset listings
15840 inline false
15841 status open
15843 \begin_layout Plain Layout
15845 # run tests
15846 \end_layout
15848 \begin_layout Plain Layout
15850 $NEWFANGLE -Rpca-test.awk $TEX_SRC | awk -f - || exit 1
15851 \end_layout
15853 \begin_layout Plain Layout
15856 \backslash
15857 chunkref{test:cromulence}>
15858 \end_layout
15860 \begin_layout Plain Layout
15863 \backslash
15864 chunkref{test:escapes}>
15865 \end_layout
15867 \begin_layout Plain Layout
15870 \backslash
15871 chunkref{test:chunk-params}>
15872 \end_layout
15874 \end_inset
15877 \end_layout
15879 \begin_layout Standard
15880 With a lyx-build-helper
15881 \end_layout
15883 \begin_layout Chunk
15884 lyx-build-helper,language=sh
15885 \end_layout
15887 \begin_layout Standard
15888 \begin_inset listings
15889 inline false
15890 status open
15892 \begin_layout Plain Layout
15894 PROJECT_DIR="$LYX_r"
15895 \end_layout
15897 \begin_layout Plain Layout
15899 LYX_SRC="$PROJECT_DIR/${LYX_i%.tex}.lyx"
15900 \end_layout
15902 \begin_layout Plain Layout
15904 TEX_DIR="$LYX_p"
15905 \end_layout
15907 \begin_layout Plain Layout
15909 TEX_SRC="$TEX_DIR/$LYX_i"
15910 \end_layout
15912 \end_inset
15915 \end_layout
15917 \begin_layout Section
15918 Extracting documentation
15919 \end_layout
15921 \begin_layout Chunk
15922 ./gen-www
15923 \end_layout
15925 \begin_layout Standard
15926 \begin_inset listings
15927 inline false
15928 status open
15930 \begin_layout Plain Layout
15932 #python -m elyxer --css lyx.css $LYX_SRC | 
15933 \backslash
15935 \end_layout
15937 \begin_layout Plain Layout
15939 #  iconv -c -f utf-8 -t ISO-8859-1//TRANSLIT | 
15940 \backslash
15942 \end_layout
15944 \begin_layout Plain Layout
15946 #  sed 's/UTF-8"
15947 \backslash
15949 \backslash
15950 )>/ISO-8859-1"
15951 \backslash
15952 1>/' > www/docs/newfangle.html
15953 \end_layout
15955 \begin_layout Plain Layout
15957 \end_layout
15959 \begin_layout Plain Layout
15961 ( mkdir -p www/docs/newfangle && cd www/docs/newfangle && 
15962 \backslash
15964 \end_layout
15966 \begin_layout Plain Layout
15968   lyx -e latex ../../../newfangle.lyx && 
15969 \backslash
15971 \end_layout
15973 \begin_layout Plain Layout
15975   htlatex ../../../newfangle.tex "xhtml,fn-in" && 
15976 \backslash
15978 \end_layout
15980 \begin_layout Plain Layout
15982   sed -i -e 's/<!--l
15983 \backslash
15985  [0-9][0-9]* *-->//g' newfangle.html
15986 \end_layout
15988 \begin_layout Plain Layout
15991 \end_layout
15993 \begin_layout Plain Layout
15995 \end_layout
15997 \begin_layout Plain Layout
15999 ( mkdir -p www/docs/literate && cd www/docs/literate && 
16000 \backslash
16002 \end_layout
16004 \begin_layout Plain Layout
16006   lyx -e latex ../../../literate.lyx && 
16007 \backslash
16009 \end_layout
16011 \begin_layout Plain Layout
16013   htlatex ../../../literate.tex "xhtml,fn-in" && 
16014 \backslash
16016 \end_layout
16018 \begin_layout Plain Layout
16020   sed -i -e 's/<!--l
16021 \backslash
16023  [0-9][0-9]* *-->$//g' literate.html
16024 \end_layout
16026 \begin_layout Plain Layout
16029 \end_layout
16031 \end_inset
16034 \end_layout
16036 \begin_layout Section
16037 Extracting from the command line
16038 \end_layout
16040 \begin_layout Standard
16041 First you will need the tex output, then you can extract:
16042 \end_layout
16044 \begin_layout Chunk
16045 lyx-build-manual,language=sh
16046 \end_layout
16048 \begin_layout Standard
16049 \begin_inset listings
16050 inline false
16051 status open
16053 \begin_layout Plain Layout
16055 lyx -e latex newfangle.lyx
16056 \end_layout
16058 \begin_layout Plain Layout
16060 newfangle -R./newfangle newfangle.tex > ./newfangle
16061 \end_layout
16063 \begin_layout Plain Layout
16065 newfangle -R./newfangle.module newfangle.tex > ./newfangle.module
16066 \end_layout
16068 \end_inset
16071 \end_layout
16073 \begin_layout Section
16074 Testing
16075 \end_layout
16077 \begin_layout Chunk
16078 test:helpers
16079 \end_layout
16081 \begin_layout Standard
16082 \begin_inset listings
16083 inline false
16084 status open
16086 \begin_layout Plain Layout
16088 passtest() {
16089 \end_layout
16091 \begin_layout Plain Layout
16093   if "$@"
16094 \end_layout
16096 \begin_layout Plain Layout
16098   then echo "Passed"
16099 \end_layout
16101 \begin_layout Plain Layout
16103   else echo "Failed"
16104 \end_layout
16106 \begin_layout Plain Layout
16108        return 1
16109 \end_layout
16111 \begin_layout Plain Layout
16113   fi
16114 \end_layout
16116 \begin_layout Plain Layout
16119 \end_layout
16121 \begin_layout Plain Layout
16123 \end_layout
16125 \begin_layout Plain Layout
16127 failtest() {
16128 \end_layout
16130 \begin_layout Plain Layout
16132   if ! "$@"
16133 \end_layout
16135 \begin_layout Plain Layout
16137   then echo "Passed"
16138 \end_layout
16140 \begin_layout Plain Layout
16142   else echo "Failed"
16143 \end_layout
16145 \begin_layout Plain Layout
16147        return 1
16148 \end_layout
16150 \begin_layout Plain Layout
16152   fi
16153 \end_layout
16155 \begin_layout Plain Layout
16158 \end_layout
16160 \end_inset
16163 \end_layout
16165 \begin_layout Part
16166 Tests
16167 \end_layout
16169 \begin_layout Chapter
16170 Chunk Parameters
16171 \end_layout
16173 \begin_layout Chunk
16174 test:chunk-params:sub,language=,params=THING;colour
16175 \end_layout
16177 \begin_layout Standard
16178 \begin_inset listings
16179 inline false
16180 status open
16182 \begin_layout Plain Layout
16184 I see a ${THING},
16185 \end_layout
16187 \begin_layout Plain Layout
16189 a ${THING} of colour ${colour}, 
16190 \end_layout
16192 \begin_layout Plain Layout
16194 and looking closer =<
16195 \backslash
16196 chunkref{test:chunk-params:sub:sub}(${colour})>
16197 \end_layout
16199 \end_inset
16202 \end_layout
16204 \begin_layout Chunk
16205 test:chunk-params:sub:sub,params=colour,language=
16206 \end_layout
16208 \begin_layout Standard
16209 \begin_inset listings
16210 inline false
16211 status open
16213 \begin_layout Plain Layout
16215 a funny shade of ${colour}
16216 \end_layout
16218 \end_inset
16221 \end_layout
16223 \begin_layout Chunk
16224 test:chunk-params:text,language=
16225 \end_layout
16227 \begin_layout Standard
16228 \begin_inset listings
16229 inline false
16230 status open
16232 \begin_layout Plain Layout
16234 What do you see? "=<
16235 \backslash
16236 chunkref{test:chunk-params:sub}(joe, red)>"
16237 \end_layout
16239 \begin_layout Plain Layout
16241 Well, fancy!
16242 \end_layout
16244 \end_inset
16247 \end_layout
16249 \begin_layout Standard
16250 Should generate output:
16251 \end_layout
16253 \begin_layout Chunk
16254 test:chunk-params:result
16255 \end_layout
16257 \begin_layout Standard
16258 \begin_inset listings
16259 inline false
16260 status open
16262 \begin_layout Plain Layout
16264 What do you see? "I see a joe,
16265 \end_layout
16267 \begin_layout Plain Layout
16269                   a joe of colour red, 
16270 \end_layout
16272 \begin_layout Plain Layout
16274                   and looking closer a funny shade of red"
16275 \end_layout
16277 \begin_layout Plain Layout
16279 Well, fancy!
16280 \end_layout
16282 \end_inset
16285 \end_layout
16287 \begin_layout Standard
16288 And this chunk will perform the test:
16289 \end_layout
16291 \begin_layout Chunk
16292 test:chunk-params
16293 \end_layout
16295 \begin_layout Standard
16296 \begin_inset listings
16297 inline false
16298 status open
16300 \begin_layout Plain Layout
16302 $NEWFANGLE -Rtest:chunk-params:result $TEX_SRC > $TMP/answer || exit 1
16303 \end_layout
16305 \begin_layout Plain Layout
16307 $NEWFANGLE -Rtest:chunk-params:text $TEX_SRC > $TMP/result || exit 1
16308 \end_layout
16310 \begin_layout Plain Layout
16312 passtest diff $TMP/answer $TMP/result || (echo test:chunk-params:text failed
16313  ; exit 1)
16314 \end_layout
16316 \end_inset
16319 \end_layout
16321 \end_body
16322 \end_document