Add feature list
[newfangle.git] / newfangle.lyx
blob879ccc467d07d5e8e60dda490b39aa59cd7f76f2
1 #LyX 1.6.4 created this file. For more info see http://www.lyx.org/
2 \lyxformat 345
3 \begin_document
4 \begin_header
5 \textclass book
6 \begin_preamble
7 %\usepackage{xcolor}
8 %\definecolor{darkgreen}{rgb}{0,0.5,0}
9 \lstset{numbers=left, stepnumber=1, numbersep=5pt, breaklines=false,
10 basicstyle=\footnotesize\ttfamily,
11 %keywordstyle=\color{darkgreen},
12 numberstyle=\tiny,language=C,columns=fullflexible,
13 numberfirstline=true}
14 \end_preamble
15 \use_default_options true
16 \begin_modules
17 logicalmkup
18 newfangle
19 \end_modules
20 \language english
21 \inputencoding auto
22 \font_roman default
23 \font_sans default
24 \font_typewriter default
25 \font_default_family default
26 \font_sc false
27 \font_osf false
28 \font_sf_scale 100
29 \font_tt_scale 100
31 \graphics default
32 \paperfontsize default
33 \spacing single
34 \use_hyperref true
35 \pdf_title "Newfangle"
36 \pdf_author "Sam Liddicott"
37 \pdf_subject "Literate Programing"
38 \pdf_keywords "notangle noweb noweave literate programming cweb"
39 \pdf_bookmarks true
40 \pdf_bookmarksnumbered false
41 \pdf_bookmarksopen false
42 \pdf_bookmarksopenlevel 1
43 \pdf_breaklinks false
44 \pdf_pdfborder false
45 \pdf_colorlinks true
46 \pdf_backref false
47 \pdf_pdfusetitle true
48 \papersize default
49 \use_geometry false
50 \use_amsmath 1
51 \use_esint 1
52 \cite_engine basic
53 \use_bibtopic false
54 \paperorientation portrait
55 \secnumdepth 3
56 \tocdepth 3
57 \paragraph_separation skip
58 \defskip medskip
59 \quotes_language english
60 \papercolumns 1
61 \papersides 1
62 \paperpagestyle default
63 \tracking_changes false
64 \output_changes false
65 \author "" 
66 \author "" 
67 \end_header
69 \begin_body
71 \begin_layout Title
72 newfangle
73 \end_layout
75 \begin_layout Author
76 Sam Liddicott
77 \end_layout
79 \begin_layout Date
80 August 2009
81 \end_layout
83 \begin_layout Chapter*
84 Introduction
85 \end_layout
87 \begin_layout Standard
89 \noun on
90 Newfangle
91 \noun default
92  is a tool for newfangled literate programming.
93  Newfangled is defined as 
94 \emph on
95 New and often needlessly novel
96 \emph default
97  by 
98 \noun on
99 TheFreeDictionary.com
100 \noun default
102 \end_layout
104 \begin_layout Standard
105 In this case, newfangled means yet another new and improved method for literate
106  programming.
107 \end_layout
109 \begin_layout Standard
111 \noun on
112 Literate Programming
113 \noun default
114  has a long history starting with the great 
115 \noun on
116 Donald Knuth
117 \noun default
118  himself, whose literate programming tools seem to make use of as many escape
119  sequences for semantic markup as TeX itself.
120 \end_layout
122 \begin_layout Standard
124 \noun on
125 Norman Ramsey
126 \noun default
127  wrote the 
128 \noun on
129 noweb
130 \noun default
131  set of tools (notangle, noweave and noroots) and helpfully reduced the
132  amount of magic character sequences to pretty much just 
133 \begin_inset Flex CharStyle:Code
134 status collapsed
136 \begin_layout Plain Layout
138 \end_layout
140 \end_inset
142  and 
143 \begin_inset Flex CharStyle:Code
144 status collapsed
146 \begin_layout Plain Layout
148 \end_layout
150 \end_inset
152 , and in doing so brought the wonders of literate programming within my
153  reach.
154 \end_layout
156 \begin_layout Standard
157 While using the LyX editor for LaTeX editing I had various troubles with
158  the noweb tools, some of which were my fault, some of which were noweb's
159  fault and some of which were LyX's fault.
160 \end_layout
162 \begin_layout Standard
164 \noun on
165 Noweb
166 \noun default
167  generally brought literate programming to the masses through removing some
168  of the complexity of the original literate programming, but this would
169  be of no advantage to me if the LyX / LaTeX combination brought more complicati
170 ons in their place.
171 \end_layout
173 \begin_layout Standard
175 \noun on
176 Newfangle
177 \noun default
178  was thus born --- as an awk replacement for notangle, adding some important
179  features, like better integration with LyX and LaTeX, multiple output format
180  conversions, and fixing notangle bugs like indentation when using -L for
181  line numbers.
182 \end_layout
184 \begin_layout Standard
185 Significantly, newfangle is just one program which replaces various programs
186  in Noweb.
187  Noweave is done away with and implemented directly as LaTeX macros, and
188  noroots is implemented as a function of the untangler 
189 \noun on
190 newfangle
191 \noun default
193 \end_layout
195 \begin_layout Standard
196 Newfangle is written in awk for portability reasons, awk being available
197  for most platforms.
198  A python conversion will probably be attempted for the benefit of LyX.
199  (Hasn't anyone implemented awk in python yet?)
200 \end_layout
202 \begin_layout Standard
203 As an extension to many literate-programming styles, Newfangle permits code
204  chunks to take parameters and thus operate somewhat like C pre-processor
205  macros, or like C++ templates.
206 \end_layout
208 \begin_layout Section*
209 Todo
210 \end_layout
212 \begin_layout Enumerate
213 ^^ is always going to be a problem, see texbytopic 1.2.2 (Work out what I
214  meant by this).
215 \end_layout
217 \begin_layout Enumerate
218 copy over up to date Makefile guide from noweb-lyx document
219 \end_layout
221 \begin_layout Enumerate
222 Make chunk-name settings only apply to chunks with that name
223 \end_layout
225 \begin_layout Enumerate
226 indent of multi-line chunks may be mode dependant (i.e.
227  not in string literals)
228 \end_layout
230 \begin_layout Enumerate
231 add support for other commands in =<...>, starting with 
232 \backslash
233 label which takes the line-number within the chunk, and maybe should also
234  take the chunk name/page
235 \end_layout
237 \begin_layout Enumerate
238 cant have listing inside a ruled box
239 \end_layout
241 \begin_layout Enumerate
242 when a parameterized chunk is included as well as the #line emission, say
243  what the paremeters were for that invocation.
244 \end_layout
246 \begin_layout Enumerate
248 \backslash
249 chunkref[3]{preamble} to include a certain chunk needs to work in newfangle.awk
250  instead of failing to be recognized at all
251 \end_layout
253 \begin_layout Enumerate
254 make in-listins labels track the chunk ref too, and make 
255 \backslash
256 chunref{[2],thing}> resolve to 41c (or d, or whatever chunk the 2nd chunk
257  of thing is
258 \end_layout
260 \begin_layout Enumerate
262 \backslash
263 chunkref in text needs a trailing space maybe, it keeps butting up to the
264  next word
265 \end_layout
267 \begin_layout Enumerate
268 because the white-space indent is output by the parent chunk, the #line
269  is that of the parent chunk.
270  White space indents must be passed to the child chunk
271 \end_layout
273 \begin_layout Chapter*
274 License
275 \end_layout
277 \begin_layout Standard
278 \begin_inset CommandInset label
279 LatexCommand label
280 name "cha:License"
282 \end_inset
284 Newfangle is licensed under the GPL 3
285 \begin_inset CommandInset citation
286 LatexCommand cite
287 key "gpl-licenses"
289 \end_inset
291  (or later).
292  This doesn't mean that you can't use or distribute newfangle with sources
293  of an incompatible license, but it means you must make the source of newfangle
294  available too.
295 \end_layout
297 \begin_layout Chunk
298 gpl3-copyright,language=
299 \end_layout
301 \begin_layout Standard
302 \begin_inset listings
303 inline false
304 status open
306 \begin_layout Plain Layout
308 newfangle - fully featured notangle replacement in awk
309 \end_layout
311 \begin_layout Plain Layout
313 \end_layout
315 \begin_layout Plain Layout
317 Copyright (C) Sam Liddicott 2009
318 \end_layout
320 \begin_layout Plain Layout
322 \end_layout
324 \begin_layout Plain Layout
326 This program is free software: you can redistribute it and/or modify
327 \end_layout
329 \begin_layout Plain Layout
331 it under the terms of the GNU General Public License as published by
332 \end_layout
334 \begin_layout Plain Layout
336 the Free Software Foundation, either version 3 of the License, or
337 \end_layout
339 \begin_layout Plain Layout
341 (at your option) any later version.
342 \end_layout
344 \begin_layout Plain Layout
346 \end_layout
348 \begin_layout Plain Layout
350 This program is distributed in the hope that it will be useful,
351 \end_layout
353 \begin_layout Plain Layout
355 but WITHOUT ANY WARRANTY; without even the implied warranty of
356 \end_layout
358 \begin_layout Plain Layout
360 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
361   See the
362 \end_layout
364 \begin_layout Plain Layout
366 GNU General Public License for more details.
367 \end_layout
369 \begin_layout Plain Layout
371 \end_layout
373 \begin_layout Plain Layout
375 You should have received a copy of the GNU General Public License
376 \end_layout
378 \begin_layout Plain Layout
380 along with this program.
381   If not, see <http://www.gnu.org/licenses/>.
382 \end_layout
384 \begin_layout Plain Layout
386 \end_layout
388 \end_inset
391 \end_layout
393 \begin_layout Standard
394 \begin_inset CommandInset toc
395 LatexCommand tableofcontents
397 \end_inset
400 \end_layout
402 \begin_layout Part
403 Using Newfangle
404 \end_layout
406 \begin_layout Chapter
407 Running Newfangle
408 \end_layout
410 \begin_layout Standard
411 Newfangle is a replacement for noweb, which consists of 
412 \begin_inset Flex CharStyle:Code
413 status collapsed
415 \begin_layout Plain Layout
416 notangle
417 \end_layout
419 \end_inset
422 \begin_inset Flex CharStyle:Code
423 status collapsed
425 \begin_layout Plain Layout
426 noroots
427 \end_layout
429 \end_inset
431  and 
432 \begin_inset Flex CharStyle:Code
433 status collapsed
435 \begin_layout Plain Layout
436 noweave
437 \end_layout
439 \end_inset
442 \end_layout
444 \begin_layout Standard
445 Like 
446 \begin_inset Flex CharStyle:Code
447 status collapsed
449 \begin_layout Plain Layout
450 notangle
451 \end_layout
453 \end_inset
455  and 
456 \begin_inset Flex CharStyle:Code
457 status collapsed
459 \begin_layout Plain Layout
460 noroots
461 \end_layout
463 \end_inset
465  it can read multiple named files, or from stdin.
466 \end_layout
468 \begin_layout Section
469 Listing roots
470 \end_layout
472 \begin_layout Standard
473 The -r option causes newfangle to behave like noroots.
474 \end_layout
476 \begin_layout LyX-Code
477 newfangle -r filename.tex
478 \end_layout
480 \begin_layout Standard
481 will print out the newfangle roots of a tex file.
483 \end_layout
485 \begin_layout Standard
486 Unlike the 
487 \begin_inset Flex CharStyle:Code
488 status collapsed
490 \begin_layout Plain Layout
491 noroots
492 \end_layout
494 \end_inset
496  command, the roots are not enclosed in 
497 \begin_inset Flex CharStyle:Code
498 status collapsed
500 \begin_layout Plain Layout
501 <<name>>
502 \end_layout
504 \end_inset
506 , unless at least one of the roots is defined using the 
507 \begin_inset Flex CharStyle:Code
508 status collapsed
510 \begin_layout Plain Layout
511 notangle
512 \end_layout
514 \end_inset
516  style 
517 \begin_inset Flex CharStyle:Code
518 status collapsed
520 \begin_layout Plain Layout
521 <<name>>=
522 \end_layout
524 \end_inset
527 \end_layout
529 \begin_layout Standard
530 Also, unlike noroots, it prints out all roots --- not just those that are
531  not used elsewhere.
532  I find that a root not being used, doesn't make it particularly top level.
533  My convention is that top level roots to be extracted begin with 
534 \begin_inset Flex CharStyle:Code
535 status collapsed
537 \begin_layout Plain Layout
539 \end_layout
541 \end_inset
543  and have the form of a filename.
544 \end_layout
546 \begin_layout Section
547 Extracting roots
548 \end_layout
550 \begin_layout Standard
551 notangle's 
552 \begin_inset Flex CharStyle:Code
553 status collapsed
555 \begin_layout Plain Layout
557 \end_layout
559 \end_inset
561  and 
562 \begin_inset Flex CharStyle:Code
563 status collapsed
565 \begin_layout Plain Layout
567 \end_layout
569 \end_inset
571  options are supported.
572 \end_layout
574 \begin_layout Standard
575 The standard way to extract a file would be:
576 \end_layout
578 \begin_layout LyX-Code
579 newfangle -R./Makefile.inc newfangle.tex > ./Makefile.inc
580 \end_layout
582 \begin_layout Standard
583 Unlike the 
584 \begin_inset Flex CharStyle:Code
585 status collapsed
587 \begin_layout Plain Layout
588 noroots
589 \end_layout
591 \end_inset
593  command, the 
594 \begin_inset Flex CharStyle:Code
595 status collapsed
597 \begin_layout Plain Layout
599 \end_layout
601 \end_inset
603  option does not break indenting; also the 
604 \begin_inset Flex CharStyle:Code
605 status collapsed
607 \begin_layout Plain Layout
609 \end_layout
611 \end_inset
613  option does not interrupt (and break) multi-line C macros --- or indeed
614  any line ending with a backslash.
615  This does mean that sometimes the compiler might calculate the source line
616  wrongly when generating error messages in such cases, but there isn't any
617  other way around if multi-line macros include other chunks.
618 \end_layout
620 \begin_layout Section
621 Formatting source in LaTeX
622 \end_layout
624 \begin_layout Standard
625 The noweave replacement is a set of LaTeX macros dependant upon 
626 \emph on
627 noweb.sty
628 \emph default
629 , and which can be included with:
630 \end_layout
632 \begin_layout LyX-Code
634 \backslash
635 usepackage{newfangle.sty}
636 \end_layout
638 \begin_layout Standard
639 The LaTeX macros are shown in section 
640 \begin_inset CommandInset ref
641 LatexCommand ref
642 reference "sec:Latex-Macros"
644 \end_inset
646 , and are part of a LyX module file 
647 \begin_inset Flex CharStyle:Code
648 status collapsed
650 \begin_layout Plain Layout
651 newfangle.module
652 \end_layout
654 \end_inset
656 , which automatically includes the macros in the document pre-amble when
657  the newfangle LyX module is used.
658 \end_layout
660 \begin_layout Standard
661 Because the noweave replacement is impemented in LaTeX, there is no processing
662  stage required before running the 
663 \begin_inset Flex CharStyle:Code
664 status collapsed
666 \begin_layout Plain Layout
667 latex
668 \end_layout
670 \end_inset
672  command.
673  LaTeX may need running two or more times, so that the code chunk references
674  can be fully calculated.
675 \end_layout
677 \begin_layout Standard
678 The 
679 \begin_inset Flex CharStyle:Code
680 status collapsed
682 \begin_layout Plain Layout
683 noweb.sty
684 \end_layout
686 \end_inset
688  package is required as it is used for formatting the code chunk captions
689 \end_layout
691 \begin_layout Standard
692 The 
693 \begin_inset Flex CharStyle:Code
694 status collapsed
696 \begin_layout Plain Layout
697 listings.sty
698 \end_layout
700 \end_inset
702  package is also required, as it is used for formatting the code chunks
703  themselves.
704 \end_layout
706 \begin_layout Standard
707 The 
708 \begin_inset Flex CharStyle:Code
709 status collapsed
711 \begin_layout Plain Layout
712 xargs.sty
713 \end_layout
715 \end_inset
717  package is also required.
718 \end_layout
720 \begin_layout Chapter
721 Literate Programming with Newfangle
722 \end_layout
724 \begin_layout Standard
725 Todo.
726  Should really follow on from a part-0 explanation of what literate programming
727  is.
728 \end_layout
730 \begin_layout Chapter
731 Using Newfangle with LyX
732 \end_layout
734 \begin_layout Section
735 Setting up Lyx
736 \end_layout
738 \begin_layout Subsection
739 Installing the LyX module
740 \end_layout
742 \begin_layout Standard
743 Copy 
744 \begin_inset Flex CharStyle:Code
745 status collapsed
747 \begin_layout Plain Layout
748 newfangle.module
749 \end_layout
751 \end_inset
753  to your LyX layouts directory, which for unix users will be 
754 \begin_inset Flex CharStyle:Code
755 status collapsed
757 \begin_layout Plain Layout
758 ~/.lyx/layouts
759 \end_layout
761 \end_inset
764 \end_layout
766 \begin_layout Standard
767 You will need to reconfigure LyX by clicking Tools\SpecialChar \menuseparator
768 Reconfigure, and then
769  re-start LyX.
770 \end_layout
772 \begin_layout Subsection
773 \begin_inset CommandInset label
774 LatexCommand label
775 name "sub:Configuring-the-build"
777 \end_inset
779 Configuring the build script
780 \end_layout
782 \begin_layout Standard
783 Make sure you don't have a conversion defined for Lyx → Program
784 \end_layout
786 \begin_layout Standard
787 From the menu Tools\SpecialChar \menuseparator
788 Preferences, add a conversion from Latex(Plain) → Program
789  as:
790 \end_layout
792 \begin_layout LyX-Code
793 set -x ; newfangle -Rlyx-build $$i | 
794 \end_layout
796 \begin_layout LyX-Code
797   env LYX_b=$$b LYX_i=$$i LYX_o=$$o LYX_p=$$p LYX_r=$$r bash
798 \end_layout
800 \begin_layout Standard
801 (But don't cut-n-paste it from this document or you'll be pasting a multi-line
802  string which will break your lyx preferences file).
804 \end_layout
806 \begin_layout Standard
807 I hope that one day, LyX will set these into the environment when calling
808  the build script.
809 \end_layout
811 \begin_layout Standard
812 You may also want to consider adding options to this conversion\SpecialChar \ldots{}
814 \end_layout
816 \begin_layout LyX-Code
817 parselog=/usr/share/lyx/scripts/listerrors
818 \end_layout
820 \begin_layout Standard
821 \SpecialChar \ldots{}
822 but if you do you will lose your stderr
823 \begin_inset Foot
824 status collapsed
826 \begin_layout Plain Layout
827 There is some bash plumbing to get a copy of stderr but this footnote is
828  too small
829 \end_layout
831 \end_inset
834 \end_layout
836 \begin_layout Standard
837 Now, a shell script chunk called 
838 \begin_inset Flex CharStyle:Code
839 status collapsed
841 \begin_layout Plain Layout
842 lyx-build
843 \end_layout
845 \end_inset
847  will be extracted and run whenever you choose the Document\SpecialChar \menuseparator
848 Build Program
849  menu item.
850 \end_layout
852 \begin_layout Standard
853 The lyx-build script for this document is in section 
854 \begin_inset CommandInset ref
855 LatexCommand ref
856 reference "lyx-build-script"
858 \end_inset
860  and on a unix system will extract 
861 \begin_inset Flex CharStyle:Code
862 status collapsed
864 \begin_layout Plain Layout
865 newfangle.module
866 \end_layout
868 \end_inset
870  and the 
871 \begin_inset Flex CharStyle:Code
872 status collapsed
874 \begin_layout Plain Layout
875 newfangle
876 \end_layout
878 \end_inset
880  awk script.
881 \end_layout
883 \begin_layout Subsection
884 Preparing your Lyx document
885 \end_layout
887 \begin_layout Standard
888 It is not necessary to base your literate document on any of the original
889  LyX literate classes; so select a regular class for your document type.
890 \end_layout
892 \begin_layout Standard
893 Add the new module 
894 \emph on
895 Newfangle Literate
896 \emph default
898 \emph on
899 Listings
900 \emph default
901  and possibly also 
902 \emph on
903 Logical Markup
904 \emph default
906 \end_layout
908 \begin_layout Standard
909 In the drop-down style listbox you should notice a new style defined, called
911 \emph on
912 Chunk
913 \emph default
915 \end_layout
917 \begin_layout Standard
918 When you wish to insert a literate chunk, you enter it's plain name in the
919  Chunk style, instead of the older method that used 
920 \begin_inset Flex CharStyle:Code
921 status collapsed
923 \begin_layout Plain Layout
924 <<name>>=
925 \end_layout
927 \end_inset
929  type tags.
930  Following the chunk name, you insert a listing with: Insert\SpecialChar \menuseparator
931 Program Listing.
932 \end_layout
934 \begin_layout Standard
935 Inside the white listing box you can type (or paste using shift+ctrl+V)
936  your listing.
937  There is not need to use ctrl+enter at the end of lines as with some older
938  LyX literate techniques --- just press enter as normal.
939 \end_layout
941 \begin_layout Subsubsection
942 Customising the listing appearance
943 \end_layout
945 \begin_layout Standard
946 In the final document, the code is formatted using the 
947 \noun on
948 lstlistings
949 \noun default
950  package.
951  The chunk style doesn't just define the chunk name, but can also define
952  any other chunk options supported by the lstlistings package 
953 \begin_inset Flex CharStyle:Code
954 status collapsed
956 \begin_layout Plain Layout
958 \backslash
959 lstset
960 \end_layout
962 \end_inset
964  command.
965  In fact, what you type in the chunk style is raw latex.
966  If you want to set the chunk language without having to right-click the
967  listing, just add 
968 \begin_inset Flex CharStyle:Code
969 status collapsed
971 \begin_layout Plain Layout
972 ,lanuage=C
973 \end_layout
975 \end_inset
977  after the chunk name.
978 \end_layout
980 \begin_layout Standard
981 Of course you can do this by editing the listings box advanced properties
982  by right-clicking on the listings box, but that takes longer, and you can't
983  see at-a-glance what the advanced settings are while editing the document;
984  also advanced settings apply only to that box --- the chunk settings apply
985  through the rest of the document
986 \begin_inset Foot
987 status collapsed
989 \begin_layout Plain Layout
990 It ought to apply only to subsequent chunks of the same name.
991  I'll fix that later
992 \end_layout
994 \end_inset
997 \begin_inset Note Note
998 status collapsed
1000 \begin_layout Plain Layout
1001 So make sure they only apply to chunks of that name
1002 \end_layout
1004 \end_inset
1007 \end_layout
1009 \begin_layout Subsubsection
1010 Global customisations
1011 \end_layout
1013 \begin_layout Standard
1014 As 
1015 \emph on
1016 lstlistings
1017 \emph default
1018  is used to set the code chunks, it's 
1019 \begin_inset Flex CharStyle:Code
1020 status collapsed
1022 \begin_layout Plain Layout
1024 \backslash
1025 lstset
1026 \end_layout
1028 \end_inset
1030  command can be used in the pre-amble to set some document wide settings.
1031 \end_layout
1033 \begin_layout Standard
1034 If your source has many words with long sequences of capital letters, then
1036 \begin_inset Flex CharStyle:Code
1037 status collapsed
1039 \begin_layout Plain Layout
1040 columns=fullflexible
1041 \end_layout
1043 \end_inset
1045  may be a good idea, or the capital letters will get crowded.
1046  (I think lstlistings ought to use a slightly smaller font for captial letters
1047  so that they still fit).
1048 \end_layout
1050 \begin_layout Standard
1051 The font family 
1052 \begin_inset Flex CharStyle:Code
1053 status collapsed
1055 \begin_layout Plain Layout
1057 \backslash
1058 ttfamily
1059 \end_layout
1061 \end_inset
1063  looks more normal for code, but has no bold (unless luximono is used, but
1064  it doesn't work for me); so I use 
1065 \begin_inset Flex CharStyle:Code
1066 status collapsed
1068 \begin_layout Plain Layout
1070 \backslash
1071 color{darkgreen}
1072 \end_layout
1074 \end_inset
1076  for my keywords.
1077  With 
1078 \begin_inset Flex CharStyle:Code
1079 status collapsed
1081 \begin_layout Plain Layout
1083 \backslash
1084 ttfamily
1085 \end_layout
1087 \end_inset
1090 \begin_inset Flex CharStyle:Code
1091 status collapsed
1093 \begin_layout Plain Layout
1094 columns=fullflexible
1095 \end_layout
1097 \end_inset
1099  is used or the wrong letter spacing is used.
1100 \end_layout
1102 \begin_layout Standard
1103 In my LeTeX pre-amble I usually specialise my code format with:
1104 \end_layout
1106 \begin_layout Chunk
1107 document-preamble,language=tex
1108 \end_layout
1110 \begin_layout Standard
1111 \begin_inset listings
1112 inline false
1113 status open
1115 \begin_layout Plain Layout
1118 \backslash
1119 usepackage{xcolor}
1120 \end_layout
1122 \begin_layout Plain Layout
1125 \backslash
1126 definecolor{darkgreen}{rgb}{0,0.5,0}
1127 \end_layout
1129 \begin_layout Plain Layout
1132 \backslash
1133 lstset{numbers=left, stepnumber=5, numbersep=5pt, breaklines=false,
1134 \end_layout
1136 \begin_layout Plain Layout
1138   basicstyle=
1139 \backslash
1140 footnotesize
1141 \backslash
1142 ttfamily,
1143 \end_layout
1145 \begin_layout Plain Layout
1147   keywordstyle=
1148 \backslash
1149 color{darkgreen},
1150 \end_layout
1152 \begin_layout Plain Layout
1154   numberstyle=
1155 \backslash
1156 tiny,language=C,columns=fullflexible,
1157 \end_layout
1159 \begin_layout Plain Layout
1161   numberfirstline=true
1162 \end_layout
1164 \begin_layout Plain Layout
1167 \end_layout
1169 \end_inset
1172 \end_layout
1174 \begin_layout Chapter
1175 Newfangle with Makefiles
1176 \end_layout
1178 \begin_layout Standard
1179 \begin_inset Note Note
1180 status open
1182 \begin_layout Plain Layout
1183 This chapter needs revising
1184 \end_layout
1186 \end_inset
1189 \begin_inset Note Greyedout
1190 status open
1192 \begin_layout Plain Layout
1193 This chapter needs revising
1194 \end_layout
1196 \end_inset
1198 Here we describe a Makefile.inc that you can include in your own Makefiles,
1199  or glue as a recursive make to other projects.
1200 \end_layout
1202 \begin_layout Standard
1203 The Makefile.inc described here was put together for a Samba4 vfs module,
1204  but can be used in any Make project, including automake projects.
1205 \end_layout
1207 \begin_layout Section
1208 A word about makefiles formats
1209 \end_layout
1211 \begin_layout Standard
1212 Whitespace formatting is very important in a Makefile.
1213  The first character of each command line must be a TAB.
1214 \end_layout
1216 \begin_layout LyX-Code
1217 target: pre-requisite
1218 \begin_inset Newline newline
1219 \end_inset
1221    →    action
1222 \begin_inset Newline newline
1223 \end_inset
1225    →    action
1226 \end_layout
1228 \begin_layout Standard
1229 But a TAB is pretty hard to enter into most of the Lyx formats and insets
1230  I've been using.
1231  An alternative is to use a semi-colon after the pre-requisite, and a backslash
1232  at the end of each line (except the last).
1233  Then any whitespace (or none) can prefix each action.
1234 \end_layout
1236 \begin_layout LyX-Code
1237 target: pre-requisite ; 
1238 \backslash
1240 \begin_inset Newline newline
1241 \end_inset
1243 ␣␣action 
1244 \backslash
1246 \begin_inset Newline newline
1247 \end_inset
1249 ␣␣action
1250 \end_layout
1252 \begin_layout Standard
1253 This is the style that we use and it works pretty well for GNU make at least.
1254 \end_layout
1256 \begin_layout Standard
1257 We also adopt a convention that code chunks whose names beginning with ./
1258  should always be automatically extracted from the document.
1259  Code chunks whose names do not begin with ./ are for internal reference.
1260  (This doesn't prevent such chunks from being extracted directly).
1261 \end_layout
1263 \begin_layout Section
1264 Boot-strapping the extraction
1265 \end_layout
1267 \begin_layout Subsection
1268 Using a Makefile
1269 \end_layout
1271 \begin_layout Standard
1272 \begin_inset CommandInset label
1273 LatexCommand label
1274 name "sub:Bootstrap-Using-a-Makefile"
1276 \end_inset
1278 It seems convenient to have the makefile extract or update the C source
1279  files as part of it's operation.
1280  It also seems convenient to have the makefile itself extracted from this
1281  document.
1282 \end_layout
1284 \begin_layout Standard
1285 It would also be convenient to have the code to extract the makefile from
1286  this document to also be part of this document, however we have to start
1287  somewhere and this unfortunately requires us to type at least a few words
1288  by hand to start things off.
1289 \end_layout
1291 \begin_layout Standard
1292 Therefore we will have a minimal root fragment, which, when extracted, can
1293  cope with extracting the rest of the source.
1294  perhaps with this shell script, which could be called 
1295 \emph on
1296 autoboot
1297 \emph default
1299 \begin_inset Note Note
1300 status open
1302 \begin_layout Plain Layout
1303 FIX THIS CHUNK AND TEST IT
1304 \end_layout
1306 \end_inset
1309 \end_layout
1311 \begin_layout Chunk
1313 \end_layout
1315 \begin_layout Standard
1316 \begin_inset listings
1317 inline false
1318 status open
1320 \begin_layout Plain Layout
1322 #! /bin/sh
1323 \end_layout
1325 \begin_layout Plain Layout
1327 \end_layout
1329 \begin_layout Plain Layout
1331 MAKE_SRC="${1:-${NW_LYX:-../../noweb-lyx/noweb-lyx3.lyx}}"
1332 \end_layout
1334 \begin_layout Plain Layout
1336 MAKE_SRC=`dirname "$MAKE_SRC"`/`basename "$MAKE_SRC" .lyx`
1337 \end_layout
1339 \begin_layout Plain Layout
1341 NOWEB_SRC="${2:-${NOWEB_SRC:-$MAKE_SRC.lyx}}"
1342 \end_layout
1344 \begin_layout Plain Layout
1346 lyx -e latex $MAKE_SRC
1347 \end_layout
1349 \begin_layout Plain Layout
1351 \end_layout
1353 \begin_layout Plain Layout
1355 newfangle -R./Makefile.inc ${MAKE_SRC}.tex 
1356 \backslash
1358 \end_layout
1360 \begin_layout Plain Layout
1362   | sed "/NEWFANGLE_SOURCE=/s/^/#/;T;aNOWEB_SOURCE=$NEWFANGLE_SRC" 
1363 \backslash
1365 \end_layout
1367 \begin_layout Plain Layout
1369   | cpif ./Makefile.inc
1370 \end_layout
1372 \begin_layout Plain Layout
1374 \end_layout
1376 \begin_layout Plain Layout
1378 make -f ./Makefile.inc newfangle_sources
1379 \end_layout
1381 \end_inset
1384 \end_layout
1386 \begin_layout Standard
1387 The general Makefile can be invoked with 
1388 \emph on
1389 ./autoboot
1390 \emph default
1391  and can also be included into any automake file to automatically re-generate
1392  the source files.
1393 \end_layout
1395 \begin_layout Standard
1396 The 
1397 \emph on
1398 autoboot
1399 \emph default
1400  can be extracted with this command:
1401 \end_layout
1403 \begin_layout LyX-Code
1404 lyx -e latex newfangle.lyx && 
1405 \backslash
1407 \end_layout
1409 \begin_layout LyX-Code
1410 newfangle newfangle.lyx > ./autoboot
1411 \end_layout
1413 \begin_layout Standard
1414 This looks simple enough, but as mentioned, newfangle has to be had from
1415  somewhere before it can be extracted.
1416 \end_layout
1418 \begin_layout Subsection
1419 \begin_inset Note Note
1420 status collapsed
1422 \begin_layout Plain Layout
1423 MERGE THIS WITH THE SECTIONS OF THIS DOCUMENT
1424 \end_layout
1426 \end_inset
1428 \SpecialChar \ldots{}
1430 \end_layout
1432 \begin_layout Standard
1433 When the lyx-build chunk is executed, the current directory will be a temporary
1434  directory, and 
1435 \begin_inset Flex CharStyle:Code
1436 status collapsed
1438 \begin_layout Plain Layout
1439 LYX_SOURCE
1440 \end_layout
1442 \end_inset
1444  will refer to the tex file in this temporary directory.
1445  This is unfortunate as our makefile wants to run from the project directory
1446  where the Lyx file is kept.
1447 \end_layout
1449 \begin_layout Standard
1450 We can extract the project directory from $$r, and derive the probable Lyx
1451  filename from the noweb file that Lyx generated.
1452 \end_layout
1454 \begin_layout Chunk
1455 lyx-build-helper
1456 \end_layout
1458 \begin_layout Standard
1459 \begin_inset listings
1460 inline false
1461 status open
1463 \begin_layout Plain Layout
1465 PROJECT_DIR="$LYX_r"
1466 \end_layout
1468 \begin_layout Plain Layout
1470 LYX_SRC="$PROJECT_DIR/${LYX_i%.tex}.lyx"
1471 \end_layout
1473 \begin_layout Plain Layout
1475 TEX_DIR="$LYX_p"
1476 \end_layout
1478 \begin_layout Plain Layout
1480 TEX_SRC="$TEX_DIR/$LYX_i"
1481 \end_layout
1483 \end_inset
1486 \end_layout
1488 \begin_layout Standard
1489 And then we can define a lyx-build fragment similar to the autoboot fragment
1490 \end_layout
1492 \begin_layout Chunk
1493 lyx-build
1494 \end_layout
1496 \begin_layout Standard
1497 \begin_inset listings
1498 inline false
1499 status open
1501 \begin_layout Plain Layout
1503 #! /bin/sh
1504 \end_layout
1506 \begin_layout Plain Layout
1509 \backslash
1510 chunkref{lyx-build-helper}>
1511 \end_layout
1513 \begin_layout Plain Layout
1515 cd $PROJECT_DIR || exit 1
1516 \end_layout
1518 \begin_layout Plain Layout
1520 \end_layout
1522 \begin_layout Plain Layout
1524 #/usr/bin/newfangle -filter ./notanglefix-filter 
1525 \backslash
1527 \end_layout
1529 \begin_layout Plain Layout
1531 #  -R./Makefile.inc "../../noweb-lyx/noweb-lyx3.lyx" 
1532 \backslash
1534 \end_layout
1536 \begin_layout Plain Layout
1538 #  | sed '/NOWEB_SOURCE=/s/=.*/=samba4-dfs.lyx/' 
1539 \backslash
1541 \end_layout
1543 \begin_layout Plain Layout
1545 #  > ./Makefile.inc
1546 \end_layout
1548 \begin_layout Plain Layout
1551 \end_layout
1553 \begin_layout Plain Layout
1555 #make -f ./Makefile.inc newfangle_sources
1556 \end_layout
1558 \end_inset
1561 \end_layout
1563 \begin_layout Section
1564 Extracting Sources
1565 \end_layout
1567 \begin_layout Subsection
1568 Including Makefile.inc
1569 \end_layout
1571 \begin_layout Standard
1572 \begin_inset CommandInset label
1573 LatexCommand label
1574 name "sub:Keeping-extracted-files"
1576 \end_inset
1578 Makefile.inc will cope with extracting all the other source files from this
1579  document and keeping them up to date.
1581 \end_layout
1583 \begin_layout Standard
1584 It may also be included by a Makefile or Makefile.am defined in a Lyx document
1585  to automatically deal with the extraction of source files and documents.
1586 \end_layout
1588 \begin_layout Standard
1589 A makefile has two parts; variables must be defined before the targets that
1590  use them.
1591 \end_layout
1593 \begin_layout Chunk
1594 ./Makefile.inc
1595 \end_layout
1597 \begin_layout Standard
1598 \begin_inset listings
1599 inline false
1600 status open
1602 \begin_layout Plain Layout
1605 \backslash
1606 chunkref{Makefile.inc-vars}>
1607 \end_layout
1609 \begin_layout Plain Layout
1612 \backslash
1613 chunkref{Makefile.inc-targets}>
1614 \end_layout
1616 \end_inset
1619 \end_layout
1621 \begin_layout Standard
1622 We first define 
1623 \begin_inset Flex CharStyle:Code
1624 status collapsed
1626 \begin_layout Plain Layout
1627 NOWEB_SOURCE
1628 \end_layout
1630 \end_inset
1632  to hold the name of this Lyx file.
1633 \end_layout
1635 \begin_layout Chunk
1636 Makefile.inc-vars
1637 \end_layout
1639 \begin_layout Standard
1640 \begin_inset listings
1641 inline false
1642 status open
1644 \begin_layout Plain Layout
1646 LYX_SOURCE=
1647 \end_layout
1649 \begin_layout Plain Layout
1651 LITERATE_SOURCE=$(LYX_SOURCE)
1652 \end_layout
1654 \end_inset
1657 \end_layout
1659 \begin_layout Subsection
1660 Recursive use of Makefile.inc
1661 \end_layout
1663 \begin_layout Standard
1664 The makefile glue described here is used when building Samba4 vfs modules.
1665 \end_layout
1667 \begin_layout Standard
1668 If you are defining a module of an existing program you may find it easier
1669  to use a slight recursive make instead of including the makefile directly.
1670  This way there is less chance of definitions in Makefile.inc interfering
1671  with definitions in the main makefile, or with definitions in other Makefile.inc
1672  from other noweb modules.
1673 \end_layout
1675 \begin_layout Standard
1676 The glue works by adding a .PHONY target to call the recursive make, and
1677  adding this target as an additional pre-requisite to the existing targets.
1678 \end_layout
1680 \begin_layout Standard
1681 In this example, the existing build system already has a build target for
1683 \begin_inset Flex CharStyle:Code
1684 status collapsed
1686 \begin_layout Plain Layout
1687 example.o
1688 \end_layout
1690 \end_inset
1692 , so we just add another pre-requisite to that.
1693  In this case we use 
1694 \begin_inset Flex CharStyle:Code
1695 status collapsed
1697 \begin_layout Plain Layout
1698 example.tex.stamp
1699 \end_layout
1701 \end_inset
1703  as a pre-requisite, the stamp file's modified time indicating when all
1704  sources were extracted.
1705 \end_layout
1707 \begin_layout Chunk
1708 makefile-glue
1709 \end_layout
1711 \begin_layout Standard
1712 \begin_inset listings
1713 inline false
1714 status open
1716 \begin_layout Plain Layout
1718 $(example_srcdir)/example.o: $(example_srcdir)/example.tex.stamp
1719 \end_layout
1721 \end_inset
1724 \end_layout
1726 \begin_layout Standard
1727 The target for this new pre-requisite is generated by a recursive make using
1728  Makefile.inc which will make sure that the source is up to date, before
1729  it is built by the main projects makefile.
1730 \end_layout
1732 \begin_layout Chunk
1733 makefile-glue
1734 \end_layout
1736 \begin_layout Standard
1737 \begin_inset listings
1738 inline false
1739 status open
1741 \begin_layout Plain Layout
1743 $(example_srcdir)/example.tex.stamp: $(example_srcdir)/example.tex ; 
1744 \backslash
1746 \end_layout
1748 \begin_layout Plain Layout
1750         cd $(example_srcdir) && 
1751 \backslash
1753 \end_layout
1755 \begin_layout Plain Layout
1757         $(MAKE) -f Makefile.inc newfangle_sources
1758 \end_layout
1760 \end_inset
1763 \end_layout
1765 \begin_layout Standard
1766 We can do similar glue for the docs, clean and distclean targets.
1767  In this example our build system is using a double colon for these targets,
1768  so we use the same in our glue.
1769 \end_layout
1771 \begin_layout Chunk
1772 makefile-glue
1773 \end_layout
1775 \begin_layout Standard
1776 \begin_inset listings
1777 inline false
1778 status open
1780 \begin_layout Plain Layout
1782 docs:: docs_example
1783 \end_layout
1785 \begin_layout Plain Layout
1787 .PHONY: docs_example
1788 \end_layout
1790 \begin_layout Plain Layout
1792 docs_example:: ; cd $(example_srcdir) && 
1793 \backslash
1795 \end_layout
1797 \begin_layout Plain Layout
1799         $(MAKE) -f Makefile.inc docs
1800 \end_layout
1802 \begin_layout Plain Layout
1804 \end_layout
1806 \begin_layout Plain Layout
1808 clean:: clean_example
1809 \end_layout
1811 \begin_layout Plain Layout
1813 .PHONEY: clean_example
1814 \end_layout
1816 \begin_layout Plain Layout
1818 clean_example: ; cd $(example_srcdir) && 
1819 \backslash
1821 \end_layout
1823 \begin_layout Plain Layout
1825         $(MAKE) -f Makefile.inc clean
1826 \end_layout
1828 \begin_layout Plain Layout
1830 \end_layout
1832 \begin_layout Plain Layout
1834 distclean:: distclean_example
1835 \end_layout
1837 \begin_layout Plain Layout
1839 .PHONY: distclean_example
1840 \end_layout
1842 \begin_layout Plain Layout
1844 distclean_example: ; cd $(example_srcdir) && 
1845 \backslash
1847 \end_layout
1849 \begin_layout Plain Layout
1851         $(MAKE) -f Makefile.inc distclean
1852 \end_layout
1854 \end_inset
1857 \end_layout
1859 \begin_layout Standard
1860 We could do similarly for install targets to install the generated docs.
1861 \end_layout
1863 \begin_layout Subsection
1864 \begin_inset CommandInset label
1865 LatexCommand label
1866 name "sub:Converting-from-Lyx"
1868 \end_inset
1870 Converting from Lyx to LaTeX
1871 \end_layout
1873 \begin_layout Standard
1874 The first stage will always be to convert the Lyx file to a LaTeX file;
1875  this must be so not only because newfangle needs to to run on a TeX file,
1876  but also because the Lyx command 
1877 \emph on
1878 server-goto-file-line
1879 \begin_inset Foot
1880 status collapsed
1882 \begin_layout Plain Layout
1883 The Lyx command 
1884 \emph on
1885 server-goto-file-line
1886 \emph default
1887  is used to position the Lyx cursor at the compiler errors.
1888 \end_layout
1890 \end_inset
1893 \emph default
1894  insists that the line number provided is a line in the TeX file, and always
1895  reverse maps this to derive the line in the Lyx docment.
1896 \begin_inset Note Note
1897 status collapsed
1899 \begin_layout Plain Layout
1900 The tex file should probably be an automake extra dist sources or something,
1901  so that it gets produced and packaged by make dist
1902 \end_layout
1904 \end_inset
1907 \end_layout
1909 \begin_layout Standard
1910 The command [[lyx -e literate noweb-lyx.lyx]] will produce [[noweb-lyx.nw]]
1911  a tex file, so we define the noweb target to be the same as the Lyx file
1912  but with the .nw extension.
1913 \end_layout
1915 \begin_layout Chunk
1916 Makefile.inc-vars
1917 \end_layout
1919 \begin_layout Standard
1920 \begin_inset listings
1921 inline false
1922 status open
1924 \begin_layout Plain Layout
1926 TEX_SOURCE=$(LYX_SOURCE:.lyx=.tex)
1927 \end_layout
1929 \end_inset
1932 \end_layout
1934 \begin_layout Chunk
1935 Makefile.inc-targets
1936 \end_layout
1938 \begin_layout Standard
1939 \begin_inset listings
1940 inline false
1941 status open
1943 \begin_layout Plain Layout
1945 $(TEX_SOURCE): $(LYX_SOURCE) ;
1946 \backslash
1948 \end_layout
1950 \begin_layout Plain Layout
1952         lyx -e latex $<
1953 \end_layout
1955 \begin_layout Plain Layout
1957 clean_tex: ; rm -f -- $(TEX_SOURCE)
1958 \end_layout
1960 \end_inset
1963 \end_layout
1965 \begin_layout Subsection
1966 Extracting Program Source
1967 \end_layout
1969 \begin_layout Standard
1970 The program source is extracted using newfangle, which is designed to operate
1971  on a LaTeX document.
1973 \end_layout
1975 \begin_layout Chunk
1976 Makefile.inc-vars
1977 \end_layout
1979 \begin_layout Standard
1980 \begin_inset listings
1981 inline false
1982 status open
1984 \begin_layout Plain Layout
1986 NEWFANGLE_SOURCE=$(TEX_SOURCE)
1987 \end_layout
1989 \end_inset
1992 \end_layout
1994 \begin_layout Standard
1995 The Lyx document can result in any number of source documents, but not all
1996  of these will be changed each time the Lyx document is updated.
1997  We certainly don't want to update the timestamps of these files and cause
1998  the whole source tree to be recompiled just because the Lyx document was
1999  edited.
2001 \end_layout
2003 \begin_layout Standard
2004 To solve this problem we use a stamp file which is always updated each time
2005  the sources are extracted from the LaTeX document.
2006  If the stamp file is older than the LaTeX document, then we can make an
2007  attempt to re-extract the sources.
2008 \end_layout
2010 \begin_layout Chunk
2011 Makefile.inc-vars
2012 \end_layout
2014 \begin_layout Standard
2015 \begin_inset listings
2016 inline false
2017 status open
2019 \begin_layout Plain Layout
2021 NEWFANGLE_SOURCE_STAMP=$(NEWFANGLE_SOURCE).stamp
2022 \end_layout
2024 \end_inset
2027 \end_layout
2029 \begin_layout Chunk
2030 Makefile.inc-targets
2031 \end_layout
2033 \begin_layout Standard
2034 \begin_inset listings
2035 inline false
2036 status open
2038 \begin_layout Plain Layout
2040 $(NEWFANGLE_SOURCE_STAMP): $(NEWFANGLE_SOURCE) 
2041 \backslash
2043 \end_layout
2045 \begin_layout Plain Layout
2047                            $(NEWFANGLE_SOURCES) ; 
2048 \backslash
2050 \end_layout
2052 \begin_layout Plain Layout
2054         echo > $(NEWFANGLE_SOURCE_STAMP)
2055 \end_layout
2057 \begin_layout Plain Layout
2059 clean_stamp: ; rm -f $(NEWFANGLE_SOURCE_STAMP)
2060 \end_layout
2062 \begin_layout Plain Layout
2064 clean: clean_stamp
2065 \end_layout
2067 \end_inset
2070 \end_layout
2072 \begin_layout Subsection
2073 Extracting C sources
2074 \end_layout
2076 \begin_layout Standard
2077 We compute 
2078 \begin_inset Flex CharStyle:Code
2079 status collapsed
2081 \begin_layout Plain Layout
2082 NEWFANGLE_SOURCES
2083 \end_layout
2085 \end_inset
2087  to hold the names of all the C source files defined in this document.
2088  We compute this only once, by means of := in assignent.
2089  The sed deletes the any <
2090 \begin_inset space \hspace*{}
2091 \length 0in
2092 \end_inset
2094 < and >
2095 \begin_inset space \hspace*{}
2096 \length 0in
2097 \end_inset
2099 > which may surround the roots names (for noroots compatibility).
2101 \end_layout
2103 \begin_layout Standard
2104 As we use chunk names beginning with ./ to denote top level fragments that
2105  should be extracted, we filter out all fragments that do not begin with
2106  ./
2107 \end_layout
2109 \begin_layout Chunk
2110 Makefile.inc-vars
2111 \end_layout
2113 \begin_layout Standard
2114 \begin_inset listings
2115 inline false
2116 status open
2118 \begin_layout Plain Layout
2120 NEWFANGLE_PREFIX:=
2121 \backslash
2123 \backslash
2125 \end_layout
2127 \begin_layout Plain Layout
2129 NEWFANGLE_SOURCES:=$(shell 
2130 \backslash
2132 \end_layout
2134 \begin_layout Plain Layout
2136   newfangle -r $(NEWFANGLE_SOURCE) |
2137 \backslash
2139 \end_layout
2141 \begin_layout Plain Layout
2143   sed -e 's/^[<][<]//;s/[>][>]$$//;/^$(NEWFANGLE_PREFIX)/!d' 
2144 \backslash
2146 \end_layout
2148 \begin_layout Plain Layout
2150       -e 's/^$(NEWFANGLE_PREFIX)/
2151 \backslash
2153 \backslash
2154 //' )
2155 \end_layout
2157 \begin_layout Plain Layout
2160 \end_layout
2162 \end_inset
2165 \end_layout
2167 \begin_layout Chunk
2168 Makefile.inc-targets
2169 \end_layout
2171 \begin_layout Standard
2172 \begin_inset listings
2173 inline false
2174 status open
2176 \begin_layout Plain Layout
2178 .PHONY: echo_newfangle_sources
2179 \end_layout
2181 \begin_layout Plain Layout
2183 echo_newfangle_sources: ; @echo $(NEWFANGLE_SOURCES)
2184 \end_layout
2186 \end_inset
2189 \end_layout
2191 \begin_layout Standard
2192 We define a convenient target called 
2193 \begin_inset Flex CharStyle:Code
2194 status collapsed
2196 \begin_layout Plain Layout
2197 newfangle_sources
2198 \end_layout
2200 \end_inset
2202  to re-extract the source if the LaTeX file has been updated.
2203 \end_layout
2205 \begin_layout Chunk
2206 Makefile.inc-targets
2207 \end_layout
2209 \begin_layout Standard
2210 \begin_inset listings
2211 inline false
2212 status open
2214 \begin_layout Plain Layout
2216 .PHONY: newfangle_sources
2217 \end_layout
2219 \begin_layout Plain Layout
2221 newfangle_sources: $(NEWFANGLE_SOURCE_STAMP)
2222 \end_layout
2224 \end_inset
2227 \end_layout
2229 \begin_layout Standard
2230 And also a convenient target to remove extracted sources.
2231 \end_layout
2233 \begin_layout Chunk
2234 Makefile.inc-targets
2235 \end_layout
2237 \begin_layout Standard
2238 \begin_inset listings
2239 inline false
2240 status open
2242 \begin_layout Plain Layout
2244 .PHONY: clean_newfangle_sources
2245 \end_layout
2247 \begin_layout Plain Layout
2249 clean_newfangle_sources: ; 
2250 \backslash
2252 \end_layout
2254 \begin_layout Plain Layout
2256         rm -f -- $(NEWFANGLE_SOURCE_STAMP) $(NEWFANGLE_SOURCES)
2257 \end_layout
2259 \end_inset
2262 \end_layout
2264 \begin_layout Standard
2265 This 
2266 \begin_inset Flex CharStyle:Code
2267 status collapsed
2269 \begin_layout Plain Layout
2270 if_extension
2271 \end_layout
2273 \end_inset
2275  macro takes 4 arguments: the filename (1), some extensions to match (2)
2276  and a some shell command to return if the filename matches the exentions
2277  (3), or not (4).
2278 \end_layout
2280 \begin_layout Chunk
2281 Makefile.inc-vars
2282 \end_layout
2284 \begin_layout Standard
2285 \begin_inset listings
2286 inline false
2287 status open
2289 \begin_layout Plain Layout
2291 if_extension=$(if $(findstring $(suffix $(1)),$(2)),$(3),$(4))
2292 \end_layout
2294 \end_inset
2297 \end_layout
2299 \begin_layout Standard
2300 For some source files like C files, we want to output the line number and
2301  filename of the original LaTeX document from which the source came.
2302 \end_layout
2304 \begin_layout Standard
2305 To make this easier we define the file extensions for which we want to do
2306  this.
2307 \end_layout
2309 \begin_layout Chunk
2310 Makefile.inc-vars
2311 \end_layout
2313 \begin_layout Standard
2314 \begin_inset listings
2315 inline false
2316 status open
2318 \begin_layout Plain Layout
2320 C_EXTENSIONS=.c .h
2321 \end_layout
2323 \end_inset
2326 \end_layout
2328 \begin_layout Standard
2329 We can then use the if_extensions macro to define a macro which expands
2330  out to the 
2331 \begin_inset Flex CharStyle:Code
2332 status collapsed
2334 \begin_layout Plain Layout
2336 \end_layout
2338 \end_inset
2340  option if newfangle is being invoked in a C source file, so that C compile
2341  errors will refer to the line number in the Lyx document.
2343 \end_layout
2345 \begin_layout Chunk
2346 Makefile.inc-vars
2347 \end_layout
2349 \begin_layout Standard
2350 \begin_inset listings
2351 inline false
2352 status open
2354 \begin_layout Plain Layout
2356 TABS=8
2357 \end_layout
2359 \begin_layout Plain Layout
2361 nf_line=-L -T$(TABS)
2362 \end_layout
2364 \begin_layout Plain Layout
2366 newfangle=newfangle 
2367 \backslash
2369 \end_layout
2371 \begin_layout Plain Layout
2373   $(call if_extension,$(2),$(C_EXTENSIONS),$(nf_line)) 
2374 \backslash
2376 \end_layout
2378 \begin_layout Plain Layout
2380     -R"$(2)" $(1)
2381 \end_layout
2383 \end_inset
2386 \end_layout
2388 \begin_layout Standard
2389 We can use a similar trick to define an 
2390 \emph on
2391 indent
2392 \emph default
2393  macro which takes just the filename as an argument and can return a pipeline
2394  stage calling the indent command.
2395  Indent can be turned off with 
2396 \begin_inset Flex CharStyle:Code
2397 status collapsed
2399 \begin_layout Plain Layout
2400 make newfangle_sources indent=
2401 \end_layout
2403 \end_inset
2406 \end_layout
2408 \begin_layout Chunk
2409 Makefile.inc-vars
2410 \end_layout
2412 \begin_layout Standard
2413 \begin_inset listings
2414 inline false
2415 status open
2417 \begin_layout Plain Layout
2419 indent_options=-npro -kr -i8 -ts8 -sob -l80 -ss -ncs
2420 \end_layout
2422 \begin_layout Plain Layout
2424 indent=$(call if_extension,$(1),$(C_EXTENSIONS),
2425 \backslash
2427 \end_layout
2429 \begin_layout Plain Layout
2431               | indent $(indent_options))
2432 \end_layout
2434 \end_inset
2437 \end_layout
2439 \begin_layout Standard
2440 We now define the pattern for extracting a file.
2441  The files are written using noweb's 
2442 \emph on
2443 cpif
2444 \begin_inset Foot
2445 status collapsed
2447 \begin_layout Plain Layout
2449 \emph on
2450 So you still need noweb installed in order to use cpif
2451 \end_layout
2453 \end_inset
2456 \begin_inset Note Note
2457 status collapsed
2459 \begin_layout Plain Layout
2461 \emph on
2462 Write an awk version
2463 \end_layout
2465 \end_inset
2468 \emph default
2469  so that the file timestamp will not be touched if the contents haven't
2470  changed.
2471  This avoids the need to rebuild the entire project because of a typographical
2472  change in the documentation, or if only a few C source files have changed.
2473 \end_layout
2475 \begin_layout Chunk
2476 Makefile.inc-vars
2477 \end_layout
2479 \begin_layout Standard
2480 \begin_inset listings
2481 inline false
2482 status open
2484 \begin_layout Plain Layout
2486 newfangle_extract=@mkdir -p $(dir $(1)) && 
2487 \backslash
2489 \end_layout
2491 \begin_layout Plain Layout
2493   $(call newfangle,$(2),$(1)) > "$(1).tmp" && 
2494 \backslash
2496 \end_layout
2498 \begin_layout Plain Layout
2500   cat "$(1).tmp" $(indent) | cpif "$(1)" 
2501 \backslash
2503 \end_layout
2505 \begin_layout Plain Layout
2507   && rm -- "$(1).tmp" || 
2508 \backslash
2510 \end_layout
2512 \begin_layout Plain Layout
2514   (echo error newfangling $(1) from $(2) ; exit 1)
2515 \end_layout
2517 \end_inset
2520 \end_layout
2522 \begin_layout Standard
2523 We define a target which will extract or update all sources.
2524  To do this we first defined a makefile template that can do this for any
2525  source file in the LaTeX document.
2526 \end_layout
2528 \begin_layout Chunk
2529 Makefile.inc-vars
2530 \end_layout
2532 \begin_layout Standard
2533 \begin_inset listings
2534 inline false
2535 status open
2537 \begin_layout Plain Layout
2539 define NEWFANGLE_template
2540 \end_layout
2542 \begin_layout Plain Layout
2544   $(1): $(2); 
2545 \backslash
2547 \end_layout
2549 \begin_layout Plain Layout
2551     $$(call newfangle_extract,$(1),$(2))
2552 \end_layout
2554 \begin_layout Plain Layout
2556   NEWFANGLE_TARGETS+=$(1)
2557 \end_layout
2559 \begin_layout Plain Layout
2561 endef
2562 \end_layout
2564 \end_inset
2567 \end_layout
2569 \begin_layout Standard
2570 We then enumerate the discovered 
2571 \begin_inset Flex CharStyle:Code
2572 status collapsed
2574 \begin_layout Plain Layout
2575 NEWTANGLE_SOURCES
2576 \end_layout
2578 \end_inset
2580  to generate a makefile rule for each one using the makefile template we
2581  defined above.
2582 \end_layout
2584 \begin_layout Chunk
2585 Makefile.inc-targets
2586 \end_layout
2588 \begin_layout Standard
2589 \begin_inset listings
2590 inline false
2591 status open
2593 \begin_layout Plain Layout
2595 $(foreach source,$(NEWFANGLE_SOURCES),
2596 \backslash
2598 \end_layout
2600 \begin_layout Plain Layout
2602   $(eval $(call NEWFANGLE_template,$(source),$(NEWFANGLE_SOURCE))) 
2603 \backslash
2605 \end_layout
2607 \begin_layout Plain Layout
2610 \end_layout
2612 \end_inset
2615 \end_layout
2617 \begin_layout Standard
2618 These will all be built with NEWFANGLE_SOURCE_STAMP.
2619 \end_layout
2621 \begin_layout Standard
2622 We also remove the generated sources on a 
2623 \emph on
2624 make distclean
2625 \emph default
2627 \end_layout
2629 \begin_layout Chunk
2630 Makefile.inc-targets
2631 \end_layout
2633 \begin_layout Standard
2634 \begin_inset listings
2635 inline false
2636 status open
2638 \begin_layout Plain Layout
2640 _distclean: clean_newfangle_sources
2641 \end_layout
2643 \end_inset
2646 \end_layout
2648 \begin_layout Subsection
2649 Extracting Documentation
2650 \end_layout
2652 \begin_layout Standard
2653 We then identify the intermediate stages of the documentation and their
2654  build and clean targets.
2655 \end_layout
2657 \begin_layout Subsubsection
2658 Running pdflatex
2659 \end_layout
2661 \begin_layout Standard
2662 We produce a pdf file from the tex file.
2663 \end_layout
2665 \begin_layout Chunk
2666 Makefile.inc-vars
2667 \end_layout
2669 \begin_layout Standard
2670 \begin_inset listings
2671 inline false
2672 status open
2674 \begin_layout Plain Layout
2676 NEWFANGLE_PDF=$(TEX_SOURCE:.tex=.pdf)
2677 \end_layout
2679 \end_inset
2682 \end_layout
2684 \begin_layout Standard
2685 We run pdflatex twice to be sure that the contents and aux files are up
2686  to date.
2687  We certainly are required to run pdflatex twice if these files do not exist!
2688 \end_layout
2690 \begin_layout Chunk
2691 Makefile.inc-targets
2692 \end_layout
2694 \begin_layout Standard
2695 \begin_inset listings
2696 inline false
2697 status open
2699 \begin_layout Plain Layout
2701 $(NEWFANGLE_PDF): $(TEX_SOURCE); pdflatex $< && pdflatex $<
2702 \end_layout
2704 \begin_layout Plain Layout
2706 clean_pdf: ; rm -f -- $(NEWFANGLE_PDF) 
2707 \backslash
2709 \end_layout
2711 \begin_layout Plain Layout
2713                       $(TEX_SOURCE:.tex=.toc) 
2714 \backslash
2716 \end_layout
2718 \begin_layout Plain Layout
2720                       $(TEX_SOURCE:.tex=.log) 
2721 \backslash
2723 \end_layout
2725 \begin_layout Plain Layout
2727                       $(TEX_SOURCE:.tex=.aux)
2728 \end_layout
2730 \end_inset
2733 \end_layout
2735 \begin_layout Subsubsection
2736 The docs as a whole
2737 \end_layout
2739 \begin_layout Standard
2740 Currently we only build pdf as a final format, but NEWFANGLE_DOCS may later
2741  hold other output formats.
2742 \end_layout
2744 \begin_layout Chunk
2745 Makefile.inc-vars
2746 \end_layout
2748 \begin_layout Standard
2749 \begin_inset listings
2750 inline false
2751 status open
2753 \begin_layout Plain Layout
2755 NEWFANGLE_DOCS=$(NEWFANGLE_PDF)
2756 \end_layout
2758 \end_inset
2761 \end_layout
2763 \begin_layout Standard
2764 We also define newfangle_docs as a convenient phony target<
2765 \end_layout
2767 \begin_layout Chunk
2768 Makefile.inc-targets
2769 \end_layout
2771 \begin_layout Standard
2772 \begin_inset listings
2773 inline false
2774 status open
2776 \begin_layout Plain Layout
2778 .PHONY: newfangle_docs
2779 \end_layout
2781 \begin_layout Plain Layout
2783 newfangle_docs: $(NEWFANGLE_DOCS)
2784 \end_layout
2786 \begin_layout Plain Layout
2788 docs: newfangle_docs
2789 \end_layout
2791 \end_inset
2794 \end_layout
2796 \begin_layout Standard
2797 And define a convenient clean_noweb_docs which we add to the regular clean
2798  target
2799 \end_layout
2801 \begin_layout Chunk
2802 Makefile.inc-targets
2803 \end_layout
2805 \begin_layout Standard
2806 \begin_inset listings
2807 inline false
2808 status open
2810 \begin_layout Plain Layout
2812 .PHONEY: clean_newfangle_docs
2813 \end_layout
2815 \begin_layout Plain Layout
2817 clean_newfangle_docs: clean_tex clean_pdf
2818 \end_layout
2820 \begin_layout Plain Layout
2822 clean: clean_newfangle_docs
2823 \end_layout
2825 \begin_layout Plain Layout
2827 \end_layout
2829 \begin_layout Plain Layout
2831 distclean_newfangle_docs: clean_tex clean_newfangle_docs
2832 \end_layout
2834 \begin_layout Plain Layout
2836 distclean: clean distclean_newfangle_docs
2837 \end_layout
2839 \end_inset
2842 \end_layout
2844 \begin_layout Subsection
2845 Other helpers
2846 \end_layout
2848 \begin_layout Standard
2849 If Makefile.inc is included into Makefile, then extracted files can be updated
2850  with this command:
2851 \end_layout
2853 \begin_layout LyX-Code
2854 make newfangle_sources
2855 \end_layout
2857 \begin_layout Standard
2858 otherwise, with:
2859 \end_layout
2861 \begin_layout LyX-Code
2862 make -f Makefile.inc newfangle_sources
2863 \end_layout
2865 \begin_layout Part
2866 Source Code
2867 \end_layout
2869 \begin_layout Chapter
2870 Newfangle awk source code
2871 \end_layout
2873 \begin_layout Standard
2874 We use the copyright notice from chapter 
2875 \begin_inset CommandInset ref
2876 LatexCommand vref
2877 reference "cha:License"
2879 \end_inset
2882 \end_layout
2884 \begin_layout Chunk
2885 ./newfangle,language=awk,morestring=[b]{/},morekeywords=else
2886 \end_layout
2888 \begin_layout Standard
2889 \begin_inset listings
2890 inline false
2891 status open
2893 \begin_layout Plain Layout
2895 #! /usr/bin/awk -f
2896 \end_layout
2898 \begin_layout Plain Layout
2900 # =<
2901 \backslash
2902 chunkref{gpl3-copyright}>
2903 \end_layout
2905 \begin_layout Plain Layout
2907 \end_layout
2909 \end_inset
2912 \end_layout
2914 \begin_layout Standard
2915 We also use code from Arnold Robbins public domain getopt (1993 revision)
2916  defined in chapter 
2917 \begin_inset CommandInset ref
2918 LatexCommand ref
2919 reference "cha:getopt"
2921 \end_inset
2923 , and naturally want to attribute this appropriately.
2924 \end_layout
2926 \begin_layout Standard
2927 \begin_inset listings
2928 inline false
2929 status open
2931 \begin_layout Plain Layout
2933 \end_layout
2935 \begin_layout Plain Layout
2937 # NOTE: Arnold Robbins public domain getopt for awk is also used:
2938 \end_layout
2940 \begin_layout Plain Layout
2943 \backslash
2944 chunkref{getopt.awk-header}>
2945 \end_layout
2947 \begin_layout Plain Layout
2949 \end_layout
2951 \begin_layout Plain Layout
2954 \backslash
2955 chunkref{getopt.awk-getopt()}>
2956 \end_layout
2958 \begin_layout Plain Layout
2960 \end_layout
2962 \end_inset
2965 \end_layout
2967 \begin_layout Standard
2968 And include the following chunks
2969 \end_layout
2971 \begin_layout Chunk
2972 ./newfangle
2973 \end_layout
2975 \begin_layout Standard
2976 \begin_inset listings
2977 inline false
2978 status open
2980 \begin_layout Plain Layout
2983 \backslash
2984 chunkref{helper-functions}>
2985 \end_layout
2987 \begin_layout Plain Layout
2990 \backslash
2991 chunkref{mode-tracker}>
2992 \end_layout
2994 \begin_layout Plain Layout
2997 \backslash
2998 chunkref{parse_chunk_args}>
2999 \end_layout
3001 \begin_layout Plain Layout
3004 \backslash
3005 chunkref{chunk-storage-functions}>
3006 \end_layout
3008 \begin_layout Plain Layout
3011 \backslash
3012 chunkref{output_chunk_names()}>
3013 \end_layout
3015 \begin_layout Plain Layout
3018 \backslash
3019 chunkref{output_chunks()}>
3020 \end_layout
3022 \begin_layout Plain Layout
3025 \backslash
3026 chunkref{write_chunk()}>
3027 \end_layout
3029 \begin_layout Plain Layout
3032 \backslash
3033 chunkref{expand_chunk_args()}>
3034 \end_layout
3036 \begin_layout Plain Layout
3039 \backslash
3040 chunkref{begin}>
3041 \end_layout
3043 \begin_layout Plain Layout
3046 \backslash
3047 chunkref{recognize-chunk}>
3048 \end_layout
3050 \begin_layout Plain Layout
3053 \backslash
3054 chunkref{end}>
3055 \end_layout
3057 \end_inset
3060 \end_layout
3062 \begin_layout Section
3063 AWK tricks
3064 \end_layout
3066 \begin_layout Standard
3067 The portable way to erase an array in awk is to split the empty string,
3068  like this:
3069 \end_layout
3071 \begin_layout Chunk
3072 awk-delete-array,params=ARRAY
3073 \end_layout
3075 \begin_layout Standard
3076 \begin_inset listings
3077 inline false
3078 status open
3080 \begin_layout Plain Layout
3082 split("", ${ARRAY});
3083 \end_layout
3085 \end_inset
3088 \end_layout
3090 \begin_layout Chunk
3091 dump-array,params=ARRAY
3092 \end_layout
3094 \begin_layout Standard
3095 \begin_inset listings
3096 inline false
3097 status open
3099 \begin_layout Plain Layout
3101 print "
3102 \backslash
3103 nDump: ${ARRAY}
3104 \backslash
3105 n--------
3106 \backslash
3107 n" > "/dev/stderr";
3108 \end_layout
3110 \begin_layout Plain Layout
3112 for (_x in ${ARRAY}) {
3113 \end_layout
3115 \begin_layout Plain Layout
3117   print _x "=" ${ARRAY}[_x] "
3118 \backslash
3119 n" > "/dev/stderr";
3120 \end_layout
3122 \begin_layout Plain Layout
3125 \end_layout
3127 \begin_layout Plain Layout
3129 print "========
3130 \backslash
3131 n" > "/dev/stderr";
3132 \end_layout
3134 \end_inset
3137 \end_layout
3139 \begin_layout Chunk
3140 ,params=
3141 \end_layout
3143 \begin_layout Section
3144 Catching errors
3145 \end_layout
3147 \begin_layout Standard
3148 Fatal errors are issued with the error function:
3149 \end_layout
3151 \begin_layout Chunk
3152 error(),append=helper-functions
3153 \end_layout
3155 \begin_layout Standard
3156 \begin_inset listings
3157 inline false
3158 status open
3160 \begin_layout Plain Layout
3162 function error(message)
3163 \end_layout
3165 \begin_layout Plain Layout
3168 \end_layout
3170 \begin_layout Plain Layout
3172   print "ERROR: " FILENAME ":" FNR " " message > "/dev/stderr";
3173 \end_layout
3175 \begin_layout Plain Layout
3177   exit 1;
3178 \end_layout
3180 \begin_layout Plain Layout
3183 \end_layout
3185 \end_inset
3188 \end_layout
3190 \begin_layout Standard
3191 \begin_inset listings
3192 inline false
3193 status open
3195 \begin_layout Plain Layout
3197 function warning(message)
3198 \end_layout
3200 \begin_layout Plain Layout
3203 \end_layout
3205 \begin_layout Plain Layout
3207   print "WARNING: " FILENAME ":" FNR " " message > "/dev/stderr";
3208 \end_layout
3210 \begin_layout Plain Layout
3212   warnings++;
3213 \end_layout
3215 \begin_layout Plain Layout
3218 \end_layout
3220 \end_inset
3223 \end_layout
3225 \begin_layout Chapter
3226 lstlistings
3227 \end_layout
3229 \begin_layout Standard
3230 LaTeX arguments to lstlistings macros are a comma seperated list of key-value
3231  pairs.
3232  Values containing commas are enclosed in 
3233 \begin_inset Flex CharStyle:Code
3234 status collapsed
3236 \begin_layout Plain Layout
3238 \end_layout
3240 \end_inset
3242  braces 
3243 \begin_inset Flex CharStyle:Code
3244 status collapsed
3246 \begin_layout Plain Layout
3248 \end_layout
3250 \end_inset
3252 , which is to be expected for LaTeX.
3253 \end_layout
3255 \begin_layout Standard
3256 A sample expressions is:
3257 \end_layout
3259 \begin_layout LyX-Code
3260 name=thomas, params={a, b}, something, something-else
3261 \end_layout
3263 \begin_layout Standard
3264 but we see that this is just a simpler form of this expression:
3265 \end_layout
3267 \begin_layout LyX-Code
3268 name=freddie, foo={bar=baz, quux={quirk, a=fleeg}}, etc
3269 \end_layout
3271 \begin_layout Standard
3272 We may consider that we need a function that can parse such LaTeX expressions
3273  and assign the values to an 
3274 \noun on
3276 \noun default
3277  associated array, perhaps using a recursive parser into a multi-dimensional
3278  hash
3279 \begin_inset Foot
3280 status collapsed
3282 \begin_layout Plain Layout
3283 as AWK doesn't have nested-hash support
3284 \end_layout
3286 \end_inset
3288 , resulting in:
3289 \end_layout
3291 \begin_layout Standard
3292 \begin_inset Tabular
3293 <lyxtabular version="3" rows="6" columns="2">
3294 <features>
3295 <column alignment="left" valignment="top" width="0">
3296 <column alignment="left" valignment="top" width="0">
3297 <row>
3298 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
3299 \begin_inset Text
3301 \begin_layout Plain Layout
3303 \end_layout
3305 \end_inset
3306 </cell>
3307 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
3308 \begin_inset Text
3310 \begin_layout Plain Layout
3311 value
3312 \end_layout
3314 \end_inset
3315 </cell>
3316 </row>
3317 <row>
3318 <cell alignment="left" valignment="top" topline="true" leftline="true" usebox="none">
3319 \begin_inset Text
3321 \begin_layout Plain Layout
3322 a[name]
3323 \end_layout
3325 \end_inset
3326 </cell>
3327 <cell alignment="left" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
3328 \begin_inset Text
3330 \begin_layout Plain Layout
3331 freddie
3332 \end_layout
3334 \end_inset
3335 </cell>
3336 </row>
3337 <row>
3338 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
3339 \begin_inset Text
3341 \begin_layout Plain Layout
3342 a[foo, bar]
3343 \end_layout
3345 \end_inset
3346 </cell>
3347 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
3348 \begin_inset Text
3350 \begin_layout Plain Layout
3352 \end_layout
3354 \end_inset
3355 </cell>
3356 </row>
3357 <row>
3358 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
3359 \begin_inset Text
3361 \begin_layout Plain Layout
3362 a[foo, quux, quirk]
3363 \end_layout
3365 \end_inset
3366 </cell>
3367 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
3368 \begin_inset Text
3370 \begin_layout Plain Layout
3372 \end_layout
3374 \end_inset
3375 </cell>
3376 </row>
3377 <row>
3378 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
3379 \begin_inset Text
3381 \begin_layout Plain Layout
3382 a[foo, quux, a]
3383 \end_layout
3385 \end_inset
3386 </cell>
3387 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
3388 \begin_inset Text
3390 \begin_layout Plain Layout
3391 fleeg
3392 \end_layout
3394 \end_inset
3395 </cell>
3396 </row>
3397 <row>
3398 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
3399 \begin_inset Text
3401 \begin_layout Plain Layout
3402 a[etc]
3403 \end_layout
3405 \end_inset
3406 </cell>
3407 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
3408 \begin_inset Text
3410 \begin_layout Plain Layout
3412 \end_layout
3414 \end_inset
3415 </cell>
3416 </row>
3417 </lyxtabular>
3419 \end_inset
3422 \end_layout
3424 \begin_layout Standard
3425 Oon reflection it seems that sometimes such nesting is not desirable, as
3426  the braces are also used to delimit values that contain commas --- we may
3427  consider that
3428 \end_layout
3430 \begin_layout LyX-Code
3431 name={williamson, freddie}
3432 \end_layout
3434 \begin_layout Standard
3435 should assign 
3436 \begin_inset Flex CharStyle:Code
3437 status collapsed
3439 \begin_layout Plain Layout
3440 williamson, freddie
3441 \end_layout
3443 \end_inset
3445  to 
3446 \begin_inset Flex CharStyle:Code
3447 status collapsed
3449 \begin_layout Plain Layout
3450 name
3451 \end_layout
3453 \end_inset
3456 \end_layout
3458 \begin_layout Standard
3459 In fact we are not so interested in the detail so as to be bothered by this,
3460  which turns out to be a good thing for two reasons.
3461  Firstly LaTeX has a malleable parser with no strict syntax, and secondly
3462  whether or not 
3463 \begin_inset Flex CharStyle:Code
3464 status collapsed
3466 \begin_layout Plain Layout
3467 williamson
3468 \end_layout
3470 \end_inset
3472  and 
3473 \begin_inset Flex CharStyle:Code
3474 status collapsed
3476 \begin_layout Plain Layout
3477 freddie
3478 \end_layout
3480 \end_inset
3482  should count as two items will be context dependant anyway.
3483 \end_layout
3485 \begin_layout Standard
3486 We need to parse this latex for only one reason; which is that we are extending
3487  lstlistings to add some additional arguments which will be used to express
3488  chunk parameters and other chunk options.
3489 \end_layout
3491 \begin_layout Section
3492 Additional lstlstings parameters
3493 \end_layout
3495 \begin_layout Standard
3496 Further on we define a 
3497 \begin_inset Flex CharStyle:Code
3498 status collapsed
3500 \begin_layout Plain Layout
3502 \backslash
3503 Chunk
3504 \end_layout
3506 \end_inset
3508  LaTeX macro whose arguments will consist of a the chunk name, optionally
3509  followed by a comma and then a comma separated list of arguments.
3510  In fact we will just need to prefix 
3511 \begin_inset Flex CharStyle:Code
3512 status collapsed
3514 \begin_layout Plain Layout
3515 name=
3516 \end_layout
3518 \end_inset
3520  to the arguments to in order to create valid lstlistings arguments.
3522 \end_layout
3524 \begin_layout Standard
3525 There will be other arguments supported too; 
3526 \end_layout
3528 \begin_layout Description
3529 params As an extension to many literate-programming styles, newfangle permits
3530  code chunks to take parameters and thus operate somewhat like C pre-processor
3531  macros, or like C++ templates.
3532  Chunk parameters are declared with a chunk argument called 
3533 \begin_inset Flex CharStyle:Code
3534 status collapsed
3536 \begin_layout Plain Layout
3537 params
3538 \end_layout
3540 \end_inset
3542 , which holds a semi-colon separated list of parameters, like this:
3543 \end_layout
3545 \begin_layout LyX-Code
3546 achunk,language=C,params=name;address
3547 \end_layout
3549 \begin_layout Description
3550 addto a named chunk that this chunk is to be included into.
3551  This saves the effort of having to declare another listing of the named
3552  chunk merely to include this one.
3553 \end_layout
3555 \begin_layout Standard
3556 Function 
3557 \begin_inset Flex Chunkref
3558 status collapsed
3560 \begin_layout Plain Layout
3561 get_chunk_args()
3562 \end_layout
3564 \end_inset
3566  will accept two paramters, 
3567 \begin_inset Flex CharStyle:Code
3568 status collapsed
3570 \begin_layout Plain Layout
3571 text
3572 \end_layout
3574 \end_inset
3576  being the text to parse, and 
3577 \begin_inset Flex CharStyle:Code
3578 status collapsed
3580 \begin_layout Plain Layout
3581 values
3582 \end_layout
3584 \end_inset
3586  being an array to receive the parsed values as described above.
3587  The optional parameter 
3588 \begin_inset Flex CharStyle:Code
3589 status collapsed
3591 \begin_layout Plain Layout
3592 path
3593 \end_layout
3595 \end_inset
3597  is used during recursion to build up the multi-dimensional array path.
3598 \end_layout
3600 \begin_layout Chunk
3601 ./newfangle
3602 \end_layout
3604 \begin_layout Standard
3605 \begin_inset listings
3606 inline false
3607 status open
3609 \begin_layout Plain Layout
3612 \backslash
3613 chunkref{get_chunk_args()}>
3614 \end_layout
3616 \end_inset
3619 \end_layout
3621 \begin_layout Chunk
3622 get_chunk_args()
3623 \end_layout
3625 \begin_layout Standard
3626 \begin_inset listings
3627 inline false
3628 status open
3630 \begin_layout Plain Layout
3632 function get_chunk_args(text, values,
3633 \end_layout
3635 \begin_layout Plain Layout
3637   # optional parameters
3638 \end_layout
3640 \begin_layout Plain Layout
3642   path, # hierarchical precursors
3643 \end_layout
3645 \begin_layout Plain Layout
3647   # local vars
3648 \end_layout
3650 \begin_layout Plain Layout
3652   a, name)
3653 \end_layout
3655 \end_inset
3658 \end_layout
3660 \begin_layout Standard
3661 The strategy is to parse the name, and then look for a value.
3662  If the value begins with a brace 
3663 \begin_inset Flex CharStyle:Code
3664 status collapsed
3666 \begin_layout Plain Layout
3668 \end_layout
3670 \end_inset
3672 , then we recurse and consume as much of the text as necessary, returning
3673  the remaining text when we encounter a leading close-brace 
3674 \begin_inset Flex CharStyle:Code
3675 status collapsed
3677 \begin_layout Plain Layout
3679 \end_layout
3681 \end_inset
3684  This being the strategy --- and executed in a loop --- we realise that
3685  we must first look for the closing brace (perhaps preceded by white space)
3686  in order to terminate the recursion, and returning remaining text.
3687 \end_layout
3689 \begin_layout Standard
3690 \begin_inset listings
3691 inline false
3692 status open
3694 \begin_layout Plain Layout
3697 \end_layout
3699 \begin_layout Plain Layout
3701   split("", next_chunk_args);
3702 \end_layout
3704 \begin_layout Plain Layout
3706   while(length(text)) {
3707 \end_layout
3709 \begin_layout Plain Layout
3711     if (match(text, "^ *}(.*)", a)) {
3712 \end_layout
3714 \begin_layout Plain Layout
3716       return a[1];
3717 \end_layout
3719 \begin_layout Plain Layout
3721     }
3722 \end_layout
3724 \begin_layout Plain Layout
3726     =<
3727 \backslash
3728 chunkref{parse-chunk-args}>
3729 \end_layout
3731 \begin_layout Plain Layout
3733   }
3734 \end_layout
3736 \begin_layout Plain Layout
3738   return text;
3739 \end_layout
3741 \begin_layout Plain Layout
3744 \end_layout
3746 \end_inset
3749 \end_layout
3751 \begin_layout Standard
3752 \begin_inset Note Note
3753 status collapsed
3755 \begin_layout Plain Layout
3756 Use BNF package here
3757 \end_layout
3759 \end_inset
3761 We can see that the text could be inspected with this regex:
3762 \end_layout
3764 \begin_layout Chunk
3765 parse-chunk-args
3766 \end_layout
3768 \begin_layout Standard
3769 \begin_inset listings
3770 inline false
3771 status open
3773 \begin_layout Plain Layout
3775 if (! match(text, " *([^,=]*[^,= ]) *(([,=]) *(([^,}]*) *,* *(.*))|)$", a))
3777 \end_layout
3779 \begin_layout Plain Layout
3781   return text;
3782 \end_layout
3784 \begin_layout Plain Layout
3787 \end_layout
3789 \end_inset
3792 \end_layout
3794 \begin_layout Standard
3795 and that 
3796 \begin_inset Flex CharStyle:Code
3797 status collapsed
3799 \begin_layout Plain Layout
3801 \end_layout
3803 \end_inset
3805  will have the following values:
3806 \end_layout
3808 \begin_layout Standard
3809 \begin_inset Tabular
3810 <lyxtabular version="3" rows="7" columns="2">
3811 <features>
3812 <column alignment="center" valignment="top" width="0">
3813 <column alignment="left" valignment="top" width="0">
3814 <row>
3815 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
3816 \begin_inset Text
3818 \begin_layout Plain Layout
3819 a[n]
3820 \end_layout
3822 \end_inset
3823 </cell>
3824 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
3825 \begin_inset Text
3827 \begin_layout Plain Layout
3828 assigned text
3829 \end_layout
3831 \end_inset
3832 </cell>
3833 </row>
3834 <row>
3835 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
3836 \begin_inset Text
3838 \begin_layout Plain Layout
3840 \end_layout
3842 \end_inset
3843 </cell>
3844 <cell alignment="left" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
3845 \begin_inset Text
3847 \begin_layout Plain Layout
3848 freddie
3849 \end_layout
3851 \end_inset
3852 </cell>
3853 </row>
3854 <row>
3855 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
3856 \begin_inset Text
3858 \begin_layout Plain Layout
3860 \end_layout
3862 \end_inset
3863 </cell>
3864 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
3865 \begin_inset Text
3867 \begin_layout Plain Layout
3868 =freddie, foo={bar=baz, quux={quirk, a=fleeg}}, etc
3869 \end_layout
3871 \end_inset
3872 </cell>
3873 </row>
3874 <row>
3875 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
3876 \begin_inset Text
3878 \begin_layout Plain Layout
3880 \end_layout
3882 \end_inset
3883 </cell>
3884 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
3885 \begin_inset Text
3887 \begin_layout Plain Layout
3889 \end_layout
3891 \end_inset
3892 </cell>
3893 </row>
3894 <row>
3895 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
3896 \begin_inset Text
3898 \begin_layout Plain Layout
3900 \end_layout
3902 \end_inset
3903 </cell>
3904 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
3905 \begin_inset Text
3907 \begin_layout Plain Layout
3908 freddie, foo={bar=baz, quux={quirk, a=fleeg}}, etc
3909 \end_layout
3911 \end_inset
3912 </cell>
3913 </row>
3914 <row>
3915 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
3916 \begin_inset Text
3918 \begin_layout Plain Layout
3920 \end_layout
3922 \end_inset
3923 </cell>
3924 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
3925 \begin_inset Text
3927 \begin_layout Plain Layout
3928 freddie
3929 \end_layout
3931 \end_inset
3932 </cell>
3933 </row>
3934 <row>
3935 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
3936 \begin_inset Text
3938 \begin_layout Plain Layout
3940 \end_layout
3942 \end_inset
3943 </cell>
3944 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
3945 \begin_inset Text
3947 \begin_layout Plain Layout
3948 , foo={bar=baz, quux={quirk, a=fleeg}}, etc
3949 \end_layout
3951 \end_inset
3952 </cell>
3953 </row>
3954 </lyxtabular>
3956 \end_inset
3959 \end_layout
3961 \begin_layout Standard
3962 a[3] will be either 
3963 \begin_inset Flex CharStyle:Code
3964 status collapsed
3966 \begin_layout Plain Layout
3968 \end_layout
3970 \end_inset
3972  or 
3973 \begin_inset Flex CharStyle:Code
3974 status collapsed
3976 \begin_layout Plain Layout
3978 \end_layout
3980 \end_inset
3982  and signify whether the option named in 
3983 \begin_inset Flex CharStyle:Code
3984 status collapsed
3986 \begin_layout Plain Layout
3987 a[1]
3988 \end_layout
3990 \end_inset
3992  has a value or not (respectively).
3993 \end_layout
3995 \begin_layout Standard
3996 If the option does have a value, then if the expression 
3997 \begin_inset Flex CharStyle:Code
3998 status collapsed
4000 \begin_layout Plain Layout
4001 substr(a[4],1,1)
4002 \end_layout
4004 \end_inset
4006  returns a brace 
4007 \begin_inset Flex CharStyle:Code
4008 status collapsed
4010 \begin_layout Plain Layout
4012 \end_layout
4014 \end_inset
4016  it will signify that we need to recurse:
4017 \end_layout
4019 \begin_layout Standard
4020 \begin_inset listings
4021 inline false
4022 status open
4024 \begin_layout Plain Layout
4026 name=a[1];
4027 \end_layout
4029 \begin_layout Plain Layout
4031 if (a[3] == "=") {
4032 \end_layout
4034 \begin_layout Plain Layout
4036   if (substr(a[4],1,1) == "{") {
4037 \end_layout
4039 \begin_layout Plain Layout
4041     text = get_chunk_args(substr(a[4],2), values, path name SUBSEP);
4042 \end_layout
4044 \begin_layout Plain Layout
4046   } else {
4047 \end_layout
4049 \begin_layout Plain Layout
4051     values[path name]=a[5];
4052 \end_layout
4054 \begin_layout Plain Layout
4056     text = a[6];
4057 \end_layout
4059 \begin_layout Plain Layout
4061   }
4062 \end_layout
4064 \begin_layout Plain Layout
4066 } else {
4067 \end_layout
4069 \begin_layout Plain Layout
4071   values[path name]="";
4072 \end_layout
4074 \begin_layout Plain Layout
4076   text = a[2];
4077 \end_layout
4079 \begin_layout Plain Layout
4082 \end_layout
4084 \end_inset
4087 \end_layout
4089 \begin_layout Standard
4090 We can test this function like this:
4091 \end_layout
4093 \begin_layout Chunk
4094 gca-test.awk
4095 \end_layout
4097 \begin_layout Standard
4098 \begin_inset listings
4099 inline false
4100 status open
4102 \begin_layout Plain Layout
4105 \backslash
4106 chunkref{get_chunk_args()}>
4107 \end_layout
4109 \begin_layout Plain Layout
4111 BEGIN {
4112 \end_layout
4114 \begin_layout Plain Layout
4116   SUBSEP=".";
4117 \end_layout
4119 \begin_layout Plain Layout
4121 \end_layout
4123 \begin_layout Plain Layout
4125   print get_chunk_args("name=freddie, foo={bar=baz, quux={quirk, a=fleeg}},
4126  etc", a);
4127 \end_layout
4129 \begin_layout Plain Layout
4131   for (b in a) {
4132 \end_layout
4134 \begin_layout Plain Layout
4136     print "a[" b "] => " a[b];
4137 \end_layout
4139 \begin_layout Plain Layout
4141   }
4142 \end_layout
4144 \begin_layout Plain Layout
4147 \end_layout
4149 \end_inset
4152 \end_layout
4154 \begin_layout Standard
4155 which should give this output:
4156 \end_layout
4158 \begin_layout Chunk
4159 gca-test.awk-results
4160 \end_layout
4162 \begin_layout Standard
4163 \begin_inset listings
4164 inline false
4165 status open
4167 \begin_layout Plain Layout
4169 a[foo.quux.quirk] => 
4170 \end_layout
4172 \begin_layout Plain Layout
4174 a[foo.quux.a] => fleeg
4175 \end_layout
4177 \begin_layout Plain Layout
4179 a[foo.bar] => baz
4180 \end_layout
4182 \begin_layout Plain Layout
4184 a[etc] => 
4185 \end_layout
4187 \begin_layout Plain Layout
4189 a[name] => freddie
4190 \end_layout
4192 \end_inset
4195 \end_layout
4197 \begin_layout Section
4198 Parsing chunk arguments
4199 \end_layout
4201 \begin_layout Standard
4202 \begin_inset CommandInset label
4203 LatexCommand label
4204 name "cha:Chunk Arguments"
4206 \end_inset
4209 \end_layout
4211 \begin_layout Standard
4212 Arguments to paramterized chunks are expressed in round brackets as a comma
4213  separated list of optional arguments.
4214  For example, a chunk that is defined with:
4215 \end_layout
4217 \begin_layout LyX-Code
4219 \backslash
4220 Chunk{achunk, params=name ; address}
4221 \end_layout
4223 \begin_layout Standard
4224 could be invoked as:
4225 \end_layout
4227 \begin_layout LyX-Code
4229 \backslash
4230 chunkref{achunk}(John Jones, jones@example.com)
4231 \end_layout
4233 \begin_layout Standard
4234 An argument list may be as simple as in 
4235 \begin_inset Flex CharStyle:Code
4236 status collapsed
4238 \begin_layout Plain Layout
4240 \backslash
4241 chunkref{pull}(thing, otherthing)
4242 \end_layout
4244 \end_inset
4246  or as complex as:
4247 \end_layout
4249 \begin_layout LyX-Code
4251 \backslash
4252 chunkref{pull}(things[x, y], get_other_things(a, "(all)")) 
4253 \end_layout
4255 \begin_layout Standard
4256 --- which for all it's commas and quotes and parenthesis represents only
4257  two parameters: 
4258 \begin_inset Flex CharStyle:Code
4259 status collapsed
4261 \begin_layout Plain Layout
4262 things[x, y]
4263 \end_layout
4265 \end_inset
4267  and 
4268 \begin_inset Flex CharStyle:Code
4269 status collapsed
4271 \begin_layout Plain Layout
4272 get_other_things(a, "(all)")
4273 \end_layout
4275 \end_inset
4278 \end_layout
4280 \begin_layout Standard
4281 If we simply split parameter list on commas, then the comma in 
4282 \begin_inset Flex CharStyle:Code
4283 status collapsed
4285 \begin_layout Plain Layout
4286 things[x,y]
4287 \end_layout
4289 \end_inset
4291  would split into two seperate arguments: 
4292 \begin_inset Flex CharStyle:Code
4293 status collapsed
4295 \begin_layout Plain Layout
4296 things[x
4297 \end_layout
4299 \end_inset
4301  and 
4302 \begin_inset Flex CharStyle:Code
4303 status collapsed
4305 \begin_layout Plain Layout
4307 \end_layout
4309 \end_inset
4311 --- neither of which make sense on their own.
4312 \end_layout
4314 \begin_layout Standard
4315 One way to prevent this would be by refusing to split text between matching
4316  delimiters, such as 
4317 \begin_inset Flex CharStyle:Code
4318 status collapsed
4320 \begin_layout Plain Layout
4322 \end_layout
4324 \end_inset
4327 \begin_inset Flex CharStyle:Code
4328 status collapsed
4330 \begin_layout Plain Layout
4332 \end_layout
4334 \end_inset
4337 \begin_inset Flex CharStyle:Code
4338 status collapsed
4340 \begin_layout Plain Layout
4342 \end_layout
4344 \end_inset
4347 \begin_inset Flex CharStyle:Code
4348 status collapsed
4350 \begin_layout Plain Layout
4352 \end_layout
4354 \end_inset
4357 \begin_inset Flex CharStyle:Code
4358 status collapsed
4360 \begin_layout Plain Layout
4362 \end_layout
4364 \end_inset
4367 \begin_inset Flex CharStyle:Code
4368 status collapsed
4370 \begin_layout Plain Layout
4372 \end_layout
4374 \end_inset
4376  and most likely also 
4377 \begin_inset Flex CharStyle:Code
4378 status collapsed
4380 \begin_layout Plain Layout
4382 \end_layout
4384 \end_inset
4387 \begin_inset Flex CharStyle:Code
4388 status collapsed
4390 \begin_layout Plain Layout
4392 \end_layout
4394 \end_inset
4396  and 
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  Of course this also makes it impossible to pass such mis-matched code fragments
4418  as parameters, but I think that it would be hard for readers to cope with
4419  authors who would pass such code unbalanced fragments as chunk parameters
4420 \begin_inset Foot
4421 status collapsed
4423 \begin_layout Plain Layout
4424 I know that I couldn't cope with users doing such things, and although the
4425  GPL3 license prevents me from actually forbidding anyone from trying, if
4426  they want it to work they'll have to write the code themselves and not
4427  expect any support from me.
4428 \end_layout
4430 \end_inset
4433 \end_layout
4435 \begin_layout Standard
4436 Unfortunately, the full set of matching delimiters may vary from language
4437  to language.
4438  In certain C++ template contexts, 
4439 \begin_inset Flex CharStyle:Code
4440 status collapsed
4442 \begin_layout Plain Layout
4444 \end_layout
4446 \end_inset
4448  and 
4449 \begin_inset Flex CharStyle:Code
4450 status collapsed
4452 \begin_layout Plain Layout
4454 \end_layout
4456 \end_inset
4458  would count as delimiters, and yet in other contexts they would not.
4459 \end_layout
4461 \begin_layout Standard
4462 This puts me in the unfortunate position of having to parse-somewhat all
4463  programming languages without knowing what they are!
4464 \end_layout
4466 \begin_layout Standard
4467 However, if this universal mode-tracking is possible, then parsing the arguments
4468  would be trivial.
4469  Such a mode tracker is described in chapter 
4470 \begin_inset CommandInset ref
4471 LatexCommand ref
4472 reference "cha:modes"
4474 \end_inset
4476  and used here with simplicity.
4477 \end_layout
4479 \begin_layout Chunk
4480 parse_chunk_args
4481 \end_layout
4483 \begin_layout Standard
4484 \begin_inset listings
4485 inline false
4486 status open
4488 \begin_layout Plain Layout
4490 function parse_chunk_args(language, text, values, mode,
4491 \end_layout
4493 \begin_layout Plain Layout
4495   # local vars
4496 \end_layout
4498 \begin_layout Plain Layout
4500   c, context, rest)
4501 \end_layout
4503 \begin_layout Plain Layout
4506 \end_layout
4508 \begin_layout Plain Layout
4510   =<
4511 \backslash
4512 chunkref{new-mode-tracker}(context, language, mode)>
4513 \end_layout
4515 \begin_layout Plain Layout
4517   rest = mode_tracker(context, text, values);
4518 \end_layout
4520 \begin_layout Plain Layout
4522   # extract values
4523 \end_layout
4525 \begin_layout Plain Layout
4527   for(c=1; c <= context[0, "values"]; c++) {
4528 \end_layout
4530 \begin_layout Plain Layout
4532     values[c] = context[0, "values", c];
4533 \end_layout
4535 \begin_layout Plain Layout
4537   }
4538 \end_layout
4540 \begin_layout Plain Layout
4542   return rest;
4543 \end_layout
4545 \begin_layout Plain Layout
4548 \end_layout
4550 \end_inset
4553 \end_layout
4555 \begin_layout Section
4556 Expanding parameters in the text
4557 \end_layout
4559 \begin_layout Standard
4560 Within the body of the chunk, the parameters are referred to with: 
4561 \begin_inset Flex CharStyle:Code
4562 status collapsed
4564 \begin_layout Plain Layout
4565 ${name}
4566 \end_layout
4568 \end_inset
4570  and 
4571 \begin_inset Flex CharStyle:Code
4572 status collapsed
4574 \begin_layout Plain Layout
4575 ${address}
4576 \end_layout
4578 \end_inset
4581  There is a strong case that a LaTeX style notation should be used, like
4583 \backslash
4584 param{name} which would be expressed in the listing as =<
4585 \backslash
4586 param{name}> and be rendered as 
4587 \begin_inset listings
4588 inline true
4589 status open
4591 \begin_layout Plain Layout
4594 \backslash
4595 param{name}>
4596 \end_layout
4598 \end_inset
4601  Such notation would make me go blind, but I do intend to adopt it
4602 \begin_inset Foot
4603 status collapsed
4605 \begin_layout Plain Layout
4606 Probably when LyX's listings inset can recognize and render it, so that
4607  I no longer have to type =<\SpecialChar \ldots{}
4609 \end_layout
4611 \end_inset
4614 \end_layout
4616 \begin_layout Standard
4617 We therefore need a function 
4618 \begin_inset Flex CharStyle:Code
4619 status collapsed
4621 \begin_layout Plain Layout
4622 expand_chunk_args
4623 \end_layout
4625 \end_inset
4627  which will take a block of text, a list of permitted parameters, and the
4628  arguments which must substitute for the parameters.
4630 \end_layout
4632 \begin_layout Standard
4633 \begin_inset CommandInset label
4634 LatexCommand label
4635 name "Here-we-split"
4637 \end_inset
4639 Here we split the text on 
4640 \begin_inset Flex CharStyle:Code
4641 status collapsed
4643 \begin_layout Plain Layout
4645 \end_layout
4647 \end_inset
4649  which means that all parts except the first will begin with a parameter
4650  name which will be terminated by 
4651 \begin_inset Flex CharStyle:Code
4652 status collapsed
4654 \begin_layout Plain Layout
4656 \end_layout
4658 \end_inset
4661  The split function will consume the literal 
4662 \begin_inset Flex CharStyle:Code
4663 status collapsed
4665 \begin_layout Plain Layout
4667 \end_layout
4669 \end_inset
4671  in each case.
4672 \end_layout
4674 \begin_layout Chunk
4675 expand_chunk_args()
4676 \end_layout
4678 \begin_layout Standard
4679 \begin_inset listings
4680 inline false
4681 status open
4683 \begin_layout Plain Layout
4685 function expand_chunk_args(text, params, args,  
4686 \end_layout
4688 \begin_layout Plain Layout
4690   p, text_array, next_text, v, t, l)
4691 \end_layout
4693 \begin_layout Plain Layout
4696 \end_layout
4698 \begin_layout Plain Layout
4700   if (split(text, text_array, "
4701 \backslash
4703 \backslash
4704 ${")) {
4705 \end_layout
4707 \begin_layout Plain Layout
4709     =<
4710 \backslash
4711 chunkref{substitute-chunk-args}>
4712 \end_layout
4714 \begin_layout Plain Layout
4716   }
4717 \end_layout
4719 \begin_layout Plain Layout
4721 \end_layout
4723 \begin_layout Plain Layout
4725   return text;
4726 \end_layout
4728 \begin_layout Plain Layout
4731 \end_layout
4733 \end_inset
4736 \end_layout
4738 \begin_layout Standard
4739 First, we produce an associative array of substitution values indexed by
4740  parameter names.
4741  This will serve as a cache, allowing us to look up the replacement values
4742  as we extract each name.
4743 \end_layout
4745 \begin_layout Chunk
4746 substitute-chunk-args
4747 \end_layout
4749 \begin_layout Standard
4750 \begin_inset listings
4751 inline false
4752 status open
4754 \begin_layout Plain Layout
4756 for(p in params) {
4757 \end_layout
4759 \begin_layout Plain Layout
4761   v[params[p]]=args[p];
4762 \end_layout
4764 \begin_layout Plain Layout
4767 \end_layout
4769 \end_inset
4772 \end_layout
4774 \begin_layout Standard
4775 We accumulate substituted text in the variable 
4776 \begin_inset Flex CharStyle:Code
4777 status collapsed
4779 \begin_layout Plain Layout
4780 text
4781 \end_layout
4783 \end_inset
4786  As the first part of the split function is the part before the delimiter
4787  --- which is 
4788 \begin_inset Flex CharStyle:Code
4789 status collapsed
4791 \begin_layout Plain Layout
4793 \end_layout
4795 \end_inset
4797  in our case --- this part will never contain a parameter reference, so
4798  we assign this directly to the result kept in 
4799 \begin_inset Flex CharStyle:Code
4800 status collapsed
4802 \begin_layout Plain Layout
4803 $text
4804 \end_layout
4806 \end_inset
4809 \begin_inset listings
4810 inline false
4811 status open
4813 \begin_layout Plain Layout
4815 text=text_array[1];
4816 \end_layout
4818 \end_inset
4821 \end_layout
4823 \begin_layout Standard
4824 We then iterate over the remaining values in the array
4825 \begin_inset Foot
4826 status collapsed
4828 \begin_layout Plain Layout
4829 I don't know why I think that it will enumerate the array in order, but
4830  it seems to work
4831 \end_layout
4833 \end_inset
4836 \begin_inset Note Note
4837 status collapsed
4839 \begin_layout Plain Layout
4840 So fix it or porve it
4841 \end_layout
4843 \end_inset
4845 , and substitute each reference for it's argument.
4846 \end_layout
4848 \begin_layout Standard
4849 \begin_inset listings
4850 inline false
4851 status open
4853 \begin_layout Plain Layout
4855 for(t=2; t in text_array; t++) {
4856 \end_layout
4858 \begin_layout Plain Layout
4860   =<
4861 \backslash
4862 chunkref{substitute-chunk-arg}>
4863 \end_layout
4865 \begin_layout Plain Layout
4868 \end_layout
4870 \end_inset
4873 \end_layout
4875 \begin_layout Standard
4876 After the split on 
4877 \begin_inset Flex CharStyle:Code
4878 status collapsed
4880 \begin_layout Plain Layout
4882 \end_layout
4884 \end_inset
4886  a valid parameter reference will consist of valid parameter name terminated
4887  by a close-brace 
4888 \begin_inset Flex CharStyle:Code
4889 status collapsed
4891 \begin_layout Plain Layout
4893 \end_layout
4895 \end_inset
4898  A valid character name begins with the underscore or a letter, and may
4899  contain letters, digits or underscores.
4900 \end_layout
4902 \begin_layout Standard
4903 A valid looking reference that is not actually the name of a parameter will
4904  be and not substituted.
4905  This is good because there is nothing to substitute anyway, and it avoids
4906  clashes when writing code for languages where ${\SpecialChar \ldots{}
4907 } is a valid construct
4908  --- such constructs will not be interfered with unless the parameter name
4909  also matches.
4910 \end_layout
4912 \begin_layout Chunk
4913 substitute-chunk-arg
4914 \end_layout
4916 \begin_layout Standard
4917 \begin_inset listings
4918 inline false
4919 status open
4921 \begin_layout Plain Layout
4923 if (match(text_array[t], "^([a-zA-Z_][a-zA-Z0-9_]*)}", l) &&
4924 \end_layout
4926 \begin_layout Plain Layout
4928     l[1] in v) 
4929 \end_layout
4931 \begin_layout Plain Layout
4934 \end_layout
4936 \begin_layout Plain Layout
4938   text = text v[l[1]] substr(text_array[t], length(l[1])+2);
4939 \end_layout
4941 \begin_layout Plain Layout
4943 } else {
4944 \end_layout
4946 \begin_layout Plain Layout
4948   text = text "${" text_array[t];
4949 \end_layout
4951 \begin_layout Plain Layout
4954 \end_layout
4956 \end_inset
4959 \end_layout
4961 \begin_layout Chapter
4962 Language Modes
4963 \end_layout
4965 \begin_layout Standard
4966 \begin_inset CommandInset label
4967 LatexCommand label
4968 name "cha:modes"
4970 \end_inset
4973 \end_layout
4975 \begin_layout Section
4976 Modes
4977 \end_layout
4979 \begin_layout Standard
4980 lstlistings and newfangle both recognize source languages, and perform some
4981  basic parsing.
4982  lstlistings can detect strings and comments within a language definition
4983  and perform suitable rendering, such as italics for comments, and visible-space
4984 s within strings.
4985 \end_layout
4987 \begin_layout Standard
4988 Newfangle similarly can recognize strings, and comments, etc, within a language,
4989  so that any chunks included with 
4990 \begin_inset Flex CharStyle:Code
4991 status collapsed
4993 \begin_layout Plain Layout
4995 \backslash
4996 chunkref
4997 \end_layout
4999 \end_inset
5001  can be suitably escape or quoted.
5002 \end_layout
5004 \begin_layout Subsection
5005 Modes to keep code together
5006 \end_layout
5008 \begin_layout Standard
5009 As an example, in the C language there are a few parse modes, affecting
5010  the interpretation of characters.
5011 \end_layout
5013 \begin_layout Standard
5014 One parse mode is the strings mode.
5015  The string mode is commenced by an un-escaped quotation mark 
5016 \begin_inset Flex CharStyle:Code
5017 status collapsed
5019 \begin_layout Plain Layout
5021 \end_layout
5023 \end_inset
5025  and terminated by the same.
5026  Within the string mode, only one additional mode can be commenced, it is
5027  the backslash mode 
5028 \begin_inset Flex CharStyle:Code
5029 status collapsed
5031 \begin_layout Plain Layout
5033 \backslash
5035 \end_layout
5037 \end_inset
5039 , which is always terminated by the folloing character.
5040 \end_layout
5042 \begin_layout Standard
5043 Other modes are 
5044 \begin_inset Flex CharStyle:Code
5045 status collapsed
5047 \begin_layout Plain Layout
5049 \end_layout
5051 \end_inset
5053  which is terminated by a 
5054 \begin_inset Flex CharStyle:Code
5055 status collapsed
5057 \begin_layout Plain Layout
5059 \end_layout
5061 \end_inset
5063  (unless it occurs in a string).
5064 \end_layout
5066 \begin_layout Standard
5067 Consider this line of C code:
5068 \end_layout
5070 \begin_layout Standard
5071 \begin_inset Formula $\mathtt{things\underbrace{[\mathtt{x,\ y}]}_{1.\ [\ mode},\ get\_other\_things\underbrace{(\mathtt{a,\overbrace{"\mathtt{(all)}"}})}_{2.\ (\ mode}^{3.\ "\ mode}}$
5072 \end_inset
5075 \end_layout
5077 \begin_layout Standard
5078 Mode nesting prevents the close parenthesis in quote mode (part 3) from
5079  terminating the parenthesis mode (part 2).
5080 \end_layout
5082 \begin_layout Standard
5083 Each language has a set of modes, the default mode being the null mode.
5084  Each mode can lead to other modes.
5085 \end_layout
5087 \begin_layout Subsection
5088 Modes to included chunks
5089 \end_layout
5091 \begin_layout Standard
5092 For instance, consider this chunk with 
5093 \begin_inset Flex CharStyle:Code
5094 status collapsed
5096 \begin_layout Plain Layout
5097 language=perl
5098 \end_layout
5100 \end_inset
5103 \end_layout
5105 \begin_layout Chunk
5106 example-perl,language=perl
5107 \end_layout
5109 \begin_layout Standard
5110 \begin_inset listings
5111 inline false
5112 status open
5114 \begin_layout Plain Layout
5116 s/"$/'/;
5117 \end_layout
5119 \end_inset
5122 \end_layout
5124 \begin_layout Standard
5125 If it were included in a chunk with 
5126 \begin_inset Flex CharStyle:Code
5127 status collapsed
5129 \begin_layout Plain Layout
5130 language=sh
5131 \end_layout
5133 \end_inset
5135 , like this:
5136 \end_layout
5138 \begin_layout Chunk
5139 example-sh,language=sh
5140 \end_layout
5142 \begin_layout Standard
5143 \begin_inset listings
5144 inline false
5145 status open
5147 \begin_layout Plain Layout
5149 perl -pe "=<
5150 \backslash
5151 chunkref{example-perl}>"
5152 \end_layout
5154 \end_inset
5157 \end_layout
5159 \begin_layout Standard
5160 newfangle would need to generate output like this if it were to work: 
5161 \end_layout
5163 \begin_layout LyX-Code
5164 perl -pe "s/
5165 \backslash
5167 \backslash
5168 $/'/;"
5169 \end_layout
5171 \begin_layout Standard
5172 See that the double quote 
5173 \begin_inset Flex CharStyle:Code
5174 status collapsed
5176 \begin_layout Plain Layout
5178 \end_layout
5180 \end_inset
5182 , and 
5183 \begin_inset Flex CharStyle:Code
5184 status collapsed
5186 \begin_layout Plain Layout
5188 \end_layout
5190 \end_inset
5192  in the regex have been quoted with a back-slash to protect them from shell
5193  interpretation.
5194 \end_layout
5196 \begin_layout Standard
5197 If that were then included in a chunk with 
5198 \begin_inset Flex CharStyle:Code
5199 status collapsed
5201 \begin_layout Plain Layout
5202 language=make
5203 \end_layout
5205 \end_inset
5207 , like this:
5208 \end_layout
5210 \begin_layout Chunk
5211 example-makefile,language=make
5212 \end_layout
5214 \begin_layout Standard
5215 \begin_inset listings
5216 inline false
5217 status open
5219 \begin_layout Plain Layout
5221 target: pre-req
5222 \end_layout
5224 \begin_layout Plain Layout
5226                 =<
5227 \backslash
5228 chunkref{example-sh}>
5229 \end_layout
5231 \end_inset
5234 \end_layout
5236 \begin_layout Standard
5237 We would need the output to look like this --- note the $$:
5238 \end_layout
5240 \begin_layout LyX-Code
5241 target: pre-req
5242 \end_layout
5244 \begin_layout LyX-Code
5245         perl -pe "s/
5246 \backslash
5248 \backslash
5249 $$/'/;"
5250 \end_layout
5252 \begin_layout Standard
5253 In order to make this work, we need to define a mode-tracker supporting
5254  each language, that can detect the various quoting modes, and provide a
5255  transformation that must be applied to any included text so that included
5256  text will be interpreted correctly after any interpolation that it may
5257  be subject to at run-time.
5258 \end_layout
5260 \begin_layout Standard
5261 For example, the sed transformation for text to be inserted into sh double-quote
5262 d strings would be something like:
5263 \end_layout
5265 \begin_layout LyX-Code
5267 \backslash
5269 \backslash
5271 \backslash
5273 \backslash
5275 \backslash
5277 \backslash
5278 /g;s/$/
5279 \backslash
5281 \backslash
5282 $/g;s/"/
5283 \backslash
5285 \backslash
5286 "/g;
5287 \end_layout
5289 \begin_layout Standard
5290 which protects 
5291 \begin_inset Flex CharStyle:Code
5292 status collapsed
5294 \begin_layout Plain Layout
5296 \backslash
5297  $ "
5298 \end_layout
5300 \end_inset
5303 \end_layout
5305 \begin_layout Standard
5306 \begin_inset Note Note
5307 status collapsed
5309 \begin_layout Plain Layout
5310 I don't think this example is true
5311 \end_layout
5313 \end_inset
5315 The mode tracker must also track nested mode-changes, as in this 
5316 \begin_inset Flex CharStyle:Code
5317 status collapsed
5319 \begin_layout Plain Layout
5321 \end_layout
5323 \end_inset
5325  example.
5326 \end_layout
5328 \begin_layout LyX-Code
5329 echo "hello `id \SpecialChar \ldots{}
5331 \end_layout
5333 \begin_layout LyX-Code
5334 \begin_inset ERT
5335 status open
5337 \begin_layout Plain Layout
5340 \backslash
5341 noindent
5342 \backslash
5343 hphantom{echo "hello `id}
5344 \end_layout
5346 \end_inset
5349 \end_layout
5351 \begin_layout Standard
5352 Any characters inserted at the point marked ↑ would need to be escaped,
5353  including 
5354 \begin_inset Flex CharStyle:Code
5355 status collapsed
5357 \begin_layout Plain Layout
5358 ` | *
5359 \end_layout
5361 \end_inset
5363  among others.
5364  First it would need escaping for the back-ticks `, and then for the double-quot
5365 es ".
5366 \end_layout
5368 \begin_layout Standard
5369 Escaping need not occur if the format and mode of the included chunk matches
5370  that of the including chunk.
5371 \end_layout
5373 \begin_layout Standard
5374 As each chunk is output a new mode tracker for that language is initialized
5375  in it's normal state.
5376  As text is output for that chunk the output mode is tracked.
5377  When a new chunk is included, a transformation appropriate to that mode
5378  is selected and pushed onto a stack of transformations.
5379  Any text to be output is first passed through this stack of transformations.
5380 \end_layout
5382 \begin_layout Standard
5383 It remains to consider if the chunk-include function should return it's
5384  generated text so that the caller can apply any transformations (and formatting
5385 ), or if it should apply the stack of transformations itself.
5386 \end_layout
5388 \begin_layout Standard
5389 Note that the transformed text should have the property of not being able
5390  to change the mode in the current chunk.
5391 \end_layout
5393 \begin_layout Standard
5394 \begin_inset Note Note
5395 status open
5397 \begin_layout Plain Layout
5398 Note chunk parameters should probably also be transformed
5399 \end_layout
5401 \end_inset
5404 \end_layout
5406 \begin_layout Section
5407 Language Mode Definitions
5408 \end_layout
5410 \begin_layout Standard
5411 All modes are stored in a single multi-dimensional hash.
5412  The first index is the language, and the second index is the mode-identifier.
5413  The third indexes are terminators, and optionally, submodes, and delimiters.
5414 \end_layout
5416 \begin_layout Standard
5417 A useful set of mode definitions for a nameless general C-type language
5418  is shown here.
5419  (Don't be confused by the double backslash escaping needed in awk.
5420  One set of escaping is for the string, and the second set of escaping is
5421  for the regex).
5423 \begin_inset Note Note
5424 status open
5426 \begin_layout Plain Layout
5427 TODO: Add =<
5428 \backslash
5429 mode{}> command which will allow us to signify that a string is regex and
5430  thus newfangle will quote it for us.
5431 \end_layout
5433 \end_inset
5436 \end_layout
5438 \begin_layout Standard
5439 Submodes are entered by the characters 
5440 \begin_inset Flex CharStyle:Code
5441 status collapsed
5443 \begin_layout Plain Layout
5445 \backslash
5447 \end_layout
5449 \end_inset
5452 \begin_inset Flex CharStyle:Code
5453 status collapsed
5455 \begin_layout Plain Layout
5457 \end_layout
5459 \end_inset
5462 \begin_inset Flex CharStyle:Code
5463 status collapsed
5465 \begin_layout Plain Layout
5467 \end_layout
5469 \end_inset
5472 \begin_inset Flex CharStyle:Code
5473 status collapsed
5475 \begin_layout Plain Layout
5477 \end_layout
5479 \end_inset
5482 \begin_inset Flex CharStyle:Code
5483 status collapsed
5485 \begin_layout Plain Layout
5487 \end_layout
5489 \end_inset
5492 \begin_inset Flex CharStyle:Code
5493 status collapsed
5495 \begin_layout Plain Layout
5497 \end_layout
5499 \end_inset
5502 \begin_inset Flex CharStyle:Code
5503 status collapsed
5505 \begin_layout Plain Layout
5507 \end_layout
5509 \end_inset
5512 \end_layout
5514 \begin_layout Chunk
5515 common-mode-definitions,params=language
5516 \end_layout
5518 \begin_layout Standard
5519 \begin_inset listings
5520 inline false
5521 status open
5523 \begin_layout Plain Layout
5525 modes[${language}, "",  "submodes" ]="
5526 \backslash
5528 \backslash
5530 \backslash
5532 \backslash
5534 \backslash
5535 "|'|{|
5536 \backslash
5538 \backslash
5540 \backslash
5542 \backslash
5544 \end_layout
5546 \end_inset
5549 \end_layout
5551 \begin_layout Standard
5552 In the default mode, a comma surrounded by un-important white space is a
5553  delimiter of language items.
5554 \end_layout
5556 \begin_layout Standard
5557 \begin_inset listings
5558 inline false
5559 status open
5561 \begin_layout Plain Layout
5563 modes[${language}, "",  "delimiters"]=" *, *";
5564 \end_layout
5566 \end_inset
5569 \end_layout
5571 \begin_layout Standard
5572 and should pass this test:
5573 \end_layout
5575 \begin_layout Standard
5576 \begin_inset Note Note
5577 status open
5579 \begin_layout Plain Layout
5580 Why do the tests run in 
5581 \begin_inset Quotes eld
5582 \end_inset
5585 \begin_inset Quotes erd
5586 \end_inset
5588  mode and not 
5589 \begin_inset Quotes eld
5590 \end_inset
5593 \begin_inset Quotes erd
5594 \end_inset
5596  mode
5597 \end_layout
5599 \end_inset
5602 \end_layout
5604 \begin_layout Chunk
5605 test:mode-definitions
5606 \end_layout
5608 \begin_layout Standard
5609 \begin_inset listings
5610 inline false
5611 status open
5613 \begin_layout Plain Layout
5615 parse_chunk_args("c-like", "1,2,3", a, "");
5616 \end_layout
5618 \begin_layout Plain Layout
5620 if (a[1] != "1") e++;
5621 \end_layout
5623 \begin_layout Plain Layout
5625 if (a[2] != "2") e++;
5626 \end_layout
5628 \begin_layout Plain Layout
5630 if (a[3] != "3") e++;
5631 \end_layout
5633 \begin_layout Plain Layout
5635 if (length(a) != 3) e++;
5636 \end_layout
5638 \begin_layout Plain Layout
5641 \backslash
5642 chunkref{pca-test.awk:summary}>
5643 \end_layout
5645 \begin_layout Plain Layout
5647 \end_layout
5649 \begin_layout Plain Layout
5651 parse_chunk_args("c-like", "joe, red", a, "");
5652 \end_layout
5654 \begin_layout Plain Layout
5656 if (a[1] != "joe") e++;
5657 \end_layout
5659 \begin_layout Plain Layout
5661 if (a[2] != "red") e++;
5662 \end_layout
5664 \begin_layout Plain Layout
5666 if (length(a) != 2) e++;
5667 \end_layout
5669 \begin_layout Plain Layout
5672 \backslash
5673 chunkref{pca-test.awk:summary}>
5674 \end_layout
5676 \begin_layout Plain Layout
5678 \end_layout
5680 \begin_layout Plain Layout
5682 parse_chunk_args("c-like", "${colour}", a, "");
5683 \end_layout
5685 \begin_layout Plain Layout
5687 if (a[1] != "${colour}") e++;
5688 \end_layout
5690 \begin_layout Plain Layout
5692 if (length(a) != 1) e++;
5693 \end_layout
5695 \begin_layout Plain Layout
5698 \backslash
5699 chunkref{pca-test.awk:summary}>
5700 \end_layout
5702 \end_inset
5705 \end_layout
5707 \begin_layout Standard
5708 Nested modes are identified by a backslash, a double or single quote, various
5709  bracket styles or a /* comment.
5710 \end_layout
5712 \begin_layout Standard
5713 For each of these sub-modes modes we must also identify at a mode terminator,
5714  and any sub-modes or delimiters that may be entered
5715 \begin_inset Foot
5716 status collapsed
5718 \begin_layout Plain Layout
5719 Because we are using the sub-mode characters as the mode identifier it means
5720  we can't currently have a mode character dependant on it's context; i.e.
5722 \begin_inset Flex CharStyle:Code
5723 status collapsed
5725 \begin_layout Plain Layout
5727 \end_layout
5729 \end_inset
5731  can't behave differently when it is inside 
5732 \begin_inset Flex CharStyle:Code
5733 status collapsed
5735 \begin_layout Plain Layout
5737 \end_layout
5739 \end_inset
5742 \end_layout
5744 \end_inset
5747 \end_layout
5749 \begin_layout Subsection
5750 Backslash
5751 \end_layout
5753 \begin_layout Standard
5754 The backslash mode has no submodes or delimiters, and is terminated by any
5755  character.
5756  Note that we are not so much interested in evaluating or interpolating
5757  content as we are in delineating content.
5758  It is no matter that a double backslash (
5759 \begin_inset Flex CharStyle:Code
5760 status collapsed
5762 \begin_layout Plain Layout
5764 \backslash
5766 \backslash
5768 \end_layout
5770 \end_inset
5772 ) may represent a single backslash while a backslash-newline may represent
5773  white space, but it does matter that the newline in a backslash newline
5774  should not be able to terminate a C pre-processor statement; and so the
5775  newline will be consumed by the backslash however it is to be interpreted.
5776 \end_layout
5778 \begin_layout Chunk
5779 common-mode-definitions
5780 \end_layout
5782 \begin_layout Standard
5783 \begin_inset listings
5784 inline false
5785 status open
5787 \begin_layout Plain Layout
5789 modes[${language}, "
5790 \backslash
5792 \backslash
5793 ", "terminators"]=".";
5794 \end_layout
5796 \end_inset
5799 \end_layout
5801 \begin_layout Subsection
5802 Strings
5803 \end_layout
5805 \begin_layout Standard
5806 Common languages support two kinds of strings quoting, double quotes and
5807  single quotes.
5808 \end_layout
5810 \begin_layout Chunk
5811 mode:common-string,params=language;quote
5812 \end_layout
5814 \begin_layout Standard
5815 In a string we have one special mode, which is the backslash.
5816  This may escape an embedded quote and prevent us thinking that it should
5817  terminate the string.
5819 \end_layout
5821 \begin_layout Standard
5822 \begin_inset listings
5823 inline false
5824 status open
5826 \begin_layout Plain Layout
5828 modes[${language}, ${quote}, "submodes" ]="
5829 \backslash
5831 \backslash
5833 \backslash
5835 \backslash
5837 \end_layout
5839 \end_inset
5842 \end_layout
5844 \begin_layout Standard
5845 Otherwise, the string will be terminated by the same character that commenced
5846  it.
5847 \end_layout
5849 \begin_layout Standard
5850 \begin_inset listings
5851 inline false
5852 status open
5854 \begin_layout Plain Layout
5856 modes[${language}, ${quote}, "terminators"]=${quote};
5857 \end_layout
5859 \end_inset
5862 \end_layout
5864 \begin_layout Standard
5865 In C type languages, certain escape sequences exist in strings.
5866  We need to define mechanism to enclode any chunks included in this mode
5867  using those escape sequences.
5868  These are expressed in two parts, s meaning search, and r meaning replace.
5869 \end_layout
5871 \begin_layout Standard
5872 The first substitution is to replace a backslash with a double backslash.
5873  We do this first as other substitutions may introduce a backslash which
5874  we would not then want to escape again here.
5875 \end_layout
5877 \begin_layout Standard
5878 \begin_inset listings
5879 inline false
5880 status open
5882 \begin_layout Plain Layout
5884 escapes[${language}, ${quote}, ++escapes[${language}, ${quote}], "s"]="
5885 \backslash
5887 \backslash
5889 \end_layout
5891 \begin_layout Plain Layout
5893 escapes[${language}, ${quote},   escapes[${language}, ${quote}], "r"]="
5894 \backslash
5896 \backslash
5898 \backslash
5900 \backslash
5902 \end_layout
5904 \end_inset
5907 \end_layout
5909 \begin_layout Standard
5910 If the quote character occurs in the text, it should be preceded by a backslash,
5911  otherwise it would terminate the string unexpectedly.
5912 \end_layout
5914 \begin_layout Standard
5915 \begin_inset listings
5916 inline false
5917 status open
5919 \begin_layout Plain Layout
5921 escapes[${language}, ${quote}, ++escapes[${language}, ${quote}], "s"]=${quote};
5922 \end_layout
5924 \begin_layout Plain Layout
5926 escapes[${language}, ${quote},   escapes[${language}, ${quote}], "r"]="
5927 \backslash
5929 \backslash
5930 " ${quote};
5931 \end_layout
5933 \end_inset
5936 \end_layout
5938 \begin_layout Standard
5939 Any newlines in the string, must be replaced by 
5940 \begin_inset Flex CharStyle:Code
5941 status collapsed
5943 \begin_layout Plain Layout
5945 \backslash
5947 \end_layout
5949 \end_inset
5952 \end_layout
5954 \begin_layout Standard
5955 \begin_inset listings
5956 inline false
5957 status open
5959 \begin_layout Plain Layout
5961 escapes[${language}, ${quote}, ++escapes[${language}, ${quote}], "s"]="
5962 \backslash
5964 \end_layout
5966 \begin_layout Plain Layout
5968 escapes[${language}, ${quote},   escapes[${language}, ${quote}], "r"]="
5969 \backslash
5971 \backslash
5973 \end_layout
5975 \end_inset
5978 \end_layout
5980 \begin_layout Standard
5981 For the common modes, we define this string handling for double and single
5982  quotes.
5983 \end_layout
5985 \begin_layout Chunk
5986 common-mode-definitions,params=language
5987 \end_layout
5989 \begin_layout Standard
5990 \begin_inset listings
5991 inline false
5992 status open
5994 \begin_layout Plain Layout
5997 \backslash
5998 chunkref{mode:common-string}(${language}, "
5999 \backslash
6000 textbackslash{}"")>
6001 \end_layout
6003 \begin_layout Plain Layout
6006 \backslash
6007 chunkref{mode:common-string}(${language}, "'")>
6008 \end_layout
6010 \end_inset
6013 \end_layout
6015 \begin_layout Standard
6016 Working strings should pass this test:
6017 \end_layout
6019 \begin_layout Chunk
6020 test:mode-definitions
6021 \end_layout
6023 \begin_layout Standard
6024 \begin_inset listings
6025 inline false
6026 status open
6028 \begin_layout Plain Layout
6030 parse_chunk_args("c-like", "say 
6031 \backslash
6032 "I said, 
6033 \backslash
6035 \backslash
6037 \backslash
6038 "Hello, how are you
6039 \backslash
6041 \backslash
6043 \backslash
6045 \backslash
6046 ", for me", a, "");
6047 \end_layout
6049 \begin_layout Plain Layout
6051 if (a[1] != "say 
6052 \backslash
6053 "I said, 
6054 \backslash
6056 \backslash
6058 \backslash
6059 "Hello, how are you
6060 \backslash
6062 \backslash
6064 \backslash
6066 \backslash
6067 "") e++;
6068 \end_layout
6070 \begin_layout Plain Layout
6072 if (a[2] != "for me") e++;
6073 \end_layout
6075 \begin_layout Plain Layout
6077 if (length(a) != 2) e++;
6078 \end_layout
6080 \begin_layout Plain Layout
6083 \backslash
6084 chunkref{pca-test.awk:summary}>
6085 \end_layout
6087 \end_inset
6090 \end_layout
6092 \begin_layout Subsection
6093 Parentheses, Braces and Brackets
6094 \end_layout
6096 \begin_layout Standard
6097 Where quotes are closed by the same character, parentheses, brackets and
6098  braces are closed by an alternate character.
6099 \end_layout
6101 \begin_layout Chunk
6102 mode:common-brackets,params=language;open;close
6103 \end_layout
6105 \begin_layout Standard
6106 \begin_inset listings
6107 inline false
6108 status open
6110 \begin_layout Plain Layout
6112 modes[${language}, ${open},  "submodes" ]="
6113 \backslash
6115 \backslash
6117 \backslash
6119 \backslash
6121 \backslash
6122 "|{|
6123 \backslash
6125 \backslash
6127 \backslash
6129 \backslash
6130 [|'|/
6131 \backslash
6133 \backslash
6135 \end_layout
6137 \begin_layout Plain Layout
6139 modes[${language}, ${open},  "delimiters"]=" *, *";
6140 \end_layout
6142 \begin_layout Plain Layout
6144 modes[${language}, ${open},  "terminators"]=${close};
6145 \end_layout
6147 \end_inset
6150 \end_layout
6152 \begin_layout Standard
6153 Note that the open is NOT a regex but the close token IS.
6155 \begin_inset Note Note
6156 status open
6158 \begin_layout Plain Layout
6159 WHen we can quote regex we won't have to put the slashes in here
6160 \end_layout
6162 \end_inset
6165 \end_layout
6167 \begin_layout Chunk
6168 common-mode-definitions,params=language
6169 \end_layout
6171 \begin_layout Standard
6172 \begin_inset listings
6173 inline false
6174 status open
6176 \begin_layout Plain Layout
6179 \backslash
6180 chunkref{mode:common-brackets}(${language}, "{", "}")>
6181 \end_layout
6183 \begin_layout Plain Layout
6186 \backslash
6187 chunkref{mode:common-brackets}(${language}, "[", "
6188 \backslash
6189 textbackslash{}
6190 \backslash
6191 textbackslash{}]")>
6192 \end_layout
6194 \begin_layout Plain Layout
6197 \backslash
6198 chunkref{mode:common-brackets}(${language}, "(", "
6199 \backslash
6200 textbackslash{}
6201 \backslash
6202 textbackslash{})")>
6203 \end_layout
6205 \end_inset
6208 \end_layout
6210 \begin_layout Subsection
6211 Customizing Standard Modes
6212 \end_layout
6214 \begin_layout Chunk
6215 mode:add-submode,params=language;mode;submode
6216 \end_layout
6218 \begin_layout Standard
6219 \begin_inset listings
6220 inline false
6221 status open
6223 \begin_layout Plain Layout
6225 modes[${language}, ${mode}, "submodes"] = modes[${language}, ${mode}, "submodes"
6226 ] "|" ${submode};
6227 \end_layout
6229 \end_inset
6232 \end_layout
6234 \begin_layout Chunk
6235 mode:add-escapes,params=language;mode;search;replace
6236 \end_layout
6238 \begin_layout Standard
6239 \begin_inset listings
6240 inline false
6241 status open
6243 \begin_layout Plain Layout
6245 escapes[${language}, ${mode}, ++escapes[${language}, ${mode}], "s"]=${search};
6246 \end_layout
6248 \begin_layout Plain Layout
6250 escapes[${language}, ${mode},   escapes[${language}, ${mode}], "r"]=${replace};
6251 \end_layout
6253 \end_inset
6256 \end_layout
6258 \begin_layout Subsection
6259 Comments
6260 \end_layout
6262 \begin_layout Standard
6263 We can define 
6264 \begin_inset Flex CharStyle:Code
6265 status collapsed
6267 \begin_layout Plain Layout
6268 /* comment */
6269 \end_layout
6271 \end_inset
6273  style comments and 
6274 \begin_inset Flex CharStyle:Code
6275 status collapsed
6277 \begin_layout Plain Layout
6278 //comment
6279 \end_layout
6281 \end_inset
6283  style comments to be added to any language:
6284 \end_layout
6286 \begin_layout Chunk
6287 mode:multi-line-comments,params=language
6288 \end_layout
6290 \begin_layout Standard
6291 \begin_inset listings
6292 inline false
6293 status open
6295 \begin_layout Plain Layout
6298 \backslash
6299 chunkref{mode:add-submode}(${language}, "", "/
6300 \backslash
6301 textbackslash{}
6302 \backslash
6303 textbackslash{}*")>
6304 \end_layout
6306 \begin_layout Plain Layout
6308 modes[${language}, "/*", "terminators"]="
6309 \backslash
6311 \backslash
6312 */";
6313 \end_layout
6315 \end_inset
6318 \end_layout
6320 \begin_layout Chunk
6321 mode:single-line-slash-comments,params=language
6322 \end_layout
6324 \begin_layout Standard
6325 \begin_inset listings
6326 inline false
6327 status open
6329 \begin_layout Plain Layout
6332 \backslash
6333 chunkref{mode:add-submode}(${language}, "", "//")>
6334 \end_layout
6336 \begin_layout Plain Layout
6338 modes[${language}, "//", "terminators"]="
6339 \backslash
6341 \end_layout
6343 \begin_layout Plain Layout
6346 \backslash
6347 chunkref{mode:add-escapes}(${language}, "//", "
6348 \backslash
6349 textbackslash{}n", "
6350 \backslash
6351 textbackslash{}n//")>
6352 \end_layout
6354 \end_inset
6357 \end_layout
6359 \begin_layout Standard
6360 We can also define 
6361 \begin_inset Flex CharStyle:Code
6362 status collapsed
6364 \begin_layout Plain Layout
6365 # comment
6366 \end_layout
6368 \end_inset
6370  style comments (as used in awk and shell scripts) in a similar manner.
6371 \end_layout
6373 \begin_layout Chunk
6374 mode:add-hash-comments,params=language
6375 \begin_inset Note Note
6376 status open
6378 \begin_layout Plain Layout
6379 I'm having to use 
6380 \backslash
6381 # for hash and 
6382 \backslash
6383 textbackslash{} for 
6384 \backslash
6385  and have hacky work-arounds in the parser for now
6386 \end_layout
6388 \end_inset
6391 \end_layout
6393 \begin_layout Standard
6394 \begin_inset listings
6395 inline false
6396 status open
6398 \begin_layout Plain Layout
6401 \backslash
6402 chunkref{mode:add-submode}(${language}, "", "
6403 \backslash
6404 #")>
6405 \end_layout
6407 \begin_layout Plain Layout
6409 modes[${language}, "#", "terminators"]="
6410 \backslash
6412 \end_layout
6414 \begin_layout Plain Layout
6417 \backslash
6418 chunkref{mode:add-escapes}(${language}, "
6419 \backslash
6420 #", "
6421 \backslash
6422 textbackslash{}n", "
6423 \backslash
6424 textbackslash{}n
6425 \backslash
6426 #")>
6427 \end_layout
6429 \end_inset
6432 \end_layout
6434 \begin_layout Standard
6435 In C, the 
6436 \begin_inset Flex CharStyle:Code
6437 status collapsed
6439 \begin_layout Plain Layout
6441 \end_layout
6443 \end_inset
6445  denotes pre-processor directives which can be multi-line 
6446 \end_layout
6448 \begin_layout Chunk
6449 mode:add-hash-defines,params=language
6450 \end_layout
6452 \begin_layout Standard
6453 \begin_inset listings
6454 inline false
6455 status open
6457 \begin_layout Plain Layout
6460 \backslash
6461 chunkref{mode:add-submode}(${language}, "", "
6462 \backslash
6463 #")>
6464 \end_layout
6466 \begin_layout Plain Layout
6468 modes[${language}, "#", "submodes" ]="
6469 \backslash
6471 \backslash
6473 \backslash
6475 \backslash
6477 \end_layout
6479 \begin_layout Plain Layout
6481 modes[${language}, "#", "terminators"]="
6482 \backslash
6484 \end_layout
6486 \begin_layout Plain Layout
6489 \backslash
6490 chunkref{mode:add-escapes}(${language}, "
6491 \backslash
6492 #", "
6493 \backslash
6494 textbackslash{}n", "
6495 \backslash
6496 textbackslash{}
6497 \backslash
6498 textbackslash{}
6499 \backslash
6500 textbackslash{}
6501 \backslash
6502 textbackslash{}
6503 \backslash
6504 textbackslash{}n")>
6505 \end_layout
6507 \end_inset
6510 \end_layout
6512 \begin_layout Standard
6513 We can add these definitions to various languages
6514 \end_layout
6516 \begin_layout Chunk
6517 mode-definitions
6518 \end_layout
6520 \begin_layout Standard
6521 \begin_inset listings
6522 inline false
6523 status open
6525 \begin_layout Plain Layout
6528 \backslash
6529 chunkref{common-mode-definitions}("c-like")>
6530 \end_layout
6532 \begin_layout Plain Layout
6534 \end_layout
6536 \begin_layout Plain Layout
6539 \backslash
6540 chunkref{common-mode-definitions}("c")>
6541 \end_layout
6543 \begin_layout Plain Layout
6546 \backslash
6547 chunkref{mode:multi-line-comments}("c")>
6548 \end_layout
6550 \begin_layout Plain Layout
6553 \backslash
6554 chunkref{mode:single-line-slash-comments}("c")>
6555 \end_layout
6557 \begin_layout Plain Layout
6560 \backslash
6561 chunkref{mode:add-hash-defines}("c")>
6562 \end_layout
6564 \begin_layout Plain Layout
6566 \end_layout
6568 \begin_layout Plain Layout
6571 \backslash
6572 chunkref{common-mode-definitions}("awk")>
6573 \end_layout
6575 \begin_layout Plain Layout
6578 \backslash
6579 chunkref{mode:add-hash-comments}("awk")>
6580 \end_layout
6582 \end_inset
6585 \end_layout
6587 \begin_layout Standard
6588 The awk definitions should allow a comment block like this:
6589 \end_layout
6591 \begin_layout Chunk
6592 test:comment-quote,language=awk
6593 \end_layout
6595 \begin_layout Standard
6596 \begin_inset listings
6597 inline false
6598 status open
6600 \begin_layout Plain Layout
6602 # Comment: =<
6603 \backslash
6604 chunkref{test:comment-text}>
6605 \end_layout
6607 \end_inset
6610 \end_layout
6612 \begin_layout Chunk
6613 test:comment-text,language=
6614 \end_layout
6616 \begin_layout Standard
6617 \begin_inset listings
6618 inline false
6619 status open
6621 \begin_layout Plain Layout
6623 Now is the time for
6624 \end_layout
6626 \begin_layout Plain Layout
6628 the quick brown fox to bring lemonade
6629 \end_layout
6631 \begin_layout Plain Layout
6633 to the party
6634 \end_layout
6636 \end_inset
6639 \end_layout
6641 \begin_layout Standard
6642 to come out like this:
6643 \end_layout
6645 \begin_layout Chunk
6646 test:comment-quote:result
6647 \end_layout
6649 \begin_layout Standard
6650 \begin_inset listings
6651 inline false
6652 status open
6654 \begin_layout Plain Layout
6656 # Comment: Now is the time for
6657 \end_layout
6659 \begin_layout Plain Layout
6661 #the quick brown fox to bring lemonade
6662 \end_layout
6664 \begin_layout Plain Layout
6666 #to the party
6667 \end_layout
6669 \end_inset
6672 \end_layout
6674 \begin_layout Standard
6675 The C definition for such a block should have it come out like this:
6676 \end_layout
6678 \begin_layout Chunk
6679 test:comment-quote:C-result
6680 \end_layout
6682 \begin_layout Standard
6683 \begin_inset listings
6684 inline false
6685 status open
6687 \begin_layout Plain Layout
6689 # Comment: Now is the time for
6690 \backslash
6692 \end_layout
6694 \begin_layout Plain Layout
6696 the quick brown fox to bring lemonade
6697 \backslash
6699 \end_layout
6701 \begin_layout Plain Layout
6703 to the party
6704 \end_layout
6706 \end_inset
6709 \end_layout
6711 \begin_layout Section
6712 Some tests
6713 \end_layout
6715 \begin_layout Standard
6716 Also, the parser must return any spare text at the end that has not been
6717  processed due to a mode terminator being found.
6718 \end_layout
6720 \begin_layout Chunk
6721 test:mode-definitions
6722 \end_layout
6724 \begin_layout Standard
6725 \begin_inset listings
6726 inline false
6727 status open
6729 \begin_layout Plain Layout
6731 rest = parse_chunk_args("c-like", "1, 2, 3) spare", a, "(");
6732 \end_layout
6734 \begin_layout Plain Layout
6736 if (a[1] != 1) e++;
6737 \end_layout
6739 \begin_layout Plain Layout
6741 if (a[2] != 2) e++;
6742 \end_layout
6744 \begin_layout Plain Layout
6746 if (a[3] != 3) e++;
6747 \end_layout
6749 \begin_layout Plain Layout
6751 if (length(a) != 3) e++;
6752 \end_layout
6754 \begin_layout Plain Layout
6756 if (rest != " spare") e++;
6757 \end_layout
6759 \begin_layout Plain Layout
6762 \backslash
6763 chunkref{pca-test.awk:summary}>
6764 \end_layout
6766 \end_inset
6769 \end_layout
6771 \begin_layout Standard
6772 We must also be able to parse the example given earlier.
6773 \end_layout
6775 \begin_layout Chunk
6776 test:mode-definitions
6777 \end_layout
6779 \begin_layout Standard
6780 \begin_inset listings
6781 inline false
6782 status open
6784 \begin_layout Plain Layout
6786 parse_chunk_args("c-like", "things[x, y], get_other_things(a, 
6787 \backslash
6788 "(all)
6789 \backslash
6790 "), 99", a, "(");
6791 \end_layout
6793 \begin_layout Plain Layout
6795 if (a[1] != "things[x, y]") e++;
6796 \end_layout
6798 \begin_layout Plain Layout
6800 if (a[2] != "get_other_things(a, 
6801 \backslash
6802 "(all)
6803 \backslash
6804 ")") e++;
6805 \end_layout
6807 \begin_layout Plain Layout
6809 if (a[3] != "99") e++;
6810 \end_layout
6812 \begin_layout Plain Layout
6814 if (length(a) != 3) e++;
6815 \end_layout
6817 \begin_layout Plain Layout
6820 \backslash
6821 chunkref{pca-test.awk:summary}>
6822 \end_layout
6824 \end_inset
6827 \end_layout
6829 \begin_layout Section
6830 A non-recursive mode tracker
6831 \end_layout
6833 \begin_layout Subsection
6834 Constructor
6835 \end_layout
6837 \begin_layout Standard
6838 The mode tracker holds its state in a stack based on a hash.
6839  This function, when passed an empty hash will intialize it.
6840 \end_layout
6842 \begin_layout Chunk
6843 new_mode_tracker()
6844 \end_layout
6846 \begin_layout Standard
6847 \begin_inset listings
6848 inline false
6849 status open
6851 \begin_layout Plain Layout
6853 function new_mode_tracker(context, language, mode) {
6854 \end_layout
6856 \begin_layout Plain Layout
6858   context[""] = 0;
6859 \end_layout
6861 \begin_layout Plain Layout
6863   context[0, "language"] = language;
6864 \end_layout
6866 \begin_layout Plain Layout
6868   context[0, "mode"] = mode;
6869 \end_layout
6871 \begin_layout Plain Layout
6874 \end_layout
6876 \end_inset
6879 \end_layout
6881 \begin_layout Standard
6882 Because awk functions cannot return an array, we must create the array first
6883  and pass it in, so we have a newfangle macro to do this:
6884 \end_layout
6886 \begin_layout Chunk
6887 new-mode-tracker,language=awk,params=context;language;mode
6888 \end_layout
6890 \begin_layout Standard
6891 \begin_inset listings
6892 inline false
6893 status open
6895 \begin_layout Plain Layout
6898 \backslash
6899 chunkref{awk-delete-array}(${context})>
6900 \end_layout
6902 \begin_layout Plain Layout
6904 new_mode_tracker(${context}, ${language}, ${mode});
6905 \end_layout
6907 \end_inset
6910 \end_layout
6912 \begin_layout Subsection
6913 Management
6914 \end_layout
6916 \begin_layout Standard
6917 And for tracking modes, we dispatch to a mode-tracker action based on the
6918  current language
6919 \end_layout
6921 \begin_layout Chunk
6922 mode_tracker,language=awk
6923 \end_layout
6925 \begin_layout Standard
6926 \begin_inset listings
6927 inline false
6928 status open
6930 \begin_layout Plain Layout
6932 function push_mode_tracker(context, language, mode,
6933 \end_layout
6935 \begin_layout Plain Layout
6937   # local vars
6938 \end_layout
6940 \begin_layout Plain Layout
6942   top)
6943 \end_layout
6945 \begin_layout Plain Layout
6948 \end_layout
6950 \begin_layout Plain Layout
6952   if (! ("" in context)) {
6953 \end_layout
6955 \begin_layout Plain Layout
6957     =<
6958 \backslash
6959 chunkref{new-mode-tracker}(context, language, mode)>
6960 \end_layout
6962 \begin_layout Plain Layout
6964   } else {
6965 \end_layout
6967 \begin_layout Plain Layout
6969     top = context[""];
6970 \end_layout
6972 \begin_layout Plain Layout
6974     if (context[top, "language"] == language && mode=="") mode = context[top,
6975  "mode"];
6976 \end_layout
6978 \begin_layout Plain Layout
6980     top++;
6981 \end_layout
6983 \begin_layout Plain Layout
6985     context[top, "language"] = language;
6986 \end_layout
6988 \begin_layout Plain Layout
6990     context[top, "mode"] = mode;
6991 \end_layout
6993 \begin_layout Plain Layout
6995     context[""] = top;
6996 \end_layout
6998 \begin_layout Plain Layout
7000   }
7001 \end_layout
7003 \begin_layout Plain Layout
7006 \end_layout
7008 \end_inset
7011 \end_layout
7013 \begin_layout Standard
7014 \begin_inset listings
7015 inline false
7016 status open
7018 \begin_layout Plain Layout
7020 function finalize_mode_tracker(context)
7021 \end_layout
7023 \begin_layout Plain Layout
7026 \end_layout
7028 \begin_layout Plain Layout
7030   if ( ("" in context) && context[""] != 0) return 0;
7031 \end_layout
7033 \begin_layout Plain Layout
7035   return 1;
7036 \end_layout
7038 \begin_layout Plain Layout
7041 \end_layout
7043 \end_inset
7046 \end_layout
7048 \begin_layout Standard
7049 This implies that any chunk must be syntactically whole; for instance, this
7050  is fine:
7051 \end_layout
7053 \begin_layout Chunk
7054 test:whole-chunk
7055 \end_layout
7057 \begin_layout Standard
7058 \begin_inset listings
7059 inline false
7060 status open
7062 \begin_layout Plain Layout
7064 if (1) {
7065 \end_layout
7067 \begin_layout Plain Layout
7069   =<
7070 \backslash
7071 chunkref{test:say-hello}>
7072 \end_layout
7074 \begin_layout Plain Layout
7077 \end_layout
7079 \end_inset
7082 \end_layout
7084 \begin_layout Chunk
7085 test:say-hello
7086 \end_layout
7088 \begin_layout Standard
7089 \begin_inset listings
7090 inline false
7091 status open
7093 \begin_layout Plain Layout
7095 print "hello";
7096 \end_layout
7098 \end_inset
7101 \end_layout
7103 \begin_layout Standard
7104 But this is not fine; the chunk 
7105 \begin_inset Flex Chunkref
7106 status collapsed
7108 \begin_layout Plain Layout
7109 test:hidden-else
7110 \end_layout
7112 \end_inset
7114  is not properly cromulent.
7115 \end_layout
7117 \begin_layout Chunk
7118 test:partial-chunk
7119 \end_layout
7121 \begin_layout Standard
7122 \begin_inset listings
7123 inline false
7124 status open
7126 \begin_layout Plain Layout
7128 if (1) {
7129 \end_layout
7131 \begin_layout Plain Layout
7133   =<
7134 \backslash
7135 chunkref{test:hidden-else}>
7136 \end_layout
7138 \begin_layout Plain Layout
7141 \end_layout
7143 \end_inset
7146 \end_layout
7148 \begin_layout Chunk
7149 test:hidden-else
7150 \end_layout
7152 \begin_layout Standard
7153 \begin_inset listings
7154 inline false
7155 status open
7157 \begin_layout Plain Layout
7159   print "I'm fine";
7160 \end_layout
7162 \begin_layout Plain Layout
7164 } else {
7165 \end_layout
7167 \begin_layout Plain Layout
7169   print "I'm not";
7170 \end_layout
7172 \end_inset
7175 \end_layout
7177 \begin_layout Standard
7178 These tests will check for correct behaviour:
7179 \end_layout
7181 \begin_layout Chunk
7182 test:cromulence
7183 \end_layout
7185 \begin_layout Standard
7186 \begin_inset listings
7187 inline false
7188 status open
7190 \begin_layout Plain Layout
7192 echo Cromulence test
7193 \end_layout
7195 \begin_layout Plain Layout
7197 passtest $NEWFANGLE -Rtest:whole-chunk $TEX_SRC &>/dev/null || ( echo "Whole
7198  chunk failed" && exit 1 )
7199 \end_layout
7201 \begin_layout Plain Layout
7203 failtest $NEWFANGLE -Rtest:partial-chunk $TEX_SRC &>/dev/null || ( echo
7204  "Partial chunk failed" && exit 1 )
7205 \end_layout
7207 \end_inset
7210 \end_layout
7212 \begin_layout Subsection
7213 Tracker
7214 \end_layout
7216 \begin_layout Standard
7217 We must avoid recursion as a language construct because we intend to employ
7218  mode-tracking to track language mode of emitted code, and the code is emitted
7219  from a function which is itself recursive, so instead we implement psuedo-recur
7220 sion using our own stack based on a hash.
7221 \end_layout
7223 \begin_layout Chunk
7224 mode_tracker()
7225 \end_layout
7227 \begin_layout Standard
7228 \begin_inset listings
7229 inline false
7230 status open
7232 \begin_layout Plain Layout
7234 function mode_tracker(context, text, values, 
7235 \end_layout
7237 \begin_layout Plain Layout
7239   # optional parameters
7240 \end_layout
7242 \begin_layout Plain Layout
7244   # local vars
7245 \end_layout
7247 \begin_layout Plain Layout
7249   mode, submodes, language,
7250 \end_layout
7252 \begin_layout Plain Layout
7254   cindex, c, a, part, item, name, result, new_values, new_mode, 
7255 \end_layout
7257 \begin_layout Plain Layout
7259   delimiters, terminators)
7260 \end_layout
7262 \begin_layout Plain Layout
7265 \end_layout
7267 \end_inset
7270 \end_layout
7272 \begin_layout Standard
7273 We could be re-commencing with a valid context, so we need to setup the
7274  state according to the last context.
7275 \end_layout
7277 \begin_layout Standard
7278 \begin_inset listings
7279 inline false
7280 status open
7282 \begin_layout Plain Layout
7284   cindex = context[""] + 0;
7285 \end_layout
7287 \begin_layout Plain Layout
7289   mode = context[cindex, "mode"];
7290 \end_layout
7292 \begin_layout Plain Layout
7294   language = context[cindex, "language" ];
7295 \end_layout
7297 \end_inset
7300 \end_layout
7302 \begin_layout Standard
7303 First we construct a single large regex combining the possible sub-modes
7304  for the current mode along with the terminators for the current mode.
7305 \end_layout
7307 \begin_layout Chunk
7308 parse_chunk_args-reset-modes
7309 \end_layout
7311 \begin_layout Standard
7312 \begin_inset listings
7313 inline false
7314 status open
7316 \begin_layout Plain Layout
7318   submodes=modes[language, mode, "submodes"];
7319 \end_layout
7321 \begin_layout Plain Layout
7323 \end_layout
7325 \begin_layout Plain Layout
7327   if ((language, mode, "delimiters") in modes) {
7328 \end_layout
7330 \begin_layout Plain Layout
7332     delimiters = modes[language, mode, "delimiters"];
7333 \end_layout
7335 \begin_layout Plain Layout
7337     if (length(submodes)>0) submodes = submodes "|";
7338 \end_layout
7340 \begin_layout Plain Layout
7342     submodes=submodes delimiters;
7343 \end_layout
7345 \begin_layout Plain Layout
7347   } else delimiters="";
7348 \end_layout
7350 \begin_layout Plain Layout
7352   if ((language, mode, "terminators") in modes) {
7353 \end_layout
7355 \begin_layout Plain Layout
7357     terminators = modes[language, mode, "terminators"];
7358 \end_layout
7360 \begin_layout Plain Layout
7362     if (length(submodes)>0) submodes = submodes "|";
7363 \end_layout
7365 \begin_layout Plain Layout
7367     submodes=submodes terminators;
7368 \end_layout
7370 \begin_layout Plain Layout
7372   } else terminators="";
7373 \end_layout
7375 \end_inset
7378 \end_layout
7380 \begin_layout Standard
7381 If we don't find anything to match on --- probably because the language
7382  is not supported --- then we return the entire text without matching anything.
7383 \end_layout
7385 \begin_layout Standard
7386 \begin_inset listings
7387 inline false
7388 status open
7390 \begin_layout Plain Layout
7392   if (! length(submodes)) return text; 
7393 \end_layout
7395 \end_inset
7398 \end_layout
7400 \begin_layout Chunk
7401 mode_tracker()
7402 \end_layout
7404 \begin_layout Standard
7405 \begin_inset listings
7406 inline false
7407 status open
7409 \begin_layout Plain Layout
7412 \backslash
7413 chunkref{parse_chunk_args-reset-modes}>
7414 \end_layout
7416 \end_inset
7419 \end_layout
7421 \begin_layout Standard
7422 We then iterate the text (until there is none left) looking for sub-modes
7423  or terminators in the regex.
7424 \end_layout
7426 \begin_layout Standard
7427 \begin_inset listings
7428 inline false
7429 status open
7431 \begin_layout Plain Layout
7433   while((cindex >= 0) && length(text)) {
7434 \end_layout
7436 \begin_layout Plain Layout
7438     if (match(text, "(" submodes ")", a)) {
7439 \end_layout
7441 \end_inset
7444 \end_layout
7446 \begin_layout Standard
7447 A bug that creeps in regularly during development is bad regexes of zero
7448  length which result in an infinite loop (as no text is consumed), so I
7449  catch that right away with this test.
7450 \end_layout
7452 \begin_layout Standard
7453 \begin_inset listings
7454 inline false
7455 status open
7457 \begin_layout Plain Layout
7459       if (RLENGTH<1) {
7460 \end_layout
7462 \begin_layout Plain Layout
7464         error(sprintf("Internal error, matched zero length submode, should
7465  be impossible - likely regex computation error
7466 \backslash
7467 n" 
7468 \backslash
7470 \end_layout
7472 \begin_layout Plain Layout
7474                 "Language=%s
7475 \backslash
7476 nmode=%s
7477 \backslash
7478 nmatch=%s
7479 \backslash
7480 n", language, mode, submodes));
7481 \end_layout
7483 \begin_layout Plain Layout
7485       }
7486 \end_layout
7488 \end_inset
7491 \end_layout
7493 \begin_layout Standard
7494 \begin_inset Flex CharStyle:Code
7495 status collapsed
7497 \begin_layout Plain Layout
7498 part
7499 \end_layout
7501 \end_inset
7503  is defined as the text up to the sub-mode or terminator, and this is appended
7504  to 
7505 \begin_inset Flex CharStyle:Code
7506 status collapsed
7508 \begin_layout Plain Layout
7509 item
7510 \end_layout
7512 \end_inset
7514  --- which is the current text being gathered.
7515  If a mode has a delimiter, then item is reset each time a delimiter is
7516  found.
7517 \end_layout
7519 \begin_layout Standard
7520 \begin_inset Formula $\mathtt{\overbrace{"\overbrace{hello}^{item},\ \overbrace{there}^{item}"}^{item},\ \overbrace{he\ said.}^{item}}$
7521 \end_inset
7524 \end_layout
7526 \begin_layout Standard
7527 \begin_inset listings
7528 inline false
7529 status open
7531 \begin_layout Plain Layout
7533       part = substr(text, 1, RSTART -1);
7534 \end_layout
7536 \begin_layout Plain Layout
7538       item = item part;
7539 \end_layout
7541 \end_inset
7544 \end_layout
7546 \begin_layout Standard
7547 We must now determine what was matched.
7548  If it was a terminator, then we must restore the previous mode.
7549 \end_layout
7551 \begin_layout Standard
7552 \begin_inset listings
7553 inline false
7554 status open
7556 \begin_layout Plain Layout
7558       if (match(a[1], "^" terminators "$")) {
7559 \end_layout
7561 \begin_layout Plain Layout
7563 #printf("%2d EXIT  MODE [%s] by [%s] [%s]
7564 \backslash
7565 n", cindex, mode, a[1], text) > "/dev/stderr"
7566 \end_layout
7568 \begin_layout Plain Layout
7570         context[cindex, "values", ++context[cindex, "values"]] = item;
7571 \end_layout
7573 \begin_layout Plain Layout
7575         delete context[cindex];
7576 \end_layout
7578 \begin_layout Plain Layout
7580         context[""] = --cindex;
7581 \end_layout
7583 \begin_layout Plain Layout
7585         if (cindex>=0) {
7586 \end_layout
7588 \begin_layout Plain Layout
7590           mode = context[cindex, "mode"];
7591 \end_layout
7593 \begin_layout Plain Layout
7595           language = context[cindex, "language"];
7596 \end_layout
7598 \begin_layout Plain Layout
7600           =<
7601 \backslash
7602 chunkref{parse_chunk_args-reset-modes}>
7603 \end_layout
7605 \begin_layout Plain Layout
7607         }
7608 \end_layout
7610 \begin_layout Plain Layout
7612         item = item a[1];
7613 \end_layout
7615 \begin_layout Plain Layout
7617         text = substr(text, 1 + length(part) + length(a[1]));
7618 \end_layout
7620 \begin_layout Plain Layout
7622       }
7623 \end_layout
7625 \end_inset
7628 \end_layout
7630 \begin_layout Standard
7631 If a delimiter was matched, then we must store the current item in the parsed
7632  values array, and reset the item.
7633 \end_layout
7635 \begin_layout Standard
7636 \begin_inset listings
7637 inline false
7638 status open
7640 \begin_layout Plain Layout
7642       else if (match(a[1], "^" delimiters "$")) {
7643 \end_layout
7645 \begin_layout Plain Layout
7647         if (cindex==0) {
7648 \end_layout
7650 \begin_layout Plain Layout
7652           context[cindex, "values", ++context[cindex, "values"]] = item;
7653 \end_layout
7655 \begin_layout Plain Layout
7657           item = "";
7658 \end_layout
7660 \begin_layout Plain Layout
7662         } else {
7663 \end_layout
7665 \begin_layout Plain Layout
7667           item = item a[1];
7668 \end_layout
7670 \begin_layout Plain Layout
7672         }
7673 \end_layout
7675 \begin_layout Plain Layout
7677         text = substr(text, 1 + length(part) + length(a[1]));
7678 \end_layout
7680 \begin_layout Plain Layout
7682       }
7683 \end_layout
7685 \end_inset
7688 \end_layout
7690 \begin_layout Standard
7691 otherwise, if a new submode is detected (all submodes have terminators),
7692  we must create a nested parse context until we find the terminator for
7693  this mode.
7694 \end_layout
7696 \begin_layout Standard
7697 \begin_inset listings
7698 inline false
7699 status open
7701 \begin_layout Plain Layout
7703  else if ((language, a[1], "terminators") in modes) {
7704 \end_layout
7706 \begin_layout Plain Layout
7708         #check if new_mode is defined
7709 \end_layout
7711 \begin_layout Plain Layout
7713         item = item a[1];
7714 \end_layout
7716 \begin_layout Plain Layout
7718 #printf("%2d ENTER MODE [%s] in [%s]
7719 \backslash
7720 n", cindex, a[1], text) > "/dev/stderr"
7721 \end_layout
7723 \begin_layout Plain Layout
7725         text = substr(text, 1 + length(part) + length(a[1]));
7726 \end_layout
7728 \begin_layout Plain Layout
7730         context[""] = ++cindex;
7731 \end_layout
7733 \begin_layout Plain Layout
7735         context[cindex, "mode"] = a[1];
7736 \end_layout
7738 \begin_layout Plain Layout
7740         context[cindex, "language"] = language;
7741 \end_layout
7743 \begin_layout Plain Layout
7745         mode = a[1];
7746 \end_layout
7748 \begin_layout Plain Layout
7750         =<
7751 \backslash
7752 chunkref{parse_chunk_args-reset-modes}>
7753 \end_layout
7755 \begin_layout Plain Layout
7757       } else {
7758 \end_layout
7760 \begin_layout Plain Layout
7762         error(sprintf("Submode '%s' set unknown mode in text: %s
7763 \backslash
7764 nLanguage %s Mode %s
7765 \backslash
7766 n", a[1], text, language, mode));
7767 \end_layout
7769 \begin_layout Plain Layout
7771         text = substr(text, 1 + length(part) + length(a[1]));
7772 \end_layout
7774 \begin_layout Plain Layout
7776       }
7777 \end_layout
7779 \begin_layout Plain Layout
7781     }
7782 \end_layout
7784 \end_inset
7787 \end_layout
7789 \begin_layout Standard
7790 In the final case, we parsed to the end of the string.
7791  If the string was entire, then we should have no nested mode context, but
7792  if the string was just a fragment we may have a mode context which must
7793  be preserved for the next fragment.
7794  Todo: Consideration ought to be given if sub-mode strings are split over
7795  two fragments.
7796 \begin_inset Note Note
7797 status collapsed
7799 \begin_layout Plain Layout
7800 Consideration ought to be given if sub-mode strings are split over two fragments.
7801 \end_layout
7803 \end_inset
7806 \end_layout
7808 \begin_layout Standard
7809 \begin_inset listings
7810 inline false
7811 status open
7813 \begin_layout Plain Layout
7815 else {
7816 \end_layout
7818 \begin_layout Plain Layout
7820       context[cindex, "values", ++context[cindex, "values"]] = item text;
7821 \end_layout
7823 \begin_layout Plain Layout
7825       text = "";
7826 \end_layout
7828 \begin_layout Plain Layout
7830       item = "";
7831 \end_layout
7833 \begin_layout Plain Layout
7835     }
7836 \end_layout
7838 \begin_layout Plain Layout
7840   }
7841 \end_layout
7843 \begin_layout Plain Layout
7845 \end_layout
7847 \begin_layout Plain Layout
7849   context["item"] = item;
7850 \end_layout
7852 \begin_layout Plain Layout
7854 \end_layout
7856 \begin_layout Plain Layout
7858   if (length(item)) context[cindex, "values", ++context[cindex, "values"]]
7859  = item;
7860 \end_layout
7862 \begin_layout Plain Layout
7864   return text;
7865 \end_layout
7867 \begin_layout Plain Layout
7870 \end_layout
7872 \end_inset
7875 \end_layout
7877 \begin_layout Subsubsection
7878 One happy chunk
7879 \end_layout
7881 \begin_layout Standard
7882 All the mode tracker chunks are referred to here:
7883 \end_layout
7885 \begin_layout Chunk
7886 mode-tracker
7887 \end_layout
7889 \begin_layout Standard
7890 \begin_inset listings
7891 inline false
7892 status open
7894 \begin_layout Plain Layout
7897 \backslash
7898 chunkref{new_mode_tracker()}>
7899 \end_layout
7901 \begin_layout Plain Layout
7904 \backslash
7905 chunkref{mode_tracker()}>
7906 \end_layout
7908 \end_inset
7911 \end_layout
7913 \begin_layout Subsubsection
7914 Tests
7915 \end_layout
7917 \begin_layout Standard
7918 We can test this function like this:
7919 \end_layout
7921 \begin_layout Chunk
7922 pca-test.awk,language=awk
7923 \end_layout
7925 \begin_layout Standard
7926 \begin_inset listings
7927 inline false
7928 status open
7930 \begin_layout Plain Layout
7933 \backslash
7934 chunkref{error()}>
7935 \end_layout
7937 \begin_layout Plain Layout
7940 \backslash
7941 chunkref{mode-tracker}>
7942 \end_layout
7944 \begin_layout Plain Layout
7947 \backslash
7948 chunkref{parse_chunk_args()}>
7949 \end_layout
7951 \begin_layout Plain Layout
7953 BEGIN {
7954 \end_layout
7956 \begin_layout Plain Layout
7958   SUBSEP=".";
7959 \end_layout
7961 \begin_layout Plain Layout
7963   =<
7964 \backslash
7965 chunkref{mode-definitions}>
7966 \end_layout
7968 \begin_layout Plain Layout
7970 \end_layout
7972 \begin_layout Plain Layout
7974   =<
7975 \backslash
7976 chunkref{test:mode-definitions}>
7977 \end_layout
7979 \begin_layout Plain Layout
7982 \end_layout
7984 \end_inset
7987 \end_layout
7989 \begin_layout Chunk
7990 pca-test.awk:summary,language=awk
7991 \end_layout
7993 \begin_layout Standard
7994 \begin_inset listings
7995 inline false
7996 status open
7998 \begin_layout Plain Layout
8000 if (e) {
8001 \end_layout
8003 \begin_layout Plain Layout
8005   printf "Failed " e
8006 \end_layout
8008 \begin_layout Plain Layout
8010   for (b in a) {
8011 \end_layout
8013 \begin_layout Plain Layout
8015     print "a[" b "] => " a[b];
8016 \end_layout
8018 \begin_layout Plain Layout
8020   }
8021 \end_layout
8023 \begin_layout Plain Layout
8025 } else {
8026 \end_layout
8028 \begin_layout Plain Layout
8030   print "Passed"
8031 \end_layout
8033 \begin_layout Plain Layout
8036 \end_layout
8038 \begin_layout Plain Layout
8040 split("", a);
8041 \end_layout
8043 \begin_layout Plain Layout
8045 e=0;
8046 \end_layout
8048 \end_inset
8051 \end_layout
8053 \begin_layout Standard
8054 which should give this output:
8055 \end_layout
8057 \begin_layout Chunk
8058 pca-test.awk-results,language=
8059 \end_layout
8061 \begin_layout Standard
8062 \begin_inset listings
8063 inline false
8064 status open
8066 \begin_layout Plain Layout
8068 a[foo.quux.quirk] => 
8069 \end_layout
8071 \begin_layout Plain Layout
8073 a[foo.quux.a] => fleeg
8074 \end_layout
8076 \begin_layout Plain Layout
8078 a[foo.bar] => baz
8079 \end_layout
8081 \begin_layout Plain Layout
8083 a[etc] => 
8084 \end_layout
8086 \begin_layout Plain Layout
8088 a[name] => freddie
8089 \end_layout
8091 \end_inset
8094 \end_layout
8096 \begin_layout Section
8097 Escaping and Quoting
8098 \end_layout
8100 \begin_layout Standard
8101 Each nested mode can optionally define a set of transforms to be applied
8102  to any text that is included from another language.
8103 \end_layout
8105 \begin_layout Standard
8106 This code can perform transforms
8107 \end_layout
8109 \begin_layout Chunk
8110 mode_tracker,language=awk
8111 \end_layout
8113 \begin_layout Standard
8114 \begin_inset listings
8115 inline false
8116 status open
8118 \begin_layout Plain Layout
8120 function transform_escape(s, r, text,
8121 \end_layout
8123 \begin_layout Plain Layout
8125     # optional
8126 \end_layout
8128 \begin_layout Plain Layout
8130     max, 
8131 \end_layout
8133 \begin_layout Plain Layout
8135         # local vars
8136 \end_layout
8138 \begin_layout Plain Layout
8140         c)
8141 \end_layout
8143 \begin_layout Plain Layout
8146 \end_layout
8148 \begin_layout Plain Layout
8150   for(c=1; c <= max && (c in s); c++) {
8151 \end_layout
8153 \begin_layout Plain Layout
8155     gsub(s[c], r[c], text);
8156 \end_layout
8158 \begin_layout Plain Layout
8160   }
8161 \end_layout
8163 \begin_layout Plain Layout
8165   return text;
8166 \end_layout
8168 \begin_layout Plain Layout
8171 \end_layout
8173 \end_inset
8176 \end_layout
8178 \begin_layout Standard
8179 This function must append from index 
8180 \begin_inset Flex CharStyle:Code
8181 status collapsed
8183 \begin_layout Plain Layout
8185 \end_layout
8187 \end_inset
8189  onwards, and escape transforms from the supplied context, and return c
8190  + number of new transforms.
8191 \end_layout
8193 \begin_layout Standard
8194 \begin_inset listings
8195 inline false
8196 status open
8198 \begin_layout Plain Layout
8200 function mode_escaper(context, s, r, src,
8201 \end_layout
8203 \begin_layout Plain Layout
8205   c, cp, cpl)
8206 \end_layout
8208 \begin_layout Plain Layout
8211 \end_layout
8213 \begin_layout Plain Layout
8215         for(c = context[""]; c >= 0; c--) {
8216 \end_layout
8218 \begin_layout Plain Layout
8220                 if ( (context[c, "language"], context[c, "mode"]) in escapes) {
8221 \end_layout
8223 \begin_layout Plain Layout
8225                         cpl = escapes[context[c, "language"], context[c, "mode"]];
8226 \end_layout
8228 \begin_layout Plain Layout
8230                         for (cp = 1; cp <= cpl; cp ++) {
8231 \end_layout
8233 \begin_layout Plain Layout
8235                                 ++src;
8236 \end_layout
8238 \begin_layout Plain Layout
8240                                 s[src] = escapes[context[c, "language"], context[c, "mode"], c, "s"];
8241 \end_layout
8243 \begin_layout Plain Layout
8245                                 r[src] = escapes[context[c, "language"], context[c, "mode"], c, "r"];
8246 \end_layout
8248 \begin_layout Plain Layout
8250                         }
8251 \end_layout
8253 \begin_layout Plain Layout
8255                 }
8256 \end_layout
8258 \begin_layout Plain Layout
8260         }
8261 \end_layout
8263 \begin_layout Plain Layout
8265         return src;
8266 \end_layout
8268 \begin_layout Plain Layout
8271 \end_layout
8273 \end_inset
8276 \end_layout
8278 \begin_layout Chunk
8279 test:escapes,language=sh
8280 \end_layout
8282 \begin_layout Standard
8283 \begin_inset listings
8284 inline false
8285 status open
8287 \begin_layout Plain Layout
8289 echo escapes test
8290 \end_layout
8292 \begin_layout Plain Layout
8294 passtest $NEWFANGLE -Rtest:comment-quote $TEX_SRC &>/dev/null || ( echo
8295  "Comment-quote failed" && exit 1 )
8296 \end_layout
8298 \end_inset
8301 \end_layout
8303 \begin_layout Chapter
8304 Recognizing Chunks
8305 \end_layout
8307 \begin_layout Standard
8308 Newfangle recognizes noweb chunks, but as we also want better LaTeX integration
8309  we will recognize any of these:
8310 \end_layout
8312 \begin_layout Itemize
8313 notangle chunks matching the pattern 
8314 \begin_inset Flex CharStyle:Code
8315 status collapsed
8317 \begin_layout Plain Layout
8319 \begin_inset space \hspace*{}
8320 \length 0in
8321 \end_inset
8323 <.*?>
8324 \begin_inset space \hspace*{}
8325 \length 0in
8326 \end_inset
8329 \end_layout
8331 \end_inset
8334 \end_layout
8336 \begin_layout Itemize
8337 a chunks beginning with 
8338 \begin_inset Flex CharStyle:Code
8339 status collapsed
8341 \begin_layout Plain Layout
8343 \backslash
8344 begin{lstlistings}
8345 \end_layout
8347 \end_inset
8349 , possibly with 
8350 \backslash
8351 Chunk{\SpecialChar \ldots{}
8352 } on the previous line
8353 \end_layout
8355 \begin_layout Itemize
8356 an older form I have used, beginning with 
8357 \begin_inset Flex CharStyle:Code
8358 status collapsed
8360 \begin_layout Plain Layout
8362 \backslash
8363 begin{Chunk}[options]
8364 \end_layout
8366 \end_inset
8368  --- also more suitable for plain LaTeX users
8369 \begin_inset Foot
8370 status collapsed
8372 \begin_layout Plain Layout
8373 Is there such a thing as plain LaTeX?
8374 \end_layout
8376 \end_inset
8379 \end_layout
8381 \begin_layout Section
8382 Chunk start
8383 \end_layout
8385 \begin_layout Standard
8386 The variable 
8387 \begin_inset Flex CharStyle:Code
8388 status collapsed
8390 \begin_layout Plain Layout
8391 chunking
8392 \end_layout
8394 \end_inset
8396  is used to signify that we are processing a code chunk and not document.
8397  In such a state, input lines will be assigned to the current chunk; otherwise
8398  they are ignored.
8399 \end_layout
8401 \begin_layout Subsection
8402 lstlistings
8403 \end_layout
8405 \begin_layout Standard
8406 Our current scheme is to recognize the new lstlisting chunks, but these
8407  may be preceded by a 
8408 \begin_inset Flex CharStyle:Code
8409 status collapsed
8411 \begin_layout Plain Layout
8413 \backslash
8414 Chunk
8415 \end_layout
8417 \end_inset
8419  command which in LyX is a more convenient way to pass the chunk name to
8420  the 
8421 \begin_inset Flex CharStyle:Code
8422 status collapsed
8424 \begin_layout Plain Layout
8426 \backslash
8427 begin{lstlistings}
8428 \end_layout
8430 \end_inset
8432  command, and a more visible way to specify other 
8433 \begin_inset Flex CharStyle:Code
8434 status collapsed
8436 \begin_layout Plain Layout
8437 lstset
8438 \end_layout
8440 \end_inset
8442  settings.
8443 \end_layout
8445 \begin_layout Standard
8446 The arguments to the 
8447 \begin_inset Flex CharStyle:Code
8448 status collapsed
8450 \begin_layout Plain Layout
8452 \backslash
8453 Chunk
8454 \end_layout
8456 \end_inset
8458  command are a name, and then a comma-seperated list of key-value pairs
8459  after the manner of 
8460 \begin_inset Flex CharStyle:Code
8461 status collapsed
8463 \begin_layout Plain Layout
8465 \backslash
8466 lstset
8467 \end_layout
8469 \end_inset
8472  (In fact within the LaTeX 
8473 \begin_inset Flex CharStyle:Code
8474 status collapsed
8476 \begin_layout Plain Layout
8478 \backslash
8479 Chunk
8480 \end_layout
8482 \end_inset
8484  macro (section 
8485 \begin_inset CommandInset ref
8486 LatexCommand ref
8487 reference "sub:The-chunk-command"
8489 \end_inset
8491 ) the text 
8492 \begin_inset Flex CharStyle:Code
8493 status collapsed
8495 \begin_layout Plain Layout
8496 name=
8497 \end_layout
8499 \end_inset
8501  is prefixed to the argument which is then literally passed to 
8502 \begin_inset Flex CharStyle:Code
8503 status collapsed
8505 \begin_layout Plain Layout
8507 \backslash
8508 lstset
8509 \end_layout
8511 \end_inset
8514 \end_layout
8516 \begin_layout Chunk
8517 recognize-chunk,language=awk
8518 \end_layout
8520 \begin_layout Standard
8521 \begin_inset listings
8522 inline false
8523 status open
8525 \begin_layout Plain Layout
8528 \backslash
8530 \backslash
8531 Chunk{/ {
8532 \end_layout
8534 \begin_layout Plain Layout
8536   if (match($0, "^
8537 \backslash
8539 \backslash
8541 \backslash
8543 \backslash
8544 Chunk{ *([^ ,}]*),?(.*)}", line)) {
8545 \end_layout
8547 \begin_layout Plain Layout
8549     next_chunk_name = line[1];
8550 \end_layout
8552 \begin_layout Plain Layout
8554     get_chunk_args(line[2], next_chunk_args);
8555 \end_layout
8557 \begin_layout Plain Layout
8559   }
8560 \end_layout
8562 \begin_layout Plain Layout
8564   next;
8565 \end_layout
8567 \begin_layout Plain Layout
8570 \end_layout
8572 \end_inset
8575 \end_layout
8577 \begin_layout Standard
8578 We also make a basic attempt to parse the name out of the 
8579 \begin_inset Flex CharStyle:Code
8580 status collapsed
8582 \begin_layout Plain Layout
8584 \backslash
8585 lstlistings[name=
8586 \begin_inset space \hspace{}
8587 \length 0in
8588 \end_inset
8590 chunk-name]
8591 \end_layout
8593 \end_inset
8595  text, otherwise we fall back to the name found in the previous chunk command.
8596  This attempt is very basic and doesn't support commas or spaces or square
8597  brackets as part of the chunkname.
8598  We also recognize 
8599 \begin_inset Flex CharStyle:Code
8600 status collapsed
8602 \begin_layout Plain Layout
8604 \backslash
8605 begin{Chunk}
8606 \end_layout
8608 \end_inset
8610  which is convenient for some users
8611 \begin_inset Foot
8612 status open
8614 \begin_layout Plain Layout
8615 but not yet supported in the LaTeX macros
8616 \end_layout
8618 \end_inset
8621 \begin_inset Note Note
8622 status collapsed
8624 \begin_layout Plain Layout
8625 Add noweave support
8626 \end_layout
8628 \end_inset
8631 \end_layout
8633 \begin_layout Standard
8634 \begin_inset listings
8635 inline false
8636 status open
8638 \begin_layout Plain Layout
8641 \backslash
8643 \backslash
8644 begin{lstlisting}|^
8645 \backslash
8647 \backslash
8648 begin{Chunk}/ {
8649 \end_layout
8651 \begin_layout Plain Layout
8653   if (match($0, "}.*[[,] *name= *{? *([^], }]*)", line)) {
8654 \end_layout
8656 \begin_layout Plain Layout
8658     new_chunk(line[1]);
8659 \end_layout
8661 \begin_layout Plain Layout
8663   } else {
8664 \end_layout
8666 \begin_layout Plain Layout
8668     new_chunk(next_chunk_name, next_chunk_args);
8669 \end_layout
8671 \begin_layout Plain Layout
8673   }
8674 \end_layout
8676 \begin_layout Plain Layout
8678   chunking=1;
8679 \end_layout
8681 \begin_layout Plain Layout
8683   next;
8684 \end_layout
8686 \begin_layout Plain Layout
8689 \end_layout
8691 \end_inset
8694 \end_layout
8696 \begin_layout Subsection
8697 Noweb
8698 \end_layout
8700 \begin_layout Standard
8701 We recognize notangle style chunks too:
8702 \end_layout
8704 \begin_layout Chunk
8705 recognize-chunk,language=awk
8706 \end_layout
8708 \begin_layout Standard
8709 \begin_inset listings
8710 inline false
8711 status open
8713 \begin_layout Plain Layout
8715 /^[<]<.*[>]>=/ {
8716 \end_layout
8718 \begin_layout Plain Layout
8720   if (match($0, "^[<]<(.*)[>]>= *$", line)) {
8721 \end_layout
8723 \begin_layout Plain Layout
8725     chunking=1;
8726 \end_layout
8728 \begin_layout Plain Layout
8730     notangle_mode=1;
8731 \end_layout
8733 \begin_layout Plain Layout
8735     new_chunk(line[1]);
8736 \end_layout
8738 \begin_layout Plain Layout
8740     next;
8741 \end_layout
8743 \begin_layout Plain Layout
8745   }
8746 \end_layout
8748 \begin_layout Plain Layout
8751 \end_layout
8753 \end_inset
8756 \end_layout
8758 \begin_layout Section
8759 Chunk end
8760 \end_layout
8762 \begin_layout Standard
8763 Likewise, we need to recognize when a chunk ends.
8764 \end_layout
8766 \begin_layout Subsection
8767 lstlistings
8768 \end_layout
8770 \begin_layout Standard
8771 The 
8772 \begin_inset Flex CharStyle:Code
8773 status collapsed
8775 \begin_layout Plain Layout
8777 \end_layout
8779 \end_inset
8781  in 
8782 \begin_inset Flex CharStyle:Code
8783 status collapsed
8785 \begin_layout Plain Layout
8786 [e]end{lislisting}
8787 \end_layout
8789 \end_inset
8791  is surrounded by square brackets so that when this document is processed,
8792  this chunk doesn't terminate early when the lstlistings package recognizes
8793  it's own end-string! 
8794 \begin_inset Note Greyedout
8795 status collapsed
8797 \begin_layout Plain Layout
8798 This doesn't make sense as the regex is anchored with ^, which this line
8799  does not begin with!
8800 \end_layout
8802 \end_inset
8805 \begin_inset Note Note
8806 status open
8808 \begin_layout Plain Layout
8809 No, it doesn't.
8810 \end_layout
8812 \end_inset
8815 \end_layout
8817 \begin_layout Chunk
8818 recognize-chunk
8819 \end_layout
8821 \begin_layout Standard
8822 \begin_inset listings
8823 inline false
8824 status open
8826 \begin_layout Plain Layout
8829 \backslash
8831 \backslash
8832 [e]nd{lstlisting}|^
8833 \backslash
8835 \backslash
8836 [e]nd{Chunk}/ {
8837 \end_layout
8839 \begin_layout Plain Layout
8841   chunking=0;
8842 \end_layout
8844 \begin_layout Plain Layout
8846   active_chunk="";
8847 \end_layout
8849 \begin_layout Plain Layout
8851   next;
8852 \end_layout
8854 \begin_layout Plain Layout
8857 \end_layout
8859 \end_inset
8862 \end_layout
8864 \begin_layout Subsection
8865 noweb
8866 \end_layout
8868 \begin_layout Chunk
8869 recognize-chunk
8870 \end_layout
8872 \begin_layout Standard
8873 \begin_inset listings
8874 inline false
8875 status open
8877 \begin_layout Plain Layout
8879 /^@ *$/ {
8880 \end_layout
8882 \begin_layout Plain Layout
8884   chunking=0;
8885 \end_layout
8887 \begin_layout Plain Layout
8889   active_chunk="";
8890 \end_layout
8892 \begin_layout Plain Layout
8895 \end_layout
8897 \end_inset
8900 \end_layout
8902 \begin_layout Standard
8903 All other recognizers are only of effect if we are chunking; there's no
8904  point in looking at lines if they aren't part of a chunk, so we just ignore
8905  them as efficiently as we can.
8906 \end_layout
8908 \begin_layout Chunk
8909 recognize-chunk
8910 \end_layout
8912 \begin_layout Standard
8913 \begin_inset listings
8914 inline false
8915 status open
8917 \begin_layout Plain Layout
8919 ! chunking { next; }
8920 \end_layout
8922 \end_inset
8925 \end_layout
8927 \begin_layout Section
8928 Chunk contents
8929 \end_layout
8931 \begin_layout Standard
8932 Chunk contents are any lines read while 
8933 \begin_inset Flex CharStyle:Code
8934 status collapsed
8936 \begin_layout Plain Layout
8937 chunking
8938 \end_layout
8940 \end_inset
8942  is true.
8943  Some chunk contents are special in that they refer to other chunks, and
8944  will be replaced by the contents of these chunks when the file is generated.
8945 \end_layout
8947 \begin_layout Standard
8948 \begin_inset CommandInset label
8949 LatexCommand label
8950 name "sub:ORS-chunk-text"
8952 \end_inset
8954 We add the output record separator 
8955 \begin_inset Flex CharStyle:Code
8956 status collapsed
8958 \begin_layout Plain Layout
8960 \end_layout
8962 \end_inset
8964  to the line now, because we will set 
8965 \begin_inset Flex CharStyle:Code
8966 status collapsed
8968 \begin_layout Plain Layout
8970 \end_layout
8972 \end_inset
8974  to the empty string when we generate the output
8975 \begin_inset Foot
8976 status collapsed
8978 \begin_layout Plain Layout
8979 So that we can print partial lines using 
8980 \begin_inset Flex CharStyle:Code
8981 status collapsed
8983 \begin_layout Plain Layout
8984 print
8985 \end_layout
8987 \end_inset
8989  instead of 
8990 \begin_inset Flex CharStyle:Code
8991 status collapsed
8993 \begin_layout Plain Layout
8994 printf
8995 \end_layout
8997 \end_inset
9000 \end_layout
9002 \end_inset
9005 \end_layout
9007 \begin_layout Chunk
9008 recognize-chunk
9009 \end_layout
9011 \begin_layout Standard
9012 \begin_inset listings
9013 inline false
9014 status open
9016 \begin_layout Plain Layout
9018 length(active_chunk) {
9019 \end_layout
9021 \begin_layout Plain Layout
9023   =<
9024 \backslash
9025 chunkref{process-chunk-tabs}>
9026 \end_layout
9028 \begin_layout Plain Layout
9030   =<
9031 \backslash
9032 chunkref{process-chunk}>
9033 \end_layout
9035 \begin_layout Plain Layout
9038 \end_layout
9040 \end_inset
9043 \end_layout
9045 \begin_layout Standard
9046 If a chunk just consisted of plain text, we could handle the chunk like
9047  this:
9048 \end_layout
9050 \begin_layout Chunk
9051 process-chunk-simple
9052 \end_layout
9054 \begin_layout Standard
9055 \begin_inset listings
9056 inline false
9057 status open
9059 \begin_layout Plain Layout
9061 chunk_line(active_chunk, $0 ORS);
9062 \end_layout
9064 \end_inset
9067 \end_layout
9069 \begin_layout Standard
9070 but in fact a chunk can include references to other chunks.
9071  Chunk includes are traditionally written as 
9072 \begin_inset Flex CharStyle:Code
9073 status collapsed
9075 \begin_layout Plain Layout
9076 <<chunk-name>>
9077 \end_layout
9079 \end_inset
9081 , but we support other variations.
9082 \end_layout
9084 \begin_layout Standard
9085 However, we also process tabs at this point, a tab at input can be replaced
9086  by a number of spaces defined by the 
9087 \begin_inset Flex CharStyle:Code
9088 status collapsed
9090 \begin_layout Plain Layout
9091 tabs
9092 \end_layout
9094 \end_inset
9096  variable, set by the 
9097 \begin_inset Flex CharStyle:Code
9098 status collapsed
9100 \begin_layout Plain Layout
9102 \end_layout
9104 \end_inset
9106  option.
9107  Of course this is poor tab behaviour, we should probably have the option
9108  to use proper counted tab-stops and process this on output.
9109 \end_layout
9111 \begin_layout Chunk
9112 process-chunk-tabs
9113 \end_layout
9115 \begin_layout Standard
9116 \begin_inset listings
9117 inline false
9118 status open
9120 \begin_layout Plain Layout
9122 if (length(tabs)) {
9123 \end_layout
9125 \begin_layout Plain Layout
9127   gsub("
9128 \backslash
9129 t", tabs);
9130 \end_layout
9132 \begin_layout Plain Layout
9135 \end_layout
9137 \end_inset
9140 \end_layout
9142 \begin_layout Subsection
9143 \begin_inset CommandInset label
9144 LatexCommand label
9145 name "sub:lstlistings-includes"
9147 \end_inset
9149 lstlistings
9150 \end_layout
9152 \begin_layout Standard
9153 If 
9154 \begin_inset Flex CharStyle:Code
9155 status collapsed
9157 \begin_layout Plain Layout
9159 \backslash
9160 lstset{escapeinside={=<}{>}}
9161 \end_layout
9163 \end_inset
9165  is set, then we can use 
9166 \begin_inset Flex CharStyle:Code
9167 status collapsed
9169 \begin_layout Plain Layout
9171 \backslash
9172 chunkref{
9173 \begin_inset space \hspace{}
9174 \length 0in
9175 \end_inset
9177 chunk-name}>
9178 \end_layout
9180 \end_inset
9182  in listings.
9183  The sequence 
9184 \begin_inset Flex CharStyle:Code
9185 status collapsed
9187 \begin_layout Plain Layout
9189 \end_layout
9191 \end_inset
9193  was chosen because:
9194 \end_layout
9196 \begin_layout Enumerate
9197 it is a better mnemonic than 
9198 \begin_inset Flex CharStyle:Code
9199 status collapsed
9201 \begin_layout Plain Layout
9202 <<chunk-name>>
9203 \end_layout
9205 \end_inset
9207  in that the = sign signifies equivalent or substitutability, 
9208 \end_layout
9210 \begin_layout Enumerate
9211 and because =< is not valid in C or in any language I can think of 
9212 \end_layout
9214 \begin_layout Enumerate
9215 and also because lstlistings doesn't like 
9216 \begin_inset Flex CharStyle:Code
9217 status collapsed
9219 \begin_layout Plain Layout
9221 \end_layout
9223 \end_inset
9225  as an end delimiter for the 
9226 \emph on
9227 texcl
9228 \emph default
9229  escape, so we must make do with a single 
9230 \begin_inset Flex CharStyle:Code
9231 status collapsed
9233 \begin_layout Plain Layout
9235 \end_layout
9237 \end_inset
9239 , which is better matched by 
9240 \begin_inset Flex CharStyle:Code
9241 status collapsed
9243 \begin_layout Plain Layout
9245 \end_layout
9247 \end_inset
9249  than 
9250 \begin_inset Flex CharStyle:Code
9251 status collapsed
9253 \begin_layout Plain Layout
9255 \end_layout
9257 \end_inset
9260 \end_layout
9262 \begin_layout Standard
9263 Unfortunately 
9264 \begin_inset Note Note
9265 status open
9267 \begin_layout Plain Layout
9268 fix this then
9269 \end_layout
9271 \end_inset
9273  the 
9274 \begin_inset Flex CharStyle:Code
9275 status collapsed
9277 \begin_layout Plain Layout
9278 =<\SpecialChar \ldots{}
9280 \end_layout
9282 \end_inset
9284  that we use re-enters a LaTeX parsing mode in which some characters are
9285  special, e.g.
9287 \begin_inset Flex CharStyle:Code
9288 status collapsed
9290 \begin_layout Plain Layout
9292 \backslash
9294 \end_layout
9296 \end_inset
9298 , and so these cause trouble if used in arguments to 
9299 \begin_inset Flex CharStyle:Code
9300 status collapsed
9302 \begin_layout Plain Layout
9304 \backslash
9305 chunkref
9306 \end_layout
9308 \end_inset
9311  At some point I must fix the LaTeX command 
9312 \begin_inset Flex CharStyle:Code
9313 status collapsed
9315 \begin_layout Plain Layout
9317 \backslash
9318 chunkref
9319 \end_layout
9321 \end_inset
9323  so that it can accept these literally, but until then, when writing chunkref
9324  argumemts that need these characters, I must use the forms 
9325 \begin_inset Flex CharStyle:Code
9326 status collapsed
9328 \begin_layout Plain Layout
9330 \backslash
9331 textbackslash{}
9332 \end_layout
9334 \end_inset
9336  and 
9337 \begin_inset Flex CharStyle:Code
9338 status collapsed
9340 \begin_layout Plain Layout
9342 \backslash
9344 \end_layout
9346 \end_inset
9348 ; so I also define a hacky chunk 
9349 \begin_inset Flex CharStyle:Code
9350 status collapsed
9352 \begin_layout Plain Layout
9353 delatex
9354 \end_layout
9356 \end_inset
9358  whose purpose it is to remove these from any arguments parsed by newfangle,
9359  and used further on.
9360 \end_layout
9362 \begin_layout Chunk
9363 delatex,params=text
9364 \end_layout
9366 \begin_layout Standard
9367 \begin_inset listings
9368 inline false
9369 status open
9371 \begin_layout Plain Layout
9373 # FILTHY HACK
9374 \end_layout
9376 \begin_layout Plain Layout
9378 gsub("
9379 \backslash
9381 \backslash
9383 \backslash
9385 \backslash
9386 #", "#", ${text});
9387 \end_layout
9389 \begin_layout Plain Layout
9391 gsub("
9392 \backslash
9394 \backslash
9396 \backslash
9398 \backslash
9399 textbackslash{}", "
9400 \backslash
9402 \backslash
9403 ", ${text});
9404 \end_layout
9406 \end_inset
9409 \end_layout
9411 \begin_layout Standard
9412 As each chunk line may contain more than one chunk include, we will split
9413  out chunk includes in an iterative fashion
9414 \begin_inset Foot
9415 status collapsed
9417 \begin_layout Plain Layout
9418 Contrary to our use of 
9419 \begin_inset Flex CharStyle:Code
9420 status collapsed
9422 \begin_layout Plain Layout
9423 split
9424 \end_layout
9426 \end_inset
9428  when substituting parameters in chapter 
9429 \begin_inset CommandInset ref
9430 LatexCommand ref
9431 reference "Here-we-split"
9433 \end_inset
9436 \end_layout
9438 \end_inset
9441 \end_layout
9443 \begin_layout Standard
9444 First, as long as the chunk contains a 
9445 \begin_inset Flex CharStyle:Code
9446 status collapsed
9448 \begin_layout Plain Layout
9450 \backslash
9451 chunkref
9452 \end_layout
9454 \end_inset
9456  command we take as much as we can up to the first 
9457 \begin_inset Flex CharStyle:Code
9458 status collapsed
9460 \begin_layout Plain Layout
9462 \backslash
9463 chunkref
9464 \end_layout
9466 \end_inset
9468  command.
9469 \end_layout
9471 \begin_layout Chunk
9472 process-chunk
9473 \end_layout
9475 \begin_layout Standard
9476 \begin_inset listings
9477 inline false
9478 status open
9480 \begin_layout Plain Layout
9482 chunk = $0;
9483 \end_layout
9485 \begin_layout Plain Layout
9487 indent = 0;
9488 \end_layout
9490 \begin_layout Plain Layout
9492 while(match(chunk, 
9493 \end_layout
9495 \begin_layout Plain Layout
9497             "([=]<
9498 \backslash
9500 \backslash
9502 \backslash
9504 \backslash
9505 chunkref{([^}>]*)}(
9506 \backslash
9508 \backslash
9510 \backslash
9512 \backslash
9513 )|)>|<<([a-zA-Z_][-a-zA-Z0-9_]*)>>)", 
9514 \end_layout
9516 \begin_layout Plain Layout
9518             line)
9519 \backslash
9521 \end_layout
9523 \begin_layout Plain Layout
9525 ) {
9526 \end_layout
9528 \begin_layout Plain Layout
9530   chunklet = substr(chunk, 1, RSTART - 1);
9531 \end_layout
9533 \end_inset
9536 \end_layout
9538 \begin_layout Standard
9539 We keep track of the indent count, by counting the number of literal characters
9540  found.
9541  We can then preserve this indent on each output line when multi-line chunks
9542  are expanded.
9543 \end_layout
9545 \begin_layout Standard
9546 We then process this first part literal text, and set the chunk which is
9547  still to be processed to be the text after the 
9548 \begin_inset Flex CharStyle:Code
9549 status collapsed
9551 \begin_layout Plain Layout
9553 \backslash
9554 chunkref
9555 \end_layout
9557 \end_inset
9559  command, which we will process next as we continue around the loop.
9560 \end_layout
9562 \begin_layout Standard
9563 \begin_inset listings
9564 inline false
9565 status open
9567 \begin_layout Plain Layout
9569   indent += length(chunklet);
9570 \end_layout
9572 \begin_layout Plain Layout
9574   chunk_line(active_chunk, chunklet);
9575 \end_layout
9577 \begin_layout Plain Layout
9579   chunk = substr(chunk, RSTART + RLENGTH);
9580 \end_layout
9582 \end_inset
9585 \end_layout
9587 \begin_layout Standard
9588 We then consider the type of chunk command we have found, whether it is
9589  the newfangle style command beginning with 
9590 \begin_inset Flex CharStyle:Code
9591 status collapsed
9593 \begin_layout Plain Layout
9595 \end_layout
9597 \end_inset
9599  or the older notangle style beginning with 
9600 \begin_inset Flex CharStyle:Code
9601 status collapsed
9603 \begin_layout Plain Layout
9605 \end_layout
9607 \end_inset
9611 \end_layout
9613 \begin_layout Standard
9614 Newfangle chunks may have parameters contained within square brackets.
9615  These will be matched in 
9616 \begin_inset Flex CharStyle:Code
9617 status collapsed
9619 \begin_layout Plain Layout
9620 line[3]
9621 \end_layout
9623 \end_inset
9625  and are considered at this stage of processing to be part of the name of
9626  the chunk to be included.
9627 \end_layout
9629 \begin_layout Standard
9630 \begin_inset listings
9631 inline false
9632 status open
9634 \begin_layout Plain Layout
9636   if (substr(line[1], 1, 1) == "=") {
9637 \end_layout
9639 \begin_layout Plain Layout
9641     # chunk name up to }
9642 \end_layout
9644 \begin_layout Plain Layout
9646         =<
9647 \backslash
9648 chunkref{delatex}(line[3])>
9649 \end_layout
9651 \begin_layout Plain Layout
9653     chunk_include(active_chunk, line[2] line[3], indent);
9654 \end_layout
9656 \begin_layout Plain Layout
9658   } else if (substr(line[1], 1, 1) == "<") {
9659 \end_layout
9661 \begin_layout Plain Layout
9663     chunk_include(active_chunk, line[4], indent);
9664 \end_layout
9666 \begin_layout Plain Layout
9668   } else {
9669 \end_layout
9671 \begin_layout Plain Layout
9673     error("Unknown chunk fragment: " line[1]);
9674 \end_layout
9676 \begin_layout Plain Layout
9678   }
9679 \end_layout
9681 \end_inset
9684 \end_layout
9686 \begin_layout Standard
9687 The loop will continue until there are no more chunkref statements in the
9688  text, at which point we process the final part of the chunk.
9689 \end_layout
9691 \begin_layout Standard
9692 \begin_inset listings
9693 inline false
9694 status open
9696 \begin_layout Plain Layout
9699 \end_layout
9701 \begin_layout Plain Layout
9703 chunk_line(active_chunk, chunk);
9704 \end_layout
9706 \end_inset
9709 \end_layout
9711 \begin_layout Standard
9712 \begin_inset CommandInset label
9713 LatexCommand label
9714 name "lone-newline"
9716 \end_inset
9718 We add the newline character as a chunklet on it's own, to make it easier
9719  to detect new lines and thus manage indentation when processing the output.
9720 \end_layout
9722 \begin_layout Standard
9723 \begin_inset listings
9724 inline false
9725 status open
9727 \begin_layout Plain Layout
9729 chunk_line(active_chunk, "
9730 \backslash
9731 n");
9732 \end_layout
9734 \end_inset
9737 \end_layout
9739 \begin_layout Standard
9740 We will also permit a chunk-part number to follow in square brackets, so
9741  that 
9742 \begin_inset Flex CharStyle:Code
9743 status collapsed
9745 \begin_layout Plain Layout
9747 \backslash
9748 chunkref{chunk-name[1]}>
9749 \end_layout
9751 \end_inset
9753  will refer to the first part only.
9754  This can make it easy to include a C function prototype in a header file,
9755  if the first part of the chunk is just the function prototype without the
9756  trailing semi-colon.
9757  The header file would include the prototype with the trailing semi-colon,
9758  like this:
9759 \end_layout
9761 \begin_layout LyX-Code
9763 \backslash
9764 chunkref{chunk-name[1]}>;
9765 \end_layout
9767 \begin_layout Standard
9768 This is handled in section 
9769 \begin_inset CommandInset ref
9770 LatexCommand ref
9771 reference "sub:Chunk-parts"
9773 \end_inset
9776 \end_layout
9778 \begin_layout Standard
9779 We should perhaps introduce a notion of language specific chunk options;
9780  so that perhaps we could specify:
9781 \end_layout
9783 \begin_layout LyX-Code
9785 \backslash
9786 chunkref{chunk-name[function-declaration]}>;
9787 \end_layout
9789 \begin_layout Standard
9790 which applies a transform 
9791 \begin_inset Flex CharStyle:Code
9792 status collapsed
9794 \begin_layout Plain Layout
9795 function-declaration
9796 \end_layout
9798 \end_inset
9800  to the chunk --- which in this case would extract a function prototype
9801  from a function.
9802 \begin_inset Note Note
9803 status open
9805 \begin_layout Plain Layout
9806 So do it
9807 \end_layout
9809 \end_inset
9812 \end_layout
9814 \begin_layout Chapter
9815 Processing Options
9816 \end_layout
9818 \begin_layout Standard
9819 At the start, first we set the default options.
9820 \end_layout
9822 \begin_layout Chunk
9823 default-options
9824 \end_layout
9826 \begin_layout Standard
9827 \begin_inset listings
9828 inline false
9829 status open
9831 \begin_layout Plain Layout
9833 debug=0;
9834 \end_layout
9836 \begin_layout Plain Layout
9838 linenos=0;
9839 \end_layout
9841 \begin_layout Plain Layout
9843 notangle_mode=0;
9844 \end_layout
9846 \begin_layout Plain Layout
9848 root="*";
9849 \end_layout
9851 \begin_layout Plain Layout
9853 tabs = "";
9854 \end_layout
9856 \end_inset
9859 \end_layout
9861 \begin_layout Standard
9862 Then we use getopt the standard way, and null out ARGV afterwards in the
9863  normal AWK fashion.
9864 \end_layout
9866 \begin_layout Chunk
9867 read-options
9868 \end_layout
9870 \begin_layout Standard
9871 \begin_inset listings
9872 inline false
9873 status open
9875 \begin_layout Plain Layout
9877 Optind = 1    # skip ARGV[0]
9878 \end_layout
9880 \begin_layout Plain Layout
9882 while(getopt(ARGC, ARGV, "R:LdT:hr")!=-1) {
9883 \end_layout
9885 \begin_layout Plain Layout
9887   =<
9888 \backslash
9889 chunkref{handle-options}>
9890 \end_layout
9892 \begin_layout Plain Layout
9895 \end_layout
9897 \begin_layout Plain Layout
9899 for (i=1; i<Optind; i++) { ARGV[i]=""; }
9900 \end_layout
9902 \end_inset
9905 \end_layout
9907 \begin_layout Standard
9908 This is how we handle our options:
9909 \end_layout
9911 \begin_layout Chunk
9912 handle-options
9913 \end_layout
9915 \begin_layout Standard
9916 \begin_inset listings
9917 inline false
9918 status open
9920 \begin_layout Plain Layout
9922 if (Optopt == "R") root = Optarg;
9923 \end_layout
9925 \begin_layout Plain Layout
9927 else if (Optopt == "r") root="";
9928 \end_layout
9930 \begin_layout Plain Layout
9932 else if (Optopt == "L") linenos = 1;
9933 \end_layout
9935 \begin_layout Plain Layout
9937 else if (Optopt == "d") debug = 1;
9938 \end_layout
9940 \begin_layout Plain Layout
9942 else if (Optopt == "T") tabs = indent_string(Optarg+0);
9943 \end_layout
9945 \begin_layout Plain Layout
9947 else if (Optopt == "h") help();
9948 \end_layout
9950 \begin_layout Plain Layout
9952 else if (Optopt == "?") help();
9953 \end_layout
9955 \end_inset
9958 \end_layout
9960 \begin_layout Standard
9961 We do all of this at the beginning of the program
9962 \end_layout
9964 \begin_layout Chunk
9965 begin
9966 \end_layout
9968 \begin_layout Standard
9969 \begin_inset listings
9970 inline false
9971 status open
9973 \begin_layout Plain Layout
9975 BEGIN {
9976 \end_layout
9978 \begin_layout Plain Layout
9980   =<
9981 \backslash
9982 chunkref{constants}>
9983 \end_layout
9985 \begin_layout Plain Layout
9987   =<
9988 \backslash
9989 chunkref{mode-definitions}>
9990 \end_layout
9992 \begin_layout Plain Layout
9994   =<
9995 \backslash
9996 chunkref{default-options}>
9997 \end_layout
9999 \begin_layout Plain Layout
10001 \end_layout
10003 \begin_layout Plain Layout
10005   =<
10006 \backslash
10007 chunkref{read-options}>
10008 \end_layout
10010 \begin_layout Plain Layout
10013 \end_layout
10015 \end_inset
10018 \end_layout
10020 \begin_layout Standard
10021 And have a simple help function
10022 \end_layout
10024 \begin_layout Chunk
10025 help()
10026 \end_layout
10028 \begin_layout Standard
10029 \begin_inset listings
10030 inline false
10031 status open
10033 \begin_layout Plain Layout
10035 function help() {
10036 \end_layout
10038 \begin_layout Plain Layout
10040   print "Usage:"
10041 \end_layout
10043 \begin_layout Plain Layout
10045   print "  newfangle [-L] -R<rootname> [source.tex ...]"
10046 \end_layout
10048 \begin_layout Plain Layout
10050   print "  newfangle -r [source.tex ...]"
10051 \end_layout
10053 \begin_layout Plain Layout
10055   print "  If the filename, source.tex is not specified then stdin is used"
10056 \end_layout
10058 \begin_layout Plain Layout
10060   print
10061 \end_layout
10063 \begin_layout Plain Layout
10065   print "-L causes the C statement: #line <lineno> 
10066 \backslash
10067 "filename
10068 \backslash
10069 "" to be issued"
10070 \end_layout
10072 \begin_layout Plain Layout
10074   print "-R causes the named root to be written to stdout"
10075 \end_layout
10077 \begin_layout Plain Layout
10079   print "-r lists all roots in the file (even those used elsewhere)"
10080 \end_layout
10082 \begin_layout Plain Layout
10084   exit 1;
10085 \end_layout
10087 \begin_layout Plain Layout
10090 \end_layout
10092 \end_inset
10095 \end_layout
10097 \begin_layout Chapter
10098 Generating the output
10099 \end_layout
10101 \begin_layout Standard
10102 We generate output by calling output_chunk, or listing the chunk names.
10103 \end_layout
10105 \begin_layout Chunk
10106 generate-output
10107 \end_layout
10109 \begin_layout Standard
10110 \begin_inset listings
10111 inline false
10112 status open
10114 \begin_layout Plain Layout
10116 if (length(root)) output_chunk(root);
10117 \end_layout
10119 \begin_layout Plain Layout
10121 else output_chunk_names();
10122 \end_layout
10124 \end_inset
10127 \end_layout
10129 \begin_layout Standard
10130 We also have some other output debugging:
10131 \end_layout
10133 \begin_layout Chunk
10134 debug-output
10135 \end_layout
10137 \begin_layout Standard
10138 \begin_inset listings
10139 inline false
10140 status open
10142 \begin_layout Plain Layout
10144 if (debug) {
10145 \end_layout
10147 \begin_layout Plain Layout
10149   print "------ chunk names "
10150 \end_layout
10152 \begin_layout Plain Layout
10154   output_chunk_names();
10155 \end_layout
10157 \begin_layout Plain Layout
10159   print "====== chunks"
10160 \end_layout
10162 \begin_layout Plain Layout
10164   output_chunks();
10165 \end_layout
10167 \begin_layout Plain Layout
10169   print "++++++ debug"
10170 \end_layout
10172 \begin_layout Plain Layout
10174   for (a in chunks) {
10175 \end_layout
10177 \begin_layout Plain Layout
10179     print a "=" chunks[a];
10180 \end_layout
10182 \begin_layout Plain Layout
10184   }
10185 \end_layout
10187 \begin_layout Plain Layout
10190 \end_layout
10192 \end_inset
10195 \end_layout
10197 \begin_layout Standard
10198 We do both of these at the end.
10199  We also set 
10200 \begin_inset Flex CharStyle:Code
10201 status collapsed
10203 \begin_layout Plain Layout
10204 ORS=""
10205 \end_layout
10207 \end_inset
10209  because each chunklet is not necessarily a complete line, and we already
10210  added 
10211 \begin_inset Flex CharStyle:Code
10212 status collapsed
10214 \begin_layout Plain Layout
10216 \end_layout
10218 \end_inset
10220  to each input line in section 
10221 \begin_inset CommandInset ref
10222 LatexCommand ref
10223 reference "sub:ORS-chunk-text"
10225 \end_inset
10228 \end_layout
10230 \begin_layout Chunk
10232 \end_layout
10234 \begin_layout Standard
10235 \begin_inset listings
10236 inline false
10237 status open
10239 \begin_layout Plain Layout
10241 END {
10242 \end_layout
10244 \begin_layout Plain Layout
10246   =<
10247 \backslash
10248 chunkref{debug-output}>
10249 \end_layout
10251 \begin_layout Plain Layout
10253   ORS="";
10254 \end_layout
10256 \begin_layout Plain Layout
10258   =<
10259 \backslash
10260 chunkref{generate-output}>
10261 \end_layout
10263 \begin_layout Plain Layout
10266 \end_layout
10268 \end_inset
10271 \end_layout
10273 \begin_layout Standard
10274 We write chunk names like this.
10275  If we seem to be running in notangle compatibility mode, then we enclose
10276  the name like this 
10277 \begin_inset Flex CharStyle:Code
10278 status collapsed
10280 \begin_layout Plain Layout
10281 <<name>>
10282 \end_layout
10284 \end_inset
10286  the same way notangle does:
10287 \end_layout
10289 \begin_layout Chunk
10290 output_chunk_names()
10291 \end_layout
10293 \begin_layout Standard
10294 \begin_inset listings
10295 inline false
10296 status open
10298 \begin_layout Plain Layout
10300 function output_chunk_names(   c, prefix, suffix) 
10301 \end_layout
10303 \begin_layout Plain Layout
10306 \end_layout
10308 \begin_layout Plain Layout
10310   if (notangle_mode) {
10311 \end_layout
10313 \begin_layout Plain Layout
10315     prefix="<<";
10316 \end_layout
10318 \begin_layout Plain Layout
10320     suffix=">>";
10321 \end_layout
10323 \begin_layout Plain Layout
10325   }
10326 \end_layout
10328 \begin_layout Plain Layout
10330   for (c in chunk_names) {
10331 \end_layout
10333 \begin_layout Plain Layout
10335     print prefix c suffix "
10336 \backslash
10338 \end_layout
10340 \begin_layout Plain Layout
10342   }
10343 \end_layout
10345 \begin_layout Plain Layout
10348 \end_layout
10350 \end_inset
10353 \end_layout
10355 \begin_layout Standard
10356 This function would write out all chunks
10357 \end_layout
10359 \begin_layout Chunk
10360 output_chunks()
10361 \end_layout
10363 \begin_layout Standard
10364 \begin_inset listings
10365 inline false
10366 status open
10368 \begin_layout Plain Layout
10370 function output_chunks(  a) 
10371 \end_layout
10373 \begin_layout Plain Layout
10376 \end_layout
10378 \begin_layout Plain Layout
10380   for (a in chunk_names) {
10381 \end_layout
10383 \begin_layout Plain Layout
10385     output_chunk(chunk_names[a]);
10386 \end_layout
10388 \begin_layout Plain Layout
10390   }
10391 \end_layout
10393 \begin_layout Plain Layout
10396 \end_layout
10398 \begin_layout Plain Layout
10400 \end_layout
10402 \begin_layout Plain Layout
10404 function output_chunk(chunk) {
10405 \end_layout
10407 \begin_layout Plain Layout
10409   newline = 1;
10410 \end_layout
10412 \begin_layout Plain Layout
10414   lineno_needed = linenos;
10415 \end_layout
10417 \begin_layout Plain Layout
10419 \end_layout
10421 \begin_layout Plain Layout
10423   write_chunk(chunk);
10424 \end_layout
10426 \begin_layout Plain Layout
10429 \end_layout
10431 \begin_layout Plain Layout
10433 \end_layout
10435 \end_inset
10438 \end_layout
10440 \begin_layout Section
10441 Assembling the chunks
10442 \end_layout
10444 \begin_layout Standard
10445 \begin_inset Flex CharStyle:Code
10446 status collapsed
10448 \begin_layout Plain Layout
10449 chunk_path
10450 \end_layout
10452 \end_inset
10454  holds a string consisting of the names of all the chunks that resulted
10455  in this chunk being output.
10457 \begin_inset Note Note
10458 status collapsed
10460 \begin_layout Plain Layout
10461 Make sure it includes the line numbers too...
10463 \end_layout
10465 \end_inset
10467 It should probably also contain the source line numbers at which each inclusion
10468  also occured.
10469 \end_layout
10471 \begin_layout Chunk
10472 write_chunk()
10473 \end_layout
10475 \begin_layout Standard
10476 We first initialize the mode tracker for this chunk.
10477 \end_layout
10479 \begin_layout Standard
10480 \begin_inset listings
10481 inline false
10482 status open
10484 \begin_layout Plain Layout
10486 function write_chunk(chunk_name) {
10487 \end_layout
10489 \begin_layout Plain Layout
10491   =<
10492 \backslash
10493 chunkref{awk-delete-array}(context)>
10494 \end_layout
10496 \begin_layout Plain Layout
10498   return write_chunk_r(chunk_name, context);
10499 \end_layout
10501 \begin_layout Plain Layout
10504 \end_layout
10506 \end_inset
10509 \end_layout
10511 \begin_layout Chunk
10512 write_chunk(),emph={chunk_path}
10513 \end_layout
10515 \begin_layout Standard
10516 \begin_inset listings
10517 inline false
10518 status open
10520 \begin_layout Plain Layout
10522 function write_chunk_r(chunk_name, context, indent, tail,
10523 \end_layout
10525 \begin_layout Plain Layout
10527   # optional vars
10528 \end_layout
10530 \begin_layout Plain Layout
10532   chunk_path, chunk_args, 
10533 \end_layout
10535 \begin_layout Plain Layout
10537   s, r, src, new_src, 
10538 \end_layout
10540 \begin_layout Plain Layout
10542   # local vars
10543 \end_layout
10545 \begin_layout Plain Layout
10547   chunk_params, part, max_part, part_line, frag, max_frag, text, 
10548 \end_layout
10550 \begin_layout Plain Layout
10552   chunklet, only_part, call_chunk_args)
10553 \end_layout
10555 \begin_layout Plain Layout
10558 \end_layout
10560 \end_inset
10563 \end_layout
10565 \begin_layout Subsection
10566 \begin_inset CommandInset label
10567 LatexCommand label
10568 name "sub:Chunk-parts"
10570 \end_inset
10572 Chunk parts
10573 \end_layout
10575 \begin_layout Standard
10576 As mentioned in section 
10577 \begin_inset CommandInset ref
10578 LatexCommand ref
10579 reference "sub:lstlistings-includes"
10581 \end_inset
10583 , a chunk name may contain a part specifier in square brackets, limiting
10584  the parts that should be emitted.
10585 \end_layout
10587 \begin_layout Standard
10588 \begin_inset listings
10589 inline false
10590 status open
10592 \begin_layout Plain Layout
10594   if (match(chunk_name, "^(.*)
10595 \backslash
10597 \backslash
10598 [([0-9]*)
10599 \backslash
10601 \backslash
10602 ]$", chunk_name_parts)) {
10603 \end_layout
10605 \begin_layout Plain Layout
10607     chunk_name = chunk_name_parts[1];
10608 \end_layout
10610 \begin_layout Plain Layout
10612     only_part = chunk_name_parts[2];
10613 \end_layout
10615 \begin_layout Plain Layout
10617   }
10618 \end_layout
10620 \end_inset
10623 \end_layout
10625 \begin_layout Standard
10626 We then create a mode tracker 
10627 \end_layout
10629 \begin_layout Standard
10630 \begin_inset listings
10631 inline false
10632 status open
10634 \begin_layout Plain Layout
10636   =<
10637 \backslash
10638 chunkref{new-mode-tracker}(context, chunks[chunk_name, "language"], "")>
10639 \end_layout
10641 \end_inset
10644 \end_layout
10646 \begin_layout Standard
10647 We extract into 
10648 \begin_inset Flex CharStyle:Code
10649 status collapsed
10651 \begin_layout Plain Layout
10652 chunk_params
10653 \end_layout
10655 \end_inset
10657  the names of the parameters that this chunk accepts, whose values were
10658  (optionally) passed in 
10659 \begin_inset Flex CharStyle:Code
10660 status collapsed
10662 \begin_layout Plain Layout
10663 chunk_args
10664 \end_layout
10666 \end_inset
10669 \end_layout
10671 \begin_layout Standard
10672 \begin_inset listings
10673 inline false
10674 status open
10676 \begin_layout Plain Layout
10678   split(chunks[chunk_name, "params"], chunk_params, " *; *");
10679 \end_layout
10681 \end_inset
10684 \end_layout
10686 \begin_layout Standard
10687 To assemble a chunk, we write out each part.
10688 \end_layout
10690 \begin_layout Chunk
10691 write_chunk()
10692 \end_layout
10694 \begin_layout Standard
10695 \begin_inset listings
10696 inline false
10697 status open
10699 \begin_layout Plain Layout
10701   if (! (chunk_name in chunk_names)) {
10702 \end_layout
10704 \begin_layout Plain Layout
10706     error(sprintf(_"The root module <<%s>> was not defined.
10707 \backslash
10708 nUsed by: %s",
10709 \backslash
10711 \end_layout
10713 \begin_layout Plain Layout
10715                   chunk_name, chunk_path));
10716 \end_layout
10718 \begin_layout Plain Layout
10720   }
10721 \end_layout
10723 \begin_layout Plain Layout
10725 \end_layout
10727 \begin_layout Plain Layout
10729   max_part = chunks[chunk_name, "part"];
10730 \end_layout
10732 \begin_layout Plain Layout
10734   for(part = 1; part <= max_part; part++) {
10735 \end_layout
10737 \begin_layout Plain Layout
10739     if (! only_part || part == only_part) {
10740 \end_layout
10742 \begin_layout Plain Layout
10744       =<
10745 \backslash
10746 chunkref{write-part}>
10747 \end_layout
10749 \begin_layout Plain Layout
10751     }
10752 \end_layout
10754 \begin_layout Plain Layout
10756   }
10757 \end_layout
10759 \begin_layout Plain Layout
10761   if (! finalize_mode_tracker(context)) {
10762 \end_layout
10764 \begin_layout Plain Layout
10766     error(sprintf(_"Module %s did not close context properly.
10767 \backslash
10768 nUsed by: %s
10769 \backslash
10770 n", chunk_name, chunk_path));
10771 \end_layout
10773 \begin_layout Plain Layout
10775   }
10776 \end_layout
10778 \begin_layout Plain Layout
10781 \end_layout
10783 \end_inset
10786 \end_layout
10788 \begin_layout Standard
10789 A part can either be a chunklet of lines, or an include of another chunk.
10790 \end_layout
10792 \begin_layout Standard
10793 Chunks may also have parameters, specified in LaTeX style with braces after
10794  the chunk name --- looking like this in the document: 
10795 \begin_inset Flex CharStyle:Code
10796 status collapsed
10798 \begin_layout Plain Layout
10799 chunkname{param1, param2}
10800 \end_layout
10802 \end_inset
10805  Arguments are passed in square brackets: 
10806 \begin_inset Flex CharStyle:Code
10807 status collapsed
10809 \begin_layout Plain Layout
10811 \backslash
10812 chunkref{chunkname}[arg1, arg2]
10813 \end_layout
10815 \end_inset
10818 \end_layout
10820 \begin_layout Standard
10821 Before we process each part, we check that the source position hasn't changed
10822  unexpectedly, so that we can know if we need to output a new file-line
10823  directive.
10824 \end_layout
10826 \begin_layout Chunk
10827 write-part
10828 \end_layout
10830 \begin_layout Standard
10831 \begin_inset listings
10832 inline false
10833 status open
10835 \begin_layout Plain Layout
10838 \backslash
10839 chunkref{check-source-jump}>
10840 \end_layout
10842 \begin_layout Plain Layout
10844 \end_layout
10846 \begin_layout Plain Layout
10848 chunklet = chunks[chunk_name, "part", part];
10849 \end_layout
10851 \begin_layout Plain Layout
10853 if (chunks[chunk_name, "part", part, "type"] == part_type_chunk) {
10854 \end_layout
10856 \begin_layout Plain Layout
10858   =<
10859 \backslash
10860 chunkref{write-included-chunk}>
10861 \end_layout
10863 \begin_layout Plain Layout
10865 } else if (chunklet SUBSEP "line" in chunks) {
10866 \end_layout
10868 \begin_layout Plain Layout
10870   =<
10871 \backslash
10872 chunkref{write-chunklets}>
10873 \end_layout
10875 \begin_layout Plain Layout
10877 } else {
10878 \end_layout
10880 \begin_layout Plain Layout
10882   # empty last chunklet
10883 \end_layout
10885 \begin_layout Plain Layout
10888 \end_layout
10890 \end_inset
10893 \end_layout
10895 \begin_layout Standard
10896 To write an included chunk, we must detect any optional chunk arguments
10897  in parenthesis.
10898  Then we recurse calling 
10899 \begin_inset Flex Chunkref
10900 status collapsed
10902 \begin_layout Plain Layout
10903 write_chunk()
10904 \end_layout
10906 \end_inset
10909 \end_layout
10911 \begin_layout Chunk
10912 write-included-chunk
10913 \end_layout
10915 \begin_layout Standard
10916 \begin_inset listings
10917 inline false
10918 status open
10920 \begin_layout Plain Layout
10922 if (match(chunklet, "^([^
10923 \backslash
10925 \backslash
10927 \backslash
10929 \backslash
10930 (]*)
10931 \backslash
10933 \backslash
10934 ((.*)
10935 \backslash
10937 \backslash
10938 )$", chunklet_parts)) {
10939 \end_layout
10941 \begin_layout Plain Layout
10943   chunklet = chunklet_parts[1];
10944 \end_layout
10946 \begin_layout Plain Layout
10948   parse_chunk_args("c-like", chunklet_parts[2], call_chunk_args, "(");
10949 \end_layout
10951 \begin_layout Plain Layout
10953   for (c in call_chunk_args) {
10954 \end_layout
10956 \begin_layout Plain Layout
10958     call_chunk_args[c] = expand_chunk_args(call_chunk_args[c], chunk_params,
10959  chunk_args);
10960 \end_layout
10962 \begin_layout Plain Layout
10964   }
10965 \end_layout
10967 \begin_layout Plain Layout
10969 } else {
10970 \end_layout
10972 \begin_layout Plain Layout
10974   split("", call_chunk_args);
10975 \end_layout
10977 \begin_layout Plain Layout
10980 \end_layout
10982 \begin_layout Plain Layout
10984 # update the transforms arrays
10985 \end_layout
10987 \begin_layout Plain Layout
10989 new_src = mode_escaper(context, s, r, src);
10990 \end_layout
10992 \begin_layout Plain Layout
10994 write_chunk_r(chunklet, context,
10995 \end_layout
10997 \begin_layout Plain Layout
10999             chunks[chunk_name, "part", part, "indent"] indent,
11000 \end_layout
11002 \begin_layout Plain Layout
11004             chunks[chunk_name, "part", part, "tail"],
11005 \end_layout
11007 \begin_layout Plain Layout
11009             chunk_path "
11010 \backslash
11011 n         " chunk_name,
11012 \end_layout
11014 \begin_layout Plain Layout
11016             call_chunk_args,
11017 \end_layout
11019 \begin_layout Plain Layout
11021                         s, r, new_src);
11022 \end_layout
11024 \end_inset
11027 \end_layout
11029 \begin_layout Standard
11030 Before we output a chunklet of lines, we first emit the file and line number
11031  if we have one, and if it is safe to do so.
11033 \end_layout
11035 \begin_layout Standard
11036 Chunklets are generally broken up by includes, so the start of a chunklet
11037  is a good place to do this.
11038  Then we output each line of the chunklet.
11039 \end_layout
11041 \begin_layout Standard
11042 When it is not safe, such as in the middle of a multi-line macro definition,
11044 \begin_inset Flex CharStyle:Code
11045 status collapsed
11047 \begin_layout Plain Layout
11048 lineno_suppressed
11049 \end_layout
11051 \end_inset
11053  is set to true, and in such a case we note that we want to emit the line
11054  statement when it is next safe.
11055 \end_layout
11057 \begin_layout Chunk
11058 write-chunklets
11059 \end_layout
11061 \begin_layout Standard
11062 \begin_inset listings
11063 inline false
11064 status open
11066 \begin_layout Plain Layout
11068 max_frag = chunks[chunklet, "line"];
11069 \end_layout
11071 \begin_layout Plain Layout
11073 for(frag = 1; frag <= max_frag; frag++) {
11074 \end_layout
11076 \begin_layout Plain Layout
11078   =<
11079 \backslash
11080 chunkref{write-file-line}>
11081 \end_layout
11083 \end_inset
11086 \end_layout
11088 \begin_layout Standard
11089 We then extract the chunklet text and expand any arguments.
11090 \end_layout
11092 \begin_layout Standard
11093 \begin_inset listings
11094 inline false
11095 status open
11097 \begin_layout Plain Layout
11099 \end_layout
11101 \begin_layout Plain Layout
11103   text = chunks[chunklet, frag];
11104 \end_layout
11106 \begin_layout Plain Layout
11109 \end_layout
11111 \begin_layout Plain Layout
11113   /* check params */
11114 \end_layout
11116 \begin_layout Plain Layout
11118   text = expand_chunk_args(text, chunk_params, chunk_args);
11119 \end_layout
11121 \end_inset
11124 \end_layout
11126 \begin_layout Standard
11127 If the text is a single newline (which we keep separate - see 
11128 \begin_inset CommandInset ref
11129 LatexCommand ref
11130 reference "lone-newline"
11132 \end_inset
11134 ) then we increment the line number.
11135  In the case where this is the last line of a chunk and it is not a top-level
11136  chunk we replace the newline with an empty string --- because the chunk
11137  that included this chunk will have the newline at the end of the line that
11138  included this chunk.
11139 \end_layout
11141 \begin_layout Standard
11142 We also note by 
11143 \begin_inset Flex CharStyle:Code
11144 status collapsed
11146 \begin_layout Plain Layout
11147 newline = 1
11148 \end_layout
11150 \end_inset
11152  that we have started a new line, so that indentation can be managed with
11153  the following piece of text.
11154 \end_layout
11156 \begin_layout Standard
11157 \begin_inset listings
11158 inline false
11159 status open
11161 \begin_layout Plain Layout
11163 \end_layout
11165 \begin_layout Plain Layout
11167  if (text == "
11168 \backslash
11169 n") {
11170 \end_layout
11172 \begin_layout Plain Layout
11174     lineno++;
11175 \end_layout
11177 \begin_layout Plain Layout
11179     if (part == max_part && frag == max_frag && length(chunk_path)) {
11180 \end_layout
11182 \begin_layout Plain Layout
11184       text = "";
11185 \end_layout
11187 \begin_layout Plain Layout
11189       break;
11190 \end_layout
11192 \begin_layout Plain Layout
11194     } else {
11195 \end_layout
11197 \begin_layout Plain Layout
11199       newline = 1;
11200 \end_layout
11202 \begin_layout Plain Layout
11204     }
11205 \end_layout
11207 \end_inset
11210 \end_layout
11212 \begin_layout Standard
11213 If this text does not represent a newline, but we see that we are the first
11214  piece of text on a newline, then we prefix our text with the current indent.
11215  NOTE: 
11216 \begin_inset Flex CharStyle:Code
11217 status collapsed
11219 \begin_layout Plain Layout
11220 newline
11221 \end_layout
11223 \end_inset
11225  is a global output-state variable, but the 
11226 \begin_inset Flex CharStyle:Code
11227 status collapsed
11229 \begin_layout Plain Layout
11230 indent
11231 \end_layout
11233 \end_inset
11235  is not.
11237 \end_layout
11239 \begin_layout Standard
11240 \begin_inset listings
11241 inline false
11242 status open
11244 \begin_layout Plain Layout
11246   } else if (length(text) || length(tail)) {
11247 \end_layout
11249 \begin_layout Plain Layout
11251     if (newline) text = indent text;
11252 \end_layout
11254 \begin_layout Plain Layout
11256     newline = 0;
11257 \end_layout
11259 \begin_layout Plain Layout
11261   }
11262 \end_layout
11264 \begin_layout Plain Layout
11266 \end_layout
11268 \end_inset
11271 \end_layout
11273 \begin_layout Standard
11274 Tail will soon no longer be relevant once mode-detection is in place.
11275 \end_layout
11277 \begin_layout Standard
11278 \begin_inset listings
11279 inline false
11280 status open
11282 \begin_layout Plain Layout
11284   text = text tail;
11285 \end_layout
11287 \begin_layout Plain Layout
11289   mode_tracker(context, text);
11290 \end_layout
11292 \begin_layout Plain Layout
11294   print transform_escape(s, r, text, src);
11295 \end_layout
11297 \end_inset
11300 \end_layout
11302 \begin_layout Standard
11303 If a line ends in a backslash --- suggesting continuation --- then we supress
11304  outputting file-line as it would probably break the continued lines.
11306 \end_layout
11308 \begin_layout Standard
11309 \begin_inset listings
11310 inline false
11311 status open
11313 \begin_layout Plain Layout
11315   if (linenos) {
11316 \end_layout
11318 \begin_layout Plain Layout
11320     lineno_suppressed = substr(lastline, length(lastline)) == "
11321 \backslash
11323 \backslash
11325 \end_layout
11327 \begin_layout Plain Layout
11329   }
11330 \end_layout
11332 \begin_layout Plain Layout
11335 \end_layout
11337 \end_inset
11340 \end_layout
11342 \begin_layout Standard
11343 Of course there is no point in actually outputting the source filename and
11344  line number (file-line) if they don't say anything new! We only need to
11345  emit them if they aren't what is expected, or if we we not able to emit
11346  one when they had changed.
11347 \end_layout
11349 \begin_layout Chunk
11350 write-file-line
11351 \end_layout
11353 \begin_layout Standard
11354 \begin_inset listings
11355 inline false
11356 status open
11358 \begin_layout Plain Layout
11360 if (newline && lineno_needed && ! lineno_suppressed) {
11361 \end_layout
11363 \begin_layout Plain Layout
11365   filename = a_filename;
11366 \end_layout
11368 \begin_layout Plain Layout
11370   lineno = a_lineno;
11371 \end_layout
11373 \begin_layout Plain Layout
11375   print "#line " lineno " 
11376 \backslash
11377 "" filename "
11378 \backslash
11380 \backslash
11382 \end_layout
11384 \begin_layout Plain Layout
11386   lineno_needed = 0;
11387 \end_layout
11389 \begin_layout Plain Layout
11392 \end_layout
11394 \end_inset
11397 \end_layout
11399 \begin_layout Standard
11400 We check if a new file-line is needed by checking if the source line matches
11401  what we (or a compiler) would expect.
11403 \end_layout
11405 \begin_layout Chunk
11406 check-source-jump
11407 \end_layout
11409 \begin_layout Standard
11410 \begin_inset listings
11411 inline false
11412 status open
11414 \begin_layout Plain Layout
11416 if (linenos && (chunk_name SUBSEP "part" SUBSEP part SUBSEP "FILENAME" in
11417  chunks)) {
11418 \end_layout
11420 \begin_layout Plain Layout
11422   a_filename = chunks[chunk_name, "part", part, "FILENAME"];
11423 \end_layout
11425 \begin_layout Plain Layout
11427   a_lineno = chunks[chunk_name, "part", part, "LINENO"];
11428 \end_layout
11430 \begin_layout Plain Layout
11432   if (a_filename != filename || a_lineno != lineno) {
11433 \end_layout
11435 \begin_layout Plain Layout
11437     lineno_needed++;
11438 \end_layout
11440 \begin_layout Plain Layout
11442   }
11443 \end_layout
11445 \begin_layout Plain Layout
11448 \end_layout
11450 \end_inset
11453 \end_layout
11455 \begin_layout Chapter
11456 Storing chunks
11457 \end_layout
11459 \begin_layout Standard
11460 Awk has pretty limited data structures, so we will use two main hashes.
11461  Uninterrupted sequences of a chunk will be stored in 
11462 \begin_inset Flex CharStyle:Code
11463 status collapsed
11465 \begin_layout Plain Layout
11466 chunklets
11467 \end_layout
11469 \end_inset
11471  and the chunklets used in a chunk will be stored in 
11472 \begin_inset Flex CharStyle:Code
11473 status collapsed
11475 \begin_layout Plain Layout
11476 chunks
11477 \end_layout
11479 \end_inset
11482 \end_layout
11484 \begin_layout Chunk
11485 constants
11486 \end_layout
11488 \begin_layout Standard
11489 \begin_inset listings
11490 inline false
11491 status open
11493 \begin_layout Plain Layout
11495 part_type_chunk=1;
11496 \end_layout
11498 \begin_layout Plain Layout
11500 SUBSEP=",";
11501 \end_layout
11503 \end_inset
11506 \end_layout
11508 \begin_layout Standard
11509 The 
11510 \begin_inset Flex CharStyle:Code
11511 status collapsed
11513 \begin_layout Plain Layout
11514 params
11515 \end_layout
11517 \end_inset
11519  mentioned are not chunk parameters for parameterized chunks, as mentioned
11520  in 
11521 \begin_inset CommandInset ref
11522 LatexCommand ref
11523 reference "cha:Chunk Arguments"
11525 \end_inset
11527 , but the lstlistings style parameters used in the 
11528 \begin_inset Flex CharStyle:Code
11529 status collapsed
11531 \begin_layout Plain Layout
11533 \backslash
11534 Chunk
11535 \end_layout
11537 \end_inset
11539  command
11540 \begin_inset Foot
11541 status collapsed
11543 \begin_layout Plain Layout
11544 The 
11545 \begin_inset Flex CharStyle:Code
11546 status collapsed
11548 \begin_layout Plain Layout
11549 params
11550 \end_layout
11552 \end_inset
11554  parameter is used to hold the parameters for parameterized chunks
11555 \end_layout
11557 \end_inset
11560 \end_layout
11562 \begin_layout Chunk
11563 chunk-storage-functions
11564 \end_layout
11566 \begin_layout Standard
11567 \begin_inset listings
11568 inline false
11569 status open
11571 \begin_layout Plain Layout
11573 function new_chunk(chunk_name, params,
11574 \end_layout
11576 \begin_layout Plain Layout
11578   # local vars
11579 \end_layout
11581 \begin_layout Plain Layout
11583   p, append )
11584 \end_layout
11586 \begin_layout Plain Layout
11589 \end_layout
11591 \begin_layout Plain Layout
11593   # HACK WHILE WE CHANGE TO ( ) for PARAM CHUNKS
11594 \end_layout
11596 \begin_layout Plain Layout
11598   gsub("
11599 \backslash
11601 \backslash
11603 \backslash
11605 \backslash
11606 )$", "", chunk_name);
11607 \end_layout
11609 \begin_layout Plain Layout
11611   if (! (chunk_name in chunk_names)) {
11612 \end_layout
11614 \begin_layout Plain Layout
11616     if (debug) print "New chunk " chunk_name;
11617 \end_layout
11619 \begin_layout Plain Layout
11621     chunk_names[chunk_name];
11622 \end_layout
11624 \begin_layout Plain Layout
11626     for (p in params) {
11627 \end_layout
11629 \begin_layout Plain Layout
11631       chunks[chunk_name, p] = params[p];
11632 \end_layout
11634 \begin_layout Plain Layout
11636     }
11637 \end_layout
11639 \begin_layout Plain Layout
11641     if ("append" in params) {
11642 \end_layout
11644 \begin_layout Plain Layout
11646       append=params["append"];
11647 \end_layout
11649 \begin_layout Plain Layout
11651       if (! (append in chunk_names)) {
11652 \end_layout
11654 \begin_layout Plain Layout
11656         warning("Chunk " chunk_name " is appended to chunk " append " which
11657  is not defined yet");
11658 \end_layout
11660 \begin_layout Plain Layout
11662         new_chunk(append);
11663 \end_layout
11665 \begin_layout Plain Layout
11667       }
11668 \end_layout
11670 \begin_layout Plain Layout
11672       chunk_include(append, chunk_name);
11673 \end_layout
11675 \begin_layout Plain Layout
11677       chunk_line(append, ORS);
11678 \end_layout
11680 \begin_layout Plain Layout
11682     }
11683 \end_layout
11685 \begin_layout Plain Layout
11687   }
11688 \end_layout
11690 \begin_layout Plain Layout
11692   active_chunk = chunk_name;
11693 \end_layout
11695 \begin_layout Plain Layout
11697   prime_chunk(chunk_name);
11698 \end_layout
11700 \begin_layout Plain Layout
11703 \end_layout
11705 \end_inset
11708 \end_layout
11710 \begin_layout Standard
11711 \begin_inset listings
11712 inline false
11713 status open
11715 \begin_layout Plain Layout
11717 \end_layout
11719 \begin_layout Plain Layout
11721 function prime_chunk(chunk_name)
11722 \end_layout
11724 \begin_layout Plain Layout
11727 \end_layout
11729 \begin_layout Plain Layout
11731   chunks[chunk_name, "part", ++chunks[chunk_name, "part"] ] = 
11732 \backslash
11734 \end_layout
11736 \begin_layout Plain Layout
11738          chunk_name SUBSEP "chunklet" SUBSEP "" ++chunks[chunk_name, "chunklet"]
11740 \end_layout
11742 \begin_layout Plain Layout
11744   chunks[chunk_name, "part", chunks[chunk_name, "part"], "FILENAME"] = FILENAME;
11745 \end_layout
11747 \begin_layout Plain Layout
11749   chunks[chunk_name, "part", chunks[chunk_name, "part"], "LINENO"] = FNR
11750  + 1;
11751 \end_layout
11753 \begin_layout Plain Layout
11756 \end_layout
11758 \begin_layout Plain Layout
11760 \end_layout
11762 \begin_layout Plain Layout
11764 function chunk_line(chunk_name, line){
11765 \end_layout
11767 \begin_layout Plain Layout
11769   chunks[chunk_name, "chunklet", chunks[chunk_name, "chunklet"],
11770 \end_layout
11772 \begin_layout Plain Layout
11774          ++chunks[chunk_name, "chunklet", chunks[chunk_name, "chunklet"],
11775  "line"]  ] = line;
11776 \end_layout
11778 \begin_layout Plain Layout
11781 \end_layout
11783 \begin_layout Plain Layout
11785 \end_layout
11787 \end_inset
11790 \end_layout
11792 \begin_layout Standard
11793 Chunk include represents a 
11794 \emph on
11795 chunkref
11796 \emph default
11797  statement, and stores the requirement to include another chunk.
11798  The parameter indent represents the quanity of literal text characters
11799  that preceded this 
11800 \emph on
11801 chunkref
11802 \emph default
11803  statement and therefore by how much additional lines of the included chunk
11804  should be indented.
11805 \end_layout
11807 \begin_layout Standard
11808 \begin_inset listings
11809 inline false
11810 status open
11812 \begin_layout Plain Layout
11814 function chunk_include(chunk_name, chunk_ref, indent, tail)
11815 \end_layout
11817 \begin_layout Plain Layout
11820 \end_layout
11822 \begin_layout Plain Layout
11824   chunks[chunk_name, "part", ++chunks[chunk_name, "part"] ] = chunk_ref;
11825 \end_layout
11827 \begin_layout Plain Layout
11829   chunks[chunk_name, "part", chunks[chunk_name, "part"], "type" ] = part_type_ch
11830 unk;
11831 \end_layout
11833 \begin_layout Plain Layout
11835   chunks[chunk_name, "part", chunks[chunk_name, "part"], "indent" ] = indent_str
11836 ing(indent);
11837 \end_layout
11839 \begin_layout Plain Layout
11841   chunks[chunk_name, "part", chunks[chunk_name, "part"], "tail" ] = tail;
11842 \end_layout
11844 \begin_layout Plain Layout
11846   prime_chunk(chunk_name);
11847 \end_layout
11849 \begin_layout Plain Layout
11852 \end_layout
11854 \begin_layout Plain Layout
11856 \end_layout
11858 \end_inset
11861 \end_layout
11863 \begin_layout Standard
11864 The indent is calculated by indent_string, which may in future convert some
11865  spaces into tab characters.
11866  This function works by generating a printf padded format string, like 
11867 \begin_inset Flex CharStyle:Code
11868 status collapsed
11870 \begin_layout Plain Layout
11871 %22s
11872 \end_layout
11874 \end_inset
11876  for an indent of 22, and then printing an empty string using that format.
11877 \end_layout
11879 \begin_layout Standard
11880 \begin_inset listings
11881 inline false
11882 status open
11884 \begin_layout Plain Layout
11886 function indent_string(indent) {
11887 \end_layout
11889 \begin_layout Plain Layout
11891   return sprintf("%" indent "s", "");
11892 \end_layout
11894 \begin_layout Plain Layout
11897 \end_layout
11899 \end_inset
11902 \end_layout
11904 \begin_layout Chapter
11905 \begin_inset CommandInset label
11906 LatexCommand label
11907 name "cha:getopt"
11909 \end_inset
11911 getopt
11912 \end_layout
11914 \begin_layout Standard
11915 I use Arnold Robbins public domain getopt (1993 revision).
11916  This is probably the same one that is covered in chapter 12 of 
11917 \begin_inset Quotes eld
11918 \end_inset
11920 Edition 3 of GAWK: Effective AWK Programming: A User's Guide for GNU Awk
11921 \begin_inset Quotes erd
11922 \end_inset
11924  but as that is licensed under the GNU Free Documentation License, Version
11925  1.3, which conflicts with the GPL3, I can't use it from there (or it's accompany
11926 ing explanations), so I do my best to explain how it works here.
11927 \end_layout
11929 \begin_layout Standard
11930 The getopt.awk header is:
11931 \end_layout
11933 \begin_layout Chunk
11934 getopt.awk-header,language=awk,morestring=[b]{/},morekeywords=else
11935 \end_layout
11937 \begin_layout Standard
11938 \begin_inset listings
11939 inline false
11940 status open
11942 \begin_layout Plain Layout
11944 # getopt.awk --- do C library getopt(3) function in awk
11945 \end_layout
11947 \begin_layout Plain Layout
11950 \end_layout
11952 \begin_layout Plain Layout
11954 # Arnold Robbins, arnold@skeeve.com, Public Domain
11955 \end_layout
11957 \begin_layout Plain Layout
11960 \end_layout
11962 \begin_layout Plain Layout
11964 # Initial version: March, 1991
11965 \end_layout
11967 \begin_layout Plain Layout
11969 # Revised: May, 1993
11970 \end_layout
11972 \begin_layout Plain Layout
11974 \end_layout
11976 \end_inset
11979 \end_layout
11981 \begin_layout Standard
11982 The provided explanation is:
11983 \end_layout
11985 \begin_layout Chunk
11986 getopt.awk-notes
11987 \end_layout
11989 \begin_layout Standard
11990 \begin_inset listings
11991 inline false
11992 status open
11994 \begin_layout Plain Layout
11996 # External variables:
11997 \end_layout
11999 \begin_layout Plain Layout
12001 #    Optind -- index in ARGV of first nonoption argument
12002 \end_layout
12004 \begin_layout Plain Layout
12006 #    Optarg -- string value of argument to current option
12007 \end_layout
12009 \begin_layout Plain Layout
12011 #    Opterr -- if nonzero, print our own diagnostic
12012 \end_layout
12014 \begin_layout Plain Layout
12016 #    Optopt -- current option letter
12017 \end_layout
12019 \begin_layout Plain Layout
12021 \end_layout
12023 \begin_layout Plain Layout
12025 # Returns:
12026 \end_layout
12028 \begin_layout Plain Layout
12030 #    -1     at end of options
12031 \end_layout
12033 \begin_layout Plain Layout
12035 #    ?      for unrecognized option
12036 \end_layout
12038 \begin_layout Plain Layout
12040 #    <c>    a character representing the current option
12041 \end_layout
12043 \begin_layout Plain Layout
12045 \end_layout
12047 \begin_layout Plain Layout
12049 # Private Data:
12050 \end_layout
12052 \begin_layout Plain Layout
12054 #    _opti  -- index in multi-flag option, e.g., -abc
12055 \end_layout
12057 \begin_layout Plain Layout
12059 \end_layout
12061 \end_inset
12064 \end_layout
12066 \begin_layout Standard
12067 The function follows.
12068  The final two parameters, 
12069 \begin_inset Flex CharStyle:Code
12070 status collapsed
12072 \begin_layout Plain Layout
12073 thisopt
12074 \end_layout
12076 \end_inset
12078  and 
12079 \begin_inset Flex CharStyle:Code
12080 status collapsed
12082 \begin_layout Plain Layout
12084 \end_layout
12086 \end_inset
12088  are local variables and not parameters --- as indicated by the multiple
12089  spaces preceding them.
12090  Awk doesn't care, the multiple spaces are a convention to help us humans.
12091 \end_layout
12093 \begin_layout Chunk
12094 getopt.awk-getopt()
12095 \end_layout
12097 \begin_layout Standard
12098 \begin_inset listings
12099 inline false
12100 status open
12102 \begin_layout Plain Layout
12104 function getopt(argc, argv, options,    thisopt, i)
12105 \end_layout
12107 \begin_layout Plain Layout
12110 \end_layout
12112 \begin_layout Plain Layout
12114     if (length(options) == 0)    # no options given
12115 \end_layout
12117 \begin_layout Plain Layout
12119         return -1
12120 \end_layout
12122 \begin_layout Plain Layout
12124     if (argv[Optind] == "--") {  # all done
12125 \end_layout
12127 \begin_layout Plain Layout
12129         Optind++
12130 \end_layout
12132 \begin_layout Plain Layout
12134         _opti = 0
12135 \end_layout
12137 \begin_layout Plain Layout
12139         return -1
12140 \end_layout
12142 \begin_layout Plain Layout
12144     } else if (argv[Optind] !~ /^-[^: 
12145 \backslash
12147 \backslash
12149 \backslash
12151 \backslash
12153 \backslash
12155 \backslash
12156 b]/) {
12157 \end_layout
12159 \begin_layout Plain Layout
12161         _opti = 0
12162 \end_layout
12164 \begin_layout Plain Layout
12166         return -1
12167 \end_layout
12169 \begin_layout Plain Layout
12171     }
12172 \end_layout
12174 \begin_layout Plain Layout
12176     if (_opti == 0)
12177 \end_layout
12179 \begin_layout Plain Layout
12181         _opti = 2
12182 \end_layout
12184 \begin_layout Plain Layout
12186     thisopt = substr(argv[Optind], _opti, 1)
12187 \end_layout
12189 \begin_layout Plain Layout
12191     Optopt = thisopt
12192 \end_layout
12194 \begin_layout Plain Layout
12196     i = index(options, thisopt)
12197 \end_layout
12199 \begin_layout Plain Layout
12201     if (i == 0) {
12202 \end_layout
12204 \begin_layout Plain Layout
12206         if (Opterr)
12207 \end_layout
12209 \begin_layout Plain Layout
12211             printf("%c -- invalid option
12212 \backslash
12214 \end_layout
12216 \begin_layout Plain Layout
12218                                   thisopt) > "/dev/stderr"
12219 \end_layout
12221 \begin_layout Plain Layout
12223         if (_opti >= length(argv[Optind])) {
12224 \end_layout
12226 \begin_layout Plain Layout
12228             Optind++
12229 \end_layout
12231 \begin_layout Plain Layout
12233             _opti = 0
12234 \end_layout
12236 \begin_layout Plain Layout
12238         } else
12239 \end_layout
12241 \begin_layout Plain Layout
12243             _opti++
12244 \end_layout
12246 \begin_layout Plain Layout
12248         return "?"
12249 \end_layout
12251 \begin_layout Plain Layout
12253     }
12254 \end_layout
12256 \end_inset
12259 \end_layout
12261 \begin_layout Standard
12262 At this point, the option has been found and we need to know if it takes
12263  any arguments.
12264 \end_layout
12266 \begin_layout Standard
12267 \begin_inset listings
12268 inline false
12269 status open
12271 \begin_layout Plain Layout
12273     if (substr(options, i + 1, 1) == ":") {
12274 \end_layout
12276 \begin_layout Plain Layout
12278         # get option argument
12279 \end_layout
12281 \begin_layout Plain Layout
12283         if (length(substr(argv[Optind], _opti + 1)) > 0)
12284 \end_layout
12286 \begin_layout Plain Layout
12288             Optarg = substr(argv[Optind], _opti + 1)
12289 \end_layout
12291 \begin_layout Plain Layout
12293         else
12294 \end_layout
12296 \begin_layout Plain Layout
12298             Optarg = argv[++Optind]
12299 \end_layout
12301 \begin_layout Plain Layout
12303         _opti = 0
12304 \end_layout
12306 \begin_layout Plain Layout
12308     } else
12309 \end_layout
12311 \begin_layout Plain Layout
12313         Optarg = ""
12314 \end_layout
12316 \begin_layout Plain Layout
12318     if (_opti == 0 || _opti >= length(argv[Optind])) {
12319 \end_layout
12321 \begin_layout Plain Layout
12323         Optind++
12324 \end_layout
12326 \begin_layout Plain Layout
12328         _opti = 0
12329 \end_layout
12331 \begin_layout Plain Layout
12333     } else
12334 \end_layout
12336 \begin_layout Plain Layout
12338         _opti++
12339 \end_layout
12341 \begin_layout Plain Layout
12343     return thisopt
12344 \end_layout
12346 \begin_layout Plain Layout
12349 \end_layout
12351 \end_inset
12353 A test program is built in, too
12354 \end_layout
12356 \begin_layout Chunk
12357 getopt.awk-begin
12358 \end_layout
12360 \begin_layout Standard
12361 \begin_inset listings
12362 inline false
12363 status open
12365 \begin_layout Plain Layout
12367 BEGIN {
12368 \end_layout
12370 \begin_layout Plain Layout
12372     Opterr = 1    # default is to diagnose
12373 \end_layout
12375 \begin_layout Plain Layout
12377     Optind = 1    # skip ARGV[0]
12378 \end_layout
12380 \begin_layout Plain Layout
12382     # test program
12383 \end_layout
12385 \begin_layout Plain Layout
12387     if (_getopt_test) {
12388 \end_layout
12390 \begin_layout Plain Layout
12392         while ((_go_c = getopt(ARGC, ARGV, "ab:cd")) != -1)
12393 \end_layout
12395 \begin_layout Plain Layout
12397             printf("c = <%c>, optarg = <%s>
12398 \backslash
12400 \end_layout
12402 \begin_layout Plain Layout
12404                                        _go_c, Optarg)
12405 \end_layout
12407 \begin_layout Plain Layout
12409         printf("non-option arguments:
12410 \backslash
12412 \end_layout
12414 \begin_layout Plain Layout
12416         for (; Optind < ARGC; Optind++)
12417 \end_layout
12419 \begin_layout Plain Layout
12421             printf("
12422 \backslash
12423 tARGV[%d] = <%s>
12424 \backslash
12426 \end_layout
12428 \begin_layout Plain Layout
12430                                     Optind, ARGV[Optind])
12431 \end_layout
12433 \begin_layout Plain Layout
12435     }
12436 \end_layout
12438 \begin_layout Plain Layout
12441 \end_layout
12443 \end_inset
12446 \end_layout
12448 \begin_layout Standard
12449 The entire getopt.awk is made out of these chunks in order
12450 \end_layout
12452 \begin_layout Chunk
12453 getopt.awk
12454 \end_layout
12456 \begin_layout Standard
12457 \begin_inset listings
12458 inline false
12459 status open
12461 \begin_layout Plain Layout
12464 \backslash
12465 chunkref{getopt.awk-header}>
12466 \end_layout
12468 \begin_layout Plain Layout
12470 \end_layout
12472 \begin_layout Plain Layout
12475 \backslash
12476 chunkref{getopt.awk-notes}>
12477 \end_layout
12479 \begin_layout Plain Layout
12482 \backslash
12483 chunkref{getopt.awk-getopt()}>
12484 \end_layout
12486 \begin_layout Plain Layout
12489 \backslash
12490 chunkref{getopt.awk-begin}>
12491 \end_layout
12493 \end_inset
12496 \end_layout
12498 \begin_layout Standard
12499 Although we only want the header and function:
12500 \end_layout
12502 \begin_layout Chunk
12503 getopt
12504 \end_layout
12506 \begin_layout Standard
12507 \begin_inset listings
12508 inline false
12509 status open
12511 \begin_layout Plain Layout
12513 # try: locate getopt.awk for the full original file
12514 \end_layout
12516 \begin_layout Plain Layout
12518 # as part of your standard awk installation
12519 \end_layout
12521 \begin_layout Plain Layout
12524 \backslash
12525 chunkref{getopt.awk-header}>
12526 \end_layout
12528 \begin_layout Plain Layout
12530 \end_layout
12532 \begin_layout Plain Layout
12535 \backslash
12536 chunkref{getopt.awk-getopt()}>
12537 \end_layout
12539 \end_inset
12542 \end_layout
12544 \begin_layout Chapter
12545 Newfangle LaTeX source code
12546 \end_layout
12548 \begin_layout Section
12549 newfangle module
12550 \end_layout
12552 \begin_layout Standard
12553 Here we define a Lyx .module file that makes it convenient to use LyX for
12554  writing such literate programs.
12555 \end_layout
12557 \begin_layout Standard
12558 This file 
12559 \begin_inset Flex CharStyle:Code
12560 status collapsed
12562 \begin_layout Plain Layout
12563 ./newfangle.module
12564 \end_layout
12566 \end_inset
12568  can be installed in your personal 
12569 \begin_inset Flex CharStyle:Code
12570 status collapsed
12572 \begin_layout Plain Layout
12573 .lyx/layouts folder
12574 \end_layout
12576 \end_inset
12579  You will need to Tools Reconfigure so that LyX notices it.
12580  It adds a new format Chunk, which should precede every listing and contain
12581  the chunk name.
12583 \end_layout
12585 \begin_layout Chunk
12586 ./newfangle.module,language=
12587 \end_layout
12589 \begin_layout Standard
12590 \begin_inset listings
12591 inline false
12592 status open
12594 \begin_layout Plain Layout
12597 \backslash
12598 DeclareLyXModule{Newfangle Literate Listings}
12599 \end_layout
12601 \begin_layout Plain Layout
12603 #DescriptionBegin
12604 \end_layout
12606 \begin_layout Plain Layout
12608 #  Newfangle literate listings allow one to write
12609 \end_layout
12611 \begin_layout Plain Layout
12613 #   literate programs after the fashion of noweb, but without having
12614 \end_layout
12616 \begin_layout Plain Layout
12618 #   to use noweave to generate the documentation.
12619  Instead the listings
12620 \end_layout
12622 \begin_layout Plain Layout
12624 #   package is extended in conjunction with the noweb package to implement
12625 \end_layout
12627 \begin_layout Plain Layout
12629 #   to code formating directly as latex.
12630 \end_layout
12632 \begin_layout Plain Layout
12634 #  The newfangle awk script
12635 \end_layout
12637 \begin_layout Plain Layout
12639 #DescriptionEnd
12640 \end_layout
12642 \begin_layout Plain Layout
12644 \end_layout
12646 \begin_layout Plain Layout
12648 Format 11
12649 \end_layout
12651 \begin_layout Plain Layout
12653 \end_layout
12655 \begin_layout Plain Layout
12657 AddToPreamble
12658 \end_layout
12660 \begin_layout Plain Layout
12663 \backslash
12664 chunkref{./newfangle.sty}>
12665 \end_layout
12667 \begin_layout Plain Layout
12669 EndPreamble
12670 \end_layout
12672 \begin_layout Plain Layout
12674 \end_layout
12676 \begin_layout Plain Layout
12679 \backslash
12680 chunkref{chunkstyle}>
12681 \end_layout
12683 \begin_layout Plain Layout
12685 \end_layout
12687 \begin_layout Plain Layout
12690 \backslash
12691 chunkref{chunkref}>
12692 \end_layout
12694 \end_inset
12697 \end_layout
12699 \begin_layout Subsection
12700 The Chunk style
12701 \end_layout
12703 \begin_layout Standard
12704 The purpose of the 
12705 \noun on
12706 chunk
12707 \noun default
12708  style is to make it easier for LyX users to provide the name to 
12709 \begin_inset Flex CharStyle:Code
12710 status collapsed
12712 \begin_layout Plain Layout
12714 \backslash
12715 lstlistings
12716 \end_layout
12718 \end_inset
12721  Normally this requires right-clicking on the listing, choosing settings,
12722  advanced, and then typing 
12723 \begin_inset Flex CharStyle:Code
12724 status collapsed
12726 \begin_layout Plain Layout
12727 name=chunk-name
12728 \end_layout
12730 \end_inset
12733  This has the further disadvantage that the name (and other options) are
12734  not generally visible during document editing.
12735 \end_layout
12737 \begin_layout Standard
12738 The chunk style is defined as a LaTeX command, so that all text on the same
12739  line is passed to the LaTeX command 
12740 \begin_inset Flex CharStyle:Code
12741 status collapsed
12743 \begin_layout Plain Layout
12744 Chunk
12745 \end_layout
12747 \end_inset
12750  This makes it easy to parse using 
12751 \begin_inset Flex CharStyle:Code
12752 status collapsed
12754 \begin_layout Plain Layout
12755 newfangle
12756 \end_layout
12758 \end_inset
12760 , and easy to pass these options on to the listings package.
12761  The first word in a chunk section should be the chunk name, and will have
12763 \begin_inset Flex CharStyle:Code
12764 status collapsed
12766 \begin_layout Plain Layout
12767 name=
12768 \end_layout
12770 \end_inset
12772  prepended to it.
12773  Any other words are accepted arguments to 
12774 \begin_inset Flex CharStyle:Code
12775 status collapsed
12777 \begin_layout Plain Layout
12779 \backslash
12780 lstset
12781 \end_layout
12783 \end_inset
12786 \end_layout
12788 \begin_layout Standard
12789 We set PassThru to 1 because the user is actually entering raw latex.
12790 \end_layout
12792 \begin_layout Chunk
12793 chunkstyle
12794 \end_layout
12796 \begin_layout Standard
12797 \begin_inset listings
12798 inline false
12799 status open
12801 \begin_layout Plain Layout
12803 Style Chunk
12804 \end_layout
12806 \begin_layout Plain Layout
12808   LatexType             Command
12809 \end_layout
12811 \begin_layout Plain Layout
12813   LatexName             Chunk
12814 \end_layout
12816 \begin_layout Plain Layout
12818   Margin                First_Dynamic
12819 \end_layout
12821 \begin_layout Plain Layout
12823   LeftMargin            Chunk:xxx
12824 \end_layout
12826 \begin_layout Plain Layout
12828   LabelSep              xx
12829 \end_layout
12831 \begin_layout Plain Layout
12833   LabelType             Static
12834 \end_layout
12836 \begin_layout Plain Layout
12838   LabelString           "Chunk:"
12839 \end_layout
12841 \begin_layout Plain Layout
12843   Align                 Left
12844 \end_layout
12846 \begin_layout Plain Layout
12848   PassThru              1
12849 \end_layout
12851 \begin_layout Plain Layout
12853 \end_layout
12855 \end_inset
12858 \end_layout
12860 \begin_layout Standard
12861 To make the label very visible we choose a larger font coloured red.
12862 \end_layout
12864 \begin_layout Standard
12865 \begin_inset listings
12866 inline false
12867 status open
12869 \begin_layout Plain Layout
12871   LabelFont
12872 \end_layout
12874 \begin_layout Plain Layout
12876     Family              Sans
12877 \end_layout
12879 \begin_layout Plain Layout
12881     Size                Large
12882 \end_layout
12884 \begin_layout Plain Layout
12886     Series              Bold
12887 \end_layout
12889 \begin_layout Plain Layout
12891     Shape               Italic
12892 \end_layout
12894 \begin_layout Plain Layout
12896     Color               red
12897 \end_layout
12899 \begin_layout Plain Layout
12901   EndFont
12902 \end_layout
12904 \begin_layout Plain Layout
12907 \end_layout
12909 \end_inset
12912 \end_layout
12914 \begin_layout Subsection
12915 The chunkref style
12916 \end_layout
12918 \begin_layout Standard
12919 We also define the Chunkref style which can be used to express cross references
12920  to chunks.
12921 \end_layout
12923 \begin_layout Chunk
12924 chunkref
12925 \end_layout
12927 \begin_layout Standard
12928 \begin_inset listings
12929 inline false
12930 status open
12932 \begin_layout Plain Layout
12934 InsetLayout Chunkref
12935 \end_layout
12937 \begin_layout Plain Layout
12939   LyxType               charstyle
12940 \end_layout
12942 \begin_layout Plain Layout
12944   LatexType             Command
12945 \end_layout
12947 \begin_layout Plain Layout
12949   LatexName             chunkref
12950 \end_layout
12952 \begin_layout Plain Layout
12954   PassThru              1
12955 \end_layout
12957 \begin_layout Plain Layout
12959   LabelFont             
12960 \end_layout
12962 \begin_layout Plain Layout
12964     Shape               Italic
12965 \end_layout
12967 \begin_layout Plain Layout
12969     Color               red
12970 \end_layout
12972 \begin_layout Plain Layout
12974   EndFont
12975 \end_layout
12977 \begin_layout Plain Layout
12980 \end_layout
12982 \end_inset
12985 \end_layout
12987 \begin_layout Section
12988 \begin_inset CommandInset label
12989 LatexCommand label
12990 name "sec:Latex-Macros"
12992 \end_inset
12994 Latex Macros
12995 \end_layout
12997 \begin_layout Standard
12998 We require the 
12999 \noun on
13000 listings
13001 \noun default
13003 \noun on
13004 noweb
13005 \noun default
13006  and 
13007 \noun on
13008 xargs
13009 \noun default
13010  packages.
13011  As noweb defines it's own 
13012 \begin_inset Flex CharStyle:Code
13013 status collapsed
13015 \begin_layout Plain Layout
13017 \backslash
13018 code
13019 \end_layout
13021 \end_inset
13023  environment, we re-define the one that LyX logical markup module expects
13024  here.
13025 \end_layout
13027 \begin_layout Chunk
13028 ./newfangle.sty,language=tex,basicstyle=
13029 \backslash
13030 ttfamily
13031 \end_layout
13033 \begin_layout Standard
13034 \begin_inset listings
13035 inline false
13036 status open
13038 \begin_layout Plain Layout
13041 \backslash
13042 usepackage{listings}%
13043 \end_layout
13045 \begin_layout Plain Layout
13048 \backslash
13049 usepackage{noweb}%
13050 \end_layout
13052 \begin_layout Plain Layout
13055 \backslash
13056 usepackage{xargs}%
13057 \end_layout
13059 \begin_layout Plain Layout
13062 \backslash
13063 renewcommand{
13064 \backslash
13065 code}[1]{
13066 \backslash
13067 texttt{#1}}%
13068 \end_layout
13070 \end_inset
13073 \end_layout
13075 \begin_layout Standard
13076 We also define a 
13077 \begin_inset Flex CharStyle:Code
13078 status collapsed
13080 \begin_layout Plain Layout
13081 CChunk
13082 \end_layout
13084 \end_inset
13086  macro, for use as: 
13087 \begin_inset Flex CharStyle:Code
13088 status collapsed
13090 \begin_layout Plain Layout
13092 \backslash
13093 begin{CChunk}
13094 \end_layout
13096 \end_inset
13098  which will need renaming to 
13099 \begin_inset Flex CharStyle:Code
13100 status collapsed
13102 \begin_layout Plain Layout
13104 \backslash
13105 begin{Chunk}
13106 \end_layout
13108 \end_inset
13110  when I can do this without clashing with 
13111 \begin_inset Flex CharStyle:Code
13112 status collapsed
13114 \begin_layout Plain Layout
13116 \backslash
13117 Chunk
13118 \end_layout
13120 \end_inset
13123 \end_layout
13125 \begin_layout Standard
13126 \begin_inset listings
13127 inline false
13128 status open
13130 \begin_layout Plain Layout
13133 \backslash
13134 lstnewenvironment{Chunk}{
13135 \backslash
13136 relax}{
13137 \backslash
13138 relax}%
13139 \end_layout
13141 \end_inset
13144 \end_layout
13146 \begin_layout Standard
13147 We also define a suitable 
13148 \begin_inset Flex CharStyle:Code
13149 status collapsed
13151 \begin_layout Plain Layout
13153 \backslash
13154 lstset
13155 \end_layout
13157 \end_inset
13159  of parameters that suit the literate programming style after the fashion
13160  of 
13161 \noun on
13162 noweave
13163 \noun default
13165 \end_layout
13167 \begin_layout Standard
13168 \begin_inset listings
13169 inline false
13170 status open
13172 \begin_layout Plain Layout
13175 \backslash
13176 lstset{numbers=left, stepnumber=5, numbersep=5pt,
13177 \end_layout
13179 \begin_layout Plain Layout
13181         breaklines=false,basicstyle=
13182 \backslash
13183 ttfamily,
13184 \end_layout
13186 \begin_layout Plain Layout
13188         numberstyle=
13189 \backslash
13190 tiny, language=C}%
13191 \end_layout
13193 \end_inset
13196 \end_layout
13198 \begin_layout Standard
13199 We also define a notangle-like mechanism for 
13200 \emph on
13201 escaping
13202 \emph default
13203  to LaTeX from the listing, and by which we can refer to other listings.
13204  We declare the 
13205 \begin_inset Flex CharStyle:Code
13206 status collapsed
13208 \begin_layout Plain Layout
13209 =<\SpecialChar \ldots{}
13211 \end_layout
13213 \end_inset
13215  sequence to contain LaTeX code, and include another like this chunk: 
13216 \begin_inset Flex CharStyle:Code
13217 status collapsed
13219 \begin_layout Plain Layout
13221 \backslash
13222 chunkref{chunkname}>
13223 \end_layout
13225 \end_inset
13228  However, because 
13229 \begin_inset Flex CharStyle:Code
13230 status collapsed
13232 \begin_layout Plain Layout
13233 =<\SpecialChar \ldots{}
13235 \end_layout
13237 \end_inset
13239  is already defined to contain LaTeX code for this document --- this is
13240  a 
13241 \noun on
13242 newfangle
13243 \noun default
13244  document after all --- the code fragment below effectively contains the
13245  LaTeX code: 
13246 \begin_inset Flex CharStyle:Code
13247 status collapsed
13249 \begin_layout Plain Layout
13251 \end_layout
13253 \end_inset
13256  To avoid problems with document generation, I had to declare an lstlistings
13257  property: 
13258 \begin_inset Flex CharStyle:Code
13259 status collapsed
13261 \begin_layout Plain Layout
13262 escapeinside={}
13263 \end_layout
13265 \end_inset
13267  for this listing only; which in LyX was done by right-clicking the listings
13268  inset, choosing 
13269 \begin_inset Flex CharStyle:Code
13270 status collapsed
13272 \begin_layout Plain Layout
13273 settings
13274 \end_layout
13276 \end_inset
13278 \SpecialChar \menuseparator
13280 \begin_inset Flex CharStyle:Code
13281 status collapsed
13283 \begin_layout Plain Layout
13284 advanced
13285 \end_layout
13287 \end_inset
13290 \end_layout
13292 \begin_layout Standard
13293 \begin_inset Note Note
13294 status collapsed
13296 \begin_layout Plain Layout
13297 =< isn't enjoyed literally here, in a listing when the escape sequence is
13298  already defined as shown...
13299  we need to somehow escape this representation...
13300 \end_layout
13302 \end_inset
13305 \end_layout
13307 \begin_layout Standard
13308 \begin_inset listings
13309 lstparams "escapeinside={}"
13310 inline false
13311 status open
13313 \begin_layout Plain Layout
13316 \backslash
13317 lstset{escapeinside={=<}{>}}%
13318 \end_layout
13320 \end_inset
13323 \end_layout
13325 \begin_layout Standard
13326 Although our macros will contain the @ symbol, they will be included in
13327  a 
13328 \begin_inset Flex CharStyle:Code
13329 status collapsed
13331 \begin_layout Plain Layout
13333 \backslash
13334 makeatletter
13335 \end_layout
13337 \end_inset
13339  section by LyX; however we keep the commented out 
13340 \begin_inset Flex CharStyle:Code
13341 status collapsed
13343 \begin_layout Plain Layout
13345 \backslash
13346 makeatletter
13347 \end_layout
13349 \end_inset
13351  as a reminder.
13352  The listings package likes to centre the titles, but noweb titles are specially
13353  formatted and must be left aligned.
13354  The simplest way to do this turned out to be by removing the definition
13355  of 
13356 \begin_inset Flex CharStyle:Code
13357 status collapsed
13359 \begin_layout Plain Layout
13361 \backslash
13362 lst@maketitle
13363 \end_layout
13365 \end_inset
13368  This may interact badly if other listings want a regular title or caption.
13369  We remember the old maketitle in case we need it.
13370 \end_layout
13372 \begin_layout Standard
13373 \begin_inset listings
13374 inline false
13375 status open
13377 \begin_layout Plain Layout
13380 \backslash
13381 makeatletter
13382 \end_layout
13384 \begin_layout Plain Layout
13386 %somehow re-defining maketitle gives us a left-aligned title
13387 \end_layout
13389 \begin_layout Plain Layout
13391 %which is extactly what our specially formatted title needs!
13392 \end_layout
13394 \begin_layout Plain Layout
13397 \backslash
13398 global
13399 \backslash
13401 \backslash
13402 newfangle@lst@maketitle
13403 \backslash
13404 lst@maketitle%
13405 \end_layout
13407 \begin_layout Plain Layout
13410 \backslash
13411 global
13412 \backslash
13414 \backslash
13415 lst@maketitle{}%
13416 \end_layout
13418 \end_inset
13421 \end_layout
13423 \begin_layout Subsection
13424 \begin_inset CommandInset label
13425 LatexCommand label
13426 name "sub:The-chunk-command"
13428 \end_inset
13430 The chunk command
13431 \end_layout
13433 \begin_layout Standard
13434 Our chunk command accepts one argument, and calls 
13435 \begin_inset Flex CharStyle:Code
13436 status collapsed
13438 \begin_layout Plain Layout
13440 \backslash
13441 ltset
13442 \end_layout
13444 \end_inset
13447  Although 
13448 \begin_inset Flex CharStyle:Code
13449 status collapsed
13451 \begin_layout Plain Layout
13453 \backslash
13454 ltset
13455 \end_layout
13457 \end_inset
13459  will note the name, this is erased when the next 
13460 \begin_inset Flex CharStyle:Code
13461 status collapsed
13463 \begin_layout Plain Layout
13465 \backslash
13466 lstlisting
13467 \end_layout
13469 \end_inset
13471  starts, so we make a note of this in 
13472 \begin_inset Flex CharStyle:Code
13473 status collapsed
13475 \begin_layout Plain Layout
13477 \backslash
13478 lst@chunkname
13479 \end_layout
13481 \end_inset
13483  and restore in in lstlistings Init hook.
13484 \end_layout
13486 \begin_layout Standard
13487 \begin_inset listings
13488 inline false
13489 status open
13491 \begin_layout Plain Layout
13494 \backslash
13496 \backslash
13497 Chunk#1{%
13498 \end_layout
13500 \begin_layout Plain Layout
13502   
13503 \backslash
13504 lstset{title={
13505 \backslash
13506 newfanglecaption},name=#1}%
13507 \end_layout
13509 \begin_layout Plain Layout
13511   
13512 \backslash
13513 global
13514 \backslash
13515 edef
13516 \backslash
13517 lst@chunkname{
13518 \backslash
13519 lst@intname}%
13520 \end_layout
13522 \begin_layout Plain Layout
13525 \end_layout
13527 \begin_layout Plain Layout
13530 \backslash
13532 \backslash
13533 lst@chunkname{
13534 \backslash
13535 empty}%
13536 \end_layout
13538 \end_inset
13541 \end_layout
13543 \begin_layout Subsubsection
13544 Chunk parameters
13545 \end_layout
13547 \begin_layout Standard
13548 Newfangle permits parameterized chunks, and requires the paramters to be
13549  specified as listings options.
13550  The newfangle script uses this, and although we don't do anything with
13551  these in the LaTeX code right now, we need to stop the listings package
13552  complaining.
13553 \end_layout
13555 \begin_layout Standard
13556 \begin_inset listings
13557 inline false
13558 status open
13560 \begin_layout Plain Layout
13563 \backslash
13564 lst@Key{params}
13565 \backslash
13566 relax{
13567 \backslash
13569 \backslash
13570 newfangle@chunk@params{#1}}%
13571 \end_layout
13573 \end_inset
13576 \end_layout
13578 \begin_layout Standard
13579 As it is common to define a chunk which then needs appending to another
13580  chunk, and annoying to have to declare a single line chunk to manage the
13581  include, we support an 
13582 \begin_inset Flex CharStyle:Code
13583 status collapsed
13585 \begin_layout Plain Layout
13586 append=
13587 \end_layout
13589 \end_inset
13591  option.
13593 \end_layout
13595 \begin_layout Standard
13596 \begin_inset listings
13597 inline false
13598 status open
13600 \begin_layout Plain Layout
13603 \backslash
13604 lst@Key{append}
13605 \backslash
13606 relax{
13607 \backslash
13609 \backslash
13610 newfangle@chunk@append{#1}}%
13611 \end_layout
13613 \end_inset
13616 \end_layout
13618 \begin_layout Subsection
13619 The noweb styled caption
13620 \end_layout
13622 \begin_layout Standard
13623 We define a public macro 
13624 \begin_inset Flex CharStyle:Code
13625 status collapsed
13627 \begin_layout Plain Layout
13629 \backslash
13630 newfanglecaption
13631 \end_layout
13633 \end_inset
13635  which can be set as a regular title.
13636  By means of 
13637 \begin_inset Flex CharStyle:Code
13638 status collapsed
13640 \begin_layout Plain Layout
13642 \backslash
13643 protect
13644 \end_layout
13646 \end_inset
13648 , It expands to 
13649 \begin_inset Flex CharStyle:Code
13650 status collapsed
13652 \begin_layout Plain Layout
13654 \backslash
13655 newfangle@caption
13656 \end_layout
13658 \end_inset
13660  at the appriate time when the caption is emitted.
13661 \end_layout
13663 \begin_layout Standard
13664 \begin_inset listings
13665 inline false
13666 status open
13668 \begin_layout Plain Layout
13671 \backslash
13673 \backslash
13674 newfanglecaption{
13675 \backslash
13676 protect
13677 \backslash
13678 newfangle@caption}%
13679 \end_layout
13681 \end_inset
13684 \end_layout
13686 \begin_layout Standard
13687 \begin_inset Float figure
13688 placement H
13689 wide false
13690 sideways false
13691 status collapsed
13693 \begin_layout Plain Layout
13694 \begin_inset Box Boxed
13695 position "t"
13696 hor_pos "c"
13697 has_inner_box 1
13698 inner_pos "t"
13699 use_parbox 0
13700 width "100col%"
13701 special "none"
13702 height "1in"
13703 height_special "totalheight"
13704 status open
13706 \begin_layout Plain Layout
13708 \begin_inset space \qquad{}
13709 \end_inset
13712 \shape italic
13713 some-chunk
13714 \shape default
13715  19b⟩
13716 \begin_inset Formula $\equiv+$
13717 \end_inset
13720 \begin_inset space \qquad{}
13721 \end_inset
13724 \begin_inset space \qquad{}
13725 \end_inset
13728 \begin_inset space \qquad{}
13729 \end_inset
13732 \begin_inset Formula $\triangleleft$
13733 \end_inset
13736 \begin_inset space \quad{}
13737 \end_inset
13740 \begin_inset Formula $\triangleright$
13741 \end_inset
13744 \end_layout
13746 \begin_layout Plain Layout
13748 \size footnotesize
13749 In this example, the current chunk is 22c, and therefore the third chunk
13750  on page 22.
13751 \end_layout
13753 \begin_layout Plain Layout
13755 \size footnotesize
13756 It's name is 
13757 \emph on
13758 some-chunk
13759 \emph default
13762 \end_layout
13764 \begin_layout Plain Layout
13766 \size footnotesize
13767 The first chunk with this name (19b) occurs as the second chunk on page
13768  19.
13769 \end_layout
13771 \begin_layout Plain Layout
13773 \size footnotesize
13774 The previous chunk (22d) with the same name is the second chunk on page
13775  22.
13776 \end_layout
13778 \begin_layout Plain Layout
13780 \size footnotesize
13781 The next chunk (24d) is the fourth chunk on page 24.
13782 \end_layout
13784 \begin_layout Plain Layout
13785 \begin_inset Caption
13787 \begin_layout Plain Layout
13788 noweb heading
13789 \end_layout
13791 \end_inset
13794 \end_layout
13796 \end_inset
13799 \end_layout
13801 \end_inset
13803 The general noweb output format compactly identifies the current chunk,
13804  and references to the first chunk, and the previous and next chunks that
13805  have the same name.
13807 \end_layout
13809 \begin_layout Standard
13810 This means that we need to keep a counter for each chunk-name, that we use
13811  to count chunks of the same name.
13813 \end_layout
13815 \begin_layout Subsection
13816 The chunk counter
13817 \end_layout
13819 \begin_layout Standard
13820 It would be natural to have a counter for each chunk name, but TeX would
13821  soon run out of counters
13822 \begin_inset Foot
13823 status collapsed
13825 \begin_layout Plain Layout
13826 \SpecialChar \ldots{}
13827 soon 
13828 \emph on
13830 \emph default
13831  run out of counters and so I had to re-write the LaTeX macros to share
13832  a counter as described here
13833 \end_layout
13835 \end_inset
13837 , so we have one counter which we save at the end of a chunk and restore
13838  at the beginning of a chunk.
13839 \end_layout
13841 \begin_layout Standard
13842 \begin_inset listings
13843 inline false
13844 status open
13846 \begin_layout Plain Layout
13849 \backslash
13850 newcounter{newfangle@chunkcounter}%
13851 \end_layout
13853 \end_inset
13856 \end_layout
13858 \begin_layout Standard
13859 We construct the name of this variable to store the counter to be the text
13861 \begin_inset Flex CharStyle:Code
13862 status collapsed
13864 \begin_layout Plain Layout
13865 lst-chunk-
13866 \end_layout
13868 \end_inset
13870  prefixed onto the chunks own name, and store it in 
13871 \begin_inset Flex CharStyle:Code
13872 status collapsed
13874 \begin_layout Plain Layout
13876 \backslash
13877 chunkcount
13878 \end_layout
13880 \end_inset
13884 \end_layout
13886 \begin_layout Standard
13887 We save the counter like this:
13888 \end_layout
13890 \begin_layout Chunk
13891 save-counter
13892 \end_layout
13894 \begin_layout Standard
13895 \begin_inset listings
13896 inline false
13897 status open
13899 \begin_layout Plain Layout
13902 \backslash
13903 global
13904 \backslash
13905 expandafter
13906 \backslash
13907 edef
13908 \backslash
13909 csname 
13910 \backslash
13911 chunkcount
13912 \backslash
13913 endcsname{
13914 \backslash
13915 arabic{newfangle@chunkcounter}}%
13916 \end_layout
13918 \end_inset
13921 \end_layout
13923 \begin_layout Standard
13924 and restore the counter like this:
13925 \end_layout
13927 \begin_layout Chunk
13928 restore-counter
13929 \end_layout
13931 \begin_layout Standard
13932 \begin_inset listings
13933 inline false
13934 status open
13936 \begin_layout Plain Layout
13939 \backslash
13940 setcounter{newfangle@chunkcounter}{
13941 \backslash
13942 csname 
13943 \backslash
13944 chunkcount
13945 \backslash
13946 endcsname}%
13947 \end_layout
13949 \end_inset
13952 \end_layout
13954 \begin_layout Chunk
13955 ./newfangle.sty
13956 \end_layout
13958 \begin_layout Standard
13959 If there does not already exist a variable whose name is stored in 
13960 \begin_inset Flex CharStyle:Code
13961 status collapsed
13963 \begin_layout Plain Layout
13965 \backslash
13966 chunkcount
13967 \end_layout
13969 \end_inset
13971 , then we know we are the first chunk with this name, and then define a
13972  counter.
13974 \end_layout
13976 \begin_layout Standard
13977 Although chunks of the same name share a common counter, they must still
13978  be distinguished.
13979  We use is the internal name of the listing, suffixed by the counter value.
13980  So the first chunk might be 
13981 \begin_inset Flex CharStyle:Code
13982 status collapsed
13984 \begin_layout Plain Layout
13985 something-1
13986 \end_layout
13988 \end_inset
13990  and the second chunk be 
13991 \begin_inset Flex CharStyle:Code
13992 status collapsed
13994 \begin_layout Plain Layout
13995 something-2
13996 \end_layout
13998 \end_inset
14000 , etc.
14001 \end_layout
14003 \begin_layout Standard
14004 We also calculate the name of the previous chunk if we can (before we increment
14005  the chunk counter).
14006  If this is the first chunk of that name, then 
14007 \begin_inset Flex CharStyle:Code
14008 status collapsed
14010 \begin_layout Plain Layout
14012 \backslash
14013 prevchunkname
14014 \end_layout
14016 \end_inset
14018  is set to 
14019 \begin_inset Flex CharStyle:Code
14020 status collapsed
14022 \begin_layout Plain Layout
14024 \backslash
14025 relax
14026 \end_layout
14028 \end_inset
14030  which the noweb package will interpret as not existing.
14031 \end_layout
14033 \begin_layout Standard
14034 \begin_inset listings
14035 inline false
14036 status open
14038 \begin_layout Plain Layout
14041 \backslash
14043 \backslash
14044 newfangle@caption{%
14045 \end_layout
14047 \begin_layout Plain Layout
14049   
14050 \backslash
14051 edef
14052 \backslash
14053 chunkcount{lst-chunk-
14054 \backslash
14055 lst@intname}%
14056 \end_layout
14058 \begin_layout Plain Layout
14060   
14061 \backslash
14062 @ifundefined{
14063 \backslash
14064 chunkcount}{%
14065 \end_layout
14067 \begin_layout Plain Layout
14069     
14070 \backslash
14071 expandafter
14072 \backslash
14073 gdef
14074 \backslash
14075 csname 
14076 \backslash
14077 chunkcount
14078 \backslash
14079 endcsname{0}%
14080 \end_layout
14082 \begin_layout Plain Layout
14084     
14085 \backslash
14086 setcounter{newfangle@chunkcounter}{
14087 \backslash
14088 csname 
14089 \backslash
14090 chunkcount
14091 \backslash
14092 endcsname}%
14093 \end_layout
14095 \begin_layout Plain Layout
14097     
14098 \backslash
14100 \backslash
14101 prevchunkname
14102 \backslash
14103 relax%
14104 \end_layout
14106 \begin_layout Plain Layout
14108   }{%
14109 \end_layout
14111 \begin_layout Plain Layout
14113     
14114 \backslash
14115 setcounter{newfangle@chunkcounter}{
14116 \backslash
14117 csname 
14118 \backslash
14119 chunkcount
14120 \backslash
14121 endcsname}%
14122 \end_layout
14124 \begin_layout Plain Layout
14126     
14127 \backslash
14128 edef
14129 \backslash
14130 prevchunkname{
14131 \backslash
14132 lst@intname-
14133 \backslash
14134 arabic{newfangle@chunkcounter}}%
14135 \end_layout
14137 \begin_layout Plain Layout
14139   }%
14140 \end_layout
14142 \end_inset
14145 \end_layout
14147 \begin_layout Standard
14148 After incrementing the chunk counter, we then define the name of this chunk,
14149  as well as the name of the first chunk.
14150 \end_layout
14152 \begin_layout Standard
14153 \begin_inset listings
14154 inline false
14155 status open
14157 \begin_layout Plain Layout
14159   
14160 \backslash
14161 addtocounter{newfangle@chunkcounter}{1}%
14162 \end_layout
14164 \begin_layout Plain Layout
14166   
14167 \backslash
14168 global
14169 \backslash
14170 expandafter
14171 \backslash
14172 edef
14173 \backslash
14174 csname 
14175 \backslash
14176 chunkcount
14177 \backslash
14178 endcsname{
14179 \backslash
14180 arabic{newfangle@chunkcounter}}%
14181 \end_layout
14183 \begin_layout Plain Layout
14185   
14186 \backslash
14187 edef
14188 \backslash
14189 chunkname{
14190 \backslash
14191 lst@intname-
14192 \backslash
14193 arabic{newfangle@chunkcounter}}%
14194 \end_layout
14196 \begin_layout Plain Layout
14198   
14199 \backslash
14200 edef
14201 \backslash
14202 firstchunkname{
14203 \backslash
14204 lst@intname-1}%
14205 \end_layout
14207 \end_inset
14210 \end_layout
14212 \begin_layout Standard
14213 We now need to calculate the name of the next chunk.
14214  We do this by temporarily skipping the counter on by one; however there
14215  may not actually be another chunk with this name! We detect this by also
14216  defining a label for each chunk based on the chunkname.
14217  If there is a next chunkname then it will define a label with that name.
14218  As labels are persistent, we can at least tell the second time LaTeX is
14219  run.
14220  If we don't find such a defined label then we define 
14221 \begin_inset Flex CharStyle:Code
14222 status collapsed
14224 \begin_layout Plain Layout
14226 \backslash
14227 nextchunkname
14228 \end_layout
14230 \end_inset
14232  to 
14233 \begin_inset Flex CharStyle:Code
14234 status collapsed
14236 \begin_layout Plain Layout
14238 \backslash
14239 relax
14240 \end_layout
14242 \end_inset
14245 \end_layout
14247 \begin_layout Standard
14248 \begin_inset listings
14249 inline false
14250 status open
14252 \begin_layout Plain Layout
14254   
14255 \backslash
14256 addtocounter{newfangle@chunkcounter}{1}%
14257 \end_layout
14259 \begin_layout Plain Layout
14261   
14262 \backslash
14263 edef
14264 \backslash
14265 nextchunkname{
14266 \backslash
14267 lst@intname-
14268 \backslash
14269 arabic{newfangle@chunkcounter}}%
14270 \end_layout
14272 \begin_layout Plain Layout
14274   
14275 \backslash
14276 @ifundefined{r@label-
14277 \backslash
14278 nextchunkname}{
14279 \backslash
14281 \backslash
14282 nextchunkname
14283 \backslash
14284 relax}{}%
14285 \end_layout
14287 \end_inset
14290 \end_layout
14292 \begin_layout Standard
14293 The noweb package requires that we define a 
14294 \begin_inset Flex CharStyle:Code
14295 status collapsed
14297 \begin_layout Plain Layout
14299 \backslash
14300 sublabel
14301 \end_layout
14303 \end_inset
14305  for every chunk, with a unique name, which is then used to print out it's
14306  navigation hints.
14307 \end_layout
14309 \begin_layout Standard
14310 We also define a regular label for this chunk, as was mentioned above when
14311  we calculated 
14312 \begin_inset Flex CharStyle:Code
14313 status collapsed
14315 \begin_layout Plain Layout
14317 \backslash
14318 nextchunkname
14319 \end_layout
14321 \end_inset
14324  This requires LaTeX to be run at least twice after new chunk sections are
14325  added --- but noweb requried that anyway.
14326 \end_layout
14328 \begin_layout Standard
14329 \begin_inset listings
14330 inline false
14331 status open
14333 \begin_layout Plain Layout
14335   
14336 \backslash
14337 sublabel{
14338 \backslash
14339 chunkname}%
14340 \end_layout
14342 \begin_layout Plain Layout
14344 % define this label for every chunk instance, so we
14345 \end_layout
14347 \begin_layout Plain Layout
14349 % can tell when we are the last chunk of this name
14350 \end_layout
14352 \begin_layout Plain Layout
14354   
14355 \backslash
14356 label{label-
14357 \backslash
14358 chunkname}%
14359 \end_layout
14361 \end_inset
14364 \end_layout
14366 \begin_layout Standard
14367 We also try and add the chunk to the list of listings, but I'm afraid we
14368  don't do very well.
14369  We want each chunk name listing once, with all of it's references.
14370 \end_layout
14372 \begin_layout Standard
14373 \begin_inset listings
14374 inline false
14375 status open
14377 \begin_layout Plain Layout
14379   
14380 \backslash
14381 addcontentsline{lol}{lstlisting}{
14382 \backslash
14383 lst@name~[
14384 \backslash
14385 protect
14386 \backslash
14387 subpageref{
14388 \backslash
14389 chunkname}]}%
14390 \end_layout
14392 \end_inset
14395 \end_layout
14397 \begin_layout Standard
14398 We then call the noweb output macros in the same way that noweave generates
14399  them, except that we don't need to call 
14400 \begin_inset Flex CharStyle:Code
14401 status collapsed
14403 \begin_layout Plain Layout
14405 \backslash
14406 nwstartdeflinemarkup
14407 \end_layout
14409 \end_inset
14411  or 
14412 \begin_inset Flex CharStyle:Code
14413 status collapsed
14415 \begin_layout Plain Layout
14417 \backslash
14418 nwenddeflinemarkup
14419 \end_layout
14421 \end_inset
14423  -- and if we do it messes up the output somewhat.
14424 \end_layout
14426 \begin_layout Standard
14427 \begin_inset listings
14428 inline false
14429 status open
14431 \begin_layout Plain Layout
14433   
14434 \backslash
14435 nwmargintag{%
14436 \end_layout
14438 \begin_layout Plain Layout
14440     {%
14441 \end_layout
14443 \begin_layout Plain Layout
14445       
14446 \backslash
14447 nwtagstyle{}%
14448 \end_layout
14450 \begin_layout Plain Layout
14452       
14453 \backslash
14454 subpageref{
14455 \backslash
14456 chunkname}%
14457 \end_layout
14459 \begin_layout Plain Layout
14461     }%
14462 \end_layout
14464 \begin_layout Plain Layout
14466   }%
14467 \end_layout
14469 \begin_layout Plain Layout
14472 \end_layout
14474 \begin_layout Plain Layout
14476   
14477 \backslash
14478 moddef{%
14479 \end_layout
14481 \begin_layout Plain Layout
14483     {
14484 \backslash
14485 lst@name}%
14486 \end_layout
14488 \begin_layout Plain Layout
14490     {%
14491 \end_layout
14493 \begin_layout Plain Layout
14495       
14496 \backslash
14497 nwtagstyle{}
14498 \backslash
14500 \end_layout
14502 \begin_layout Plain Layout
14504       
14505 \backslash
14506 @ifundefined{newfangle@chunk@params}{}{%
14507 \end_layout
14509 \begin_layout Plain Layout
14511         (
14512 \backslash
14513 newfangle@chunk@params)%
14514 \end_layout
14516 \begin_layout Plain Layout
14518       }%
14519 \end_layout
14521 \begin_layout Plain Layout
14523       [
14524 \backslash
14525 csname 
14526 \backslash
14527 chunkcount
14528 \backslash
14529 endcsname]~%
14530 \end_layout
14532 \begin_layout Plain Layout
14534       
14535 \backslash
14536 subpageref{
14537 \backslash
14538 firstchunkname}%
14539 \end_layout
14541 \begin_layout Plain Layout
14543     }%
14544 \end_layout
14546 \begin_layout Plain Layout
14548     
14549 \backslash
14550 @ifundefined{newfangle@chunk@append}{}{%
14551 \end_layout
14553 \begin_layout Plain Layout
14555     
14556 \backslash
14557 ifx{}
14558 \backslash
14559 newfangle@chunk@append{x}
14560 \backslash
14561 else%
14562 \end_layout
14564 \begin_layout Plain Layout
14566         ,~add~to~
14567 \backslash
14568 newfangle@chunk@append%
14569 \end_layout
14571 \begin_layout Plain Layout
14573     
14574 \backslash
14576 \end_layout
14578 \begin_layout Plain Layout
14580     }%
14581 \end_layout
14583 \begin_layout Plain Layout
14586 \backslash
14587 global
14588 \backslash
14590 \backslash
14591 newfangle@chunk@append{}%
14592 \end_layout
14594 \begin_layout Plain Layout
14597 \backslash
14598 lstset{append=x}%
14599 \end_layout
14601 \begin_layout Plain Layout
14603   }%
14604 \end_layout
14606 \begin_layout Plain Layout
14609 \end_layout
14611 \begin_layout Plain Layout
14613   
14614 \backslash
14616 \backslash
14617 relax
14618 \backslash
14619 prevchunkname
14620 \backslash
14621 endmoddef
14622 \backslash
14623 else
14624 \backslash
14625 plusendmoddef
14626 \backslash
14628 \end_layout
14630 \begin_layout Plain Layout
14632 %  
14633 \backslash
14634 nwstartdeflinemarkup%
14635 \end_layout
14637 \begin_layout Plain Layout
14639   
14640 \backslash
14641 nwprevnextdefs{
14642 \backslash
14643 prevchunkname}{
14644 \backslash
14645 nextchunkname}%
14646 \end_layout
14648 \begin_layout Plain Layout
14650 %  
14651 \backslash
14652 nwenddeflinemarkup%
14653 \end_layout
14655 \begin_layout Plain Layout
14658 \end_layout
14660 \end_inset
14663 \end_layout
14665 \begin_layout Standard
14666 Originally this was developed as a 
14667 \begin_inset Flex CharStyle:Code
14668 status collapsed
14670 \begin_layout Plain Layout
14671 listings
14672 \end_layout
14674 \end_inset
14676  aspect, in the Init hook, but it was found easier to affect the title without
14677  using a hook --- 
14678 \begin_inset Flex CharStyle:Code
14679 status collapsed
14681 \begin_layout Plain Layout
14683 \backslash
14684 lst@AddToHookExe{PreSet}
14685 \end_layout
14687 \end_inset
14689  is still required to set the listings name to the name passed to the 
14690 \begin_inset Flex CharStyle:Code
14691 status collapsed
14693 \begin_layout Plain Layout
14695 \backslash
14696 Chunk
14697 \end_layout
14699 \end_inset
14701  command, though.
14702 \end_layout
14704 \begin_layout Standard
14705 \begin_inset listings
14706 inline false
14707 status open
14709 \begin_layout Plain Layout
14712 \backslash
14713 lst@BeginAspect{newfangle}
14714 \end_layout
14716 \begin_layout Plain Layout
14719 \backslash
14720 lst@Key{newfangle}{true}[t]{
14721 \backslash
14722 lstKV@SetIf{#1}{true}}
14723 \end_layout
14725 \begin_layout Plain Layout
14728 \backslash
14729 lst@AddToHookExe{PreSet}{
14730 \backslash
14731 global
14732 \backslash
14734 \backslash
14735 lst@intname
14736 \backslash
14737 lst@chunkname}
14738 \end_layout
14740 \begin_layout Plain Layout
14743 \backslash
14744 lst@AddToHook{Init}{}%
14745 \backslash
14746 newfangle@caption}
14747 \end_layout
14749 \begin_layout Plain Layout
14752 \backslash
14753 lst@EndAspect
14754 \end_layout
14756 \end_inset
14759 \end_layout
14761 \begin_layout Subsection
14762 Cross references
14763 \end_layout
14765 \begin_layout Standard
14766 We define the 
14767 \backslash
14768 chunkref command which makes it easy to generate visual references to different
14769  code chunks, e.g.
14770 \end_layout
14772 \begin_layout Standard
14773 \begin_inset Tabular
14774 <lyxtabular version="3" rows="4" columns="2">
14775 <features>
14776 <column alignment="center" valignment="top" width="0">
14777 <column alignment="center" valignment="top" width="0">
14778 <row>
14779 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
14780 \begin_inset Text
14782 \begin_layout Plain Layout
14783 Macro
14784 \end_layout
14786 \end_inset
14787 </cell>
14788 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
14789 \begin_inset Text
14791 \begin_layout Plain Layout
14792 Appearance
14793 \end_layout
14795 \end_inset
14796 </cell>
14797 </row>
14798 <row>
14799 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
14800 \begin_inset Text
14802 \begin_layout Plain Layout
14804 \backslash
14805 chunkref{preamble}
14806 \end_layout
14808 \end_inset
14809 </cell>
14810 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
14811 \begin_inset Text
14813 \begin_layout Plain Layout
14814 \begin_inset ERT
14815 status open
14817 \begin_layout Plain Layout
14820 \backslash
14821 chunkref{preamble}
14822 \end_layout
14824 \end_inset
14827 \end_layout
14829 \end_inset
14830 </cell>
14831 </row>
14832 <row>
14833 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
14834 \begin_inset Text
14836 \begin_layout Plain Layout
14838 \backslash
14839 chunkref[3]{preamble}
14840 \end_layout
14842 \end_inset
14843 </cell>
14844 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
14845 \begin_inset Text
14847 \begin_layout Plain Layout
14848 \begin_inset ERT
14849 status open
14851 \begin_layout Plain Layout
14854 \backslash
14855 chunkref[3]{preamble}
14856 \end_layout
14858 \end_inset
14861 \end_layout
14863 \end_inset
14864 </cell>
14865 </row>
14866 <row>
14867 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
14868 \begin_inset Text
14870 \begin_layout Plain Layout
14872 \backslash
14873 chunkref{preamble}[arg1, arg2]
14874 \end_layout
14876 \end_inset
14877 </cell>
14878 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
14879 \begin_inset Text
14881 \begin_layout Plain Layout
14882 \begin_inset ERT
14883 status open
14885 \begin_layout Plain Layout
14888 \backslash
14889 chunkref{preamble}[arg1, arg2]
14890 \end_layout
14892 \end_inset
14895 \end_layout
14897 \end_inset
14898 </cell>
14899 </row>
14900 </lyxtabular>
14902 \end_inset
14905 \end_layout
14907 \begin_layout Standard
14908 Chunkref can also be used within a code chunk to include another code chunk.
14909  The third optional parameter to chunkref is a comma sepatarated list of
14910  arguments, which will replace defined parameters in the chunkref.
14911 \begin_inset Note Note
14912 status open
14914 \begin_layout Plain Layout
14915 Darn it, if I have: =<
14916 \backslash
14917 chunkref{new-mode-tracker}[{chunks[chunk_name, "language"]},{mode}]> the
14918  inner braces (inside [ ]) cause _ to signify subscript even though we have
14919  lst@ReplaceIn
14920 \end_layout
14922 \end_inset
14925 \end_layout
14927 \begin_layout Standard
14928 \begin_inset listings
14929 inline false
14930 status open
14932 \begin_layout Plain Layout
14935 \backslash
14937 \backslash
14938 chunkref@args#1,{%
14939 \end_layout
14941 \begin_layout Plain Layout
14943   
14944 \backslash
14946 \backslash
14947 arg{#1}%
14948 \end_layout
14950 \begin_layout Plain Layout
14952   
14953 \backslash
14954 lst@ReplaceIn
14955 \backslash
14957 \backslash
14958 lst@filenamerpl%
14959 \end_layout
14961 \begin_layout Plain Layout
14963   
14964 \backslash
14965 arg%
14966 \end_layout
14968 \begin_layout Plain Layout
14970   
14971 \backslash
14972 @ifnextchar){
14973 \backslash
14974 relax}{, 
14975 \backslash
14976 chunkref@args}%
14977 \end_layout
14979 \begin_layout Plain Layout
14982 \end_layout
14984 \begin_layout Plain Layout
14987 \backslash
14988 newcommand
14989 \backslash
14990 chunkref[2][0]{%
14991 \end_layout
14993 \begin_layout Plain Layout
14995   
14996 \backslash
14997 @ifnextchar({
14998 \backslash
14999 chunkref@i{#1}{#2}}{
15000 \backslash
15001 chunkref@i{#1}{#2}()}%
15002 \end_layout
15004 \begin_layout Plain Layout
15007 \end_layout
15009 \begin_layout Plain Layout
15012 \backslash
15014 \backslash
15015 chunkref@i#1#2(#3){%
15016 \end_layout
15018 \begin_layout Plain Layout
15020   
15021 \backslash
15023 \backslash
15024 zero{0}%
15025 \end_layout
15027 \begin_layout Plain Layout
15029   
15030 \backslash
15032 \backslash
15033 chunk{#2}%
15034 \end_layout
15036 \begin_layout Plain Layout
15038   
15039 \backslash
15041 \backslash
15042 chunkno{#1}%
15043 \end_layout
15045 \begin_layout Plain Layout
15047   
15048 \backslash
15050 \backslash
15051 chunkargs{#3}%
15052 \end_layout
15054 \begin_layout Plain Layout
15056   
15057 \backslash
15059 \backslash
15060 chunkno
15061 \backslash
15062 zero%
15063 \end_layout
15065 \begin_layout Plain Layout
15067     
15068 \backslash
15070 \backslash
15071 chunkname{#2-1}%
15072 \end_layout
15074 \begin_layout Plain Layout
15076   
15077 \backslash
15078 else%
15079 \end_layout
15081 \begin_layout Plain Layout
15083     
15084 \backslash
15086 \backslash
15087 chunkname{#2-
15088 \backslash
15089 chunkno}%
15090 \end_layout
15092 \begin_layout Plain Layout
15094   
15095 \backslash
15097 \end_layout
15099 \begin_layout Plain Layout
15101   
15102 \backslash
15104 \backslash
15105 lst@arg
15106 \backslash
15107 chunk%
15108 \end_layout
15110 \begin_layout Plain Layout
15112   
15113 \backslash
15114 lst@ReplaceIn
15115 \backslash
15116 chunk
15117 \backslash
15118 lst@filenamerpl%
15119 \end_layout
15121 \begin_layout Plain Layout
15123   
15124 \backslash
15125 LA{%
15126 \backslash
15127 moddef{%
15128 \end_layout
15130 \begin_layout Plain Layout
15132     {
15133 \backslash
15134 chunk}%
15135 \end_layout
15137 \begin_layout Plain Layout
15139     {%
15140 \end_layout
15142 \begin_layout Plain Layout
15144       
15145 \backslash
15146 nwtagstyle{}
15147 \backslash
15149 \end_layout
15151 \begin_layout Plain Layout
15153       
15154 \backslash
15156 \backslash
15157 chunkno
15158 \backslash
15159 zero%
15160 \end_layout
15162 \begin_layout Plain Layout
15164       
15165 \backslash
15166 else%
15167 \end_layout
15169 \begin_layout Plain Layout
15171       [
15172 \backslash
15173 chunkno]%
15174 \end_layout
15176 \begin_layout Plain Layout
15178       
15179 \backslash
15181 \end_layout
15183 \begin_layout Plain Layout
15185       
15186 \backslash
15188 \backslash
15189 chunkargs
15190 \backslash
15191 empty%
15192 \end_layout
15194 \begin_layout Plain Layout
15196       
15197 \backslash
15198 else%
15199 \end_layout
15201 \begin_layout Plain Layout
15203         (
15204 \backslash
15205 chunkref@args #3,)%
15206 \end_layout
15208 \begin_layout Plain Layout
15210       
15211 \backslash
15213 \end_layout
15215 \begin_layout Plain Layout
15217       ~
15218 \backslash
15219 subpageref{
15220 \backslash
15221 chunkname}%
15222 \end_layout
15224 \begin_layout Plain Layout
15226     }%
15227 \end_layout
15229 \begin_layout Plain Layout
15231   }%
15232 \end_layout
15234 \begin_layout Plain Layout
15236   
15237 \backslash
15239 \backslash
15240 endmoddef%
15241 \end_layout
15243 \begin_layout Plain Layout
15246 \end_layout
15248 \end_inset
15251 \end_layout
15253 \begin_layout Subsection
15254 The end
15255 \end_layout
15257 \begin_layout Standard
15258 \begin_inset listings
15259 inline false
15260 status open
15262 \begin_layout Plain Layout
15265 \end_layout
15267 \begin_layout Plain Layout
15270 \backslash
15271 makeatother
15272 \end_layout
15274 \end_inset
15277 \end_layout
15279 \begin_layout Chapter
15280 Extracting newfangle
15281 \end_layout
15283 \begin_layout Section
15284 Extracting from Lyx
15285 \end_layout
15287 \begin_layout Standard
15288 To extract from LyX, you will need to configure LyX as explained in section
15290 \begin_inset CommandInset ref
15291 LatexCommand ref
15292 reference "sub:Configuring-the-build"
15294 \end_inset
15297 \end_layout
15299 \begin_layout Standard
15300 \begin_inset CommandInset label
15301 LatexCommand label
15302 name "lyx-build-script"
15304 \end_inset
15306 And this lyx-build scrap will extract newfangle for me.
15307 \end_layout
15309 \begin_layout Chunk
15310 lyx-build,language=sh
15311 \end_layout
15313 \begin_layout Standard
15314 \begin_inset listings
15315 inline false
15316 status open
15318 \begin_layout Plain Layout
15320 #! /bin/sh
15321 \end_layout
15323 \begin_layout Plain Layout
15325 set -x
15326 \end_layout
15328 \begin_layout Plain Layout
15330 \end_layout
15332 \begin_layout Plain Layout
15335 \backslash
15336 chunkref{lyx-build-helper}>
15337 \end_layout
15339 \begin_layout Plain Layout
15341 cd $PROJECT_DIR || exit 1
15342 \end_layout
15344 \begin_layout Plain Layout
15346 \end_layout
15348 \begin_layout Plain Layout
15350 python -m elyxer --css lyx.css $LYX_SRC | 
15351 \backslash
15353 \end_layout
15355 \begin_layout Plain Layout
15357   iconv -c -f utf-8 -t ISO-8859-1//TRANSLIT | 
15358 \backslash
15360 \end_layout
15362 \begin_layout Plain Layout
15364   sed 's/UTF-8"
15365 \backslash
15367 \backslash
15368 )>/ISO-8859-1"
15369 \backslash
15370 1>/' > www/docs/newfangle.html
15371 \end_layout
15373 \begin_layout Plain Layout
15375 /usr/local/bin/newfangle -R./newfangle $TEX_SRC > ./newfangle
15376 \end_layout
15378 \begin_layout Plain Layout
15380 /usr/local/bin/newfangle -R./newfangle.module $TEX_SRC > ./newfangle.module
15381 \end_layout
15383 \begin_layout Plain Layout
15385 \end_layout
15387 \begin_layout Plain Layout
15390 \backslash
15391 chunkref{test:helpers}>
15392 \end_layout
15394 \begin_layout Plain Layout
15396 export NEWFANGLE=./newfangle
15397 \end_layout
15399 \begin_layout Plain Layout
15401 export TMP=${TMP:-/tmp}
15402 \end_layout
15404 \begin_layout Plain Layout
15407 \backslash
15408 chunkref{test:run-tests}>
15409 \end_layout
15411 \begin_layout Plain Layout
15413 # Now check that we can extract a newfangle that also passes the tests!
15414 \end_layout
15416 \begin_layout Plain Layout
15418 $NEWFANGLE -R./newfangle $TEX_SRC > ./new-newfangle
15419 \end_layout
15421 \begin_layout Plain Layout
15423 export NEWFANGLE=./new-newfangle
15424 \end_layout
15426 \begin_layout Plain Layout
15429 \backslash
15430 chunkref{test:run-tests}>
15431 \end_layout
15433 \end_inset
15436 \end_layout
15438 \begin_layout Chunk
15439 test:run-tests
15440 \end_layout
15442 \begin_layout Standard
15443 \begin_inset listings
15444 inline false
15445 status open
15447 \begin_layout Plain Layout
15449 # run tests
15450 \end_layout
15452 \begin_layout Plain Layout
15454 $NEWFANGLE -Rpca-test.awk $TEX_SRC | awk -f - || exit 1
15455 \end_layout
15457 \begin_layout Plain Layout
15460 \backslash
15461 chunkref{test:cromulence}>
15462 \end_layout
15464 \begin_layout Plain Layout
15467 \backslash
15468 chunkref{test:escapes}>
15469 \end_layout
15471 \begin_layout Plain Layout
15474 \backslash
15475 chunkref{test:chunk-params}>
15476 \end_layout
15478 \end_inset
15481 \end_layout
15483 \begin_layout Standard
15484 With a lyx-build-helper
15485 \end_layout
15487 \begin_layout Chunk
15488 lyx-build-helper,language=sh
15489 \end_layout
15491 \begin_layout Standard
15492 \begin_inset listings
15493 inline false
15494 status open
15496 \begin_layout Plain Layout
15498 PROJECT_DIR="$LYX_r"
15499 \end_layout
15501 \begin_layout Plain Layout
15503 LYX_SRC="$PROJECT_DIR/${LYX_i%.tex}.lyx"
15504 \end_layout
15506 \begin_layout Plain Layout
15508 TEX_DIR="$LYX_p"
15509 \end_layout
15511 \begin_layout Plain Layout
15513 TEX_SRC="$TEX_DIR/$LYX_i"
15514 \end_layout
15516 \end_inset
15519 \end_layout
15521 \begin_layout Section
15522 Extracting from the command line
15523 \end_layout
15525 \begin_layout Standard
15526 First you will need the tex output, then you can extract:
15527 \end_layout
15529 \begin_layout Chunk
15530 lyx-build-manual,language=sh
15531 \end_layout
15533 \begin_layout Standard
15534 \begin_inset listings
15535 inline false
15536 status open
15538 \begin_layout Plain Layout
15540 lyx -e latex newfangle.lyx
15541 \end_layout
15543 \begin_layout Plain Layout
15545 newfangle -R./newfangle newfangle.tex > ./newfangle
15546 \end_layout
15548 \begin_layout Plain Layout
15550 newfangle -R./newfangle.module newfangle.tex > ./newfangle.module
15551 \end_layout
15553 \end_inset
15556 \end_layout
15558 \begin_layout Section
15559 Testing
15560 \end_layout
15562 \begin_layout Chunk
15563 test:helpers
15564 \end_layout
15566 \begin_layout Standard
15567 \begin_inset listings
15568 inline false
15569 status open
15571 \begin_layout Plain Layout
15573 passtest() {
15574 \end_layout
15576 \begin_layout Plain Layout
15578   if "$@"
15579 \end_layout
15581 \begin_layout Plain Layout
15583   then echo "Passed"
15584 \end_layout
15586 \begin_layout Plain Layout
15588   else echo "Failed"
15589 \end_layout
15591 \begin_layout Plain Layout
15593        return 1
15594 \end_layout
15596 \begin_layout Plain Layout
15598   fi
15599 \end_layout
15601 \begin_layout Plain Layout
15604 \end_layout
15606 \begin_layout Plain Layout
15608 \end_layout
15610 \begin_layout Plain Layout
15612 failtest() {
15613 \end_layout
15615 \begin_layout Plain Layout
15617   if ! "$@"
15618 \end_layout
15620 \begin_layout Plain Layout
15622   then echo "Passed"
15623 \end_layout
15625 \begin_layout Plain Layout
15627   else echo "Failed"
15628 \end_layout
15630 \begin_layout Plain Layout
15632        return 1
15633 \end_layout
15635 \begin_layout Plain Layout
15637   fi
15638 \end_layout
15640 \begin_layout Plain Layout
15643 \end_layout
15645 \end_inset
15648 \end_layout
15650 \begin_layout Part
15651 Tests
15652 \end_layout
15654 \begin_layout Chapter
15655 Chunk Parameters
15656 \end_layout
15658 \begin_layout Chunk
15659 test:chunk-params:sub,language=,params=THING;colour
15660 \end_layout
15662 \begin_layout Standard
15663 \begin_inset listings
15664 inline false
15665 status open
15667 \begin_layout Plain Layout
15669 I see a ${THING},
15670 \end_layout
15672 \begin_layout Plain Layout
15674 a ${THING} of colour ${colour}, 
15675 \end_layout
15677 \begin_layout Plain Layout
15679 and looking closer =<
15680 \backslash
15681 chunkref{test:chunk-params:sub:sub}(${colour})>
15682 \end_layout
15684 \end_inset
15687 \end_layout
15689 \begin_layout Chunk
15690 test:chunk-params:sub:sub,params=colour,language=
15691 \end_layout
15693 \begin_layout Standard
15694 \begin_inset listings
15695 inline false
15696 status open
15698 \begin_layout Plain Layout
15700 a funny shade of ${colour}
15701 \end_layout
15703 \end_inset
15706 \end_layout
15708 \begin_layout Chunk
15709 test:chunk-params:text,language=
15710 \end_layout
15712 \begin_layout Standard
15713 \begin_inset listings
15714 inline false
15715 status open
15717 \begin_layout Plain Layout
15719 What do you see? "=<
15720 \backslash
15721 chunkref{test:chunk-params:sub}(joe, red)>"
15722 \end_layout
15724 \begin_layout Plain Layout
15726 Well, fancy!
15727 \end_layout
15729 \end_inset
15732 \end_layout
15734 \begin_layout Standard
15735 Should generate output:
15736 \end_layout
15738 \begin_layout Chunk
15739 test:chunk-params:result
15740 \end_layout
15742 \begin_layout Standard
15743 \begin_inset listings
15744 inline false
15745 status open
15747 \begin_layout Plain Layout
15749 What do you see? "I see a joe,
15750 \end_layout
15752 \begin_layout Plain Layout
15754                   a joe of colour red, 
15755 \end_layout
15757 \begin_layout Plain Layout
15759                   and looking closer a funny shade of red"
15760 \end_layout
15762 \begin_layout Plain Layout
15764 Well, fancy!
15765 \end_layout
15767 \end_inset
15770 \end_layout
15772 \begin_layout Standard
15773 And this chunk will perform the test:
15774 \end_layout
15776 \begin_layout Chunk
15777 test:chunk-params
15778 \end_layout
15780 \begin_layout Standard
15781 \begin_inset listings
15782 inline false
15783 status open
15785 \begin_layout Plain Layout
15787 $NEWFANGLE -Rtest:chunk-params:result $TEX_SRC > $TMP/answer || exit 1
15788 \end_layout
15790 \begin_layout Plain Layout
15792 $NEWFANGLE -Rtest:chunk-params:text $TEX_SRC > $TMP/result || exit 1
15793 \end_layout
15795 \begin_layout Plain Layout
15797 passtest diff $TMP/answer $TMP/result || (echo test:chunk-params:text failed
15798  ; exit 1)
15799 \end_layout
15801 \end_inset
15804 \end_layout
15806 \end_body
15807 \end_document