Add tests for modes, and start to correct docs
[newfangle.git] / newfangle.lyx
blob19a5fd442039d42b6e60da5e5acf0a9fb24b19b7
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  whose literate programming tools seem to make use of as many escaped abbreviati
119 ons for semantic markup as TeX itself.
120 \end_layout
122 \begin_layout Standard
124 \noun on
125 Norman Ramsey
126 \noun default
127  wrote the 
128 \noun on
129 noweb
130 \noun default
131  set of tools (notangle, noweave and noroots) and helpfully reduced the
132  amount of magic character sequences to just 
133 \begin_inset Flex CharStyle:Code
134 status collapsed
136 \begin_layout Plain Layout
138 \end_layout
140 \end_inset
142  and 
143 \begin_inset Flex CharStyle:Code
144 status collapsed
146 \begin_layout Plain Layout
148 \end_layout
150 \end_inset
152 , and in doing so brought the wonders of literate programming within my
153  reach.
154 \end_layout
156 \begin_layout Standard
157 Using LyX for LaTeX editing, I had various troubles with the noweb tools,
158  some of which were my fault, some of which were noweb's fault and some
159  of which were LyX's fault.
160 \end_layout
162 \begin_layout Standard
164 \noun on
165 Noweb
166 \noun default
167  generally brought literate programming to the masses through removing some
168  of the complexity of the original literate programming, but this would
169  be of no advantage to me if the LyX / LaTeX combination brought more complicati
170 ons in their place.
171 \end_layout
173 \begin_layout Standard
175 \noun on
176 Newfangle
177 \noun default
178  was thus born --- as an awk replacement for notangle, adding some important
179  features, like better integration with LyX and LaTeX, multiple output format
180  conversions, and fixing notangle bugs like indentation when using -L for
181  line numbers.
182 \end_layout
184 \begin_layout Standard
185 Significantly, newfangle is just one program which replaces various programs
186  in Noweb.
187  Specifically noweave is done away with and implemented directly as LaTeX
188  macros, and noroots is implemented as a function of the untangler 
189 \noun on
190 newfangle
191 \noun default
193 \end_layout
195 \begin_layout Standard
196 Newfangle is written in awk for portability reasons, awk being available
197  for most platforms.
198  A python conversion will probably be attempted for the benefit of LyX.
199  (Hasn't anyone implemented awk in python yet?)
200 \end_layout
202 \begin_layout Section*
203 Todo
204 \end_layout
206 \begin_layout Enumerate
207 ^^ is always going to be a problem, see texbytopic 1.2.2 (Work out what I
208  meant by this).
209 \end_layout
211 \begin_layout Enumerate
212 copy over up to date Makefile guide from noweb-lyx document
213 \end_layout
215 \begin_layout Enumerate
216 Make chunk-name settings only apply to chunks with that name
217 \end_layout
219 \begin_layout Enumerate
220 indent of multi-line chunks may be mode dependant (i.e.
221  not in string literals)
222 \end_layout
224 \begin_layout Enumerate
225 support chunk-param usage =<
226 \backslash
227 param{name}>
228 \end_layout
230 \begin_layout Enumerate
231 trim spaces from param
232 \end_layout
234 \begin_layout Enumerate
235 add support for other commands in =<...>, starting with 
236 \backslash
237 label which takes the line-number within the chunk, and maybe should also
238  take the chunk name/page
239 \end_layout
241 \begin_layout Enumerate
242 cant have listing inside a ruled box
243 \end_layout
245 \begin_layout Enumerate
246 when a parameterized chunk is included as well as the #line emission, say
247  what the paremeters were for that invocation.
248 \end_layout
250 \begin_layout Enumerate
251 with 2 macro expansions on one line ${} ${} the first is too greedy and
252  looks to the final }
253 \end_layout
255 \begin_layout Enumerate
257 \backslash
258 chunkref[3]{preamble} to include a certain chunk needs to work in newfangle.awk
259  instead of failing to be recognized at all
260 \end_layout
262 \begin_layout Enumerate
263 make in-listins labels track the chunk ref too, and make 
264 \backslash
265 chunref{[2],thing}> resolve to 41c (or d, or whatever chunk the 2nd chunk
266  of thing is
267 \end_layout
269 \begin_layout Enumerate
271 \backslash
272 chunkref in text needs a trailing space maybe, it keeps butting up to the
273  next word
274 \end_layout
276 \begin_layout Enumerate
277 because the white-space indent is output by the parent chunk, the #line
278  is that of the parent chunk.
279  White space indents must be passed to the child chunk
280 \end_layout
282 \begin_layout Chapter*
283 License
284 \end_layout
286 \begin_layout Standard
287 \begin_inset CommandInset label
288 LatexCommand label
289 name "cha:License"
291 \end_inset
293 Newfangle is licensed under the GPL 3
294 \begin_inset CommandInset citation
295 LatexCommand cite
296 key "gpl-licenses"
298 \end_inset
300  (or later).
301  This doesn't mean that you can't use or distribute newfangle with sources
302  of an incompatible license, but it means you must make the source of newfangle
303  available too.
304 \end_layout
306 \begin_layout Chunk
307 gpl3-copyright,language=
308 \end_layout
310 \begin_layout Standard
311 \begin_inset listings
312 inline false
313 status open
315 \begin_layout Plain Layout
317 #newfangle - fully featured notangle replacement in awk
318 \end_layout
320 \begin_layout Plain Layout
323 \end_layout
325 \begin_layout Plain Layout
327 #Copyright (C) Sam Liddicott 2009
328 \end_layout
330 \begin_layout Plain Layout
333 \end_layout
335 \begin_layout Plain Layout
337 #This program is free software: you can redistribute it and/or modify
338 \end_layout
340 \begin_layout Plain Layout
342 #it under the terms of the GNU General Public License as published by
343 \end_layout
345 \begin_layout Plain Layout
347 #the Free Software Foundation, either version 3 of the License, or
348 \end_layout
350 \begin_layout Plain Layout
352 #(at your option) any later version.
353 \end_layout
355 \begin_layout Plain Layout
358 \end_layout
360 \begin_layout Plain Layout
362 #This program is distributed in the hope that it will be useful,
363 \end_layout
365 \begin_layout Plain Layout
367 #but WITHOUT ANY WARRANTY; without even the implied warranty of
368 \end_layout
370 \begin_layout Plain Layout
372 #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
373   See the
374 \end_layout
376 \begin_layout Plain Layout
378 #GNU General Public License for more details.
379 \end_layout
381 \begin_layout Plain Layout
384 \end_layout
386 \begin_layout Plain Layout
388 #You should have received a copy of the GNU General Public License
389 \end_layout
391 \begin_layout Plain Layout
393 #along with this program.
394   If not, see <http://www.gnu.org/licenses/>.
395 \end_layout
397 \end_inset
400 \end_layout
402 \begin_layout Standard
403 \begin_inset CommandInset toc
404 LatexCommand tableofcontents
406 \end_inset
409 \end_layout
411 \begin_layout Part
412 Using Newfangle
413 \end_layout
415 \begin_layout Chapter
416 Running Newfangle
417 \end_layout
419 \begin_layout Standard
420 Newfangle is a replacement for noweb, which consists of 
421 \begin_inset Flex CharStyle:Code
422 status collapsed
424 \begin_layout Plain Layout
425 notangle
426 \end_layout
428 \end_inset
431 \begin_inset Flex CharStyle:Code
432 status collapsed
434 \begin_layout Plain Layout
435 noroots
436 \end_layout
438 \end_inset
440  and 
441 \begin_inset Flex CharStyle:Code
442 status collapsed
444 \begin_layout Plain Layout
445 noweave
446 \end_layout
448 \end_inset
451 \end_layout
453 \begin_layout Standard
454 Like 
455 \begin_inset Flex CharStyle:Code
456 status collapsed
458 \begin_layout Plain Layout
459 notangle
460 \end_layout
462 \end_inset
464  and 
465 \begin_inset Flex CharStyle:Code
466 status collapsed
468 \begin_layout Plain Layout
469 noroots
470 \end_layout
472 \end_inset
474  it can read multiple named files, or from stdin.
475 \end_layout
477 \begin_layout Section
478 Listing roots
479 \end_layout
481 \begin_layout Standard
482 The -r option causes newfangle to behave like noroots.
483 \end_layout
485 \begin_layout LyX-Code
486 newfangle -r filename.tex
487 \end_layout
489 \begin_layout Standard
490 will print out the newfangle roots of a tex file.
492 \end_layout
494 \begin_layout Standard
495 Unlike the 
496 \begin_inset Flex CharStyle:Code
497 status collapsed
499 \begin_layout Plain Layout
500 noroots
501 \end_layout
503 \end_inset
505  command, the roots are not enclosed in 
506 \begin_inset Flex CharStyle:Code
507 status collapsed
509 \begin_layout Plain Layout
510 <<name>>
511 \end_layout
513 \end_inset
515 , unless at least one of the roots is defined using the 
516 \begin_inset Flex CharStyle:Code
517 status collapsed
519 \begin_layout Plain Layout
520 notangle
521 \end_layout
523 \end_inset
525  style 
526 \begin_inset Flex CharStyle:Code
527 status collapsed
529 \begin_layout Plain Layout
530 <<name>>=
531 \end_layout
533 \end_inset
536 \end_layout
538 \begin_layout Standard
539 Also, unlike noroots, it prints out all roots --- not just those that are
540  not used elsewhere.
541  I find that a root not being used, doesn't make it particularly top level.
542  My convention is that top level roots to be extracted begin with 
543 \begin_inset Flex CharStyle:Code
544 status collapsed
546 \begin_layout Plain Layout
548 \end_layout
550 \end_inset
552  and have the form of a filename.
553 \end_layout
555 \begin_layout Section
556 Extracting roots
557 \end_layout
559 \begin_layout Standard
560 notangle's 
561 \begin_inset Flex CharStyle:Code
562 status collapsed
564 \begin_layout Plain Layout
566 \end_layout
568 \end_inset
570  and 
571 \begin_inset Flex CharStyle:Code
572 status collapsed
574 \begin_layout Plain Layout
576 \end_layout
578 \end_inset
580  options are supported.
581 \end_layout
583 \begin_layout Standard
584 The standard way to extract a file would be:
585 \end_layout
587 \begin_layout LyX-Code
588 newfangle -R./Makefile.inc newfangle.tex > ./Makefile.inc
589 \end_layout
591 \begin_layout Standard
592 Unlike the 
593 \begin_inset Flex CharStyle:Code
594 status collapsed
596 \begin_layout Plain Layout
597 noroots
598 \end_layout
600 \end_inset
602  command, the 
603 \begin_inset Flex CharStyle:Code
604 status collapsed
606 \begin_layout Plain Layout
608 \end_layout
610 \end_inset
612  option does not break indenting; also the 
613 \begin_inset Flex CharStyle:Code
614 status collapsed
616 \begin_layout Plain Layout
618 \end_layout
620 \end_inset
622  option does not interrupt (and break) multi-line C macros --- or indeed
623  any line ending with a backslash.
624  This does mean that sometimes the compiler might calculate the source line
625  wrongly when generating error messages in such cases, but there isn't any
626  other way around if multi-line macros include other chunks.
627 \end_layout
629 \begin_layout Section
630 Formatting source in LaTeX
631 \end_layout
633 \begin_layout Standard
634 The noweave replacement is a set of LaTeX macros dependant upon 
635 \emph on
636 noweb.sty
637 \emph default
638 , and which can be included with:
639 \end_layout
641 \begin_layout LyX-Code
643 \backslash
644 usepackage{newfangle.sty}
645 \end_layout
647 \begin_layout Standard
648 The LaTeX macros are shown in section 
649 \begin_inset CommandInset ref
650 LatexCommand ref
651 reference "sec:Latex-Macros"
653 \end_inset
655 , and are part of a LyX module file 
656 \begin_inset Flex CharStyle:Code
657 status collapsed
659 \begin_layout Plain Layout
660 newfangle.module
661 \end_layout
663 \end_inset
665 , which automatically includes the macros in the document pre-amble when
666  the newfangle LyX module is used.
667 \end_layout
669 \begin_layout Standard
670 Because the noweave replacement is impemented in LaTeX, there is no processing
671  stage required before running the 
672 \begin_inset Flex CharStyle:Code
673 status collapsed
675 \begin_layout Plain Layout
676 latex
677 \end_layout
679 \end_inset
681  command.
682  LaTeX may need running two or more times, so that the code chunk references
683  can be fully calculated.
684 \end_layout
686 \begin_layout Standard
687 The 
688 \begin_inset Flex CharStyle:Code
689 status collapsed
691 \begin_layout Plain Layout
692 noweb.sty
693 \end_layout
695 \end_inset
697  package is required as it is used for formatting the code chunk captions
698 \end_layout
700 \begin_layout Standard
701 The 
702 \begin_inset Flex CharStyle:Code
703 status collapsed
705 \begin_layout Plain Layout
706 listings.sty
707 \end_layout
709 \end_inset
711  package is also required, as it is used for formatting the code chunks
712  themselves.
713 \end_layout
715 \begin_layout Standard
716 The 
717 \begin_inset Flex CharStyle:Code
718 status collapsed
720 \begin_layout Plain Layout
721 xargs.sty
722 \end_layout
724 \end_inset
726  package is also required.
727 \end_layout
729 \begin_layout Chapter
730 Literate Programming with Newfangle
731 \end_layout
733 \begin_layout Standard
734 Todo.
735  Should really follow on from a part-0 explanation of what literate programming
736  is.
737 \end_layout
739 \begin_layout Chapter
740 Using Newfangle with LyX
741 \end_layout
743 \begin_layout Section
744 Setting up Lyx
745 \end_layout
747 \begin_layout Subsection
748 Installing the LyX module
749 \end_layout
751 \begin_layout Standard
752 Copy 
753 \begin_inset Flex CharStyle:Code
754 status collapsed
756 \begin_layout Plain Layout
757 newfangle.module
758 \end_layout
760 \end_inset
762  to your LyX layouts directory, which for unix users will be 
763 \begin_inset Flex CharStyle:Code
764 status collapsed
766 \begin_layout Plain Layout
767 ~/.lyx/layouts
768 \end_layout
770 \end_inset
773 \end_layout
775 \begin_layout Standard
776 You will need to reconfigure LyX by clicking Tools\SpecialChar \menuseparator
777 Reconfigure, and then
778  re-start LyX.
779 \end_layout
781 \begin_layout Subsection
782 \begin_inset CommandInset label
783 LatexCommand label
784 name "sub:Configuring-the-build"
786 \end_inset
788 Configuring the build script
789 \end_layout
791 \begin_layout Standard
792 Make sure you don't have a conversion defined for Lyx → Program
793 \end_layout
795 \begin_layout Standard
796 From the menu Tools\SpecialChar \menuseparator
797 Preferences, add a conversion from Latex(Plain) → Program
798  as:
799 \end_layout
801 \begin_layout LyX-Code
802 set -x ; newfangle -Rlyx-build $$i | 
803 \end_layout
805 \begin_layout LyX-Code
806   env LYX_b=$$b LYX_i=$$i LYX_o=$$o LYX_p=$$p LYX_r=$$r bash
807 \end_layout
809 \begin_layout Standard
810 (But don't cut-n-paste it from this document or you'll be pasting a multi-line
811  string which will break your lyx preferences file).
813 \end_layout
815 \begin_layout Standard
816 I hope that one day, LyX will set these into the environment when calling
817  the build script.
818 \end_layout
820 \begin_layout Standard
821 You may also want to consider adding options to this conversion\SpecialChar \ldots{}
823 \end_layout
825 \begin_layout LyX-Code
826 parselog=/usr/share/lyx/scripts/listerrors
827 \end_layout
829 \begin_layout Standard
830 \SpecialChar \ldots{}
831 but if you do you will lose your stderr
832 \begin_inset Foot
833 status collapsed
835 \begin_layout Plain Layout
836 There is some bash plumbing to get a copy of stderr but this footnote is
837  too small
838 \end_layout
840 \end_inset
843 \end_layout
845 \begin_layout Standard
846 Now, a shell script chunk called 
847 \begin_inset Flex CharStyle:Code
848 status collapsed
850 \begin_layout Plain Layout
851 lyx-build
852 \end_layout
854 \end_inset
856  will be extracted and run whenever you choose the Document\SpecialChar \menuseparator
857 Build Program
858  menu item.
859 \end_layout
861 \begin_layout Standard
862 The lyx-build script for this document is in section 
863 \begin_inset CommandInset ref
864 LatexCommand ref
865 reference "lyx-build-script"
867 \end_inset
869  and on a unix system will extract 
870 \begin_inset Flex CharStyle:Code
871 status collapsed
873 \begin_layout Plain Layout
874 newfangle.module
875 \end_layout
877 \end_inset
879  and the 
880 \begin_inset Flex CharStyle:Code
881 status collapsed
883 \begin_layout Plain Layout
884 newfangle
885 \end_layout
887 \end_inset
889  awk script.
890 \end_layout
892 \begin_layout Subsection
893 Preparing your Lyx document
894 \end_layout
896 \begin_layout Standard
897 It is not necessary to base your literate document on any of the original
898  LyX literate classes; so select a regular class for your document type.
899 \end_layout
901 \begin_layout Standard
902 Add the new module 
903 \emph on
904 Newfangle Literate
905 \emph default
907 \emph on
908 Listings
909 \emph default
910  and possibly also 
911 \emph on
912 Logical Markup
913 \emph default
915 \end_layout
917 \begin_layout Standard
918 In the drop-down style listbox you should notice a new style defined, called
920 \emph on
921 Chunk
922 \emph default
924 \end_layout
926 \begin_layout Standard
927 When you wish to insert a literate chunk, you enter it's plain name in the
928  Chunk style, instead of the older method that used 
929 \begin_inset Flex CharStyle:Code
930 status collapsed
932 \begin_layout Plain Layout
933 <<name>>=
934 \end_layout
936 \end_inset
938  type tags.
939  Following the chunk name, you insert a listing with: Insert\SpecialChar \menuseparator
940 Program Listing.
941 \end_layout
943 \begin_layout Standard
944 Inside the white listing box you can type (or paste using shift+ctrl+V)
945  your listing.
946  There is not need to use ctrl+enter at the end of lines as with some older
947  LyX literate techniques --- just press enter as normal.
948 \end_layout
950 \begin_layout Subsubsection
951 Customising the listing appearance
952 \end_layout
954 \begin_layout Standard
955 In the final document, the code is formatted using the 
956 \noun on
957 lstlistings
958 \noun default
959  package.
960  The chunk style doesn't just define the chunk name, but can also define
961  any other chunk options supported by the lstlistings package 
962 \begin_inset Flex CharStyle:Code
963 status collapsed
965 \begin_layout Plain Layout
967 \backslash
968 lstset
969 \end_layout
971 \end_inset
973  command.
974  In fact, what you type in the chunk style is raw latex.
975  If you want to set the chunk language without having to right-click the
976  listing, just add 
977 \begin_inset Flex CharStyle:Code
978 status collapsed
980 \begin_layout Plain Layout
981 ,lanuage=C
982 \end_layout
984 \end_inset
986  after the chunk name.
987 \end_layout
989 \begin_layout Standard
990 Of course you can do this by editing the listings box advanced properties
991  by right-clicking on the listings box, but that takes longer, and you can't
992  see at-a-glance what the advanced settings are while editing the document;
993  also advanced settings apply only to that box --- the chunk settings apply
994  through the rest of the document
995 \begin_inset Foot
996 status collapsed
998 \begin_layout Plain Layout
999 It ought to apply only to subsequent chunks of the same name.
1000  I'll fix that later
1001 \end_layout
1003 \end_inset
1006 \begin_inset Note Note
1007 status collapsed
1009 \begin_layout Plain Layout
1010 So make sure they only apply to chunks of that name
1011 \end_layout
1013 \end_inset
1016 \end_layout
1018 \begin_layout Subsubsection
1019 Global customisations
1020 \end_layout
1022 \begin_layout Standard
1023 As 
1024 \emph on
1025 lstlistings
1026 \emph default
1027  is used to set the code chunks, it's 
1028 \begin_inset Flex CharStyle:Code
1029 status collapsed
1031 \begin_layout Plain Layout
1033 \backslash
1034 lstset
1035 \end_layout
1037 \end_inset
1039  command can be used in the pre-amble to set some document wide settings.
1040 \end_layout
1042 \begin_layout Standard
1043 If your source has many words with long sequences of capital letters, then
1045 \begin_inset Flex CharStyle:Code
1046 status collapsed
1048 \begin_layout Plain Layout
1049 columns=fullflexible
1050 \end_layout
1052 \end_inset
1054  may be a good idea, or the capital letters will get crowded.
1055  (I think lstlistings ought to use a slightly smaller font for captial letters
1056  so that they still fit).
1057 \end_layout
1059 \begin_layout Standard
1060 The font family 
1061 \begin_inset Flex CharStyle:Code
1062 status collapsed
1064 \begin_layout Plain Layout
1066 \backslash
1067 ttfamily
1068 \end_layout
1070 \end_inset
1072  looks more normal for code, but has no bold (unless luximono is used, but
1073  it doesn't work for me); so I use 
1074 \begin_inset Flex CharStyle:Code
1075 status collapsed
1077 \begin_layout Plain Layout
1079 \backslash
1080 color{darkgreen}
1081 \end_layout
1083 \end_inset
1085  for my keywords.
1086  With 
1087 \begin_inset Flex CharStyle:Code
1088 status collapsed
1090 \begin_layout Plain Layout
1092 \backslash
1093 ttfamily
1094 \end_layout
1096 \end_inset
1099 \begin_inset Flex CharStyle:Code
1100 status collapsed
1102 \begin_layout Plain Layout
1103 columns=fullflexible
1104 \end_layout
1106 \end_inset
1108  is used or the wrong letter spacing is used.
1109 \end_layout
1111 \begin_layout Standard
1112 In my LeTeX pre-amble I usually specialise my code format with:
1113 \end_layout
1115 \begin_layout Chunk
1116 document-preamble,language=tex
1117 \end_layout
1119 \begin_layout Standard
1120 \begin_inset listings
1121 inline false
1122 status open
1124 \begin_layout Plain Layout
1127 \backslash
1128 usepackage{xcolor}
1129 \end_layout
1131 \begin_layout Plain Layout
1134 \backslash
1135 definecolor{darkgreen}{rgb}{0,0.5,0}
1136 \end_layout
1138 \begin_layout Plain Layout
1141 \backslash
1142 lstset{numbers=left, stepnumber=5, numbersep=5pt, breaklines=false,
1143 \end_layout
1145 \begin_layout Plain Layout
1147   basicstyle=
1148 \backslash
1149 footnotesize
1150 \backslash
1151 ttfamily,
1152 \end_layout
1154 \begin_layout Plain Layout
1156   keywordstyle=
1157 \backslash
1158 color{darkgreen},
1159 \end_layout
1161 \begin_layout Plain Layout
1163   numberstyle=
1164 \backslash
1165 tiny,language=C,columns=fullflexible,
1166 \end_layout
1168 \begin_layout Plain Layout
1170   numberfirstline=true
1171 \end_layout
1173 \begin_layout Plain Layout
1176 \end_layout
1178 \end_inset
1181 \end_layout
1183 \begin_layout Chapter
1184 Newfangle with Makefiles
1185 \end_layout
1187 \begin_layout Standard
1188 \begin_inset Note Note
1189 status open
1191 \begin_layout Plain Layout
1192 This chapter needs revising
1193 \end_layout
1195 \end_inset
1198 \begin_inset Note Greyedout
1199 status open
1201 \begin_layout Plain Layout
1202 This chapter needs revising
1203 \end_layout
1205 \end_inset
1207 Here we describe a Makefile.inc that you can include in your own Makefiles,
1208  or glue as a recursive make to other projects.
1209 \end_layout
1211 \begin_layout Standard
1212 The Makefile.inc described here was put together for a Samba4 vfs module,
1213  but can be used in any Make project, including automake projects.
1214 \end_layout
1216 \begin_layout Section
1217 A word about makefiles formats
1218 \end_layout
1220 \begin_layout Standard
1221 Whitespace formatting is very important in a Makefile.
1222  The first character of each command line must be a TAB.
1223 \end_layout
1225 \begin_layout LyX-Code
1226 target: pre-requisite
1227 \begin_inset Newline newline
1228 \end_inset
1230    →    action
1231 \begin_inset Newline newline
1232 \end_inset
1234    →    action
1235 \end_layout
1237 \begin_layout Standard
1238 But a TAB is pretty hard to enter into most of the Lyx formats and insets
1239  I've been using.
1240  An alternative is to use a semi-colon after the pre-requisite, and a backslash
1241  at the end of each line (except the last).
1242  Then any whitespace (or none) can prefix each action.
1243 \end_layout
1245 \begin_layout LyX-Code
1246 target: pre-requisite ; 
1247 \backslash
1249 \begin_inset Newline newline
1250 \end_inset
1252 ␣␣action 
1253 \backslash
1255 \begin_inset Newline newline
1256 \end_inset
1258 ␣␣action
1259 \end_layout
1261 \begin_layout Standard
1262 This is the style that we use and it works pretty well for GNU make at least.
1263 \end_layout
1265 \begin_layout Standard
1266 We also adopt a convention that code chunks whose names beginning with ./
1267  should always be automatically extracted from the document.
1268  Code chunks whose names do not begin with ./ are for internal reference.
1269  (This doesn't prevent such chunks from being extracted directly).
1270 \end_layout
1272 \begin_layout Section
1273 Boot-strapping the extraction
1274 \end_layout
1276 \begin_layout Subsection
1277 Using a Makefile
1278 \end_layout
1280 \begin_layout Standard
1281 \begin_inset CommandInset label
1282 LatexCommand label
1283 name "sub:Bootstrap-Using-a-Makefile"
1285 \end_inset
1287 It seems convenient to have the makefile extract or update the C source
1288  files as part of it's operation.
1289  It also seems convenient to have the makefile itself extracted from this
1290  document.
1291 \end_layout
1293 \begin_layout Standard
1294 It would also be convenient to have the code to extract the makefile from
1295  this document to also be part of this document, however we have to start
1296  somewhere and this unfortunately requires us to type at least a few words
1297  by hand to start things off.
1298 \end_layout
1300 \begin_layout Standard
1301 Therefore we will have a minimal root fragment, which, when extracted, can
1302  cope with extracting the rest of the source.
1303  perhaps with this shell script, which could be called 
1304 \emph on
1305 autoboot
1306 \emph default
1308 \begin_inset Note Note
1309 status open
1311 \begin_layout Plain Layout
1312 FIX THIS CHUNK AND TEST IT
1313 \end_layout
1315 \end_inset
1318 \end_layout
1320 \begin_layout Chunk
1322 \end_layout
1324 \begin_layout Standard
1325 \begin_inset listings
1326 inline false
1327 status open
1329 \begin_layout Plain Layout
1331 #! /bin/sh
1332 \end_layout
1334 \begin_layout Plain Layout
1336 \end_layout
1338 \begin_layout Plain Layout
1340 MAKE_SRC="${1:-${NW_LYX:-../../noweb-lyx/noweb-lyx3.lyx}}"
1341 \end_layout
1343 \begin_layout Plain Layout
1345 MAKE_SRC=`dirname "$MAKE_SRC"`/`basename "$MAKE_SRC" .lyx`
1346 \end_layout
1348 \begin_layout Plain Layout
1350 NOWEB_SRC="${2:-${NOWEB_SRC:-$MAKE_SRC.lyx}}"
1351 \end_layout
1353 \begin_layout Plain Layout
1355 lyx -e latex $MAKE_SRC
1356 \end_layout
1358 \begin_layout Plain Layout
1360 \end_layout
1362 \begin_layout Plain Layout
1364 newfangle -R./Makefile.inc ${MAKE_SRC}.tex 
1365 \backslash
1367 \end_layout
1369 \begin_layout Plain Layout
1371   | sed "/NEWFANGLE_SOURCE=/s/^/#/;T;aNOWEB_SOURCE=$NEWFANGLE_SRC" 
1372 \backslash
1374 \end_layout
1376 \begin_layout Plain Layout
1378   | cpif ./Makefile.inc
1379 \end_layout
1381 \begin_layout Plain Layout
1383 \end_layout
1385 \begin_layout Plain Layout
1387 make -f ./Makefile.inc newfangle_sources
1388 \end_layout
1390 \end_inset
1393 \end_layout
1395 \begin_layout Standard
1396 The general Makefile can be invoked with 
1397 \emph on
1398 ./autoboot
1399 \emph default
1400  and can also be included into any automake file to automatically re-generate
1401  the source files.
1402 \end_layout
1404 \begin_layout Standard
1405 The 
1406 \emph on
1407 autoboot
1408 \emph default
1409  can be extracted with this command:
1410 \end_layout
1412 \begin_layout LyX-Code
1413 lyx -e latex newfangle.lyx && 
1414 \backslash
1416 \end_layout
1418 \begin_layout LyX-Code
1419 newfangle newfangle.lyx > ./autoboot
1420 \end_layout
1422 \begin_layout Standard
1423 This looks simple enough, but as mentioned, newfangle has to be had from
1424  somewhere before it can be extracted.
1425 \end_layout
1427 \begin_layout Subsection
1428 \begin_inset Note Note
1429 status collapsed
1431 \begin_layout Plain Layout
1432 MERGE THIS WITH THE SECTIONS OF THIS DOCUMENT
1433 \end_layout
1435 \end_inset
1437 \SpecialChar \ldots{}
1439 \end_layout
1441 \begin_layout Standard
1442 When the lyx-build chunk is executed, the current directory will be a temporary
1443  directory, and 
1444 \begin_inset Flex CharStyle:Code
1445 status collapsed
1447 \begin_layout Plain Layout
1448 LYX_SOURCE
1449 \end_layout
1451 \end_inset
1453  will refer to the tex file in this temporary directory.
1454  This is unfortunate as our makefile wants to run from the project directory
1455  where the Lyx file is kept.
1456 \end_layout
1458 \begin_layout Standard
1459 We can extract the project directory from $$r, and derive the probable Lyx
1460  filename from the noweb file that Lyx generated.
1461 \end_layout
1463 \begin_layout Chunk
1464 lyx-build-helper
1465 \end_layout
1467 \begin_layout Standard
1468 \begin_inset listings
1469 inline false
1470 status open
1472 \begin_layout Plain Layout
1474 PROJECT_DIR="$LYX_r"
1475 \end_layout
1477 \begin_layout Plain Layout
1479 LYX_SRC="$PROJECT_DIR/${LYX_i%.tex}.lyx"
1480 \end_layout
1482 \begin_layout Plain Layout
1484 TEX_DIR="$LYX_p"
1485 \end_layout
1487 \begin_layout Plain Layout
1489 TEX_SRC="$TEX_DIR/$LYX_i"
1490 \end_layout
1492 \end_inset
1495 \end_layout
1497 \begin_layout Standard
1498 And then we can define a lyx-build fragment similar to the autoboot fragment
1499 \end_layout
1501 \begin_layout Chunk
1502 lyx-build
1503 \end_layout
1505 \begin_layout Standard
1506 \begin_inset listings
1507 inline false
1508 status open
1510 \begin_layout Plain Layout
1512 #! /bin/sh
1513 \end_layout
1515 \begin_layout Plain Layout
1518 \backslash
1519 chunkref{lyx-build-helper}>
1520 \end_layout
1522 \begin_layout Plain Layout
1524 cd $PROJECT_DIR || exit 1
1525 \end_layout
1527 \begin_layout Plain Layout
1529 \end_layout
1531 \begin_layout Plain Layout
1533 #/usr/bin/newfangle -filter ./notanglefix-filter 
1534 \backslash
1536 \end_layout
1538 \begin_layout Plain Layout
1540 #  -R./Makefile.inc "../../noweb-lyx/noweb-lyx3.lyx" 
1541 \backslash
1543 \end_layout
1545 \begin_layout Plain Layout
1547 #  | sed '/NOWEB_SOURCE=/s/=.*/=samba4-dfs.lyx/' 
1548 \backslash
1550 \end_layout
1552 \begin_layout Plain Layout
1554 #  > ./Makefile.inc
1555 \end_layout
1557 \begin_layout Plain Layout
1560 \end_layout
1562 \begin_layout Plain Layout
1564 #make -f ./Makefile.inc newfangle_sources
1565 \end_layout
1567 \end_inset
1570 \end_layout
1572 \begin_layout Section
1573 Extracting Sources
1574 \end_layout
1576 \begin_layout Subsection
1577 Including Makefile.inc
1578 \end_layout
1580 \begin_layout Standard
1581 \begin_inset CommandInset label
1582 LatexCommand label
1583 name "sub:Keeping-extracted-files"
1585 \end_inset
1587 Makefile.inc will cope with extracting all the other source files from this
1588  document and keeping them up to date.
1590 \end_layout
1592 \begin_layout Standard
1593 It may also be included by a Makefile or Makefile.am defined in a Lyx document
1594  to automatically deal with the extraction of source files and documents.
1595 \end_layout
1597 \begin_layout Standard
1598 A makefile has two parts; variables must be defined before the targets that
1599  use them.
1600 \end_layout
1602 \begin_layout Chunk
1603 ./Makefile.inc
1604 \end_layout
1606 \begin_layout Standard
1607 \begin_inset listings
1608 inline false
1609 status open
1611 \begin_layout Plain Layout
1614 \backslash
1615 chunkref{Makefile.inc-vars}>
1616 \end_layout
1618 \begin_layout Plain Layout
1621 \backslash
1622 chunkref{Makefile.inc-targets}>
1623 \end_layout
1625 \end_inset
1628 \end_layout
1630 \begin_layout Standard
1631 We first define 
1632 \begin_inset Flex CharStyle:Code
1633 status collapsed
1635 \begin_layout Plain Layout
1636 NOWEB_SOURCE
1637 \end_layout
1639 \end_inset
1641  to hold the name of this Lyx file.
1642 \end_layout
1644 \begin_layout Chunk
1645 Makefile.inc-vars
1646 \end_layout
1648 \begin_layout Standard
1649 \begin_inset listings
1650 inline false
1651 status open
1653 \begin_layout Plain Layout
1655 LYX_SOURCE=
1656 \end_layout
1658 \begin_layout Plain Layout
1660 LITERATE_SOURCE=$(LYX_SOURCE)
1661 \end_layout
1663 \end_inset
1666 \end_layout
1668 \begin_layout Subsection
1669 Recursive use of Makefile.inc
1670 \end_layout
1672 \begin_layout Standard
1673 The makefile glue described here is used when building Samba4 vfs modules.
1674 \end_layout
1676 \begin_layout Standard
1677 If you are defining a module of an existing program you may find it easier
1678  to use a slight recursive make instead of including the makefile directly.
1679  This way there is less chance of definitions in Makefile.inc interfering
1680  with definitions in the main makefile, or with definitions in other Makefile.inc
1681  from other noweb modules.
1682 \end_layout
1684 \begin_layout Standard
1685 The glue works by adding a .PHONY target to call the recursive make, and
1686  adding this target as an additional pre-requisite to the existing targets.
1687 \end_layout
1689 \begin_layout Standard
1690 In this example, the existing build system already has a build target for
1692 \begin_inset Flex CharStyle:Code
1693 status collapsed
1695 \begin_layout Plain Layout
1696 example.o
1697 \end_layout
1699 \end_inset
1701 , so we just add another pre-requisite to that.
1702  In this case we use 
1703 \begin_inset Flex CharStyle:Code
1704 status collapsed
1706 \begin_layout Plain Layout
1707 example.tex.stamp
1708 \end_layout
1710 \end_inset
1712  as a pre-requisite, the stamp file's modified time indicating when all
1713  sources were extracted.
1714 \end_layout
1716 \begin_layout Chunk
1717 makefile-glue
1718 \end_layout
1720 \begin_layout Standard
1721 \begin_inset listings
1722 inline false
1723 status open
1725 \begin_layout Plain Layout
1727 $(example_srcdir)/example.o: $(example_srcdir)/example.tex.stamp
1728 \end_layout
1730 \end_inset
1733 \end_layout
1735 \begin_layout Standard
1736 The target for this new pre-requisite is generated by a recursive make using
1737  Makefile.inc which will make sure that the source is up to date, before
1738  it is built by the main projects makefile.
1739 \end_layout
1741 \begin_layout Chunk
1742 makefile-glue
1743 \end_layout
1745 \begin_layout Standard
1746 \begin_inset listings
1747 inline false
1748 status open
1750 \begin_layout Plain Layout
1752 $(example_srcdir)/example.tex.stamp: $(example_srcdir)/example.tex ; 
1753 \backslash
1755 \end_layout
1757 \begin_layout Plain Layout
1759         cd $(example_srcdir) && 
1760 \backslash
1762 \end_layout
1764 \begin_layout Plain Layout
1766         $(MAKE) -f Makefile.inc newfangle_sources
1767 \end_layout
1769 \end_inset
1772 \end_layout
1774 \begin_layout Standard
1775 We can do similar glue for the docs, clean and distclean targets.
1776  In this example our build system is using a double colon for these targets,
1777  so we use the same in our glue.
1778 \end_layout
1780 \begin_layout Chunk
1781 makefile-glue
1782 \end_layout
1784 \begin_layout Standard
1785 \begin_inset listings
1786 inline false
1787 status open
1789 \begin_layout Plain Layout
1791 docs:: docs_example
1792 \end_layout
1794 \begin_layout Plain Layout
1796 .PHONY: docs_example
1797 \end_layout
1799 \begin_layout Plain Layout
1801 docs_example:: ; cd $(example_srcdir) && 
1802 \backslash
1804 \end_layout
1806 \begin_layout Plain Layout
1808         $(MAKE) -f Makefile.inc docs
1809 \end_layout
1811 \begin_layout Plain Layout
1813 \end_layout
1815 \begin_layout Plain Layout
1817 clean:: clean_example
1818 \end_layout
1820 \begin_layout Plain Layout
1822 .PHONEY: clean_example
1823 \end_layout
1825 \begin_layout Plain Layout
1827 clean_example: ; cd $(example_srcdir) && 
1828 \backslash
1830 \end_layout
1832 \begin_layout Plain Layout
1834         $(MAKE) -f Makefile.inc clean
1835 \end_layout
1837 \begin_layout Plain Layout
1839 \end_layout
1841 \begin_layout Plain Layout
1843 distclean:: distclean_example
1844 \end_layout
1846 \begin_layout Plain Layout
1848 .PHONY: distclean_example
1849 \end_layout
1851 \begin_layout Plain Layout
1853 distclean_example: ; cd $(example_srcdir) && 
1854 \backslash
1856 \end_layout
1858 \begin_layout Plain Layout
1860         $(MAKE) -f Makefile.inc distclean
1861 \end_layout
1863 \end_inset
1866 \end_layout
1868 \begin_layout Standard
1869 We could do similarly for install targets to install the generated docs.
1870 \end_layout
1872 \begin_layout Subsection
1873 \begin_inset CommandInset label
1874 LatexCommand label
1875 name "sub:Converting-from-Lyx"
1877 \end_inset
1879 Converting from Lyx to LaTeX
1880 \end_layout
1882 \begin_layout Standard
1883 The first stage will always be to convert the Lyx file to a LaTeX file;
1884  this must be so not only because newfangle needs to to run on a TeX file,
1885  but also because the Lyx command 
1886 \emph on
1887 server-goto-file-line
1888 \begin_inset Foot
1889 status collapsed
1891 \begin_layout Plain Layout
1892 The Lyx command 
1893 \emph on
1894 server-goto-file-line
1895 \emph default
1896  is used to position the Lyx cursor at the compiler errors.
1897 \end_layout
1899 \end_inset
1902 \emph default
1903  insists that the line number provided is a line in the TeX file, and always
1904  reverse maps this to derive the line in the Lyx docment.
1905 \begin_inset Note Note
1906 status collapsed
1908 \begin_layout Plain Layout
1909 The tex file should probably be an automake extra dist sources or something,
1910  so that it gets produced and packaged by make dist
1911 \end_layout
1913 \end_inset
1916 \end_layout
1918 \begin_layout Standard
1919 The command [[lyx -e literate noweb-lyx.lyx]] will produce [[noweb-lyx.nw]]
1920  a tex file, so we define the noweb target to be the same as the Lyx file
1921  but with the .nw extension.
1922 \end_layout
1924 \begin_layout Chunk
1925 Makefile.inc-vars
1926 \end_layout
1928 \begin_layout Standard
1929 \begin_inset listings
1930 inline false
1931 status open
1933 \begin_layout Plain Layout
1935 TEX_SOURCE=$(LYX_SOURCE:.lyx=.tex)
1936 \end_layout
1938 \end_inset
1941 \end_layout
1943 \begin_layout Chunk
1944 Makefile.inc-targets
1945 \end_layout
1947 \begin_layout Standard
1948 \begin_inset listings
1949 inline false
1950 status open
1952 \begin_layout Plain Layout
1954 $(TEX_SOURCE): $(LYX_SOURCE) ;
1955 \backslash
1957 \end_layout
1959 \begin_layout Plain Layout
1961         lyx -e latex $<
1962 \end_layout
1964 \begin_layout Plain Layout
1966 clean_tex: ; rm -f -- $(TEX_SOURCE)
1967 \end_layout
1969 \end_inset
1972 \end_layout
1974 \begin_layout Subsection
1975 Extracting Program Source
1976 \end_layout
1978 \begin_layout Standard
1979 The program source is extracted using newfangle, which is designed to operate
1980  on a LaTeX document.
1982 \end_layout
1984 \begin_layout Chunk
1985 Makefile.inc-vars
1986 \end_layout
1988 \begin_layout Standard
1989 \begin_inset listings
1990 inline false
1991 status open
1993 \begin_layout Plain Layout
1995 NEWFANGLE_SOURCE=$(TEX_SOURCE)
1996 \end_layout
1998 \end_inset
2001 \end_layout
2003 \begin_layout Standard
2004 The Lyx document can result in any number of source documents, but not all
2005  of these will be changed each time the Lyx document is updated.
2006  We certainly don't want to update the timestamps of these files and cause
2007  the whole source tree to be recompiled just because the Lyx document was
2008  edited.
2010 \end_layout
2012 \begin_layout Standard
2013 To solve this problem we use a stamp file which is always updated each time
2014  the sources are extracted from the LaTeX document.
2015  If the stamp file is older than the LaTeX document, then we can make an
2016  attempt to re-extract the sources.
2017 \end_layout
2019 \begin_layout Chunk
2020 Makefile.inc-vars
2021 \end_layout
2023 \begin_layout Standard
2024 \begin_inset listings
2025 inline false
2026 status open
2028 \begin_layout Plain Layout
2030 NEWFANGLE_SOURCE_STAMP=$(NEWFANGLE_SOURCE).stamp
2031 \end_layout
2033 \end_inset
2036 \end_layout
2038 \begin_layout Chunk
2039 Makefile.inc-targets
2040 \end_layout
2042 \begin_layout Standard
2043 \begin_inset listings
2044 inline false
2045 status open
2047 \begin_layout Plain Layout
2049 $(NEWFANGLE_SOURCE_STAMP): $(NEWFANGLE_SOURCE) 
2050 \backslash
2052 \end_layout
2054 \begin_layout Plain Layout
2056                            $(NEWFANGLE_SOURCES) ; 
2057 \backslash
2059 \end_layout
2061 \begin_layout Plain Layout
2063         echo > $(NEWFANGLE_SOURCE_STAMP)
2064 \end_layout
2066 \begin_layout Plain Layout
2068 clean_stamp: ; rm -f $(NEWFANGLE_SOURCE_STAMP)
2069 \end_layout
2071 \begin_layout Plain Layout
2073 clean: clean_stamp
2074 \end_layout
2076 \end_inset
2079 \end_layout
2081 \begin_layout Subsection
2082 Extracting C sources
2083 \end_layout
2085 \begin_layout Standard
2086 We compute 
2087 \begin_inset Flex CharStyle:Code
2088 status collapsed
2090 \begin_layout Plain Layout
2091 NEWFANGLE_SOURCES
2092 \end_layout
2094 \end_inset
2096  to hold the names of all the C source files defined in this document.
2097  We compute this only once, by means of := in assignent.
2098  The sed deletes the any <
2099 \begin_inset space \hspace*{}
2100 \length 0in
2101 \end_inset
2103 < and >
2104 \begin_inset space \hspace*{}
2105 \length 0in
2106 \end_inset
2108 > which may surround the roots names (for noroots compatibility).
2110 \end_layout
2112 \begin_layout Standard
2113 As we use chunk names beginning with ./ to denote top level fragments that
2114  should be extracted, we filter out all fragments that do not begin with
2115  ./
2116 \end_layout
2118 \begin_layout Chunk
2119 Makefile.inc-vars
2120 \end_layout
2122 \begin_layout Standard
2123 \begin_inset listings
2124 inline false
2125 status open
2127 \begin_layout Plain Layout
2129 NEWFANGLE_PREFIX:=
2130 \backslash
2132 \backslash
2134 \end_layout
2136 \begin_layout Plain Layout
2138 NEWFANGLE_SOURCES:=$(shell 
2139 \backslash
2141 \end_layout
2143 \begin_layout Plain Layout
2145   newfangle -r $(NEWFANGLE_SOURCE) |
2146 \backslash
2148 \end_layout
2150 \begin_layout Plain Layout
2152   sed -e 's/^[<][<]//;s/[>][>]$$//;/^$(NEWFANGLE_PREFIX)/!d' 
2153 \backslash
2155 \end_layout
2157 \begin_layout Plain Layout
2159       -e 's/^$(NEWFANGLE_PREFIX)/
2160 \backslash
2162 \backslash
2163 //' )
2164 \end_layout
2166 \begin_layout Plain Layout
2169 \end_layout
2171 \end_inset
2174 \end_layout
2176 \begin_layout Chunk
2177 Makefile.inc-targets
2178 \end_layout
2180 \begin_layout Standard
2181 \begin_inset listings
2182 inline false
2183 status open
2185 \begin_layout Plain Layout
2187 .PHONY: echo_newfangle_sources
2188 \end_layout
2190 \begin_layout Plain Layout
2192 echo_newfangle_sources: ; @echo $(NEWFANGLE_SOURCES)
2193 \end_layout
2195 \end_inset
2198 \end_layout
2200 \begin_layout Standard
2201 We define a convenient target called 
2202 \begin_inset Flex CharStyle:Code
2203 status collapsed
2205 \begin_layout Plain Layout
2206 newfangle_sources
2207 \end_layout
2209 \end_inset
2211  to re-extract the source if the LaTeX file has been updated.
2212 \end_layout
2214 \begin_layout Chunk
2215 Makefile.inc-targets
2216 \end_layout
2218 \begin_layout Standard
2219 \begin_inset listings
2220 inline false
2221 status open
2223 \begin_layout Plain Layout
2225 .PHONY: newfangle_sources
2226 \end_layout
2228 \begin_layout Plain Layout
2230 newfangle_sources: $(NEWFANGLE_SOURCE_STAMP)
2231 \end_layout
2233 \end_inset
2236 \end_layout
2238 \begin_layout Standard
2239 And also a convenient target to remove extracted sources.
2240 \end_layout
2242 \begin_layout Chunk
2243 Makefile.inc-targets
2244 \end_layout
2246 \begin_layout Standard
2247 \begin_inset listings
2248 inline false
2249 status open
2251 \begin_layout Plain Layout
2253 .PHONY: clean_newfangle_sources
2254 \end_layout
2256 \begin_layout Plain Layout
2258 clean_newfangle_sources: ; 
2259 \backslash
2261 \end_layout
2263 \begin_layout Plain Layout
2265         rm -f -- $(NEWFANGLE_SOURCE_STAMP) $(NEWFANGLE_SOURCES)
2266 \end_layout
2268 \end_inset
2271 \end_layout
2273 \begin_layout Standard
2274 This 
2275 \begin_inset Flex CharStyle:Code
2276 status collapsed
2278 \begin_layout Plain Layout
2279 if_extension
2280 \end_layout
2282 \end_inset
2284  macro takes 4 arguments: the filename (1), some extensions to match (2)
2285  and a some shell command to return if the filename matches the exentions
2286  (3), or not (4).
2287 \end_layout
2289 \begin_layout Chunk
2290 Makefile.inc-vars
2291 \end_layout
2293 \begin_layout Standard
2294 \begin_inset listings
2295 inline false
2296 status open
2298 \begin_layout Plain Layout
2300 if_extension=$(if $(findstring $(suffix $(1)),$(2)),$(3),$(4))
2301 \end_layout
2303 \end_inset
2306 \end_layout
2308 \begin_layout Standard
2309 For some source files like C files, we want to output the line number and
2310  filename of the original LaTeX document from which the source came.
2311 \end_layout
2313 \begin_layout Standard
2314 To make this easier we define the file extensions for which we want to do
2315  this.
2316 \end_layout
2318 \begin_layout Chunk
2319 Makefile.inc-vars
2320 \end_layout
2322 \begin_layout Standard
2323 \begin_inset listings
2324 inline false
2325 status open
2327 \begin_layout Plain Layout
2329 C_EXTENSIONS=.c .h
2330 \end_layout
2332 \end_inset
2335 \end_layout
2337 \begin_layout Standard
2338 We can then use the if_extensions macro to define a macro which expands
2339  out to the 
2340 \begin_inset Flex CharStyle:Code
2341 status collapsed
2343 \begin_layout Plain Layout
2345 \end_layout
2347 \end_inset
2349  option if newfangle is being invoked in a C source file, so that C compile
2350  errors will refer to the line number in the Lyx document.
2352 \end_layout
2354 \begin_layout Chunk
2355 Makefile.inc-vars
2356 \end_layout
2358 \begin_layout Standard
2359 \begin_inset listings
2360 inline false
2361 status open
2363 \begin_layout Plain Layout
2365 TABS=8
2366 \end_layout
2368 \begin_layout Plain Layout
2370 nf_line=-L -T$(TABS)
2371 \end_layout
2373 \begin_layout Plain Layout
2375 newfangle=newfangle 
2376 \backslash
2378 \end_layout
2380 \begin_layout Plain Layout
2382   $(call if_extension,$(2),$(C_EXTENSIONS),$(nf_line)) 
2383 \backslash
2385 \end_layout
2387 \begin_layout Plain Layout
2389     -R"$(2)" $(1)
2390 \end_layout
2392 \end_inset
2395 \end_layout
2397 \begin_layout Standard
2398 We can use a similar trick to define an 
2399 \emph on
2400 indent
2401 \emph default
2402  macro which takes just the filename as an argument and can return a pipeline
2403  stage calling the indent command.
2404  Indent can be turned off with 
2405 \begin_inset Flex CharStyle:Code
2406 status collapsed
2408 \begin_layout Plain Layout
2409 make newfangle_sources indent=
2410 \end_layout
2412 \end_inset
2415 \end_layout
2417 \begin_layout Chunk
2418 Makefile.inc-vars
2419 \end_layout
2421 \begin_layout Standard
2422 \begin_inset listings
2423 inline false
2424 status open
2426 \begin_layout Plain Layout
2428 indent_options=-npro -kr -i8 -ts8 -sob -l80 -ss -ncs
2429 \end_layout
2431 \begin_layout Plain Layout
2433 indent=$(call if_extension,$(1),$(C_EXTENSIONS),
2434 \backslash
2436 \end_layout
2438 \begin_layout Plain Layout
2440               | indent $(indent_options))
2441 \end_layout
2443 \end_inset
2446 \end_layout
2448 \begin_layout Standard
2449 We now define the pattern for extracting a file.
2450  The files are written using noweb's 
2451 \emph on
2452 cpif
2453 \begin_inset Foot
2454 status collapsed
2456 \begin_layout Plain Layout
2458 \emph on
2459 So you still need noweb installed in order to use cpif
2460 \end_layout
2462 \end_inset
2465 \begin_inset Note Note
2466 status collapsed
2468 \begin_layout Plain Layout
2470 \emph on
2471 Write an awk version
2472 \end_layout
2474 \end_inset
2477 \emph default
2478  so that the file timestamp will not be touched if the contents haven't
2479  changed.
2480  This avoids the need to rebuild the entire project because of a typographical
2481  change in the documentation, or if only a few C source files have changed.
2482 \end_layout
2484 \begin_layout Chunk
2485 Makefile.inc-vars
2486 \end_layout
2488 \begin_layout Standard
2489 \begin_inset listings
2490 inline false
2491 status open
2493 \begin_layout Plain Layout
2495 newfangle_extract=@mkdir -p $(dir $(1)) && 
2496 \backslash
2498 \end_layout
2500 \begin_layout Plain Layout
2502   $(call newfangle,$(2),$(1)) > "$(1).tmp" && 
2503 \backslash
2505 \end_layout
2507 \begin_layout Plain Layout
2509   cat "$(1).tmp" $(indent) | cpif "$(1)" 
2510 \backslash
2512 \end_layout
2514 \begin_layout Plain Layout
2516   && rm -- "$(1).tmp" || 
2517 \backslash
2519 \end_layout
2521 \begin_layout Plain Layout
2523   (echo error newfangling $(1) from $(2) ; exit 1)
2524 \end_layout
2526 \end_inset
2529 \end_layout
2531 \begin_layout Standard
2532 We define a target which will extract or update all sources.
2533  To do this we first defined a makefile template that can do this for any
2534  source file in the LaTeX document.
2535 \end_layout
2537 \begin_layout Chunk
2538 Makefile.inc-vars
2539 \end_layout
2541 \begin_layout Standard
2542 \begin_inset listings
2543 inline false
2544 status open
2546 \begin_layout Plain Layout
2548 define NEWFANGLE_template
2549 \end_layout
2551 \begin_layout Plain Layout
2553   $(1): $(2); 
2554 \backslash
2556 \end_layout
2558 \begin_layout Plain Layout
2560     $$(call newfangle_extract,$(1),$(2))
2561 \end_layout
2563 \begin_layout Plain Layout
2565   NEWFANGLE_TARGETS+=$(1)
2566 \end_layout
2568 \begin_layout Plain Layout
2570 endef
2571 \end_layout
2573 \end_inset
2576 \end_layout
2578 \begin_layout Standard
2579 We then enumerate the discovered 
2580 \begin_inset Flex CharStyle:Code
2581 status collapsed
2583 \begin_layout Plain Layout
2584 NEWTANGLE_SOURCES
2585 \end_layout
2587 \end_inset
2589  to generate a makefile rule for each one using the makefile template we
2590  defined above.
2591 \end_layout
2593 \begin_layout Chunk
2594 Makefile.inc-targets
2595 \end_layout
2597 \begin_layout Standard
2598 \begin_inset listings
2599 inline false
2600 status open
2602 \begin_layout Plain Layout
2604 $(foreach source,$(NEWFANGLE_SOURCES),
2605 \backslash
2607 \end_layout
2609 \begin_layout Plain Layout
2611   $(eval $(call NEWFANGLE_template,$(source),$(NEWFANGLE_SOURCE))) 
2612 \backslash
2614 \end_layout
2616 \begin_layout Plain Layout
2619 \end_layout
2621 \end_inset
2624 \end_layout
2626 \begin_layout Standard
2627 These will all be built with NEWFANGLE_SOURCE_STAMP.
2628 \end_layout
2630 \begin_layout Standard
2631 We also remove the generated sources on a 
2632 \emph on
2633 make distclean
2634 \emph default
2636 \end_layout
2638 \begin_layout Chunk
2639 Makefile.inc-targets
2640 \end_layout
2642 \begin_layout Standard
2643 \begin_inset listings
2644 inline false
2645 status open
2647 \begin_layout Plain Layout
2649 _distclean: clean_newfangle_sources
2650 \end_layout
2652 \end_inset
2655 \end_layout
2657 \begin_layout Subsection
2658 Extracting Documentation
2659 \end_layout
2661 \begin_layout Standard
2662 We then identify the intermediate stages of the documentation and their
2663  build and clean targets.
2664 \end_layout
2666 \begin_layout Subsubsection
2667 Running pdflatex
2668 \end_layout
2670 \begin_layout Standard
2671 We produce a pdf file from the tex file.
2672 \end_layout
2674 \begin_layout Chunk
2675 Makefile.inc-vars
2676 \end_layout
2678 \begin_layout Standard
2679 \begin_inset listings
2680 inline false
2681 status open
2683 \begin_layout Plain Layout
2685 NEWFANGLE_PDF=$(TEX_SOURCE:.tex=.pdf)
2686 \end_layout
2688 \end_inset
2691 \end_layout
2693 \begin_layout Standard
2694 We run pdflatex twice to be sure that the contents and aux files are up
2695  to date.
2696  We certainly are required to run pdflatex twice if these files do not exist!
2697 \end_layout
2699 \begin_layout Chunk
2700 Makefile.inc-targets
2701 \end_layout
2703 \begin_layout Standard
2704 \begin_inset listings
2705 inline false
2706 status open
2708 \begin_layout Plain Layout
2710 $(NEWFANGLE_PDF): $(TEX_SOURCE); pdflatex $< && pdflatex $<
2711 \end_layout
2713 \begin_layout Plain Layout
2715 clean_pdf: ; rm -f -- $(NEWFANGLE_PDF) 
2716 \backslash
2718 \end_layout
2720 \begin_layout Plain Layout
2722                       $(TEX_SOURCE:.tex=.toc) 
2723 \backslash
2725 \end_layout
2727 \begin_layout Plain Layout
2729                       $(TEX_SOURCE:.tex=.log) 
2730 \backslash
2732 \end_layout
2734 \begin_layout Plain Layout
2736                       $(TEX_SOURCE:.tex=.aux)
2737 \end_layout
2739 \end_inset
2742 \end_layout
2744 \begin_layout Subsubsection
2745 The docs as a whole
2746 \end_layout
2748 \begin_layout Standard
2749 Currently we only build pdf as a final format, but NEWFANGLE_DOCS may later
2750  hold other output formats.
2751 \end_layout
2753 \begin_layout Chunk
2754 Makefile.inc-vars
2755 \end_layout
2757 \begin_layout Standard
2758 \begin_inset listings
2759 inline false
2760 status open
2762 \begin_layout Plain Layout
2764 NEWFANGLE_DOCS=$(NEWFANGLE_PDF)
2765 \end_layout
2767 \end_inset
2770 \end_layout
2772 \begin_layout Standard
2773 We also define newfangle_docs as a convenient phony target<
2774 \end_layout
2776 \begin_layout Chunk
2777 Makefile.inc-targets
2778 \end_layout
2780 \begin_layout Standard
2781 \begin_inset listings
2782 inline false
2783 status open
2785 \begin_layout Plain Layout
2787 .PHONY: newfangle_docs
2788 \end_layout
2790 \begin_layout Plain Layout
2792 newfangle_docs: $(NEWFANGLE_DOCS)
2793 \end_layout
2795 \begin_layout Plain Layout
2797 docs: newfangle_docs
2798 \end_layout
2800 \end_inset
2803 \end_layout
2805 \begin_layout Standard
2806 And define a convenient clean_noweb_docs which we add to the regular clean
2807  target
2808 \end_layout
2810 \begin_layout Chunk
2811 Makefile.inc-targets
2812 \end_layout
2814 \begin_layout Standard
2815 \begin_inset listings
2816 inline false
2817 status open
2819 \begin_layout Plain Layout
2821 .PHONEY: clean_newfangle_docs
2822 \end_layout
2824 \begin_layout Plain Layout
2826 clean_newfangle_docs: clean_tex clean_pdf
2827 \end_layout
2829 \begin_layout Plain Layout
2831 clean: clean_newfangle_docs
2832 \end_layout
2834 \begin_layout Plain Layout
2836 \end_layout
2838 \begin_layout Plain Layout
2840 distclean_newfangle_docs: clean_tex clean_newfangle_docs
2841 \end_layout
2843 \begin_layout Plain Layout
2845 distclean: clean distclean_newfangle_docs
2846 \end_layout
2848 \end_inset
2851 \end_layout
2853 \begin_layout Subsection
2854 Other helpers
2855 \end_layout
2857 \begin_layout Standard
2858 If Makefile.inc is included into Makefile, then extracted files can be updated
2859  with this command:
2860 \end_layout
2862 \begin_layout LyX-Code
2863 make newfangle_sources
2864 \end_layout
2866 \begin_layout Standard
2867 otherwise, with:
2868 \end_layout
2870 \begin_layout LyX-Code
2871 make -f Makefile.inc newfangle_sources
2872 \end_layout
2874 \begin_layout Part
2875 Source Code
2876 \end_layout
2878 \begin_layout Chapter
2879 Newfangle awk source code
2880 \end_layout
2882 \begin_layout Standard
2883 We use the copyright notice from chapter 
2884 \begin_inset CommandInset ref
2885 LatexCommand vref
2886 reference "cha:License"
2888 \end_inset
2891 \end_layout
2893 \begin_layout Chunk
2894 ./newfangle,language=awk,morestring=[b]{/},morekeywords=else
2895 \end_layout
2897 \begin_layout Standard
2898 \begin_inset listings
2899 inline false
2900 status open
2902 \begin_layout Plain Layout
2904 #! /usr/bin/awk -f
2905 \end_layout
2907 \begin_layout Plain Layout
2910 \backslash
2911 chunkref{gpl3-copyright}>
2912 \end_layout
2914 \end_inset
2917 \end_layout
2919 \begin_layout Standard
2920 We also use code from Arnold Robbins public domain getopt (1993 revision)
2921  defined in chapter 
2922 \begin_inset CommandInset ref
2923 LatexCommand ref
2924 reference "cha:getopt"
2926 \end_inset
2928 , and naturally want to attribute this appropriately.
2929 \end_layout
2931 \begin_layout Standard
2932 \begin_inset listings
2933 inline false
2934 status open
2936 \begin_layout Plain Layout
2938 \end_layout
2940 \begin_layout Plain Layout
2942 # NOTE: Arnold Robbins public domain getopt for awk is also used:
2943 \end_layout
2945 \begin_layout Plain Layout
2948 \backslash
2949 chunkref{getopt.awk-header}>
2950 \end_layout
2952 \begin_layout Plain Layout
2954 \end_layout
2956 \begin_layout Plain Layout
2959 \backslash
2960 chunkref{getopt.awk-getopt()}>
2961 \end_layout
2963 \begin_layout Plain Layout
2965 \end_layout
2967 \end_inset
2970 \end_layout
2972 \begin_layout Standard
2973 And include the following chunks
2974 \end_layout
2976 \begin_layout Chunk
2977 ./newfangle
2978 \end_layout
2980 \begin_layout Standard
2981 \begin_inset listings
2982 inline false
2983 status open
2985 \begin_layout Plain Layout
2988 \backslash
2989 chunkref{helper-functions}>
2990 \end_layout
2992 \begin_layout Plain Layout
2995 \backslash
2996 chunkref{mode-tracker}>
2997 \end_layout
2999 \begin_layout Plain Layout
3002 \backslash
3003 chunkref{chunk-storage-functions}>
3004 \end_layout
3006 \begin_layout Plain Layout
3009 \backslash
3010 chunkref{output_chunk_names()}>
3011 \end_layout
3013 \begin_layout Plain Layout
3016 \backslash
3017 chunkref{output_chunks()}>
3018 \end_layout
3020 \begin_layout Plain Layout
3023 \backslash
3024 chunkref{write_chunk()}>
3025 \end_layout
3027 \begin_layout Plain Layout
3030 \backslash
3031 chunkref{expand_chunk_args()}>
3032 \end_layout
3034 \begin_layout Plain Layout
3037 \backslash
3038 chunkref{begin}>
3039 \end_layout
3041 \begin_layout Plain Layout
3044 \backslash
3045 chunkref{recognize-chunk}>
3046 \end_layout
3048 \begin_layout Plain Layout
3051 \backslash
3052 chunkref{end}>
3053 \end_layout
3055 \end_inset
3058 \end_layout
3060 \begin_layout Section
3061 AWK tricks
3062 \end_layout
3064 \begin_layout Standard
3065 The portable way to erase an array in awk is to split the empty string,
3066  like this:
3067 \end_layout
3069 \begin_layout Chunk
3070 awk-delete-array,params=ARRAY
3071 \end_layout
3073 \begin_layout Standard
3074 \begin_inset listings
3075 inline false
3076 status open
3078 \begin_layout Plain Layout
3080 split("", ${ARRAY});
3081 \end_layout
3083 \end_inset
3086 \end_layout
3088 \begin_layout Chunk
3089 dump-array,params=ARRAY
3090 \end_layout
3092 \begin_layout Standard
3093 \begin_inset listings
3094 inline false
3095 status open
3097 \begin_layout Plain Layout
3099 print "
3100 \backslash
3101 nDump: ${ARRAY}
3102 \backslash
3103 n--------
3104 \backslash
3105 n" > "/dev/stderr";
3106 \end_layout
3108 \begin_layout Plain Layout
3110 for (_x in ${ARRAY}) {
3111 \end_layout
3113 \begin_layout Plain Layout
3115   print _x "=" ${ARRAY}[_x] "
3116 \backslash
3117 n" > "/dev/stderr";
3118 \end_layout
3120 \begin_layout Plain Layout
3123 \end_layout
3125 \begin_layout Plain Layout
3127 print "========
3128 \backslash
3129 n" > "/dev/stderr";
3130 \end_layout
3132 \end_inset
3135 \end_layout
3137 \begin_layout Chunk
3138 ,params=
3139 \end_layout
3141 \begin_layout Section
3142 Catching errors
3143 \end_layout
3145 \begin_layout Standard
3146 Fatal errors are issued with the error function:
3147 \end_layout
3149 \begin_layout Chunk
3150 error(),append=helper-functions
3151 \end_layout
3153 \begin_layout Standard
3154 \begin_inset listings
3155 inline false
3156 status open
3158 \begin_layout Plain Layout
3160 function error(message)
3161 \end_layout
3163 \begin_layout Plain Layout
3166 \end_layout
3168 \begin_layout Plain Layout
3170   print "ERROR: " FILENAME ":" FNR " " message > "/dev/stderr";
3171 \end_layout
3173 \begin_layout Plain Layout
3175   exit 1;
3176 \end_layout
3178 \begin_layout Plain Layout
3181 \end_layout
3183 \end_inset
3186 \end_layout
3188 \begin_layout Standard
3189 \begin_inset listings
3190 inline false
3191 status open
3193 \begin_layout Plain Layout
3195 function warning(message)
3196 \end_layout
3198 \begin_layout Plain Layout
3201 \end_layout
3203 \begin_layout Plain Layout
3205   print "WARNING: " FILENAME ":" FNR " " message > "/dev/stderr";
3206 \end_layout
3208 \begin_layout Plain Layout
3210   warnings++;
3211 \end_layout
3213 \begin_layout Plain Layout
3216 \end_layout
3218 \end_inset
3221 \end_layout
3223 \begin_layout Chapter
3224 lstlistings
3225 \end_layout
3227 \begin_layout Standard
3228 LaTeX arguments to lstlistings macros are a comma seperated list of key-value
3229  pairs.
3230  Values containing commas are enclosed in { braces }.
3231 \end_layout
3233 \begin_layout Standard
3234 We need a function that can parse such an expression and assign the values
3235  to an 
3236 \noun on
3238 \noun default
3239  associated array.
3240 \end_layout
3242 \begin_layout Standard
3243 A sample expressions is:
3244 \end_layout
3246 \begin_layout LyX-Code
3247 name=thomas, params={a, b}, something, something-else
3248 \end_layout
3250 \begin_layout Standard
3251 but we see that this is just a simpler form of this expression:
3252 \end_layout
3254 \begin_layout LyX-Code
3255 name=freddie, foo={bar=baz, quux={quirk, a=fleeg}}, etc
3256 \end_layout
3258 \begin_layout Standard
3259 And that it would be a good idea to use a recursive parser into a multi-dimensio
3260 nal hash
3261 \begin_inset Foot
3262 status collapsed
3264 \begin_layout Plain Layout
3265 as AWK doesn't have nested-hash support
3266 \end_layout
3268 \end_inset
3270 , resulting in:
3271 \end_layout
3273 \begin_layout Standard
3274 \begin_inset Tabular
3275 <lyxtabular version="3" rows="6" columns="2">
3276 <features>
3277 <column alignment="left" valignment="top" width="0">
3278 <column alignment="left" valignment="top" width="0">
3279 <row>
3280 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
3281 \begin_inset Text
3283 \begin_layout Plain Layout
3285 \end_layout
3287 \end_inset
3288 </cell>
3289 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
3290 \begin_inset Text
3292 \begin_layout Plain Layout
3293 value
3294 \end_layout
3296 \end_inset
3297 </cell>
3298 </row>
3299 <row>
3300 <cell alignment="left" valignment="top" topline="true" leftline="true" usebox="none">
3301 \begin_inset Text
3303 \begin_layout Plain Layout
3304 a[name]
3305 \end_layout
3307 \end_inset
3308 </cell>
3309 <cell alignment="left" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
3310 \begin_inset Text
3312 \begin_layout Plain Layout
3313 freddie
3314 \end_layout
3316 \end_inset
3317 </cell>
3318 </row>
3319 <row>
3320 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
3321 \begin_inset Text
3323 \begin_layout Plain Layout
3324 a[foo, bar]
3325 \end_layout
3327 \end_inset
3328 </cell>
3329 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
3330 \begin_inset Text
3332 \begin_layout Plain Layout
3334 \end_layout
3336 \end_inset
3337 </cell>
3338 </row>
3339 <row>
3340 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
3341 \begin_inset Text
3343 \begin_layout Plain Layout
3344 a[foo, quux, quirk]
3345 \end_layout
3347 \end_inset
3348 </cell>
3349 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
3350 \begin_inset Text
3352 \begin_layout Plain Layout
3354 \end_layout
3356 \end_inset
3357 </cell>
3358 </row>
3359 <row>
3360 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
3361 \begin_inset Text
3363 \begin_layout Plain Layout
3364 a[foo, quux, a]
3365 \end_layout
3367 \end_inset
3368 </cell>
3369 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
3370 \begin_inset Text
3372 \begin_layout Plain Layout
3373 fleeg
3374 \end_layout
3376 \end_inset
3377 </cell>
3378 </row>
3379 <row>
3380 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
3381 \begin_inset Text
3383 \begin_layout Plain Layout
3384 a[etc]
3385 \end_layout
3387 \end_inset
3388 </cell>
3389 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
3390 \begin_inset Text
3392 \begin_layout Plain Layout
3394 \end_layout
3396 \end_inset
3397 </cell>
3398 </row>
3399 </lyxtabular>
3401 \end_inset
3404 \end_layout
3406 \begin_layout Standard
3407 On reflection it seems that sometimes such nesting is not desirable, as
3408  the braces are also used to delimit values that contain commas --- we may
3409  consider that
3410 \end_layout
3412 \begin_layout LyX-Code
3413 name={williamson, freddie}
3414 \end_layout
3416 \begin_layout Standard
3417 should assign 
3418 \begin_inset Flex CharStyle:Code
3419 status collapsed
3421 \begin_layout Plain Layout
3422 williamson, freddie
3423 \end_layout
3425 \end_inset
3427  to 
3428 \begin_inset Flex CharStyle:Code
3429 status collapsed
3431 \begin_layout Plain Layout
3432 name
3433 \end_layout
3435 \end_inset
3437  --- so I may change this behaviour.
3438 \begin_inset Note Note
3439 status collapsed
3441 \begin_layout Plain Layout
3442 So change it
3443 \end_layout
3445 \end_inset
3448 \end_layout
3450 \begin_layout Standard
3451 Function 
3452 \begin_inset Flex Chunkref
3453 status collapsed
3455 \begin_layout Plain Layout
3456 get_chunk_args()
3457 \end_layout
3459 \end_inset
3461  will accept two paramters, 
3462 \begin_inset Flex CharStyle:Code
3463 status collapsed
3465 \begin_layout Plain Layout
3466 text
3467 \end_layout
3469 \end_inset
3471  being the text to parse, and 
3472 \begin_inset Flex CharStyle:Code
3473 status collapsed
3475 \begin_layout Plain Layout
3476 values
3477 \end_layout
3479 \end_inset
3481  being an array to receive the parsed values as described above.
3482  The optional parameter 
3483 \begin_inset Flex CharStyle:Code
3484 status collapsed
3486 \begin_layout Plain Layout
3487 path
3488 \end_layout
3490 \end_inset
3492  is used during recursion to build up the multi-dimensional array path.
3493 \end_layout
3495 \begin_layout Chunk
3496 ./newfangle
3497 \end_layout
3499 \begin_layout Standard
3500 \begin_inset listings
3501 inline false
3502 status open
3504 \begin_layout Plain Layout
3507 \backslash
3508 chunkref{get_chunk_args()}>
3509 \end_layout
3511 \end_inset
3514 \end_layout
3516 \begin_layout Chunk
3517 get_chunk_args()
3518 \end_layout
3520 \begin_layout Standard
3521 \begin_inset listings
3522 inline false
3523 status open
3525 \begin_layout Plain Layout
3527 function get_chunk_args(text, values,
3528 \end_layout
3530 \begin_layout Plain Layout
3532   # optional parameters
3533 \end_layout
3535 \begin_layout Plain Layout
3537   path, # hierarchical precursors
3538 \end_layout
3540 \begin_layout Plain Layout
3542   # local vars
3543 \end_layout
3545 \begin_layout Plain Layout
3547   a, name)
3548 \end_layout
3550 \end_inset
3553 \end_layout
3555 \begin_layout Standard
3556 The strategy is to parse the name, and then look for a value.
3557  If the value begins with a brace 
3558 \begin_inset Flex CharStyle:Code
3559 status collapsed
3561 \begin_layout Plain Layout
3563 \end_layout
3565 \end_inset
3567 , then we recurse and consume as much of the text as necessary, returning
3568  the remaining text when we encounter a leading close-brace 
3569 \begin_inset Flex CharStyle:Code
3570 status collapsed
3572 \begin_layout Plain Layout
3574 \end_layout
3576 \end_inset
3579  This being the strategy --- and executed in a loop --- we realise that
3580  we must first look for the closing brace (perhaps preceded by white space)
3581  in order to terminate the recursion, and returning remaining text.
3582 \end_layout
3584 \begin_layout Standard
3585 \begin_inset listings
3586 inline false
3587 status open
3589 \begin_layout Plain Layout
3592 \end_layout
3594 \begin_layout Plain Layout
3596   split("", next_chunk_args);
3597 \end_layout
3599 \begin_layout Plain Layout
3601   while(length(text)) {
3602 \end_layout
3604 \begin_layout Plain Layout
3606     if (match(text, "^ *}(.*)", a)) {
3607 \end_layout
3609 \begin_layout Plain Layout
3611       return a[1];
3612 \end_layout
3614 \begin_layout Plain Layout
3616     }
3617 \end_layout
3619 \begin_layout Plain Layout
3621     =<
3622 \backslash
3623 chunkref{parse-chunk-args}>
3624 \end_layout
3626 \begin_layout Plain Layout
3628   }
3629 \end_layout
3631 \begin_layout Plain Layout
3633   return text;
3634 \end_layout
3636 \begin_layout Plain Layout
3639 \end_layout
3641 \end_inset
3644 \end_layout
3646 \begin_layout Standard
3647 \begin_inset Note Note
3648 status collapsed
3650 \begin_layout Plain Layout
3651 Use BNF package here
3652 \end_layout
3654 \end_inset
3656 We can see that the text could be inspected with this regex:
3657 \end_layout
3659 \begin_layout Chunk
3660 parse-chunk-args
3661 \end_layout
3663 \begin_layout Standard
3664 \begin_inset listings
3665 inline false
3666 status open
3668 \begin_layout Plain Layout
3670 if (! match(text, " *([^,=]*[^,= ]) *(([,=]) *(([^,}]*) *,* *(.*))|)$", a))
3672 \end_layout
3674 \begin_layout Plain Layout
3676   return text;
3677 \end_layout
3679 \begin_layout Plain Layout
3682 \end_layout
3684 \end_inset
3687 \end_layout
3689 \begin_layout Standard
3690 and that 
3691 \begin_inset Flex CharStyle:Code
3692 status collapsed
3694 \begin_layout Plain Layout
3696 \end_layout
3698 \end_inset
3700  will have the following values:
3701 \end_layout
3703 \begin_layout Standard
3704 \begin_inset Tabular
3705 <lyxtabular version="3" rows="7" columns="2">
3706 <features>
3707 <column alignment="center" valignment="top" width="0">
3708 <column alignment="left" valignment="top" width="0">
3709 <row>
3710 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
3711 \begin_inset Text
3713 \begin_layout Plain Layout
3714 a[n]
3715 \end_layout
3717 \end_inset
3718 </cell>
3719 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
3720 \begin_inset Text
3722 \begin_layout Plain Layout
3723 assigned text
3724 \end_layout
3726 \end_inset
3727 </cell>
3728 </row>
3729 <row>
3730 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
3731 \begin_inset Text
3733 \begin_layout Plain Layout
3735 \end_layout
3737 \end_inset
3738 </cell>
3739 <cell alignment="left" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
3740 \begin_inset Text
3742 \begin_layout Plain Layout
3743 freddie
3744 \end_layout
3746 \end_inset
3747 </cell>
3748 </row>
3749 <row>
3750 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
3751 \begin_inset Text
3753 \begin_layout Plain Layout
3755 \end_layout
3757 \end_inset
3758 </cell>
3759 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
3760 \begin_inset Text
3762 \begin_layout Plain Layout
3763 =freddie, foo={bar=baz, quux={quirk, a=fleeg}}, etc
3764 \end_layout
3766 \end_inset
3767 </cell>
3768 </row>
3769 <row>
3770 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
3771 \begin_inset Text
3773 \begin_layout Plain Layout
3775 \end_layout
3777 \end_inset
3778 </cell>
3779 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
3780 \begin_inset Text
3782 \begin_layout Plain Layout
3784 \end_layout
3786 \end_inset
3787 </cell>
3788 </row>
3789 <row>
3790 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
3791 \begin_inset Text
3793 \begin_layout Plain Layout
3795 \end_layout
3797 \end_inset
3798 </cell>
3799 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
3800 \begin_inset Text
3802 \begin_layout Plain Layout
3803 freddie, foo={bar=baz, quux={quirk, a=fleeg}}, etc
3804 \end_layout
3806 \end_inset
3807 </cell>
3808 </row>
3809 <row>
3810 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
3811 \begin_inset Text
3813 \begin_layout Plain Layout
3815 \end_layout
3817 \end_inset
3818 </cell>
3819 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
3820 \begin_inset Text
3822 \begin_layout Plain Layout
3823 freddie
3824 \end_layout
3826 \end_inset
3827 </cell>
3828 </row>
3829 <row>
3830 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
3831 \begin_inset Text
3833 \begin_layout Plain Layout
3835 \end_layout
3837 \end_inset
3838 </cell>
3839 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
3840 \begin_inset Text
3842 \begin_layout Plain Layout
3843 , foo={bar=baz, quux={quirk, a=fleeg}}, etc
3844 \end_layout
3846 \end_inset
3847 </cell>
3848 </row>
3849 </lyxtabular>
3851 \end_inset
3854 \end_layout
3856 \begin_layout Standard
3857 a[3] will be either 
3858 \begin_inset Flex CharStyle:Code
3859 status collapsed
3861 \begin_layout Plain Layout
3863 \end_layout
3865 \end_inset
3867  or 
3868 \begin_inset Flex CharStyle:Code
3869 status collapsed
3871 \begin_layout Plain Layout
3873 \end_layout
3875 \end_inset
3877  and signify whether the option named in 
3878 \begin_inset Flex CharStyle:Code
3879 status collapsed
3881 \begin_layout Plain Layout
3882 a[1]
3883 \end_layout
3885 \end_inset
3887  has a value or not (respectively).
3888 \end_layout
3890 \begin_layout Standard
3891 If the option does have a value, then if the expression 
3892 \begin_inset Flex CharStyle:Code
3893 status collapsed
3895 \begin_layout Plain Layout
3896 substr(a[4],1,1)
3897 \end_layout
3899 \end_inset
3901  returns a brace 
3902 \begin_inset Flex CharStyle:Code
3903 status collapsed
3905 \begin_layout Plain Layout
3907 \end_layout
3909 \end_inset
3911  it will signify that we need to recurse:
3912 \end_layout
3914 \begin_layout Standard
3915 \begin_inset listings
3916 inline false
3917 status open
3919 \begin_layout Plain Layout
3921 name=a[1];
3922 \end_layout
3924 \begin_layout Plain Layout
3926 if (a[3] == "=") {
3927 \end_layout
3929 \begin_layout Plain Layout
3931   if (substr(a[4],1,1) == "{") {
3932 \end_layout
3934 \begin_layout Plain Layout
3936     text = get_chunk_args(substr(a[4],2), values, path name SUBSEP);
3937 \end_layout
3939 \begin_layout Plain Layout
3941   } else {
3942 \end_layout
3944 \begin_layout Plain Layout
3946     values[path name]=a[5];
3947 \end_layout
3949 \begin_layout Plain Layout
3951     text = a[6];
3952 \end_layout
3954 \begin_layout Plain Layout
3956   }
3957 \end_layout
3959 \begin_layout Plain Layout
3961 } else {
3962 \end_layout
3964 \begin_layout Plain Layout
3966   values[path name]="";
3967 \end_layout
3969 \begin_layout Plain Layout
3971   text = a[2];
3972 \end_layout
3974 \begin_layout Plain Layout
3977 \end_layout
3979 \end_inset
3982 \end_layout
3984 \begin_layout Standard
3985 We can test this function like this:
3986 \end_layout
3988 \begin_layout Chunk
3989 gca-test.awk
3990 \end_layout
3992 \begin_layout Standard
3993 \begin_inset listings
3994 inline false
3995 status open
3997 \begin_layout Plain Layout
4000 \backslash
4001 chunkref{get_chunk_args()}>
4002 \end_layout
4004 \begin_layout Plain Layout
4006 BEGIN {
4007 \end_layout
4009 \begin_layout Plain Layout
4011   SUBSEP=".";
4012 \end_layout
4014 \begin_layout Plain Layout
4016 \end_layout
4018 \begin_layout Plain Layout
4020   print get_chunk_args("name=freddie, foo={bar=baz, quux={quirk, a=fleeg}},
4021  etc", a);
4022 \end_layout
4024 \begin_layout Plain Layout
4026   for (b in a) {
4027 \end_layout
4029 \begin_layout Plain Layout
4031     print "a[" b "] => " a[b];
4032 \end_layout
4034 \begin_layout Plain Layout
4036   }
4037 \end_layout
4039 \begin_layout Plain Layout
4042 \end_layout
4044 \end_inset
4047 \end_layout
4049 \begin_layout Standard
4050 which should give this output:
4051 \end_layout
4053 \begin_layout Chunk
4054 gca-test.awk-results
4055 \end_layout
4057 \begin_layout Standard
4058 \begin_inset listings
4059 inline false
4060 status open
4062 \begin_layout Plain Layout
4064 a[foo.quux.quirk] => 
4065 \end_layout
4067 \begin_layout Plain Layout
4069 a[foo.quux.a] => fleeg
4070 \end_layout
4072 \begin_layout Plain Layout
4074 a[foo.bar] => baz
4075 \end_layout
4077 \begin_layout Plain Layout
4079 a[etc] => 
4080 \end_layout
4082 \begin_layout Plain Layout
4084 a[name] => freddie
4085 \end_layout
4087 \end_inset
4090 \end_layout
4092 \begin_layout Chapter
4093 Expanding chunk arguments
4094 \end_layout
4096 \begin_layout Standard
4097 \begin_inset CommandInset label
4098 LatexCommand label
4099 name "cha:Chunk Arguments"
4101 \end_inset
4104 \begin_inset Note Note
4105 status open
4107 \begin_layout Plain Layout
4108 Explain this in the documentation section too
4109 \end_layout
4111 \end_inset
4113 As an extension to many literate-programming styles, newfangle permits code
4114  chunks to take parameters and thus operate somewhat like C pre-processor
4115  macros, or like C++ templates.
4116 \end_layout
4118 \begin_layout Standard
4119 Chunk parameters are declared with a chunk argument called 
4120 \begin_inset Flex CharStyle:Code
4121 status collapsed
4123 \begin_layout Plain Layout
4124 params
4125 \end_layout
4127 \end_inset
4129 , which holds a semi-colon separated list of parameters, like this:
4130 \end_layout
4132 \begin_layout LyX-Code
4133 achunk,language=C,params=name;address
4134 \end_layout
4136 \begin_layout Standard
4137 When such a chunk is included, the arguments are expressed in round brackets
4138  as a comma separated list of optional arguments:
4139 \begin_inset Note Note
4140 status open
4142 \begin_layout Plain Layout
4143 We ought to support qouting in {} like ({Jones, John}, Jones@example.com)
4144 \end_layout
4146 \end_inset
4149 \end_layout
4151 \begin_layout LyX-Code
4153 \backslash
4154 chunkref{achunk}(John Jones, jones@example.com)
4155 \end_layout
4157 \begin_layout Standard
4158 Within the body of a chunk, the parameters are referred to with: 
4159 \begin_inset Flex CharStyle:Code
4160 status collapsed
4162 \begin_layout Plain Layout
4163 ${name}
4164 \end_layout
4166 \end_inset
4168  and 
4169 \begin_inset Flex CharStyle:Code
4170 status collapsed
4172 \begin_layout Plain Layout
4173 ${address}
4174 \end_layout
4176 \end_inset
4179  There is a strong case that a LaTeX style notation should be used, like
4181 \backslash
4182 param{name} which would be expressed in the listing as =<
4183 \backslash
4184 param{name}> and be rendered as 
4185 \begin_inset listings
4186 inline true
4187 status open
4189 \begin_layout Plain Layout
4192 \backslash
4193 param{name}>
4194 \end_layout
4196 \end_inset
4199  Such notation would make me go blind, but I do intend to adopt it.
4200 \end_layout
4202 \begin_layout Standard
4203 We therefore need a function 
4204 \begin_inset Flex CharStyle:Code
4205 status collapsed
4207 \begin_layout Plain Layout
4208 expand_chunk_args
4209 \end_layout
4211 \end_inset
4213  which will take a block of text, a list of permitted parameters and the
4214  arguments which must substitute for the parameters.
4216 \end_layout
4218 \begin_layout Standard
4219 We also need to be able to parse a parameter list into an array of parameters.
4220 \end_layout
4222 \begin_layout Section
4223 Parsing argument lists
4224 \end_layout
4226 \begin_layout Standard
4227 An argument list may be as simple as in 
4228 \begin_inset Flex CharStyle:Code
4229 status collapsed
4231 \begin_layout Plain Layout
4233 \backslash
4234 chunkref{pull}(thing, otherthing)
4235 \end_layout
4237 \end_inset
4239  or as complex as:
4240 \end_layout
4242 \begin_layout LyX-Code
4244 \backslash
4245 chunkref{pull}(things[x, y], get_other_things(a, "(all)")) 
4246 \end_layout
4248 \begin_layout Standard
4249 --- which for all it's commas and quotes and parenthesis represents only
4250  two parameters: 
4251 \begin_inset Flex CharStyle:Code
4252 status collapsed
4254 \begin_layout Plain Layout
4255 things[x, y]
4256 \end_layout
4258 \end_inset
4260  and 
4261 \begin_inset Flex CharStyle:Code
4262 status collapsed
4264 \begin_layout Plain Layout
4265 get_other_things(a, "(all)")
4266 \end_layout
4268 \end_inset
4271 \end_layout
4273 \begin_layout Standard
4274 If we simply split parameter list on commas, then the comma in 
4275 \begin_inset Flex CharStyle:Code
4276 status collapsed
4278 \begin_layout Plain Layout
4279 things[x,y]
4280 \end_layout
4282 \end_inset
4284  would split into two seperate arguments: 
4285 \begin_inset Flex CharStyle:Code
4286 status collapsed
4288 \begin_layout Plain Layout
4289 things[x
4290 \end_layout
4292 \end_inset
4294  and 
4295 \begin_inset Flex CharStyle:Code
4296 status collapsed
4298 \begin_layout Plain Layout
4300 \end_layout
4302 \end_inset
4304 --- neither of which make sense on their own.
4305 \end_layout
4307 \begin_layout Standard
4308 One way to prevent this would be by refusing to split text between maching
4309  delimiters, such as 
4310 \begin_inset Flex CharStyle:Code
4311 status collapsed
4313 \begin_layout Plain Layout
4315 \end_layout
4317 \end_inset
4320 \begin_inset Flex CharStyle:Code
4321 status collapsed
4323 \begin_layout Plain Layout
4325 \end_layout
4327 \end_inset
4330 \begin_inset Flex CharStyle:Code
4331 status collapsed
4333 \begin_layout Plain Layout
4335 \end_layout
4337 \end_inset
4340 \begin_inset Flex CharStyle:Code
4341 status collapsed
4343 \begin_layout Plain Layout
4345 \end_layout
4347 \end_inset
4350 \begin_inset Flex CharStyle:Code
4351 status collapsed
4353 \begin_layout Plain Layout
4355 \end_layout
4357 \end_inset
4360 \begin_inset Flex CharStyle:Code
4361 status collapsed
4363 \begin_layout Plain Layout
4365 \end_layout
4367 \end_inset
4369  and most likely also 
4370 \begin_inset Flex CharStyle:Code
4371 status collapsed
4373 \begin_layout Plain Layout
4375 \end_layout
4377 \end_inset
4380 \begin_inset Flex CharStyle:Code
4381 status collapsed
4383 \begin_layout Plain Layout
4385 \end_layout
4387 \end_inset
4389  and 
4390 \begin_inset Flex CharStyle:Code
4391 status collapsed
4393 \begin_layout Plain Layout
4395 \end_layout
4397 \end_inset
4400 \begin_inset Flex CharStyle:Code
4401 status collapsed
4403 \begin_layout Plain Layout
4405 \end_layout
4407 \end_inset
4410  Of course this also makes it impossible to pass such mis-matched code fragments
4411  as parameters, but I think that it would be hard for readers to cope with
4412  authors who would pass such code unbalanced fragments as chunk parameters
4413 \begin_inset Foot
4414 status collapsed
4416 \begin_layout Plain Layout
4417 I know that I couldn't cope with users doing such things, and although the
4418  GPL3 license prevents me from actually forbidding anyone from trying, if
4419  they want it to work they'll have to write the code themselves and not
4420  expect any support from me.
4421 \end_layout
4423 \end_inset
4426 \end_layout
4428 \begin_layout Standard
4429 Unfortunately, the full set of matching delimiters may vary from language
4430  to language.
4431  In certain C++ template contexts, 
4432 \begin_inset Flex CharStyle:Code
4433 status collapsed
4435 \begin_layout Plain Layout
4437 \end_layout
4439 \end_inset
4441  and 
4442 \begin_inset Flex CharStyle:Code
4443 status collapsed
4445 \begin_layout Plain Layout
4447 \end_layout
4449 \end_inset
4451  would count as delimiters, and yet in other contexts they would not.
4452 \end_layout
4454 \begin_layout Standard
4455 This puts me in the unfortunate position of having to parse-somewhat all
4456  programming languages without knowing what they are!
4457 \end_layout
4459 \begin_layout Standard
4460 This is the basis of mode-tracking, by tracking parse-modes for different
4461  languages.
4462 \end_layout
4464 \begin_layout Subsection
4465 Parse modes
4466 \end_layout
4468 \begin_layout Standard
4469 In the C language there are a few parse modes, affecting the interpretation
4470  of characters.
4471 \end_layout
4473 \begin_layout Standard
4474 One parse mode is the strings mode.
4475  The string mode is commenced by an un-escaped quotation mark 
4476 \begin_inset Flex CharStyle:Code
4477 status collapsed
4479 \begin_layout Plain Layout
4481 \end_layout
4483 \end_inset
4485  and terminated by the same.
4486  Within the string mode, only one additional mode can be commenced, it is
4487  the backslash mode 
4488 \begin_inset Flex CharStyle:Code
4489 status collapsed
4491 \begin_layout Plain Layout
4493 \backslash
4495 \end_layout
4497 \end_inset
4499 , which is always terminated by the folloing character.
4500 \end_layout
4502 \begin_layout Standard
4503 Other modes are 
4504 \begin_inset Flex CharStyle:Code
4505 status collapsed
4507 \begin_layout Plain Layout
4509 \end_layout
4511 \end_inset
4513  which is terminated by a 
4514 \begin_inset Flex CharStyle:Code
4515 status collapsed
4517 \begin_layout Plain Layout
4519 \end_layout
4521 \end_inset
4523  (unless it occurs in a string).
4524 \end_layout
4526 \begin_layout Standard
4527 Consider this line of C code:
4528 \end_layout
4530 \begin_layout Standard
4531 \begin_inset Formula $\mathtt{things\underbrace{[\mathtt{x,\ y}]}_{1.\ [\ mode},\ get\_other\_things\underbrace{(\mathtt{a,\overbrace{"\mathtt{(all)}"}})}_{2.\ (\ mode}^{3.\ "\ mode}}$
4532 \end_inset
4535 \end_layout
4537 \begin_layout Standard
4538 Mode nesting prevents the close parenthesis in quote mode (part 3) from
4539  terminating the parenthesis mode (part 2).
4540 \end_layout
4542 \begin_layout Standard
4543 Each language has a set of modes, the default mode being the null mode.
4544  Each mode can lead to other modes.
4545 \end_layout
4547 \begin_layout Standard
4548 Modes are stored in a multi-dimensional hash.
4549  The first index is the language, and the second is the mode-identifier.
4550  The third indexes are terminators, and optionally, submodes, and delimiters.
4551 \end_layout
4553 \begin_layout Standard
4554 A useful set of mode definitions for a nameless general C-type language
4555  is show here.
4556  (Don't be confused by the double backslash escaping needed in awk.
4557  One set of escaping is for the string, and the second set of escaping is
4558  for the regex).
4559 \end_layout
4561 \begin_layout Chunk
4562 mode-definitions
4563 \end_layout
4565 \begin_layout Standard
4566 \begin_inset listings
4567 inline false
4568 status open
4570 \begin_layout Plain Layout
4572 modes["", "",  "delimeters"]=" *, *";
4573 \end_layout
4575 \begin_layout Plain Layout
4577 modes["", "",  "submodes" ]="
4578 \backslash
4580 \backslash
4582 \backslash
4584 \backslash
4586 \backslash
4587 "|'|{|
4588 \backslash
4590 \backslash
4592 \backslash
4594 \backslash
4596 \backslash
4598 \backslash
4600 \end_layout
4602 \end_inset
4605 \end_layout
4607 \begin_layout Standard
4608 In the default mode, a comma surrounded by un-important white space is a
4609  delimiter of language items; and should pass this test:
4610 \end_layout
4612 \begin_layout Chunk
4613 test:mode-definitions
4614 \end_layout
4616 \begin_layout Standard
4617 \begin_inset listings
4618 inline false
4619 status open
4621 \begin_layout Plain Layout
4623 parse_chunk_args("", "1,2,3)", a, "(");
4624 \end_layout
4626 \begin_layout Plain Layout
4628 if (a[1] != "1") e++;
4629 \end_layout
4631 \begin_layout Plain Layout
4633 if (a[2] != "2") e++;
4634 \end_layout
4636 \begin_layout Plain Layout
4638 if (a[3] != "3") e++;
4639 \end_layout
4641 \begin_layout Plain Layout
4643 if (length(a) != 3) e++;
4644 \end_layout
4646 \begin_layout Plain Layout
4649 \backslash
4650 chunkref{pca-test.awk:summary}>
4651 \end_layout
4653 \begin_layout Plain Layout
4655 \end_layout
4657 \begin_layout Plain Layout
4659 parse_chunk_args("", "joe, red", a, "(");
4660 \end_layout
4662 \begin_layout Plain Layout
4664 if (a[1] != "joe") e++;
4665 \end_layout
4667 \begin_layout Plain Layout
4669 if (a[2] != "red") e++;
4670 \end_layout
4672 \begin_layout Plain Layout
4674 if (length(a) != 2) e++;
4675 \end_layout
4677 \begin_layout Plain Layout
4680 \backslash
4681 chunkref{pca-test.awk:summary}>
4682 \end_layout
4684 \begin_layout Plain Layout
4686 \end_layout
4688 \begin_layout Plain Layout
4690 parse_chunk_args("", "${colour}", a, "(");
4691 \end_layout
4693 \begin_layout Plain Layout
4695 if (a[1] != "${colour}") e++;
4696 \end_layout
4698 \begin_layout Plain Layout
4700 if (length(a) != 1) e++;
4701 \end_layout
4703 \begin_layout Plain Layout
4706 \backslash
4707 chunkref{pca-test.awk:summary}>
4708 \end_layout
4710 \end_inset
4713 \end_layout
4715 \begin_layout Standard
4716 Nested modes are identified by a backslash, a double or single quote, various
4717  bracket styles or a /* comment.
4718 \end_layout
4720 \begin_layout Standard
4721 For each of these sub-modes modes we must also identify at a mode terminator,
4722  and any sub-modes or delimiters that may be entered
4723 \begin_inset Foot
4724 status collapsed
4726 \begin_layout Plain Layout
4727 Because we are using the sub-mode characters as the mode identifier it means
4728  we can't currently have a mode character dependant on it's context; i.e.
4730 \begin_inset Flex CharStyle:Code
4731 status collapsed
4733 \begin_layout Plain Layout
4735 \end_layout
4737 \end_inset
4739  can't behave differently when it is inside 
4740 \begin_inset Flex CharStyle:Code
4741 status collapsed
4743 \begin_layout Plain Layout
4745 \end_layout
4747 \end_inset
4750 \end_layout
4752 \end_inset
4755 \end_layout
4757 \begin_layout Subsubsection
4758 Backslash
4759 \end_layout
4761 \begin_layout Standard
4762 The backslash mode has no submodes or delimiters, and is terminated by any
4763  character.
4764  Note that we are not so much interested in evaluating or interpolating
4765  content as we are in delineating content.
4766  It is no matter that a double backslash (
4767 \begin_inset Flex CharStyle:Code
4768 status collapsed
4770 \begin_layout Plain Layout
4772 \backslash
4774 \backslash
4776 \end_layout
4778 \end_inset
4780 ) may represent a single backslash while a backslash-newline may represent
4781  white space, but it does matter that the newline in a backslash newline
4782  should not be able to terminate a C pre-processor statement; and so the
4783  newline will be consumed by the backslash however it is to be interpreted.
4784 \end_layout
4786 \begin_layout Chunk
4787 mode-definitions
4788 \end_layout
4790 \begin_layout Standard
4791 \begin_inset listings
4792 inline false
4793 status open
4795 \begin_layout Plain Layout
4797 modes["", "
4798 \backslash
4800 \backslash
4801 ", "terminators"]=".";
4802 \end_layout
4804 \end_inset
4807 \end_layout
4809 \begin_layout Subsubsection
4810 Strings
4811 \end_layout
4813 \begin_layout Standard
4814 In a string we have one special mode, which is the backslash.
4815  This may escape an embedded quote and prevent us thinking that it should
4816  terminate the string.
4817  Otherwise, the string will be terminated by a double-quote.
4818 \end_layout
4820 \begin_layout Standard
4821 \begin_inset listings
4822 inline false
4823 status open
4825 \begin_layout Plain Layout
4827 modes["", "
4828 \backslash
4829 "", "submodes" ]="
4830 \backslash
4832 \backslash
4834 \backslash
4836 \backslash
4838 \end_layout
4840 \begin_layout Plain Layout
4842 modes["", "
4843 \backslash
4844 "", "terminators"]="
4845 \backslash
4847 \end_layout
4849 \end_inset
4852 \end_layout
4854 \begin_layout Standard
4855 Working strings should pass this test:
4856 \end_layout
4858 \begin_layout Chunk
4859 test:mode-definitions
4860 \end_layout
4862 \begin_layout Standard
4863 \begin_inset listings
4864 inline false
4865 status open
4867 \begin_layout Plain Layout
4869 parse_chunk_args("", "say 
4870 \backslash
4871 "I said, 
4872 \backslash
4874 \backslash
4876 \backslash
4877 "Hello, how are you
4878 \backslash
4880 \backslash
4882 \backslash
4884 \backslash
4885 ", for me", a, "(");
4886 \end_layout
4888 \begin_layout Plain Layout
4890 if (a[1] != "say 
4891 \backslash
4892 "I said, 
4893 \backslash
4895 \backslash
4897 \backslash
4898 "Hello, how are you
4899 \backslash
4901 \backslash
4903 \backslash
4905 \backslash
4906 "") e++;
4907 \end_layout
4909 \begin_layout Plain Layout
4911 if (a[2] != "for me") e++;
4912 \end_layout
4914 \begin_layout Plain Layout
4916 if (length(a) != 2) e++;
4917 \end_layout
4919 \begin_layout Plain Layout
4922 \backslash
4923 chunkref{pca-test.awk:summary}>
4924 \end_layout
4926 \end_inset
4929 \end_layout
4931 \begin_layout Chunk
4932 mode-definitions
4933 \end_layout
4935 \begin_layout Standard
4936 \begin_inset listings
4937 inline false
4938 status open
4940 \begin_layout Plain Layout
4942 modes["", "{",  "submodes" ]="
4943 \backslash
4945 \backslash
4947 \backslash
4949 \backslash
4951 \backslash
4952 "|{|
4953 \backslash
4955 \backslash
4957 \backslash
4959 \backslash
4960 [|'|/
4961 \backslash
4963 \backslash
4965 \end_layout
4967 \begin_layout Plain Layout
4969 modes["", "{",  "delimeters"]=" *, *";
4970 \end_layout
4972 \begin_layout Plain Layout
4974 modes["", "{",  "terminators"]="}";
4975 \end_layout
4977 \begin_layout Plain Layout
4979 modes["", "[",  "submodes" ]="
4980 \backslash
4982 \backslash
4984 \backslash
4986 \backslash
4988 \backslash
4989 "|{|
4990 \backslash
4992 \backslash
4994 \backslash
4996 \backslash
4997 [|'|/
4998 \backslash
5000 \backslash
5002 \end_layout
5004 \begin_layout Plain Layout
5006 modes["", "[",  "delimiters"]=" *, *";
5007 \end_layout
5009 \begin_layout Plain Layout
5011 modes["", "[",  "terminators"]="
5012 \backslash
5014 \backslash
5016 \end_layout
5018 \begin_layout Plain Layout
5020 modes["", "(",  "submodes" ]="
5021 \backslash
5023 \backslash
5025 \backslash
5027 \backslash
5029 \backslash
5030 "|{|
5031 \backslash
5033 \backslash
5035 \backslash
5037 \backslash
5038 [|'|/
5039 \backslash
5041 \backslash
5043 \end_layout
5045 \begin_layout Plain Layout
5047 modes["", "(",  "delimiters"]=" *, *";
5048 \end_layout
5050 \begin_layout Plain Layout
5052 modes["", "(",  "terminators"]="
5053 \backslash
5055 \backslash
5057 \end_layout
5059 \begin_layout Plain Layout
5061 modes["", "'",  "submodes" ]="
5062 \backslash
5064 \backslash
5066 \backslash
5068 \backslash
5070 \end_layout
5072 \begin_layout Plain Layout
5074 modes["", "'",  "terminators"]="'";
5075 \end_layout
5077 \begin_layout Plain Layout
5079 modes["", "/*", "submodes"]="
5080 \backslash
5082 \backslash
5083 */";
5084 \end_layout
5086 \begin_layout Plain Layout
5088 modes["", "/*", "terminators"]="*/";
5089 \end_layout
5091 \begin_layout Plain Layout
5093 modes["", "//", "submodes"]="
5094 \backslash
5096 \end_layout
5098 \begin_layout Plain Layout
5100 modes["", "//", "terminators"]="
5101 \backslash
5103 \end_layout
5105 \begin_layout Plain Layout
5107 modes["", "",   "submodes" ]="
5108 \backslash
5110 \backslash
5112 \backslash
5114 \backslash
5116 \backslash
5117 "|{|
5118 \backslash
5120 \backslash
5122 \backslash
5124 \backslash
5125 [|'|/
5126 \backslash
5128 \backslash
5130 \end_layout
5132 \end_inset
5135 \end_layout
5137 \begin_layout Standard
5138 This test should also pass.
5139 \end_layout
5141 \begin_layout Chunk
5142 test:mode-definitions
5143 \end_layout
5145 \begin_layout Standard
5146 \begin_inset listings
5147 inline false
5148 status open
5150 \begin_layout Plain Layout
5152 parse_chunk_args("", "things[x, y], get_other_things(a, 
5153 \backslash
5154 "(all)
5155 \backslash
5156 "), 99", a, "(");
5157 \end_layout
5159 \begin_layout Plain Layout
5161 if (a[1] != "things[x, y]") e++;
5162 \end_layout
5164 \begin_layout Plain Layout
5166 if (a[2] != "get_other_things(a, 
5167 \backslash
5168 "(all)
5169 \backslash
5170 ")") e++;
5171 \end_layout
5173 \begin_layout Plain Layout
5175 if (a[3] != "99") e++;
5176 \end_layout
5178 \begin_layout Plain Layout
5180 if (length(a) != 3) e++;
5181 \end_layout
5183 \begin_layout Plain Layout
5186 \backslash
5187 chunkref{pca-test.awk:summary}>
5188 \end_layout
5190 \end_inset
5193 \end_layout
5195 \begin_layout Chunk
5196 parse_chunk_args
5197 \end_layout
5199 \begin_layout Standard
5200 \begin_inset listings
5201 inline false
5202 status open
5204 \begin_layout Plain Layout
5206 function parse_chunk_args(language, text, values,
5207 \end_layout
5209 \begin_layout Plain Layout
5211   # optional parameters
5212 \end_layout
5214 \begin_layout Plain Layout
5216   mode, 
5217 \end_layout
5219 \begin_layout Plain Layout
5221   path, # hierarchical precursors
5222 \end_layout
5224 \begin_layout Plain Layout
5226   stack, # delimiters to be matched
5227 \end_layout
5229 \begin_layout Plain Layout
5231   submodes,
5232 \end_layout
5234 \begin_layout Plain Layout
5236   # local vars
5237 \end_layout
5239 \begin_layout Plain Layout
5241   c, a, part, item, name, result, new_values, new_mode, delimiters)
5242 \end_layout
5244 \begin_layout Plain Layout
5247 \end_layout
5249 \begin_layout Plain Layout
5251 #  split(chunklet_parts[2], call_chunk_args, " *, *");
5252 \end_layout
5254 \end_inset
5257 \end_layout
5259 \begin_layout Standard
5260 The strategy is to parse the name, and then look for a value.
5261  If the value begins with a brace 
5262 \begin_inset Flex CharStyle:Code
5263 status collapsed
5265 \begin_layout Plain Layout
5267 \end_layout
5269 \end_inset
5271 , then we recurse and consume as much of the text as necessary, returning
5272  the remaining text when we encounter a leading close-brace 
5273 \begin_inset Flex CharStyle:Code
5274 status collapsed
5276 \begin_layout Plain Layout
5278 \end_layout
5280 \end_inset
5283  This being the strategy --- and executed in a loop --- we realise that
5284  we must first look for the closing brace (perhaps preceded by white space)
5285  in order to terminate the recursion, and returning remaining text.
5286 \end_layout
5288 \begin_layout Standard
5289 \begin_inset listings
5290 inline false
5291 status open
5293 \begin_layout Plain Layout
5295   submodes=modes[language, mode, "submodes"];
5296 \end_layout
5298 \begin_layout Plain Layout
5300   if ((language, mode, "delimiters") in modes) {
5301 \end_layout
5303 \begin_layout Plain Layout
5305     delimiters = modes[language, mode, "delimiters"];
5306 \end_layout
5308 \begin_layout Plain Layout
5310     submodes=submodes "|" delimiters;
5311 \end_layout
5313 \begin_layout Plain Layout
5315   }
5316 \end_layout
5318 \begin_layout Plain Layout
5320   if ((language, mode, "terminators") in modes) {
5321 \end_layout
5323 \begin_layout Plain Layout
5325     submodes=submodes "|" modes[language, mode, "terminators"];
5326 \end_layout
5328 \begin_layout Plain Layout
5330   }
5331 \end_layout
5333 \begin_layout Plain Layout
5335   while(length(text)) {
5336 \end_layout
5338 \begin_layout Plain Layout
5340     if (match(text, "(" submodes ")", a)) {
5341 \end_layout
5343 \begin_layout Plain Layout
5345       if (RLENGTH<1) {
5346 \end_layout
5348 \begin_layout Plain Layout
5350         error("Internal error, matched zero length submode, should be impossible
5351  - likely regex computation error");
5352 \end_layout
5354 \begin_layout Plain Layout
5356       }
5357 \end_layout
5359 \begin_layout Plain Layout
5361       part = substr(text, 1, RSTART -1);
5362 \end_layout
5364 \begin_layout Plain Layout
5366       item = item part;
5367 \end_layout
5369 \begin_layout Plain Layout
5371       if (match(a[1], "^" modes[language, mode, "terminators"] "$")) {
5372 \end_layout
5374 \begin_layout Plain Layout
5376        values[++c] = item;
5377 \end_layout
5379 \begin_layout Plain Layout
5381        return result item a[1];
5382 \end_layout
5384 \begin_layout Plain Layout
5386       }
5387 \end_layout
5389 \begin_layout Plain Layout
5391       if (match(a[1], "^" delimiters "$")) {
5392 \end_layout
5394 \begin_layout Plain Layout
5396         values[++c] = item;
5397 \end_layout
5399 \begin_layout Plain Layout
5401         text = substr(text, 1 + length(part) + length(a[1]));
5402 \end_layout
5404 \begin_layout Plain Layout
5406         result = result item a[1];
5407 \end_layout
5409 \begin_layout Plain Layout
5411         item = "";
5412 \end_layout
5414 \begin_layout Plain Layout
5416       } else if ((language, a[1], "terminators") in modes) {
5417 \end_layout
5419 \begin_layout Plain Layout
5421         new_mode=a[1];
5422 \end_layout
5424 \begin_layout Plain Layout
5426         #check if new_mode is defined
5427 \end_layout
5429 \begin_layout Plain Layout
5431         text = substr(text, 1 + length(part) + length(a[1]));
5432 \end_layout
5434 \begin_layout Plain Layout
5436         s = parse_chunk_args(language, text,new_values,new_mode);
5437 \end_layout
5439 \begin_layout Plain Layout
5441         text = substr(text, length(s) +1);
5442 \end_layout
5444 \begin_layout Plain Layout
5446         item = item a[1] s;
5447 \end_layout
5449 \begin_layout Plain Layout
5451       } else {
5452 \end_layout
5454 \begin_layout Plain Layout
5456         error(sprintf("Submode '%s' set unknown mode in text: %s", new_mode,
5457  text));
5458 \end_layout
5460 \begin_layout Plain Layout
5462         text = substr(text, 1 + length(part) + length(a[1]));
5463 \end_layout
5465 \begin_layout Plain Layout
5467       }
5468 \end_layout
5470 \begin_layout Plain Layout
5472     } else {
5473 \end_layout
5475 \begin_layout Plain Layout
5477       result = result item text;
5478 \end_layout
5480 \begin_layout Plain Layout
5482       values[++c] = text;
5483 \end_layout
5485 \begin_layout Plain Layout
5487       text = "";
5488 \end_layout
5490 \begin_layout Plain Layout
5492       item = "";
5493 \end_layout
5495 \begin_layout Plain Layout
5497     }
5498 \end_layout
5500 \begin_layout Plain Layout
5502   }
5503 \end_layout
5505 \begin_layout Plain Layout
5507   if (length(item)) values[++c] = item;
5508 \end_layout
5510 \begin_layout Plain Layout
5512   return result item;
5513 \end_layout
5515 \begin_layout Plain Layout
5518 \end_layout
5520 \end_inset
5523 \end_layout
5525 \begin_layout Standard
5526 We can test this function like this:
5527 \end_layout
5529 \begin_layout Chunk
5530 pca-test.awk
5531 \end_layout
5533 \begin_layout Standard
5534 \begin_inset listings
5535 inline false
5536 status open
5538 \begin_layout Plain Layout
5541 \backslash
5542 chunkref{error()}>
5543 \end_layout
5545 \begin_layout Plain Layout
5548 \backslash
5549 chunkref{parse_chunk_args()}>
5550 \end_layout
5552 \begin_layout Plain Layout
5554 BEGIN {
5555 \end_layout
5557 \begin_layout Plain Layout
5559   SUBSEP=".";
5560 \end_layout
5562 \begin_layout Plain Layout
5564   =<
5565 \backslash
5566 chunkref{mode-definitions}>
5567 \end_layout
5569 \begin_layout Plain Layout
5571 \end_layout
5573 \begin_layout Plain Layout
5575   =<
5576 \backslash
5577 chunkref{test:mode-definitions}>
5578 \end_layout
5580 \begin_layout Plain Layout
5583 \end_layout
5585 \end_inset
5588 \end_layout
5590 \begin_layout Chunk
5591 pca-test.awk:summary
5592 \end_layout
5594 \begin_layout Standard
5595 \begin_inset listings
5596 inline false
5597 status open
5599 \begin_layout Plain Layout
5601 if (e) {
5602 \end_layout
5604 \begin_layout Plain Layout
5606   printf "Failed " e
5607 \end_layout
5609 \begin_layout Plain Layout
5611   for (b in a) {
5612 \end_layout
5614 \begin_layout Plain Layout
5616     print "a[" b "] => " a[b];
5617 \end_layout
5619 \begin_layout Plain Layout
5621   }
5622 \end_layout
5624 \begin_layout Plain Layout
5626 } else {
5627 \end_layout
5629 \begin_layout Plain Layout
5631   print "Passed"
5632 \end_layout
5634 \begin_layout Plain Layout
5637 \end_layout
5639 \begin_layout Plain Layout
5641 split("", a);
5642 \end_layout
5644 \begin_layout Plain Layout
5646 e=0;
5647 \end_layout
5649 \end_inset
5652 \end_layout
5654 \begin_layout Standard
5655 which should give this output:
5656 \end_layout
5658 \begin_layout Chunk
5659 pca-test.awk-results
5660 \end_layout
5662 \begin_layout Standard
5663 \begin_inset listings
5664 inline false
5665 status open
5667 \begin_layout Plain Layout
5669 a[foo.quux.quirk] => 
5670 \end_layout
5672 \begin_layout Plain Layout
5674 a[foo.quux.a] => fleeg
5675 \end_layout
5677 \begin_layout Plain Layout
5679 a[foo.bar] => baz
5680 \end_layout
5682 \begin_layout Plain Layout
5684 a[etc] => 
5685 \end_layout
5687 \begin_layout Plain Layout
5689 a[name] => freddie
5690 \end_layout
5692 \end_inset
5695 \end_layout
5697 \begin_layout Section
5698 Expanding parameters
5699 \end_layout
5701 \begin_layout Standard
5702 \begin_inset CommandInset label
5703 LatexCommand label
5704 name "Here-we-split"
5706 \end_inset
5708 Here we split the text on 
5709 \begin_inset Flex CharStyle:Code
5710 status collapsed
5712 \begin_layout Plain Layout
5714 \end_layout
5716 \end_inset
5718  which means that all parts except the first will begin with a parameter
5719  name.
5720  The split function will consume the literal 
5721 \begin_inset Flex CharStyle:Code
5722 status collapsed
5724 \begin_layout Plain Layout
5726 \end_layout
5728 \end_inset
5730  in each case.
5731 \end_layout
5733 \begin_layout Chunk
5734 expand_chunk_args()
5735 \end_layout
5737 \begin_layout Standard
5738 \begin_inset listings
5739 inline false
5740 status open
5742 \begin_layout Plain Layout
5744 function expand_chunk_args(text, params, args,  
5745 \end_layout
5747 \begin_layout Plain Layout
5749   p, text_array, next_text, v, t, l)
5750 \end_layout
5752 \begin_layout Plain Layout
5755 \end_layout
5757 \begin_layout Plain Layout
5759   if (split(text, text_array, "
5760 \backslash
5762 \backslash
5763 ${")) {
5764 \end_layout
5766 \begin_layout Plain Layout
5768     =<
5769 \backslash
5770 chunkref{substitute-chunk-args}>
5771 \end_layout
5773 \begin_layout Plain Layout
5775   }
5776 \end_layout
5778 \begin_layout Plain Layout
5780   return text;
5781 \end_layout
5783 \begin_layout Plain Layout
5786 \end_layout
5788 \end_inset
5791 \end_layout
5793 \begin_layout Standard
5794 First, we produce an associative array of substitution values indexed by
5795  parameter names
5796 \end_layout
5798 \begin_layout Chunk
5799 substitute-chunk-args
5800 \end_layout
5802 \begin_layout Standard
5803 \begin_inset listings
5804 inline false
5805 status open
5807 \begin_layout Plain Layout
5809 for(p in params) {
5810 \end_layout
5812 \begin_layout Plain Layout
5814   v[params[p]]=args[p];
5815 \end_layout
5817 \begin_layout Plain Layout
5820 \end_layout
5822 \end_inset
5825 \end_layout
5827 \begin_layout Standard
5828 We accumulate substituted text in the variable 
5829 \begin_inset Flex CharStyle:Code
5830 status collapsed
5832 \begin_layout Plain Layout
5833 text
5834 \end_layout
5836 \end_inset
5839  As the first part of the split function is the part before the delimiter
5840  --- which is 
5841 \begin_inset Flex CharStyle:Code
5842 status collapsed
5844 \begin_layout Plain Layout
5846 \end_layout
5848 \end_inset
5850  in our case --- this part will never contain a parameter reference, so
5851  we assign this directly to the result kept in 
5852 \begin_inset Flex CharStyle:Code
5853 status collapsed
5855 \begin_layout Plain Layout
5856 $text
5857 \end_layout
5859 \end_inset
5862 \begin_inset listings
5863 inline false
5864 status open
5866 \begin_layout Plain Layout
5868 text=text_array[1];
5869 \end_layout
5871 \end_inset
5874 \end_layout
5876 \begin_layout Standard
5877 We then iterate over the remaining values in the array
5878 \begin_inset Foot
5879 status collapsed
5881 \begin_layout Plain Layout
5882 I don't know why I think that it will enumerate the array in order, but
5883  it seems to work
5884 \end_layout
5886 \end_inset
5889 \begin_inset Note Note
5890 status collapsed
5892 \begin_layout Plain Layout
5893 So fix it or porve it
5894 \end_layout
5896 \end_inset
5898 , and substitute each reference for it's argument.
5899 \end_layout
5901 \begin_layout Standard
5902 \begin_inset listings
5903 inline false
5904 status open
5906 \begin_layout Plain Layout
5908 for(t in text_array) if (t>1) {
5909 \end_layout
5911 \begin_layout Plain Layout
5913   =<
5914 \backslash
5915 chunkref{substitute-chunk-arg}>
5916 \end_layout
5918 \begin_layout Plain Layout
5921 \end_layout
5923 \end_inset
5926 \end_layout
5928 \begin_layout Standard
5929 After the split on 
5930 \begin_inset Flex CharStyle:Code
5931 status collapsed
5933 \begin_layout Plain Layout
5935 \end_layout
5937 \end_inset
5939  a valid parameter reference will consist of valid parameter name terminated
5940  by a close-brace 
5941 \begin_inset Flex CharStyle:Code
5942 status collapsed
5944 \begin_layout Plain Layout
5946 \end_layout
5948 \end_inset
5951  A valid character name begins with the underscore or a letter, and may
5952  contain letters, digits or underscores.
5953 \end_layout
5955 \begin_layout Standard
5956 A valid looking reference that is not actually the name of a parameter will
5957  be and not substituted.
5958  This is good because there is nothing to substitute anyway, and it avoids
5959  clashes when writing code for languages where ${\SpecialChar \ldots{}
5960 } is a valid construct
5961  --- such constructs will not be interfered with unless the parameter name
5962  also matches.
5963 \end_layout
5965 \begin_layout Chunk
5966 substitute-chunk-arg
5967 \end_layout
5969 \begin_layout Standard
5970 \begin_inset listings
5971 inline false
5972 status open
5974 \begin_layout Plain Layout
5976 if (match(text_array[t], "^([a-zA-Z_][a-zA-Z0-9_]*)}", l) &&
5977 \end_layout
5979 \begin_layout Plain Layout
5981     l[1] in v) 
5982 \end_layout
5984 \begin_layout Plain Layout
5987 \end_layout
5989 \begin_layout Plain Layout
5991   text = text v[l[1]] substr(text_array[t], length(l[1])+2);
5992 \end_layout
5994 \begin_layout Plain Layout
5996 } else {
5997 \end_layout
5999 \begin_layout Plain Layout
6001   text = text "${" text_array[t];
6002 \end_layout
6004 \begin_layout Plain Layout
6007 \end_layout
6009 \end_inset
6012 \end_layout
6014 \begin_layout Chapter
6015 Recognizing Chunks
6016 \end_layout
6018 \begin_layout Standard
6019 Newfangle recognizes noweb chunks, but as we also want better LaTeX integration
6020  we will recognize any of these:
6021 \end_layout
6023 \begin_layout Itemize
6024 notangle chunks matching the pattern 
6025 \begin_inset Flex CharStyle:Code
6026 status collapsed
6028 \begin_layout Plain Layout
6030 \begin_inset space \hspace*{}
6031 \length 0in
6032 \end_inset
6034 <.*?>
6035 \begin_inset space \hspace*{}
6036 \length 0in
6037 \end_inset
6040 \end_layout
6042 \end_inset
6045 \end_layout
6047 \begin_layout Itemize
6048 a chunks beginning with 
6049 \begin_inset Flex CharStyle:Code
6050 status collapsed
6052 \begin_layout Plain Layout
6054 \backslash
6055 begin{lstlistings}
6056 \end_layout
6058 \end_inset
6060 , possibly with 
6061 \backslash
6062 Chunk{\SpecialChar \ldots{}
6063 } on the previous line
6064 \end_layout
6066 \begin_layout Itemize
6067 an older form I have used, beginning with 
6068 \begin_inset Flex CharStyle:Code
6069 status collapsed
6071 \begin_layout Plain Layout
6073 \backslash
6074 begin{Chunk}[options]
6075 \end_layout
6077 \end_inset
6079  --- also more suitable for plain LaTeX users
6080 \begin_inset Foot
6081 status collapsed
6083 \begin_layout Plain Layout
6084 Is there such a thing as plain LaTeX?
6085 \end_layout
6087 \end_inset
6090 \end_layout
6092 \begin_layout Section
6093 Chunk start
6094 \end_layout
6096 \begin_layout Standard
6097 The variable 
6098 \begin_inset Flex CharStyle:Code
6099 status collapsed
6101 \begin_layout Plain Layout
6102 chunking
6103 \end_layout
6105 \end_inset
6107  is used to signify that we are processing a code chunk and not document.
6108  In such a state, input lines will be assigned to the current chunk; otherwise
6109  they are ignored.
6110 \end_layout
6112 \begin_layout Subsection
6113 lstlistings
6114 \end_layout
6116 \begin_layout Standard
6117 Our current scheme is to recognize the new lstlisting chunks, but these
6118  may be preceded by a 
6119 \begin_inset Flex CharStyle:Code
6120 status collapsed
6122 \begin_layout Plain Layout
6124 \backslash
6125 Chunk
6126 \end_layout
6128 \end_inset
6130  command which in LyX is a more convenient way to pass the chunk name to
6131  the 
6132 \begin_inset Flex CharStyle:Code
6133 status collapsed
6135 \begin_layout Plain Layout
6137 \backslash
6138 begin{lstlistings}
6139 \end_layout
6141 \end_inset
6143  command, and a more visible way to specify other 
6144 \begin_inset Flex CharStyle:Code
6145 status collapsed
6147 \begin_layout Plain Layout
6148 lstset
6149 \end_layout
6151 \end_inset
6153  settings.
6154 \end_layout
6156 \begin_layout Standard
6157 The arguments to the 
6158 \begin_inset Flex CharStyle:Code
6159 status collapsed
6161 \begin_layout Plain Layout
6163 \backslash
6164 Chunk
6165 \end_layout
6167 \end_inset
6169  command are a name, and then a comma-seperated list of key-value pairs
6170  after the manner of 
6171 \begin_inset Flex CharStyle:Code
6172 status collapsed
6174 \begin_layout Plain Layout
6176 \backslash
6177 lstset
6178 \end_layout
6180 \end_inset
6183  (In fact within the LaTeX 
6184 \begin_inset Flex CharStyle:Code
6185 status collapsed
6187 \begin_layout Plain Layout
6189 \backslash
6190 Chunk
6191 \end_layout
6193 \end_inset
6195  macro (section 
6196 \begin_inset CommandInset ref
6197 LatexCommand ref
6198 reference "sub:The-chunk-command"
6200 \end_inset
6202 ) the text 
6203 \begin_inset Flex CharStyle:Code
6204 status collapsed
6206 \begin_layout Plain Layout
6207 name=
6208 \end_layout
6210 \end_inset
6212  is prefixed to the argument which is then literally passed to 
6213 \begin_inset Flex CharStyle:Code
6214 status collapsed
6216 \begin_layout Plain Layout
6218 \backslash
6219 lstset
6220 \end_layout
6222 \end_inset
6225 \end_layout
6227 \begin_layout Chunk
6228 recognize-chunk
6229 \end_layout
6231 \begin_layout Standard
6232 \begin_inset listings
6233 inline false
6234 status open
6236 \begin_layout Plain Layout
6239 \backslash
6241 \backslash
6242 Chunk{/ {
6243 \end_layout
6245 \begin_layout Plain Layout
6247   if (match($0, "^
6248 \backslash
6250 \backslash
6252 \backslash
6254 \backslash
6255 Chunk{ *([^ ,}]*),?(.*)}", line)) {
6256 \end_layout
6258 \begin_layout Plain Layout
6260     next_chunk_name = line[1];
6261 \end_layout
6263 \begin_layout Plain Layout
6265     get_chunk_args(line[2], next_chunk_args);
6266 \end_layout
6268 \begin_layout Plain Layout
6270   }
6271 \end_layout
6273 \begin_layout Plain Layout
6275   next;
6276 \end_layout
6278 \begin_layout Plain Layout
6281 \end_layout
6283 \end_inset
6286 \end_layout
6288 \begin_layout Standard
6289 We also make a basic attempt to parse the name out of the 
6290 \begin_inset Flex CharStyle:Code
6291 status collapsed
6293 \begin_layout Plain Layout
6295 \backslash
6296 lstlistings[name=
6297 \begin_inset space \hspace{}
6298 \length 0in
6299 \end_inset
6301 chunk-name]
6302 \end_layout
6304 \end_inset
6306  text, otherwise we fall back to the name found in the previous chunk command.
6307  This attempt is very basic and doesn't support commas or spaces or square
6308  brackets as part of the chunkname.
6309  We also recognize 
6310 \begin_inset Flex CharStyle:Code
6311 status collapsed
6313 \begin_layout Plain Layout
6315 \backslash
6316 begin{Chunk}
6317 \end_layout
6319 \end_inset
6321  which is convenient for some users
6322 \begin_inset Foot
6323 status open
6325 \begin_layout Plain Layout
6326 but not yet supported in the LaTeX macros
6327 \end_layout
6329 \end_inset
6332 \begin_inset Note Note
6333 status collapsed
6335 \begin_layout Plain Layout
6336 Add noweave support
6337 \end_layout
6339 \end_inset
6342 \end_layout
6344 \begin_layout Standard
6345 \begin_inset listings
6346 inline false
6347 status open
6349 \begin_layout Plain Layout
6352 \backslash
6354 \backslash
6355 begin{lstlisting}|^
6356 \backslash
6358 \backslash
6359 begin{Chunk}/ {
6360 \end_layout
6362 \begin_layout Plain Layout
6364   if (match($0, "}.*[[,] *name= *{? *([^], }]*)", line)) {
6365 \end_layout
6367 \begin_layout Plain Layout
6369     new_chunk(line[1]);
6370 \end_layout
6372 \begin_layout Plain Layout
6374   } else {
6375 \end_layout
6377 \begin_layout Plain Layout
6379     new_chunk(next_chunk_name, next_chunk_args);
6380 \end_layout
6382 \begin_layout Plain Layout
6384   }
6385 \end_layout
6387 \begin_layout Plain Layout
6389   chunking=1;
6390 \end_layout
6392 \begin_layout Plain Layout
6394   next;
6395 \end_layout
6397 \begin_layout Plain Layout
6400 \end_layout
6402 \end_inset
6405 \end_layout
6407 \begin_layout Subsection
6408 Noweb
6409 \end_layout
6411 \begin_layout Standard
6412 We recognize notangle style chunks too:
6413 \end_layout
6415 \begin_layout Chunk
6416 recognize-chunk
6417 \end_layout
6419 \begin_layout Standard
6420 \begin_inset listings
6421 inline false
6422 status open
6424 \begin_layout Plain Layout
6426 /^[<]<.*[>]>=/ {
6427 \end_layout
6429 \begin_layout Plain Layout
6431   if (match($0, "^[<]<(.*)[>]>= *$", line)) {
6432 \end_layout
6434 \begin_layout Plain Layout
6436     chunking=1;
6437 \end_layout
6439 \begin_layout Plain Layout
6441     notangle_mode=1;
6442 \end_layout
6444 \begin_layout Plain Layout
6446     new_chunk(line[1]);
6447 \end_layout
6449 \begin_layout Plain Layout
6451     next;
6452 \end_layout
6454 \begin_layout Plain Layout
6456   }
6457 \end_layout
6459 \begin_layout Plain Layout
6462 \end_layout
6464 \end_inset
6467 \end_layout
6469 \begin_layout Section
6470 Chunk end
6471 \end_layout
6473 \begin_layout Standard
6474 Likewise, we need to recognize when a chunk ends.
6475 \end_layout
6477 \begin_layout Subsection
6478 lstlistings
6479 \end_layout
6481 \begin_layout Standard
6482 The 
6483 \begin_inset Flex CharStyle:Code
6484 status collapsed
6486 \begin_layout Plain Layout
6488 \end_layout
6490 \end_inset
6492  in 
6493 \begin_inset Flex CharStyle:Code
6494 status collapsed
6496 \begin_layout Plain Layout
6497 [e]end{lislisting}
6498 \end_layout
6500 \end_inset
6502  is surrounded by square brackets so that when this document is processed,
6503  this chunk doesn't terminate early when the lstlistings package recognizes
6504  it's own end-string! 
6505 \begin_inset Note Greyedout
6506 status collapsed
6508 \begin_layout Plain Layout
6509 This doesn't make sense as the regex is anchored with ^, which this line
6510  does not begin with!
6511 \end_layout
6513 \end_inset
6516 \begin_inset Note Note
6517 status open
6519 \begin_layout Plain Layout
6520 No, it doesn't.
6521 \end_layout
6523 \end_inset
6526 \end_layout
6528 \begin_layout Chunk
6529 recognize-chunk
6530 \end_layout
6532 \begin_layout Standard
6533 \begin_inset listings
6534 inline false
6535 status open
6537 \begin_layout Plain Layout
6540 \backslash
6542 \backslash
6543 [e]nd{lstlisting}|^
6544 \backslash
6546 \backslash
6547 [e]nd{Chunk}/ {
6548 \end_layout
6550 \begin_layout Plain Layout
6552   chunking=0;
6553 \end_layout
6555 \begin_layout Plain Layout
6557   active_chunk="";
6558 \end_layout
6560 \begin_layout Plain Layout
6562   next;
6563 \end_layout
6565 \begin_layout Plain Layout
6568 \end_layout
6570 \end_inset
6573 \end_layout
6575 \begin_layout Subsection
6576 noweb
6577 \end_layout
6579 \begin_layout Chunk
6580 recognize-chunk
6581 \end_layout
6583 \begin_layout Standard
6584 \begin_inset listings
6585 inline false
6586 status open
6588 \begin_layout Plain Layout
6590 /^@ *$/ {
6591 \end_layout
6593 \begin_layout Plain Layout
6595   chunking=0;
6596 \end_layout
6598 \begin_layout Plain Layout
6600   active_chunk="";
6601 \end_layout
6603 \begin_layout Plain Layout
6606 \end_layout
6608 \end_inset
6611 \end_layout
6613 \begin_layout Standard
6614 All other recognizers are only of effect if we are chunking; there's no
6615  point in looking at lines if they aren't part of a chunk, so we just ignore
6616  them as efficiently as we can.
6617 \end_layout
6619 \begin_layout Chunk
6620 recognize-chunk
6621 \end_layout
6623 \begin_layout Standard
6624 \begin_inset listings
6625 inline false
6626 status open
6628 \begin_layout Plain Layout
6630 ! chunking { next; }
6631 \end_layout
6633 \end_inset
6636 \end_layout
6638 \begin_layout Section
6639 Chunk contents
6640 \end_layout
6642 \begin_layout Standard
6643 Chunk contents are any lines read while 
6644 \begin_inset Flex CharStyle:Code
6645 status collapsed
6647 \begin_layout Plain Layout
6648 chunking
6649 \end_layout
6651 \end_inset
6653  is true.
6654  Some chunk contents are special in that they refer to other chunks, and
6655  will be replaced by the contents of these chunks when the file is generated.
6656 \end_layout
6658 \begin_layout Standard
6659 \begin_inset CommandInset label
6660 LatexCommand label
6661 name "sub:ORS-chunk-text"
6663 \end_inset
6665 We add the output record separator 
6666 \begin_inset Flex CharStyle:Code
6667 status collapsed
6669 \begin_layout Plain Layout
6671 \end_layout
6673 \end_inset
6675  to the line now, because we will set 
6676 \begin_inset Flex CharStyle:Code
6677 status collapsed
6679 \begin_layout Plain Layout
6681 \end_layout
6683 \end_inset
6685  to the empty string when we generate the output
6686 \begin_inset Foot
6687 status collapsed
6689 \begin_layout Plain Layout
6690 So that we can print partial lines using 
6691 \begin_inset Flex CharStyle:Code
6692 status collapsed
6694 \begin_layout Plain Layout
6695 print
6696 \end_layout
6698 \end_inset
6700  instead of 
6701 \begin_inset Flex CharStyle:Code
6702 status collapsed
6704 \begin_layout Plain Layout
6705 printf
6706 \end_layout
6708 \end_inset
6711 \end_layout
6713 \end_inset
6716 \end_layout
6718 \begin_layout Chunk
6719 recognize-chunk
6720 \end_layout
6722 \begin_layout Standard
6723 \begin_inset listings
6724 inline false
6725 status open
6727 \begin_layout Plain Layout
6729 length(active_chunk) {
6730 \end_layout
6732 \begin_layout Plain Layout
6734   =<
6735 \backslash
6736 chunkref{process-chunk-tabs}>
6737 \end_layout
6739 \begin_layout Plain Layout
6741   =<
6742 \backslash
6743 chunkref{process-chunk}>
6744 \end_layout
6746 \begin_layout Plain Layout
6749 \end_layout
6751 \end_inset
6754 \end_layout
6756 \begin_layout Standard
6757 If a chunk just consisted of plain text, we could handle the chunk like
6758  this:
6759 \end_layout
6761 \begin_layout Chunk
6762 process-chunk-simple
6763 \end_layout
6765 \begin_layout Standard
6766 \begin_inset listings
6767 inline false
6768 status open
6770 \begin_layout Plain Layout
6772 chunk_line(active_chunk, $0 ORS);
6773 \end_layout
6775 \end_inset
6778 \end_layout
6780 \begin_layout Standard
6781 but in fact a chunk can include references to other chunks.
6782  Chunk includes are traditionally written as 
6783 \begin_inset Flex CharStyle:Code
6784 status collapsed
6786 \begin_layout Plain Layout
6787 <<chunk-name>>
6788 \end_layout
6790 \end_inset
6792 , but we support other variations.
6793 \end_layout
6795 \begin_layout Standard
6796 However, we also process tabs at this point, a tab at input can be replaced
6797  by a number of spaces defined by the 
6798 \begin_inset Flex CharStyle:Code
6799 status collapsed
6801 \begin_layout Plain Layout
6802 tabs
6803 \end_layout
6805 \end_inset
6807  variable, set by the 
6808 \begin_inset Flex CharStyle:Code
6809 status collapsed
6811 \begin_layout Plain Layout
6813 \end_layout
6815 \end_inset
6817  option.
6818  Of course this is poor tab behaviour, we should probably have the option
6819  to use proper counted tab-stops and process this on output.
6820 \end_layout
6822 \begin_layout Chunk
6823 process-chunk-tabs
6824 \end_layout
6826 \begin_layout Standard
6827 \begin_inset listings
6828 inline false
6829 status open
6831 \begin_layout Plain Layout
6833 if (length(tabs)) {
6834 \end_layout
6836 \begin_layout Plain Layout
6838   gsub("
6839 \backslash
6840 t", tabs);
6841 \end_layout
6843 \begin_layout Plain Layout
6846 \end_layout
6848 \end_inset
6851 \end_layout
6853 \begin_layout Subsection
6854 \begin_inset CommandInset label
6855 LatexCommand label
6856 name "sub:lstlistings-includes"
6858 \end_inset
6860 lstlistings
6861 \end_layout
6863 \begin_layout Standard
6864 If 
6865 \begin_inset Flex CharStyle:Code
6866 status collapsed
6868 \begin_layout Plain Layout
6870 \backslash
6871 lstset{escapeinside={=<}{>}}
6872 \end_layout
6874 \end_inset
6876  is set, then we can use 
6877 \begin_inset Flex CharStyle:Code
6878 status collapsed
6880 \begin_layout Plain Layout
6882 \backslash
6883 chunkref{
6884 \begin_inset space \hspace{}
6885 \length 0in
6886 \end_inset
6888 chunk-name}>
6889 \end_layout
6891 \end_inset
6893  in listings.
6894  The sequence 
6895 \begin_inset Flex CharStyle:Code
6896 status collapsed
6898 \begin_layout Plain Layout
6900 \end_layout
6902 \end_inset
6904  was chosen because:
6905 \end_layout
6907 \begin_layout Enumerate
6908 it is a better mnemonic than 
6909 \begin_inset Flex CharStyle:Code
6910 status collapsed
6912 \begin_layout Plain Layout
6913 <<chunk-name>>
6914 \end_layout
6916 \end_inset
6918  in that the = sign signifies equivalent or substitutability, 
6919 \end_layout
6921 \begin_layout Enumerate
6922 and because =< is not valid in C or in any language I can think of 
6923 \end_layout
6925 \begin_layout Enumerate
6926 and also because lstlistings doesn't like 
6927 \begin_inset Flex CharStyle:Code
6928 status collapsed
6930 \begin_layout Plain Layout
6932 \end_layout
6934 \end_inset
6936  as an end delimiter for the 
6937 \emph on
6938 texcl
6939 \emph default
6940  escape, so we must make do with a single 
6941 \begin_inset Flex CharStyle:Code
6942 status collapsed
6944 \begin_layout Plain Layout
6946 \end_layout
6948 \end_inset
6950 , which is better matched by 
6951 \begin_inset Flex CharStyle:Code
6952 status collapsed
6954 \begin_layout Plain Layout
6956 \end_layout
6958 \end_inset
6960  than 
6961 \begin_inset Flex CharStyle:Code
6962 status collapsed
6964 \begin_layout Plain Layout
6966 \end_layout
6968 \end_inset
6971 \end_layout
6973 \begin_layout Standard
6974 As each chunk line may contain more than one chunk include, we will split
6975  out chunk includes in an iterative fashion
6976 \begin_inset Foot
6977 status open
6979 \begin_layout Plain Layout
6980 Contrary to our use of 
6981 \begin_inset Flex CharStyle:Code
6982 status collapsed
6984 \begin_layout Plain Layout
6985 split
6986 \end_layout
6988 \end_inset
6990  when substituting parameters in chapter 
6991 \begin_inset CommandInset ref
6992 LatexCommand ref
6993 reference "Here-we-split"
6995 \end_inset
6998 \end_layout
7000 \end_inset
7003 \end_layout
7005 \begin_layout Standard
7006 First, as long as the chunk contains a 
7007 \begin_inset Flex CharStyle:Code
7008 status collapsed
7010 \begin_layout Plain Layout
7012 \backslash
7013 chunkref
7014 \end_layout
7016 \end_inset
7018  command we take as much as we can up to the first 
7019 \begin_inset Flex CharStyle:Code
7020 status collapsed
7022 \begin_layout Plain Layout
7024 \backslash
7025 chunkref
7026 \end_layout
7028 \end_inset
7030  command.
7031 \end_layout
7033 \begin_layout Chunk
7034 process-chunk
7035 \end_layout
7037 \begin_layout Standard
7038 \begin_inset listings
7039 inline false
7040 status open
7042 \begin_layout Plain Layout
7044 chunk = $0;
7045 \end_layout
7047 \begin_layout Plain Layout
7049 indent = 0;
7050 \end_layout
7052 \begin_layout Plain Layout
7054 while(match(chunk, 
7055 \end_layout
7057 \begin_layout Plain Layout
7059             "([=]<
7060 \backslash
7062 \backslash
7064 \backslash
7066 \backslash
7067 chunkref{([^}>]*)}(
7068 \backslash
7070 \backslash
7072 \backslash
7074 \backslash
7075 )|)>|<<([a-zA-Z_][-a-zA-Z0-9_]*)>>)", 
7076 \end_layout
7078 \begin_layout Plain Layout
7080             line)
7081 \backslash
7083 \end_layout
7085 \begin_layout Plain Layout
7087 ) {
7088 \end_layout
7090 \begin_layout Plain Layout
7092   chunklet = substr(chunk, 1, RSTART - 1);
7093 \end_layout
7095 \end_inset
7098 \end_layout
7100 \begin_layout Standard
7101 We keep track of the indent count, by counting the number of literal characters
7102  found.
7103  We can then preserve this indent on each output line when multi-line chunks
7104  are expanded.
7105 \end_layout
7107 \begin_layout Standard
7108 We then process this first part literal text, and set the chunk which is
7109  still to be processed to be the text after the 
7110 \begin_inset Flex CharStyle:Code
7111 status collapsed
7113 \begin_layout Plain Layout
7115 \backslash
7116 chunkref
7117 \end_layout
7119 \end_inset
7121  command, which we will process next as we continue around the loop.
7122 \end_layout
7124 \begin_layout Standard
7125 \begin_inset listings
7126 inline false
7127 status open
7129 \begin_layout Plain Layout
7131   indent += length(chunklet);
7132 \end_layout
7134 \begin_layout Plain Layout
7136   chunk_line(active_chunk, chunklet);
7137 \end_layout
7139 \begin_layout Plain Layout
7141   chunk = substr(chunk, RSTART + RLENGTH);
7142 \end_layout
7144 \end_inset
7147 \end_layout
7149 \begin_layout Standard
7150 We then consider the type of chunk command we have found, whether it is
7151  the newfangle style command beginning with 
7152 \begin_inset Flex CharStyle:Code
7153 status collapsed
7155 \begin_layout Plain Layout
7157 \end_layout
7159 \end_inset
7161  or the older notangle style beginning with 
7162 \begin_inset Flex CharStyle:Code
7163 status collapsed
7165 \begin_layout Plain Layout
7167 \end_layout
7169 \end_inset
7173 \end_layout
7175 \begin_layout Standard
7176 Newfangle chunks may have parameters contained within square brackets.
7177  These will be matched in 
7178 \begin_inset Flex CharStyle:Code
7179 status collapsed
7181 \begin_layout Plain Layout
7182 line[3]
7183 \end_layout
7185 \end_inset
7187  and are considered at this stage of processing to be part of the name of
7188  the chunk to be included.
7189 \end_layout
7191 \begin_layout Standard
7192 \begin_inset listings
7193 inline false
7194 status open
7196 \begin_layout Plain Layout
7198   if (substr(line[1], 1, 1) == "=") {
7199 \end_layout
7201 \begin_layout Plain Layout
7203     # chunk name up to }
7204 \end_layout
7206 \begin_layout Plain Layout
7208     chunk_include(active_chunk, line[2] line[3], indent);
7209 \end_layout
7211 \begin_layout Plain Layout
7213   } else if (substr(line[1], 1, 1) == "<") {
7214 \end_layout
7216 \begin_layout Plain Layout
7218     chunk_include(active_chunk, line[4], indent);
7219 \end_layout
7221 \begin_layout Plain Layout
7223   } else {
7224 \end_layout
7226 \begin_layout Plain Layout
7228     error("Unknown chunk fragment: " line[1]);
7229 \end_layout
7231 \begin_layout Plain Layout
7233   }
7234 \end_layout
7236 \end_inset
7239 \end_layout
7241 \begin_layout Standard
7242 The loop will continue until there are no more chunkref statements in the
7243  text, at which point we process the final part of the chunk.
7244 \end_layout
7246 \begin_layout Standard
7247 \begin_inset listings
7248 inline false
7249 status open
7251 \begin_layout Plain Layout
7254 \end_layout
7256 \begin_layout Plain Layout
7258 chunk_line(active_chunk, chunk);
7259 \end_layout
7261 \end_inset
7264 \end_layout
7266 \begin_layout Standard
7267 \begin_inset CommandInset label
7268 LatexCommand label
7269 name "lone-newline"
7271 \end_inset
7273 We add the newline character as a chunklet on it's own, to make it easier
7274  to detect new lines and thus manage indentation when processing the output.
7275 \end_layout
7277 \begin_layout Standard
7278 \begin_inset listings
7279 inline false
7280 status open
7282 \begin_layout Plain Layout
7284 chunk_line(active_chunk, "
7285 \backslash
7286 n");
7287 \end_layout
7289 \end_inset
7292 \end_layout
7294 \begin_layout Standard
7295 We will also permit a chunk-part number to follow in square brackets, so
7296  that 
7297 \begin_inset Flex CharStyle:Code
7298 status collapsed
7300 \begin_layout Plain Layout
7302 \backslash
7303 chunkref{chunk-name[1]}>
7304 \end_layout
7306 \end_inset
7308  will refer to the first part only.
7309  This can make it easy to include a C function prototype in a header file,
7310  if the first part of the chunk is just the function prototype without the
7311  trailing semi-colon.
7312  The header file would include the prototype with the trailing semi-colon,
7313  like this:
7314 \end_layout
7316 \begin_layout LyX-Code
7318 \backslash
7319 chunkref{chunk-name[1]}>;
7320 \end_layout
7322 \begin_layout Standard
7323 This is handled in section 
7324 \begin_inset CommandInset ref
7325 LatexCommand ref
7326 reference "sub:Chunk-parts"
7328 \end_inset
7331 \end_layout
7333 \begin_layout Standard
7334 We should perhaps introduce a notion of language specific chunk options;
7335  so that perhaps we could specify:
7336 \end_layout
7338 \begin_layout LyX-Code
7340 \backslash
7341 chunkref{chunk-name[function-declaration]}>;
7342 \end_layout
7344 \begin_layout Standard
7345 which applies a transform 
7346 \begin_inset Flex CharStyle:Code
7347 status collapsed
7349 \begin_layout Plain Layout
7350 function-declaration
7351 \end_layout
7353 \end_inset
7355  to the chunk --- which in this case would extract a function prototype
7356  from a function.
7357 \begin_inset Note Note
7358 status open
7360 \begin_layout Plain Layout
7361 So do it
7362 \end_layout
7364 \end_inset
7367 \end_layout
7369 \begin_layout Chapter
7370 Processing Options
7371 \end_layout
7373 \begin_layout Standard
7374 At the start, first we set the default options.
7375 \end_layout
7377 \begin_layout Chunk
7378 default-options
7379 \end_layout
7381 \begin_layout Standard
7382 \begin_inset listings
7383 inline false
7384 status open
7386 \begin_layout Plain Layout
7388 debug=0;
7389 \end_layout
7391 \begin_layout Plain Layout
7393 linenos=0;
7394 \end_layout
7396 \begin_layout Plain Layout
7398 notangle_mode=0;
7399 \end_layout
7401 \begin_layout Plain Layout
7403 root="*";
7404 \end_layout
7406 \begin_layout Plain Layout
7408 tabs = "";
7409 \end_layout
7411 \end_inset
7414 \end_layout
7416 \begin_layout Standard
7417 Then we use getopt the standard way, and null out ARGV afterwards in the
7418  normal AWK fashion.
7419 \end_layout
7421 \begin_layout Chunk
7422 read-options
7423 \end_layout
7425 \begin_layout Standard
7426 \begin_inset listings
7427 inline false
7428 status open
7430 \begin_layout Plain Layout
7432 Optind = 1    # skip ARGV[0]
7433 \end_layout
7435 \begin_layout Plain Layout
7437 while(getopt(ARGC, ARGV, "R:LdT:hr")!=-1) {
7438 \end_layout
7440 \begin_layout Plain Layout
7442   =<
7443 \backslash
7444 chunkref{handle-options}>
7445 \end_layout
7447 \begin_layout Plain Layout
7450 \end_layout
7452 \begin_layout Plain Layout
7454 for (i=1; i<Optind; i++) { ARGV[i]=""; }
7455 \end_layout
7457 \end_inset
7460 \end_layout
7462 \begin_layout Standard
7463 This is how we handle our options:
7464 \end_layout
7466 \begin_layout Chunk
7467 handle-options
7468 \end_layout
7470 \begin_layout Standard
7471 \begin_inset listings
7472 inline false
7473 status open
7475 \begin_layout Plain Layout
7477 if (Optopt == "R") root = Optarg;
7478 \end_layout
7480 \begin_layout Plain Layout
7482 else if (Optopt == "r") root="";
7483 \end_layout
7485 \begin_layout Plain Layout
7487 else if (Optopt == "L") linenos = 1;
7488 \end_layout
7490 \begin_layout Plain Layout
7492 else if (Optopt == "d") debug = 1;
7493 \end_layout
7495 \begin_layout Plain Layout
7497 else if (Optopt == "T") tabs = indent_string(Optarg+0);
7498 \end_layout
7500 \begin_layout Plain Layout
7502 else if (Optopt == "h") help();
7503 \end_layout
7505 \begin_layout Plain Layout
7507 else if (Optopt == "?") help();
7508 \end_layout
7510 \end_inset
7513 \end_layout
7515 \begin_layout Standard
7516 We do all of this at the beginning of the program
7517 \end_layout
7519 \begin_layout Chunk
7520 begin
7521 \end_layout
7523 \begin_layout Standard
7524 \begin_inset listings
7525 inline false
7526 status open
7528 \begin_layout Plain Layout
7530 BEGIN {
7531 \end_layout
7533 \begin_layout Plain Layout
7535   =<
7536 \backslash
7537 chunkref{constants}>
7538 \end_layout
7540 \begin_layout Plain Layout
7542   =<
7543 \backslash
7544 chunkref{mode-definitions}>
7545 \end_layout
7547 \begin_layout Plain Layout
7549   =<
7550 \backslash
7551 chunkref{default-options}>
7552 \end_layout
7554 \begin_layout Plain Layout
7556 \end_layout
7558 \begin_layout Plain Layout
7560   =<
7561 \backslash
7562 chunkref{read-options}>
7563 \end_layout
7565 \begin_layout Plain Layout
7568 \end_layout
7570 \end_inset
7573 \end_layout
7575 \begin_layout Standard
7576 And have a simple help function
7577 \end_layout
7579 \begin_layout Chunk
7580 help()
7581 \end_layout
7583 \begin_layout Standard
7584 \begin_inset listings
7585 inline false
7586 status open
7588 \begin_layout Plain Layout
7590 function help() {
7591 \end_layout
7593 \begin_layout Plain Layout
7595   print "Usage:"
7596 \end_layout
7598 \begin_layout Plain Layout
7600   print "  newfangle [-L] -R<rootname> [source.tex ...]"
7601 \end_layout
7603 \begin_layout Plain Layout
7605   print "  newfangle -r [source.tex ...]"
7606 \end_layout
7608 \begin_layout Plain Layout
7610   print "  If the filename, source.tex is not specified then stdin is used"
7611 \end_layout
7613 \begin_layout Plain Layout
7615   print
7616 \end_layout
7618 \begin_layout Plain Layout
7620   print "-L causes the C statement: #line <lineno> 
7621 \backslash
7622 "filename
7623 \backslash
7624 "" to be issued"
7625 \end_layout
7627 \begin_layout Plain Layout
7629   print "-R causes the named root to be written to stdout"
7630 \end_layout
7632 \begin_layout Plain Layout
7634   print "-r lists all roots in the file (even those used elsewhere)"
7635 \end_layout
7637 \begin_layout Plain Layout
7639   exit 1;
7640 \end_layout
7642 \begin_layout Plain Layout
7645 \end_layout
7647 \end_inset
7650 \end_layout
7652 \begin_layout Chapter
7653 Chunk Language Modes
7654 \end_layout
7656 \begin_layout Standard
7657 \begin_inset CommandInset label
7658 LatexCommand label
7659 name "cha:modes"
7661 \end_inset
7664 \begin_inset Note Greyedout
7665 status open
7667 \begin_layout Plain Layout
7668 This feature is in-development and does not work yet
7669 \end_layout
7671 \end_inset
7674 \begin_inset Note Note
7675 status open
7677 \begin_layout Plain Layout
7678 In Progress!
7679 \end_layout
7681 \end_inset
7684 \end_layout
7686 \begin_layout Standard
7687 lstlistings and newfangle both recognize source languages, and perform some
7688  basic parsing.
7689  lstlistings can detect strings and comments within a language definition
7690  and perform suitable rendering, such as italics for comments, and visible-space
7691 s within strings.
7692 \end_layout
7694 \begin_layout Standard
7695 Newfangle similarly can recognize strings, and comments, etc, within a language,
7696  so that any chunks included with 
7697 \begin_inset Flex CharStyle:Code
7698 status collapsed
7700 \begin_layout Plain Layout
7702 \backslash
7703 chunkref
7704 \end_layout
7706 \end_inset
7708  can be suitably quoted.
7709 \end_layout
7711 \begin_layout Standard
7712 For instance, consider this chunk with 
7713 \begin_inset Flex CharStyle:Code
7714 status collapsed
7716 \begin_layout Plain Layout
7717 language=perl
7718 \end_layout
7720 \end_inset
7723 \end_layout
7725 \begin_layout Chunk
7726 example-perl,language=perl
7727 \end_layout
7729 \begin_layout Standard
7730 \begin_inset listings
7731 inline false
7732 status open
7734 \begin_layout Plain Layout
7736 s/"$/'/;
7737 \end_layout
7739 \end_inset
7742 \end_layout
7744 \begin_layout Standard
7745 If it were included in a chunk with 
7746 \begin_inset Flex CharStyle:Code
7747 status collapsed
7749 \begin_layout Plain Layout
7750 language=sh
7751 \end_layout
7753 \end_inset
7755 , like this:
7756 \end_layout
7758 \begin_layout Chunk
7759 example-sh,language=sh
7760 \end_layout
7762 \begin_layout Standard
7763 \begin_inset listings
7764 inline false
7765 status open
7767 \begin_layout Plain Layout
7769 perl -pe "=<
7770 \backslash
7771 chunkref{example-perl}>"
7772 \end_layout
7774 \end_inset
7777 \end_layout
7779 \begin_layout Standard
7780 would need to generate output like this if it were to work: 
7781 \end_layout
7783 \begin_layout LyX-Code
7784 perl -pe "s/
7785 \backslash
7787 \backslash
7788 $/'/;"
7789 \end_layout
7791 \begin_layout Standard
7792 See that the double quote " as part of the regex has been quoted with a
7793  slash to protect it from shell interpretation.
7794 \end_layout
7796 \begin_layout Standard
7797 If that were then included in a chunk with 
7798 \begin_inset Flex CharStyle:Code
7799 status collapsed
7801 \begin_layout Plain Layout
7802 language=make
7803 \end_layout
7805 \end_inset
7807 , like this:
7808 \end_layout
7810 \begin_layout Chunk
7811 example-makefile,language=make
7812 \end_layout
7814 \begin_layout Standard
7815 \begin_inset listings
7816 inline false
7817 status open
7819 \begin_layout Plain Layout
7821 target: pre-req
7822 \end_layout
7824 \begin_layout Plain Layout
7826                 =<
7827 \backslash
7828 chunkref{example-sh}>
7829 \end_layout
7831 \end_inset
7834 \end_layout
7836 \begin_layout Standard
7837 We would need the output to look like this --- note the $$:
7838 \end_layout
7840 \begin_layout LyX-Code
7841 target: pre-req
7842 \end_layout
7844 \begin_layout LyX-Code
7845         perl -pe "s/
7846 \backslash
7848 \backslash
7849 $$/'/;"
7850 \end_layout
7852 \begin_layout Standard
7853 In order to make this work, we need to define a mode-tracker for each supported
7854  language, that can detect the various quoting modes, and provide a transformati
7855 on that must be applied to any included text so that included text will
7856  be interpreted correctly after the additional interpolation that it will
7857  be subject to at run-time.
7858 \end_layout
7860 \begin_layout Standard
7861 For example, the transformation for text to be inserted into sh double-quoted
7862  strings would be something like:
7863 \end_layout
7865 \begin_layout LyX-Code
7867 \backslash
7869 \backslash
7871 \backslash
7873 \backslash
7875 \backslash
7877 \backslash
7878 /g;s/$/
7879 \backslash
7881 \backslash
7882 $/g;s/"/
7883 \backslash
7885 \backslash
7886 "/g;
7887 \end_layout
7889 \begin_layout Standard
7890 which protects 
7891 \begin_inset Flex CharStyle:Code
7892 status collapsed
7894 \begin_layout Plain Layout
7896 \backslash
7897  $ "
7898 \end_layout
7900 \end_inset
7903 \end_layout
7905 \begin_layout Standard
7906 \begin_inset Note Note
7907 status collapsed
7909 \begin_layout Plain Layout
7910 I don't think this example is true
7911 \end_layout
7913 \end_inset
7915 The mode tracker must also track nested mode-changes, as in this 
7916 \begin_inset Flex CharStyle:Code
7917 status collapsed
7919 \begin_layout Plain Layout
7921 \end_layout
7923 \end_inset
7925  example.
7926 \end_layout
7928 \begin_layout LyX-Code
7929 echo "hello `id **`"
7930 \end_layout
7932 \begin_layout Standard
7933 Any literal text inserted at the point marked ** would need to be escaped
7934  in all kinds of ways, including 
7935 \begin_inset Flex CharStyle:Code
7936 status collapsed
7938 \begin_layout Plain Layout
7939 ` | *
7940 \end_layout
7942 \end_inset
7944  among others.
7945  First it would need escaping for the back-ticks `, and then for the double-quot
7946 es ".
7947 \end_layout
7949 \begin_layout Standard
7950 Escaping need not occur if the format and mode of the included chunk matches
7951  that of the including chunk, which would suggest that any back-ticks might
7952  need to be part of the included chunk and not including chunk
7953 \begin_inset Note Note
7954 status collapsed
7956 \begin_layout Plain Layout
7957 or is it the other way around?
7958 \end_layout
7960 \end_inset
7963 \end_layout
7965 \begin_layout Standard
7966 As each chunk is output a new mode tracker for that language is initialized
7967  in it's normal state.
7968  As text is output for that chunk the output mode is tracked.
7969  When a new chunk is included, a transformation appropriate to that mode
7970  is selected and pushed onto a stack of transformations.
7971  Any text to be output is first passed through this stack of transformations.
7972 \end_layout
7974 \begin_layout Standard
7975 It remains to consider if the chunk-include function should return it's
7976  generated text so that the caller can apply any transformations (and formatting
7977 ), or if it should apply the stack of transformations itself.
7978 \end_layout
7980 \begin_layout Standard
7981 Note that the transformed text should have the property of not being able
7982  to change the mode in the current chunk.
7983 \end_layout
7985 \begin_layout Standard
7986 \begin_inset Note Note
7987 status open
7989 \begin_layout Plain Layout
7990 Note chunk parameters should probably also be transformed
7991 \end_layout
7993 \end_inset
7996 \end_layout
7998 \begin_layout Chunk
7999 new_mode()
8000 \end_layout
8002 \begin_layout Standard
8003 \begin_inset listings
8004 inline false
8005 status open
8007 \begin_layout Plain Layout
8009 function new_mode(language, mode) {
8010 \end_layout
8012 \begin_layout Plain Layout
8014   mode["language"] = language;
8015 \end_layout
8017 \begin_layout Plain Layout
8019   mode["state"]="";
8020 \end_layout
8022 \begin_layout Plain Layout
8025 \end_layout
8027 \end_inset
8030 \end_layout
8032 \begin_layout Standard
8033 Because awk functions cannot return an array, we must create the array first
8034  and pass it in.
8035 \end_layout
8037 \begin_layout Chunk
8038 new-mode,params=language;mode
8039 \end_layout
8041 \begin_layout Standard
8042 \begin_inset listings
8043 inline false
8044 status open
8046 \begin_layout Plain Layout
8049 \backslash
8050 chunkref{awk-delete-array}(${mode})>
8051 \end_layout
8053 \begin_layout Plain Layout
8055 new_mode(${language}, ${mode});
8056 \end_layout
8058 \end_inset
8061 \end_layout
8063 \begin_layout Standard
8064 And for tracking modes, we dispatch to a mode-tracker action based on the
8065  current language
8066 \end_layout
8068 \begin_layout Chunk
8069 track_mode()
8070 \end_layout
8072 \begin_layout Standard
8073 \begin_inset listings
8074 inline false
8075 status open
8077 \begin_layout Plain Layout
8079 function track_mode(mode, text) {
8080 \end_layout
8082 \begin_layout Plain Layout
8084   if (mode["language"] == "C") {
8085 \end_layout
8087 \begin_layout Plain Layout
8089     =<
8090 \backslash
8091 chunkref{track-mode-C}>
8092 \end_layout
8094 \begin_layout Plain Layout
8096     return;
8097 \end_layout
8099 \begin_layout Plain Layout
8101   }
8102 \end_layout
8104 \begin_layout Plain Layout
8107 \end_layout
8109 \end_inset
8112 \end_layout
8114 \begin_layout Standard
8115 For each mode, we look for a character that has the power to change the
8116  mode.
8117 \end_layout
8119 \begin_layout Standard
8120 In plain mode:
8121 \end_layout
8123 \begin_layout List
8124 \labelwidthstring 00.00.0000
8125 \begin_inset Quotes eld
8126 \end_inset
8128  enters double-quote mode
8129 \end_layout
8131 \begin_layout List
8132 \labelwidthstring 00.00.0000
8133 ' enters single-quote mode
8134 \end_layout
8136 \begin_layout List
8137 \labelwidthstring 00.00.0000
8138 trailing-
8139 \backslash
8140  enters multi-line mode
8141 \end_layout
8143 \begin_layout List
8144 \labelwidthstring 00.00.0000
8145 # enters #define sub-mode, needs 
8146 \backslash
8147  escaping end of line too
8148 \end_layout
8150 \begin_layout List
8151 \labelwidthstring 00.00.0000
8152 /* enters comment mode
8153 \end_layout
8155 \begin_layout Standard
8156 In double-quote mode, escape 
8157 \backslash
8158  and 
8159 \begin_inset Quotes eld
8160 \end_inset
8162  and newline
8163 \end_layout
8165 \begin_layout Standard
8167 \backslash
8168  escapes prevents 
8169 \begin_inset Quotes eld
8170 \end_inset
8172  from leaving mode
8173 \end_layout
8175 \begin_layout Standard
8176 \begin_inset Quotes eld
8177 \end_inset
8179  leaves mode
8180 \end_layout
8182 \begin_layout Standard
8183 newline needs to close and re-open string or something
8184 \end_layout
8186 \begin_layout Standard
8187 in single-quote mode escape 
8188 \backslash
8189  and 
8190 \begin_inset Quotes eld
8191 \end_inset
8194 \end_layout
8196 \begin_layout Chunk
8197 track-mode-C
8198 \end_layout
8200 \begin_layout Standard
8201 \begin_inset listings
8202 inline false
8203 status open
8205 \begin_layout Plain Layout
8207 \end_layout
8209 \end_inset
8212 \end_layout
8214 \begin_layout Chunk
8215 mode-tracker
8216 \end_layout
8218 \begin_layout Standard
8219 \begin_inset listings
8220 inline false
8221 status open
8223 \begin_layout Plain Layout
8226 \backslash
8227 chunkref{new_mode()}>
8228 \end_layout
8230 \begin_layout Plain Layout
8233 \backslash
8234 chunkref{parse_chunk_args}>
8235 \end_layout
8237 \end_inset
8240 \end_layout
8242 \begin_layout Chapter
8243 Generating the output
8244 \end_layout
8246 \begin_layout Standard
8247 We generate output by calling output_chunk, or listing the chunk names.
8248 \end_layout
8250 \begin_layout Chunk
8251 generate-output
8252 \end_layout
8254 \begin_layout Standard
8255 \begin_inset listings
8256 inline false
8257 status open
8259 \begin_layout Plain Layout
8261 if (length(root)) output_chunk(root);
8262 \end_layout
8264 \begin_layout Plain Layout
8266 else output_chunk_names();
8267 \end_layout
8269 \end_inset
8272 \end_layout
8274 \begin_layout Standard
8275 We also have some other output debugging:
8276 \end_layout
8278 \begin_layout Chunk
8279 debug-output
8280 \end_layout
8282 \begin_layout Standard
8283 \begin_inset listings
8284 inline false
8285 status open
8287 \begin_layout Plain Layout
8289 if (debug) {
8290 \end_layout
8292 \begin_layout Plain Layout
8294   print "------ chunk names "
8295 \end_layout
8297 \begin_layout Plain Layout
8299   output_chunk_names();
8300 \end_layout
8302 \begin_layout Plain Layout
8304   print "====== chunks"
8305 \end_layout
8307 \begin_layout Plain Layout
8309   output_chunks();
8310 \end_layout
8312 \begin_layout Plain Layout
8314   print "++++++ debug"
8315 \end_layout
8317 \begin_layout Plain Layout
8319   for (a in chunks) {
8320 \end_layout
8322 \begin_layout Plain Layout
8324     print a "=" chunks[a];
8325 \end_layout
8327 \begin_layout Plain Layout
8329   }
8330 \end_layout
8332 \begin_layout Plain Layout
8335 \end_layout
8337 \end_inset
8340 \end_layout
8342 \begin_layout Standard
8343 We do both of these at the end.
8344  We also set 
8345 \begin_inset Flex CharStyle:Code
8346 status collapsed
8348 \begin_layout Plain Layout
8349 ORS=""
8350 \end_layout
8352 \end_inset
8354  because each chunklet is not necessarily a complete line, and we already
8355  added 
8356 \begin_inset Flex CharStyle:Code
8357 status collapsed
8359 \begin_layout Plain Layout
8361 \end_layout
8363 \end_inset
8365  to each input line in section 
8366 \begin_inset CommandInset ref
8367 LatexCommand ref
8368 reference "sub:ORS-chunk-text"
8370 \end_inset
8373 \end_layout
8375 \begin_layout Chunk
8377 \end_layout
8379 \begin_layout Standard
8380 \begin_inset listings
8381 inline false
8382 status open
8384 \begin_layout Plain Layout
8386 END {
8387 \end_layout
8389 \begin_layout Plain Layout
8391   =<
8392 \backslash
8393 chunkref{debug-output}>
8394 \end_layout
8396 \begin_layout Plain Layout
8398   ORS="";
8399 \end_layout
8401 \begin_layout Plain Layout
8403   =<
8404 \backslash
8405 chunkref{generate-output}>
8406 \end_layout
8408 \begin_layout Plain Layout
8411 \end_layout
8413 \end_inset
8416 \end_layout
8418 \begin_layout Standard
8419 We write chunk names like this.
8420  If we seem to be running in notangle compatibility mode, then we enclose
8421  the name like this 
8422 \begin_inset Flex CharStyle:Code
8423 status collapsed
8425 \begin_layout Plain Layout
8426 <<name>>
8427 \end_layout
8429 \end_inset
8431  the same way notangle does:
8432 \end_layout
8434 \begin_layout Chunk
8435 output_chunk_names()
8436 \end_layout
8438 \begin_layout Standard
8439 \begin_inset listings
8440 inline false
8441 status open
8443 \begin_layout Plain Layout
8445 function output_chunk_names(   c, prefix, suffix) 
8446 \end_layout
8448 \begin_layout Plain Layout
8451 \end_layout
8453 \begin_layout Plain Layout
8455   if (notangle_mode) {
8456 \end_layout
8458 \begin_layout Plain Layout
8460     prefix="<<";
8461 \end_layout
8463 \begin_layout Plain Layout
8465     suffix=">>";
8466 \end_layout
8468 \begin_layout Plain Layout
8470   }
8471 \end_layout
8473 \begin_layout Plain Layout
8475   for (c in chunk_names) {
8476 \end_layout
8478 \begin_layout Plain Layout
8480     print prefix c suffix "
8481 \backslash
8483 \end_layout
8485 \begin_layout Plain Layout
8487   }
8488 \end_layout
8490 \begin_layout Plain Layout
8493 \end_layout
8495 \end_inset
8498 \end_layout
8500 \begin_layout Standard
8501 This function would write out all chunks
8502 \end_layout
8504 \begin_layout Chunk
8505 output_chunks()
8506 \end_layout
8508 \begin_layout Standard
8509 \begin_inset listings
8510 inline false
8511 status open
8513 \begin_layout Plain Layout
8515 function output_chunks(  a) 
8516 \end_layout
8518 \begin_layout Plain Layout
8521 \end_layout
8523 \begin_layout Plain Layout
8525   for (a in chunk_names) {
8526 \end_layout
8528 \begin_layout Plain Layout
8530     output_chunk(chunk_names[a]);
8531 \end_layout
8533 \begin_layout Plain Layout
8535   }
8536 \end_layout
8538 \begin_layout Plain Layout
8541 \end_layout
8543 \begin_layout Plain Layout
8545 \end_layout
8547 \begin_layout Plain Layout
8549 function output_chunk(chunk) {
8550 \end_layout
8552 \begin_layout Plain Layout
8554   newline = 1;
8555 \end_layout
8557 \begin_layout Plain Layout
8559   lineno_needed = linenos;
8560 \end_layout
8562 \begin_layout Plain Layout
8564 \end_layout
8566 \begin_layout Plain Layout
8568   write_chunk(chunk);
8569 \end_layout
8571 \begin_layout Plain Layout
8574 \end_layout
8576 \begin_layout Plain Layout
8578 \end_layout
8580 \end_inset
8583 \end_layout
8585 \begin_layout Section
8586 Assembling the chunks
8587 \end_layout
8589 \begin_layout Standard
8590 \begin_inset Flex CharStyle:Code
8591 status collapsed
8593 \begin_layout Plain Layout
8594 chunk_path
8595 \end_layout
8597 \end_inset
8599  holds a string consisting of the names of all the chunks that resulted
8600  in this chunk being output.
8602 \begin_inset Note Note
8603 status collapsed
8605 \begin_layout Plain Layout
8606 Make sure it includes the line numbers too...
8608 \end_layout
8610 \end_inset
8612 It should probably also contain the source line numbers at which each inclusion
8613  also occured.
8614 \end_layout
8616 \begin_layout Chunk
8617 write_chunk(),emph={chunk_path}
8618 \end_layout
8620 \begin_layout Standard
8621 \begin_inset listings
8622 inline false
8623 status open
8625 \begin_layout Plain Layout
8627 function write_chunk(chunk_name, indent, tail,
8628 \end_layout
8630 \begin_layout Plain Layout
8632   # optional vars
8633 \end_layout
8635 \begin_layout Plain Layout
8637   chunk_path, chunk_args, 
8638 \end_layout
8640 \begin_layout Plain Layout
8642   # local vars
8643 \end_layout
8645 \begin_layout Plain Layout
8647   part, max_part, part_line, frag, max_frag, text, 
8648 \end_layout
8650 \begin_layout Plain Layout
8652   chunklet, only_part, call_chunk_args, mode)
8653 \end_layout
8655 \begin_layout Plain Layout
8658 \end_layout
8660 \end_inset
8663 \end_layout
8665 \begin_layout Subsection
8666 \begin_inset CommandInset label
8667 LatexCommand label
8668 name "sub:Chunk-parts"
8670 \end_inset
8672 Chunk parts
8673 \end_layout
8675 \begin_layout Standard
8676 As mentioned in section 
8677 \begin_inset CommandInset ref
8678 LatexCommand ref
8679 reference "sub:lstlistings-includes"
8681 \end_inset
8683 , a chunk name may contain a part specifier in square brackets, limiting
8684  the parts that should be emitted.
8685 \end_layout
8687 \begin_layout Standard
8688 \begin_inset listings
8689 inline false
8690 status open
8692 \begin_layout Plain Layout
8694   if (match(chunk_name, "^(.*)
8695 \backslash
8697 \backslash
8698 [([0-9]*)
8699 \backslash
8701 \backslash
8702 ]$", chunk_name_parts)) {
8703 \end_layout
8705 \begin_layout Plain Layout
8707     chunk_name = chunk_name_parts[1];
8708 \end_layout
8710 \begin_layout Plain Layout
8712     only_part = chunk_name_parts[2];
8713 \end_layout
8715 \begin_layout Plain Layout
8717   }
8718 \end_layout
8720 \end_inset
8723 \end_layout
8725 \begin_layout Standard
8726 We first create the mode tracker for this chunk.
8727 \end_layout
8729 \begin_layout Standard
8730 #  =<
8731 \backslash
8732 chunkref{awk-delete-array}(mode)>
8733 \end_layout
8735 \begin_layout Standard
8736 \begin_inset listings
8737 inline false
8738 status open
8740 \begin_layout Plain Layout
8742   split("", mode);
8743 \end_layout
8745 \begin_layout Plain Layout
8747   new_mode(chunks[chunk_name, "language"], mode);
8748 \end_layout
8750 \end_inset
8753 \end_layout
8755 \begin_layout Standard
8756 #  =<
8757 \backslash
8758 chunkref{new-mode}(chunks[chunk_name, "language"], mode)>
8759 \end_layout
8761 \begin_layout Standard
8762 We extract into 
8763 \begin_inset Flex CharStyle:Code
8764 status collapsed
8766 \begin_layout Plain Layout
8767 chunk_params
8768 \end_layout
8770 \end_inset
8772  the names of the parameters that this chunk accepts, whose values were
8773  (optionally) passed in 
8774 \begin_inset Flex CharStyle:Code
8775 status collapsed
8777 \begin_layout Plain Layout
8778 chunk_args
8779 \end_layout
8781 \end_inset
8784 \end_layout
8786 \begin_layout Standard
8787 \begin_inset listings
8788 inline false
8789 status open
8791 \begin_layout Plain Layout
8793   split(chunks[chunk_name, "params"], chunk_params, " *; *");
8794 \end_layout
8796 \end_inset
8799 \end_layout
8801 \begin_layout Standard
8802 To assemble a chunk, we write out each part.
8803 \end_layout
8805 \begin_layout Chunk
8806 write_chunk()
8807 \end_layout
8809 \begin_layout Standard
8810 \begin_inset listings
8811 inline false
8812 status open
8814 \begin_layout Plain Layout
8816   if (! (chunk_name in chunk_names)) {
8817 \end_layout
8819 \begin_layout Plain Layout
8821     error(sprintf(_"The root module <<%s>> was not defined.
8822 \backslash
8823 nUsed by: %s",
8824 \backslash
8826 \end_layout
8828 \begin_layout Plain Layout
8830                   chunk_name, chunk_path));
8831 \end_layout
8833 \begin_layout Plain Layout
8835   }
8836 \end_layout
8838 \begin_layout Plain Layout
8840 \end_layout
8842 \begin_layout Plain Layout
8844   max_part = chunks[chunk_name, "part"];
8845 \end_layout
8847 \begin_layout Plain Layout
8849   for(part = 1; part <= max_part; part++) {
8850 \end_layout
8852 \begin_layout Plain Layout
8854     if (! only_part || part == only_part) {
8855 \end_layout
8857 \begin_layout Plain Layout
8859       =<
8860 \backslash
8861 chunkref{write-part}>
8862 \end_layout
8864 \begin_layout Plain Layout
8866     }
8867 \end_layout
8869 \begin_layout Plain Layout
8871   }
8872 \end_layout
8874 \begin_layout Plain Layout
8877 \end_layout
8879 \end_inset
8882 \end_layout
8884 \begin_layout Standard
8885 A part can either be a chunklet of lines, or an include of another chunk.
8886 \end_layout
8888 \begin_layout Standard
8889 Chunks may also have parameters, specified in LaTeX style with braces after
8890  the chunk name --- looking like this in the document: 
8891 \begin_inset Flex CharStyle:Code
8892 status collapsed
8894 \begin_layout Plain Layout
8895 chunkname{param1, param2}
8896 \end_layout
8898 \end_inset
8901  Arguments are passed in square brackets: 
8902 \begin_inset Flex CharStyle:Code
8903 status collapsed
8905 \begin_layout Plain Layout
8907 \backslash
8908 chunkref{chunkname}[arg1, arg2]
8909 \end_layout
8911 \end_inset
8914 \end_layout
8916 \begin_layout Standard
8917 Before we process each part, we check that the source position hasn't changed
8918  unexpectedly, so that we can know if we need to output a new file-line
8919  directive.
8920 \end_layout
8922 \begin_layout Chunk
8923 write-part
8924 \end_layout
8926 \begin_layout Standard
8927 \begin_inset listings
8928 inline false
8929 status open
8931 \begin_layout Plain Layout
8934 \backslash
8935 chunkref{check-source-jump}>
8936 \end_layout
8938 \begin_layout Plain Layout
8940 \end_layout
8942 \begin_layout Plain Layout
8944 chunklet = chunks[chunk_name, "part", part];
8945 \end_layout
8947 \begin_layout Plain Layout
8949 if (chunks[chunk_name, "part", part, "type"] == part_type_chunk) {
8950 \end_layout
8952 \begin_layout Plain Layout
8954   =<
8955 \backslash
8956 chunkref{write-included-chunk}>
8957 \end_layout
8959 \begin_layout Plain Layout
8961 } else if (chunklet SUBSEP "line" in chunks) {
8962 \end_layout
8964 \begin_layout Plain Layout
8966   =<
8967 \backslash
8968 chunkref{write-chunklets}>
8969 \end_layout
8971 \begin_layout Plain Layout
8973 } else {
8974 \end_layout
8976 \begin_layout Plain Layout
8978   # empty last chunklet
8979 \end_layout
8981 \begin_layout Plain Layout
8984 \end_layout
8986 \end_inset
8989 \end_layout
8991 \begin_layout Standard
8992 To write an included chunk, we must detect any optional chunk arguments
8993  in parenthesis.
8994  Then we recurse calling 
8995 \begin_inset Flex Chunkref
8996 status collapsed
8998 \begin_layout Plain Layout
8999 write_chunk()
9000 \end_layout
9002 \end_inset
9005 \end_layout
9007 \begin_layout Chunk
9008 write-included-chunk
9009 \end_layout
9011 \begin_layout Standard
9012 \begin_inset listings
9013 inline false
9014 status open
9016 \begin_layout Plain Layout
9018 if (match(chunklet, "^([^
9019 \backslash
9021 \backslash
9022 []*)
9023 \backslash
9025 \backslash
9026 ((.*)
9027 \backslash
9029 \backslash
9030 )$", chunklet_parts)) {
9031 \end_layout
9033 \begin_layout Plain Layout
9035   chunklet = chunklet_parts[1];
9036 \end_layout
9038 \begin_layout Plain Layout
9040   parse_chunk_args("", chunklet_parts[2], call_chunk_args, "(");
9041 \end_layout
9043 \begin_layout Plain Layout
9045   for (c in call_chunk_args) {
9046 \end_layout
9048 \begin_layout Plain Layout
9050     call_chunk_args[c] = expand_chunk_args(call_chunk_args[c], chunk_params,
9051  chunk_args);
9052 \end_layout
9054 \begin_layout Plain Layout
9056   }
9057 \end_layout
9059 \begin_layout Plain Layout
9061 } else {
9062 \end_layout
9064 \begin_layout Plain Layout
9066   split("", call_chunk_args);
9067 \end_layout
9069 \begin_layout Plain Layout
9072 \end_layout
9074 \begin_layout Plain Layout
9076 write_chunk(chunklet,
9077 \end_layout
9079 \begin_layout Plain Layout
9081             chunks[chunk_name, "part", part, "indent"] indent,
9082 \end_layout
9084 \begin_layout Plain Layout
9086             chunks[chunk_name, "part", part, "tail"],
9087 \end_layout
9089 \begin_layout Plain Layout
9091             chunk_path "
9092 \backslash
9093 n         " chunk_name,
9094 \end_layout
9096 \begin_layout Plain Layout
9098             call_chunk_args);
9099 \end_layout
9101 \end_inset
9104 \end_layout
9106 \begin_layout Standard
9107 Before we output a chunklet of lines, we first emit the file and line number
9108  if we have one, and if it is safe to do so.
9110 \end_layout
9112 \begin_layout Standard
9113 Chunklets are generally broken up by includes, so the start of a chunklet
9114  is a good place to do this.
9115  Then we output each line of the chunklet.
9116 \end_layout
9118 \begin_layout Standard
9119 When it is not safe, such as in the middle of a multi-line macro definition,
9121 \begin_inset Flex CharStyle:Code
9122 status collapsed
9124 \begin_layout Plain Layout
9125 lineno_suppressed
9126 \end_layout
9128 \end_inset
9130  is set to true, and in such a case we note that we want to emit the line
9131  statement when it is next safe.
9132 \end_layout
9134 \begin_layout Chunk
9135 write-chunklets
9136 \end_layout
9138 \begin_layout Standard
9139 \begin_inset listings
9140 inline false
9141 status open
9143 \begin_layout Plain Layout
9145 max_frag = chunks[chunklet, "line"];
9146 \end_layout
9148 \begin_layout Plain Layout
9150 for(frag = 1; frag <= max_frag; frag++) {
9151 \end_layout
9153 \begin_layout Plain Layout
9155   =<
9156 \backslash
9157 chunkref{write-file-line}>
9158 \end_layout
9160 \end_inset
9163 \end_layout
9165 \begin_layout Standard
9166 We then extract the chunklet text and expand any arguments.
9167 \end_layout
9169 \begin_layout Standard
9170 \begin_inset listings
9171 inline false
9172 status open
9174 \begin_layout Plain Layout
9176 \end_layout
9178 \begin_layout Plain Layout
9180   text = chunks[chunklet, frag];
9181 \end_layout
9183 \begin_layout Plain Layout
9186 \end_layout
9188 \begin_layout Plain Layout
9190   /* check params */
9191 \end_layout
9193 \begin_layout Plain Layout
9195   text = expand_chunk_args(text, chunk_params, chunk_args);
9196 \end_layout
9198 \end_inset
9201 \end_layout
9203 \begin_layout Standard
9204 If the text is a single newline (which we keep separate - see 
9205 \begin_inset CommandInset ref
9206 LatexCommand ref
9207 reference "lone-newline"
9209 \end_inset
9211 ) then we increment the line number.
9212  In the case where this is the last line of a chunk and it is not a top-level
9213  chunk we replace the newline with an empty string --- because the chunk
9214  that included this chunk will have the newline at the end of the line that
9215  included this chunk.
9216 \end_layout
9218 \begin_layout Standard
9219 We also note by 
9220 \begin_inset Flex CharStyle:Code
9221 status collapsed
9223 \begin_layout Plain Layout
9224 newline = 1
9225 \end_layout
9227 \end_inset
9229  that we have started a new line, so that indentation can be managed with
9230  the following piece of text.
9231 \end_layout
9233 \begin_layout Standard
9234 \begin_inset listings
9235 inline false
9236 status open
9238 \begin_layout Plain Layout
9240 \end_layout
9242 \begin_layout Plain Layout
9244  if (text == "
9245 \backslash
9246 n") {
9247 \end_layout
9249 \begin_layout Plain Layout
9251     lineno++;
9252 \end_layout
9254 \begin_layout Plain Layout
9256     if (part == max_part && frag == max_frag && length(chunk_path)) {
9257 \end_layout
9259 \begin_layout Plain Layout
9261       text = "";
9262 \end_layout
9264 \begin_layout Plain Layout
9266       break;
9267 \end_layout
9269 \begin_layout Plain Layout
9271     } else {
9272 \end_layout
9274 \begin_layout Plain Layout
9276       newline = 1;
9277 \end_layout
9279 \begin_layout Plain Layout
9281     }
9282 \end_layout
9284 \end_inset
9287 \end_layout
9289 \begin_layout Standard
9290 If this text does not represent a newline, but we see that we are the first
9291  piece of text on a newline, then we prefix our text with the current indent.
9292  NOTE: 
9293 \begin_inset Flex CharStyle:Code
9294 status collapsed
9296 \begin_layout Plain Layout
9297 newline
9298 \end_layout
9300 \end_inset
9302  is a global output-state variable, but the 
9303 \begin_inset Flex CharStyle:Code
9304 status collapsed
9306 \begin_layout Plain Layout
9307 indent
9308 \end_layout
9310 \end_inset
9312  is not.
9314 \end_layout
9316 \begin_layout Standard
9317 \begin_inset listings
9318 inline false
9319 status open
9321 \begin_layout Plain Layout
9323   } else if (length(text) || length(tail)) {
9324 \end_layout
9326 \begin_layout Plain Layout
9328     if (newline) text = indent text;
9329 \end_layout
9331 \begin_layout Plain Layout
9333     newline = 0;
9334 \end_layout
9336 \begin_layout Plain Layout
9338   }
9339 \end_layout
9341 \begin_layout Plain Layout
9343 \end_layout
9345 \end_inset
9348 \end_layout
9350 \begin_layout Standard
9351 Tail will soon no longer be relevant once mode-detection is in place.
9352 \end_layout
9354 \begin_layout Standard
9355 \begin_inset listings
9356 inline false
9357 status open
9359 \begin_layout Plain Layout
9361   text = text tail;
9362 \end_layout
9364 \begin_layout Plain Layout
9366 #  track_mode(mode, text);
9367 \end_layout
9369 \begin_layout Plain Layout
9371   print text;
9372 \end_layout
9374 \end_inset
9377 \end_layout
9379 \begin_layout Standard
9380 If a line ends in a backslash --- suggesting continuation --- then we supress
9381  outputting file-line as it would probably break the continued lines.
9383 \end_layout
9385 \begin_layout Standard
9386 \begin_inset listings
9387 inline false
9388 status open
9390 \begin_layout Plain Layout
9392   if (linenos) {
9393 \end_layout
9395 \begin_layout Plain Layout
9397     lineno_suppressed = substr(lastline, length(lastline)) == "
9398 \backslash
9400 \backslash
9402 \end_layout
9404 \begin_layout Plain Layout
9406   }
9407 \end_layout
9409 \begin_layout Plain Layout
9412 \end_layout
9414 \end_inset
9417 \end_layout
9419 \begin_layout Standard
9420 Of course there is no point in actually outputting the source filename and
9421  line number (file-line) if they don't say anything new! We only need to
9422  emit them if they aren't what is expected, or if we we not able to emit
9423  one when they had changed.
9424 \end_layout
9426 \begin_layout Chunk
9427 write-file-line
9428 \end_layout
9430 \begin_layout Standard
9431 \begin_inset listings
9432 inline false
9433 status open
9435 \begin_layout Plain Layout
9437 if (newline && lineno_needed && ! lineno_suppressed) {
9438 \end_layout
9440 \begin_layout Plain Layout
9442   filename = a_filename;
9443 \end_layout
9445 \begin_layout Plain Layout
9447   lineno = a_lineno;
9448 \end_layout
9450 \begin_layout Plain Layout
9452   print "#line " lineno " 
9453 \backslash
9454 "" filename "
9455 \backslash
9457 \backslash
9459 \end_layout
9461 \begin_layout Plain Layout
9463   lineno_needed = 0;
9464 \end_layout
9466 \begin_layout Plain Layout
9469 \end_layout
9471 \end_inset
9474 \end_layout
9476 \begin_layout Standard
9477 We check if a new file-line is needed by checking if the source line matches
9478  what we (or a compiler) would expect.
9480 \end_layout
9482 \begin_layout Chunk
9483 check-source-jump
9484 \end_layout
9486 \begin_layout Standard
9487 \begin_inset listings
9488 inline false
9489 status open
9491 \begin_layout Plain Layout
9493 if (linenos && (chunk_name SUBSEP "part" SUBSEP part SUBSEP "FILENAME" in
9494  chunks)) {
9495 \end_layout
9497 \begin_layout Plain Layout
9499   a_filename = chunks[chunk_name, "part", part, "FILENAME"];
9500 \end_layout
9502 \begin_layout Plain Layout
9504   a_lineno = chunks[chunk_name, "part", part, "LINENO"];
9505 \end_layout
9507 \begin_layout Plain Layout
9509   if (a_filename != filename || a_lineno != lineno) {
9510 \end_layout
9512 \begin_layout Plain Layout
9514     lineno_needed++;
9515 \end_layout
9517 \begin_layout Plain Layout
9519   }
9520 \end_layout
9522 \begin_layout Plain Layout
9525 \end_layout
9527 \end_inset
9530 \end_layout
9532 \begin_layout Chapter
9533 Storing chunks
9534 \end_layout
9536 \begin_layout Standard
9537 Awk has pretty limited data structures, so we will use two main hashes.
9538  Uninterrupted sequences of a chunk will be stored in 
9539 \begin_inset Flex CharStyle:Code
9540 status collapsed
9542 \begin_layout Plain Layout
9543 chunklets
9544 \end_layout
9546 \end_inset
9548  and the chunklets used in a chunk will be stored in 
9549 \begin_inset Flex CharStyle:Code
9550 status collapsed
9552 \begin_layout Plain Layout
9553 chunks
9554 \end_layout
9556 \end_inset
9559 \end_layout
9561 \begin_layout Chunk
9562 constants
9563 \end_layout
9565 \begin_layout Standard
9566 \begin_inset listings
9567 inline false
9568 status open
9570 \begin_layout Plain Layout
9572 part_type_chunk=1;
9573 \end_layout
9575 \begin_layout Plain Layout
9577 SUBSEP=",";
9578 \end_layout
9580 \end_inset
9583 \end_layout
9585 \begin_layout Standard
9586 The 
9587 \begin_inset Flex CharStyle:Code
9588 status collapsed
9590 \begin_layout Plain Layout
9591 params
9592 \end_layout
9594 \end_inset
9596  mentioned are not chunk parameters for parameterized chunks, as mentioned
9597  in 
9598 \begin_inset CommandInset ref
9599 LatexCommand ref
9600 reference "cha:Chunk Arguments"
9602 \end_inset
9604 , but the lstlistings style parameters used in the 
9605 \begin_inset Flex CharStyle:Code
9606 status collapsed
9608 \begin_layout Plain Layout
9610 \backslash
9611 Chunk
9612 \end_layout
9614 \end_inset
9616  command
9617 \begin_inset Foot
9618 status collapsed
9620 \begin_layout Plain Layout
9621 The 
9622 \begin_inset Flex CharStyle:Code
9623 status collapsed
9625 \begin_layout Plain Layout
9626 params
9627 \end_layout
9629 \end_inset
9631  parameter is used to hold the parameters for parameterized chunks
9632 \end_layout
9634 \end_inset
9637 \end_layout
9639 \begin_layout Chunk
9640 chunk-storage-functions
9641 \end_layout
9643 \begin_layout Standard
9644 \begin_inset listings
9645 inline false
9646 status open
9648 \begin_layout Plain Layout
9650 function new_chunk(chunk_name, params,
9651 \end_layout
9653 \begin_layout Plain Layout
9655   # local vars
9656 \end_layout
9658 \begin_layout Plain Layout
9660   p, append )
9661 \end_layout
9663 \begin_layout Plain Layout
9666 \end_layout
9668 \begin_layout Plain Layout
9670   # HACK WHILE WE CHANGE TO ( ) for PARAM CHUNKS
9671 \end_layout
9673 \begin_layout Plain Layout
9675   gsub("
9676 \backslash
9678 \backslash
9680 \backslash
9682 \backslash
9683 )$", "", chunk_name);
9684 \end_layout
9686 \begin_layout Plain Layout
9688   if (! (chunk_name in chunk_names)) {
9689 \end_layout
9691 \begin_layout Plain Layout
9693     if (debug) print "New chunk " chunk_name;
9694 \end_layout
9696 \begin_layout Plain Layout
9698     chunk_names[chunk_name];
9699 \end_layout
9701 \begin_layout Plain Layout
9703     for (p in params) {
9704 \end_layout
9706 \begin_layout Plain Layout
9708       chunks[chunk_name, p] = params[p];
9709 \end_layout
9711 \begin_layout Plain Layout
9713     }
9714 \end_layout
9716 \begin_layout Plain Layout
9718     if ("append" in params) {
9719 \end_layout
9721 \begin_layout Plain Layout
9723       append=params["append"];
9724 \end_layout
9726 \begin_layout Plain Layout
9728       if (! (append in chunk_names)) {
9729 \end_layout
9731 \begin_layout Plain Layout
9733         warning("Chunk " chunk_name " is appended to chunk " append " which
9734  is not defined yet");
9735 \end_layout
9737 \begin_layout Plain Layout
9739         new_chunk(append);
9740 \end_layout
9742 \begin_layout Plain Layout
9744       }
9745 \end_layout
9747 \begin_layout Plain Layout
9749       chunk_include(append, chunk_name);
9750 \end_layout
9752 \begin_layout Plain Layout
9754       chunk_line(append, ORS);
9755 \end_layout
9757 \begin_layout Plain Layout
9759     }
9760 \end_layout
9762 \begin_layout Plain Layout
9764   }
9765 \end_layout
9767 \begin_layout Plain Layout
9769   active_chunk = chunk_name;
9770 \end_layout
9772 \begin_layout Plain Layout
9774   prime_chunk(chunk_name);
9775 \end_layout
9777 \begin_layout Plain Layout
9780 \end_layout
9782 \end_inset
9785 \end_layout
9787 \begin_layout Standard
9788 \begin_inset listings
9789 inline false
9790 status open
9792 \begin_layout Plain Layout
9794 \end_layout
9796 \begin_layout Plain Layout
9798 function prime_chunk(chunk_name)
9799 \end_layout
9801 \begin_layout Plain Layout
9804 \end_layout
9806 \begin_layout Plain Layout
9808   chunks[chunk_name, "part", ++chunks[chunk_name, "part"] ] = 
9809 \backslash
9811 \end_layout
9813 \begin_layout Plain Layout
9815          chunk_name SUBSEP "chunklet" SUBSEP "" ++chunks[chunk_name, "chunklet"]
9817 \end_layout
9819 \begin_layout Plain Layout
9821   chunks[chunk_name, "part", chunks[chunk_name, "part"], "FILENAME"] = FILENAME;
9822 \end_layout
9824 \begin_layout Plain Layout
9826   chunks[chunk_name, "part", chunks[chunk_name, "part"], "LINENO"] = FNR
9827  + 1;
9828 \end_layout
9830 \begin_layout Plain Layout
9833 \end_layout
9835 \begin_layout Plain Layout
9837 \end_layout
9839 \begin_layout Plain Layout
9841 function chunk_line(chunk_name, line){
9842 \end_layout
9844 \begin_layout Plain Layout
9846   chunks[chunk_name, "chunklet", chunks[chunk_name, "chunklet"],
9847 \end_layout
9849 \begin_layout Plain Layout
9851          ++chunks[chunk_name, "chunklet", chunks[chunk_name, "chunklet"],
9852  "line"]  ] = line;
9853 \end_layout
9855 \begin_layout Plain Layout
9858 \end_layout
9860 \begin_layout Plain Layout
9862 \end_layout
9864 \end_inset
9867 \end_layout
9869 \begin_layout Standard
9870 Chunk include represents a 
9871 \emph on
9872 chunkref
9873 \emph default
9874  statement, and stores the requirement to include another chunk.
9875  The parameter indent represents the quanity of literal text characters
9876  that preceded this 
9877 \emph on
9878 chunkref
9879 \emph default
9880  statement and therefore by how much additional lines of the included chunk
9881  should be indented.
9882 \end_layout
9884 \begin_layout Standard
9885 \begin_inset listings
9886 inline false
9887 status open
9889 \begin_layout Plain Layout
9891 function chunk_include(chunk_name, chunk_ref, indent, tail)
9892 \end_layout
9894 \begin_layout Plain Layout
9897 \end_layout
9899 \begin_layout Plain Layout
9901   chunks[chunk_name, "part", ++chunks[chunk_name, "part"] ] = chunk_ref;
9902 \end_layout
9904 \begin_layout Plain Layout
9906   chunks[chunk_name, "part", chunks[chunk_name, "part"], "type" ] = part_type_ch
9907 unk;
9908 \end_layout
9910 \begin_layout Plain Layout
9912   chunks[chunk_name, "part", chunks[chunk_name, "part"], "indent" ] = indent_str
9913 ing(indent);
9914 \end_layout
9916 \begin_layout Plain Layout
9918   chunks[chunk_name, "part", chunks[chunk_name, "part"], "tail" ] = tail;
9919 \end_layout
9921 \begin_layout Plain Layout
9923   prime_chunk(chunk_name);
9924 \end_layout
9926 \begin_layout Plain Layout
9929 \end_layout
9931 \begin_layout Plain Layout
9933 \end_layout
9935 \end_inset
9938 \end_layout
9940 \begin_layout Standard
9941 The indent is calculated by indent_string, which may in future convert some
9942  spaces into tab characters.
9943  This function works by generating a printf padded format string, like 
9944 \begin_inset Flex CharStyle:Code
9945 status collapsed
9947 \begin_layout Plain Layout
9948 %22s
9949 \end_layout
9951 \end_inset
9953  for an indent of 22, and then printing an empty string using that format.
9954 \end_layout
9956 \begin_layout Standard
9957 \begin_inset listings
9958 inline false
9959 status open
9961 \begin_layout Plain Layout
9963 function indent_string(indent) {
9964 \end_layout
9966 \begin_layout Plain Layout
9968   return sprintf("%" indent "s", "");
9969 \end_layout
9971 \begin_layout Plain Layout
9974 \end_layout
9976 \end_inset
9979 \end_layout
9981 \begin_layout Chapter
9982 \begin_inset CommandInset label
9983 LatexCommand label
9984 name "cha:getopt"
9986 \end_inset
9988 getopt
9989 \end_layout
9991 \begin_layout Standard
9992 I use Arnold Robbins public domain getopt (1993 revision).
9993  This is probably the same one that is covered in chapter 12 of 
9994 \begin_inset Quotes eld
9995 \end_inset
9997 Edition 3 of GAWK: Effective AWK Programming: A User's Guide for GNU Awk
9998 \begin_inset Quotes erd
9999 \end_inset
10001  but as that is licensed under the GNU Free Documentation License, Version
10002  1.3, which conflicts with the GPL3, I can't use it from there (or it's accompany
10003 ing explanations), so I do my best to explain how it works here.
10004 \end_layout
10006 \begin_layout Standard
10007 The getopt.awk header is:
10008 \end_layout
10010 \begin_layout Chunk
10011 getopt.awk-header,language=awk,morestring=[b]{/},morekeywords=else
10012 \end_layout
10014 \begin_layout Standard
10015 \begin_inset listings
10016 inline false
10017 status open
10019 \begin_layout Plain Layout
10021 # getopt.awk --- do C library getopt(3) function in awk
10022 \end_layout
10024 \begin_layout Plain Layout
10027 \end_layout
10029 \begin_layout Plain Layout
10031 # Arnold Robbins, arnold@skeeve.com, Public Domain
10032 \end_layout
10034 \begin_layout Plain Layout
10037 \end_layout
10039 \begin_layout Plain Layout
10041 # Initial version: March, 1991
10042 \end_layout
10044 \begin_layout Plain Layout
10046 # Revised: May, 1993
10047 \end_layout
10049 \end_inset
10052 \end_layout
10054 \begin_layout Standard
10055 The provided explanation is:
10056 \end_layout
10058 \begin_layout Chunk
10059 getopt.awk-notes
10060 \end_layout
10062 \begin_layout Standard
10063 \begin_inset listings
10064 inline false
10065 status open
10067 \begin_layout Plain Layout
10069 # External variables:
10070 \end_layout
10072 \begin_layout Plain Layout
10074 #    Optind -- index in ARGV of first nonoption argument
10075 \end_layout
10077 \begin_layout Plain Layout
10079 #    Optarg -- string value of argument to current option
10080 \end_layout
10082 \begin_layout Plain Layout
10084 #    Opterr -- if nonzero, print our own diagnostic
10085 \end_layout
10087 \begin_layout Plain Layout
10089 #    Optopt -- current option letter
10090 \end_layout
10092 \begin_layout Plain Layout
10094 \end_layout
10096 \begin_layout Plain Layout
10098 # Returns:
10099 \end_layout
10101 \begin_layout Plain Layout
10103 #    -1     at end of options
10104 \end_layout
10106 \begin_layout Plain Layout
10108 #    ?      for unrecognized option
10109 \end_layout
10111 \begin_layout Plain Layout
10113 #    <c>    a character representing the current option
10114 \end_layout
10116 \begin_layout Plain Layout
10118 \end_layout
10120 \begin_layout Plain Layout
10122 # Private Data:
10123 \end_layout
10125 \begin_layout Plain Layout
10127 #    _opti  -- index in multi-flag option, e.g., -abc
10128 \end_layout
10130 \end_inset
10133 \end_layout
10135 \begin_layout Standard
10136 The function follows.
10137  The final two parameters, 
10138 \begin_inset Flex CharStyle:Code
10139 status collapsed
10141 \begin_layout Plain Layout
10142 thisopt
10143 \end_layout
10145 \end_inset
10147  and 
10148 \begin_inset Flex CharStyle:Code
10149 status collapsed
10151 \begin_layout Plain Layout
10153 \end_layout
10155 \end_inset
10157  are local variables and not parameters --- as indicated by the multiple
10158  spaces preceding them.
10159  Awk doesn't care, the multiple spaces are a convention to help us humans.
10160 \end_layout
10162 \begin_layout Chunk
10163 getopt.awk-getopt()
10164 \end_layout
10166 \begin_layout Standard
10167 \begin_inset listings
10168 inline false
10169 status open
10171 \begin_layout Plain Layout
10173 function getopt(argc, argv, options,    thisopt, i)
10174 \end_layout
10176 \begin_layout Plain Layout
10179 \end_layout
10181 \begin_layout Plain Layout
10183     if (length(options) == 0)    # no options given
10184 \end_layout
10186 \begin_layout Plain Layout
10188         return -1
10189 \end_layout
10191 \begin_layout Plain Layout
10193     if (argv[Optind] == "--") {  # all done
10194 \end_layout
10196 \begin_layout Plain Layout
10198         Optind++
10199 \end_layout
10201 \begin_layout Plain Layout
10203         _opti = 0
10204 \end_layout
10206 \begin_layout Plain Layout
10208         return -1
10209 \end_layout
10211 \begin_layout Plain Layout
10213     } else if (argv[Optind] !~ /^-[^: 
10214 \backslash
10216 \backslash
10218 \backslash
10220 \backslash
10222 \backslash
10224 \backslash
10225 b]/) {
10226 \end_layout
10228 \begin_layout Plain Layout
10230         _opti = 0
10231 \end_layout
10233 \begin_layout Plain Layout
10235         return -1
10236 \end_layout
10238 \begin_layout Plain Layout
10240     }
10241 \end_layout
10243 \begin_layout Plain Layout
10245     if (_opti == 0)
10246 \end_layout
10248 \begin_layout Plain Layout
10250         _opti = 2
10251 \end_layout
10253 \begin_layout Plain Layout
10255     thisopt = substr(argv[Optind], _opti, 1)
10256 \end_layout
10258 \begin_layout Plain Layout
10260     Optopt = thisopt
10261 \end_layout
10263 \begin_layout Plain Layout
10265     i = index(options, thisopt)
10266 \end_layout
10268 \begin_layout Plain Layout
10270     if (i == 0) {
10271 \end_layout
10273 \begin_layout Plain Layout
10275         if (Opterr)
10276 \end_layout
10278 \begin_layout Plain Layout
10280             printf("%c -- invalid option
10281 \backslash
10283 \end_layout
10285 \begin_layout Plain Layout
10287                                   thisopt) > "/dev/stderr"
10288 \end_layout
10290 \begin_layout Plain Layout
10292         if (_opti >= length(argv[Optind])) {
10293 \end_layout
10295 \begin_layout Plain Layout
10297             Optind++
10298 \end_layout
10300 \begin_layout Plain Layout
10302             _opti = 0
10303 \end_layout
10305 \begin_layout Plain Layout
10307         } else
10308 \end_layout
10310 \begin_layout Plain Layout
10312             _opti++
10313 \end_layout
10315 \begin_layout Plain Layout
10317         return "?"
10318 \end_layout
10320 \begin_layout Plain Layout
10322     }
10323 \end_layout
10325 \end_inset
10328 \end_layout
10330 \begin_layout Standard
10331 At this point, the option has been found and we need to know if it takes
10332  any arguments.
10333 \end_layout
10335 \begin_layout Standard
10336 \begin_inset listings
10337 inline false
10338 status open
10340 \begin_layout Plain Layout
10342     if (substr(options, i + 1, 1) == ":") {
10343 \end_layout
10345 \begin_layout Plain Layout
10347         # get option argument
10348 \end_layout
10350 \begin_layout Plain Layout
10352         if (length(substr(argv[Optind], _opti + 1)) > 0)
10353 \end_layout
10355 \begin_layout Plain Layout
10357             Optarg = substr(argv[Optind], _opti + 1)
10358 \end_layout
10360 \begin_layout Plain Layout
10362         else
10363 \end_layout
10365 \begin_layout Plain Layout
10367             Optarg = argv[++Optind]
10368 \end_layout
10370 \begin_layout Plain Layout
10372         _opti = 0
10373 \end_layout
10375 \begin_layout Plain Layout
10377     } else
10378 \end_layout
10380 \begin_layout Plain Layout
10382         Optarg = ""
10383 \end_layout
10385 \begin_layout Plain Layout
10387     if (_opti == 0 || _opti >= length(argv[Optind])) {
10388 \end_layout
10390 \begin_layout Plain Layout
10392         Optind++
10393 \end_layout
10395 \begin_layout Plain Layout
10397         _opti = 0
10398 \end_layout
10400 \begin_layout Plain Layout
10402     } else
10403 \end_layout
10405 \begin_layout Plain Layout
10407         _opti++
10408 \end_layout
10410 \begin_layout Plain Layout
10412     return thisopt
10413 \end_layout
10415 \begin_layout Plain Layout
10418 \end_layout
10420 \end_inset
10422 A test program is built in, too
10423 \end_layout
10425 \begin_layout Chunk
10426 getopt.awk-begin
10427 \end_layout
10429 \begin_layout Standard
10430 \begin_inset listings
10431 inline false
10432 status open
10434 \begin_layout Plain Layout
10436 BEGIN {
10437 \end_layout
10439 \begin_layout Plain Layout
10441     Opterr = 1    # default is to diagnose
10442 \end_layout
10444 \begin_layout Plain Layout
10446     Optind = 1    # skip ARGV[0]
10447 \end_layout
10449 \begin_layout Plain Layout
10451     # test program
10452 \end_layout
10454 \begin_layout Plain Layout
10456     if (_getopt_test) {
10457 \end_layout
10459 \begin_layout Plain Layout
10461         while ((_go_c = getopt(ARGC, ARGV, "ab:cd")) != -1)
10462 \end_layout
10464 \begin_layout Plain Layout
10466             printf("c = <%c>, optarg = <%s>
10467 \backslash
10469 \end_layout
10471 \begin_layout Plain Layout
10473                                        _go_c, Optarg)
10474 \end_layout
10476 \begin_layout Plain Layout
10478         printf("non-option arguments:
10479 \backslash
10481 \end_layout
10483 \begin_layout Plain Layout
10485         for (; Optind < ARGC; Optind++)
10486 \end_layout
10488 \begin_layout Plain Layout
10490             printf("
10491 \backslash
10492 tARGV[%d] = <%s>
10493 \backslash
10495 \end_layout
10497 \begin_layout Plain Layout
10499                                     Optind, ARGV[Optind])
10500 \end_layout
10502 \begin_layout Plain Layout
10504     }
10505 \end_layout
10507 \begin_layout Plain Layout
10510 \end_layout
10512 \end_inset
10515 \end_layout
10517 \begin_layout Standard
10518 The entire getopt.awk is made out of these chunks in order
10519 \end_layout
10521 \begin_layout Chunk
10522 getopt.awk
10523 \end_layout
10525 \begin_layout Standard
10526 \begin_inset listings
10527 inline false
10528 status open
10530 \begin_layout Plain Layout
10533 \backslash
10534 chunkref{getopt.awk-header}>
10535 \end_layout
10537 \begin_layout Plain Layout
10539 \end_layout
10541 \begin_layout Plain Layout
10544 \backslash
10545 chunkref{getopt.awk-notes}>
10546 \end_layout
10548 \begin_layout Plain Layout
10551 \backslash
10552 chunkref{getopt.awk-getopt()}>
10553 \end_layout
10555 \begin_layout Plain Layout
10558 \backslash
10559 chunkref{getopt.awk-begin}>
10560 \end_layout
10562 \end_inset
10565 \end_layout
10567 \begin_layout Standard
10568 Although we only want the header and function:
10569 \end_layout
10571 \begin_layout Chunk
10572 getopt
10573 \end_layout
10575 \begin_layout Standard
10576 \begin_inset listings
10577 inline false
10578 status open
10580 \begin_layout Plain Layout
10582 # try: locate getopt.awk for the full original file
10583 \end_layout
10585 \begin_layout Plain Layout
10587 # as part of your standard awk installation
10588 \end_layout
10590 \begin_layout Plain Layout
10593 \backslash
10594 chunkref{getopt.awk-header}>
10595 \end_layout
10597 \begin_layout Plain Layout
10599 \end_layout
10601 \begin_layout Plain Layout
10604 \backslash
10605 chunkref{getopt.awk-getopt()}>
10606 \end_layout
10608 \end_inset
10611 \end_layout
10613 \begin_layout Chapter
10614 Newfangle LaTeX source code
10615 \end_layout
10617 \begin_layout Section
10618 newfangle module
10619 \end_layout
10621 \begin_layout Standard
10622 Here we define a Lyx .module file that makes it convenient to use LyX for
10623  writing such literate programs.
10624 \end_layout
10626 \begin_layout Standard
10627 This file 
10628 \begin_inset Flex CharStyle:Code
10629 status collapsed
10631 \begin_layout Plain Layout
10632 ./newfangle.module
10633 \end_layout
10635 \end_inset
10637  can be installed in your personal 
10638 \begin_inset Flex CharStyle:Code
10639 status collapsed
10641 \begin_layout Plain Layout
10642 .lyx/layouts folder
10643 \end_layout
10645 \end_inset
10648  You will need to Tools Reconfigure so that LyX notices it.
10649  It adds a new format Chunk, which should precede every listing and contain
10650  the chunk name.
10652 \end_layout
10654 \begin_layout Chunk
10655 ./newfangle.module,language=
10656 \end_layout
10658 \begin_layout Standard
10659 \begin_inset listings
10660 inline false
10661 status open
10663 \begin_layout Plain Layout
10666 \backslash
10667 DeclareLyXModule{Newfangle Literate Listings}
10668 \end_layout
10670 \begin_layout Plain Layout
10672 #DescriptionBegin
10673 \end_layout
10675 \begin_layout Plain Layout
10677 #  Newfangle literate listings allow one to write
10678 \end_layout
10680 \begin_layout Plain Layout
10682 #   literate programs after the fashion of noweb, but without having
10683 \end_layout
10685 \begin_layout Plain Layout
10687 #   to use noweave to generate the documentation.
10688  Instead the listings
10689 \end_layout
10691 \begin_layout Plain Layout
10693 #   package is extended in conjunction with the noweb package to implement
10694 \end_layout
10696 \begin_layout Plain Layout
10698 #   to code formating directly as latex.
10699 \end_layout
10701 \begin_layout Plain Layout
10703 #  The newfangle awk script
10704 \end_layout
10706 \begin_layout Plain Layout
10708 #DescriptionEnd
10709 \end_layout
10711 \begin_layout Plain Layout
10713 \end_layout
10715 \begin_layout Plain Layout
10717 Format 11
10718 \end_layout
10720 \begin_layout Plain Layout
10722 \end_layout
10724 \begin_layout Plain Layout
10726 AddToPreamble
10727 \end_layout
10729 \begin_layout Plain Layout
10732 \backslash
10733 chunkref{./newfangle.sty}>
10734 \end_layout
10736 \begin_layout Plain Layout
10738 EndPreamble
10739 \end_layout
10741 \begin_layout Plain Layout
10743 \end_layout
10745 \begin_layout Plain Layout
10748 \backslash
10749 chunkref{chunkstyle}>
10750 \end_layout
10752 \begin_layout Plain Layout
10754 \end_layout
10756 \begin_layout Plain Layout
10759 \backslash
10760 chunkref{chunkref}>
10761 \end_layout
10763 \end_inset
10766 \end_layout
10768 \begin_layout Subsection
10769 The Chunk style
10770 \end_layout
10772 \begin_layout Standard
10773 The purpose of the 
10774 \noun on
10775 chunk
10776 \noun default
10777  style is to make it easier for LyX users to provide the name to 
10778 \begin_inset Flex CharStyle:Code
10779 status collapsed
10781 \begin_layout Plain Layout
10783 \backslash
10784 lstlistings
10785 \end_layout
10787 \end_inset
10790  Normally this requires right-clicking on the listing, choosing settings,
10791  advanced, and then typing 
10792 \begin_inset Flex CharStyle:Code
10793 status collapsed
10795 \begin_layout Plain Layout
10796 name=chunk-name
10797 \end_layout
10799 \end_inset
10802  This has the further disadvantage that the name (and other options) are
10803  not generally visible during document editing.
10804 \end_layout
10806 \begin_layout Standard
10807 The chunk style is defined as a LaTeX command, so that all text on the same
10808  line is passed to the LaTeX command 
10809 \begin_inset Flex CharStyle:Code
10810 status collapsed
10812 \begin_layout Plain Layout
10813 Chunk
10814 \end_layout
10816 \end_inset
10819  This makes it easy to parse using 
10820 \begin_inset Flex CharStyle:Code
10821 status collapsed
10823 \begin_layout Plain Layout
10824 newfangle
10825 \end_layout
10827 \end_inset
10829 , and easy to pass these options on to the listings package.
10830  The first word in a chunk section should be the chunk name, and will have
10832 \begin_inset Flex CharStyle:Code
10833 status collapsed
10835 \begin_layout Plain Layout
10836 name=
10837 \end_layout
10839 \end_inset
10841  prepended to it.
10842  Any other words are accepted arguments to 
10843 \begin_inset Flex CharStyle:Code
10844 status collapsed
10846 \begin_layout Plain Layout
10848 \backslash
10849 lstset
10850 \end_layout
10852 \end_inset
10855 \end_layout
10857 \begin_layout Standard
10858 We set PassThru to 1 because the user is actually entering raw latex.
10859 \end_layout
10861 \begin_layout Chunk
10862 chunkstyle
10863 \end_layout
10865 \begin_layout Standard
10866 \begin_inset listings
10867 inline false
10868 status open
10870 \begin_layout Plain Layout
10872 Style Chunk
10873 \end_layout
10875 \begin_layout Plain Layout
10877   LatexType             Command
10878 \end_layout
10880 \begin_layout Plain Layout
10882   LatexName             Chunk
10883 \end_layout
10885 \begin_layout Plain Layout
10887   Margin                First_Dynamic
10888 \end_layout
10890 \begin_layout Plain Layout
10892   LeftMargin            Chunk:xxx
10893 \end_layout
10895 \begin_layout Plain Layout
10897   LabelSep              xx
10898 \end_layout
10900 \begin_layout Plain Layout
10902   LabelType             Static
10903 \end_layout
10905 \begin_layout Plain Layout
10907   LabelString           "Chunk:"
10908 \end_layout
10910 \begin_layout Plain Layout
10912   Align                 Left
10913 \end_layout
10915 \begin_layout Plain Layout
10917   PassThru              1
10918 \end_layout
10920 \begin_layout Plain Layout
10922 \end_layout
10924 \end_inset
10927 \end_layout
10929 \begin_layout Standard
10930 To make the label very visible we choose a larger font coloured red.
10931 \end_layout
10933 \begin_layout Standard
10934 \begin_inset listings
10935 inline false
10936 status open
10938 \begin_layout Plain Layout
10940   LabelFont
10941 \end_layout
10943 \begin_layout Plain Layout
10945     Family              Sans
10946 \end_layout
10948 \begin_layout Plain Layout
10950     Size                Large
10951 \end_layout
10953 \begin_layout Plain Layout
10955     Series              Bold
10956 \end_layout
10958 \begin_layout Plain Layout
10960     Shape               Italic
10961 \end_layout
10963 \begin_layout Plain Layout
10965     Color               red
10966 \end_layout
10968 \begin_layout Plain Layout
10970   EndFont
10971 \end_layout
10973 \begin_layout Plain Layout
10976 \end_layout
10978 \end_inset
10981 \end_layout
10983 \begin_layout Subsection
10984 The chunkref style
10985 \end_layout
10987 \begin_layout Standard
10988 We also define the Chunkref style which can be used to express cross references
10989  to chunks.
10990 \end_layout
10992 \begin_layout Chunk
10993 chunkref
10994 \end_layout
10996 \begin_layout Standard
10997 \begin_inset listings
10998 inline false
10999 status open
11001 \begin_layout Plain Layout
11003 InsetLayout Chunkref
11004 \end_layout
11006 \begin_layout Plain Layout
11008   LyxType               charstyle
11009 \end_layout
11011 \begin_layout Plain Layout
11013   LatexType             Command
11014 \end_layout
11016 \begin_layout Plain Layout
11018   LatexName             chunkref
11019 \end_layout
11021 \begin_layout Plain Layout
11023   PassThru              1
11024 \end_layout
11026 \begin_layout Plain Layout
11028   LabelFont             
11029 \end_layout
11031 \begin_layout Plain Layout
11033     Shape               Italic
11034 \end_layout
11036 \begin_layout Plain Layout
11038     Color               red
11039 \end_layout
11041 \begin_layout Plain Layout
11043   EndFont
11044 \end_layout
11046 \begin_layout Plain Layout
11049 \end_layout
11051 \end_inset
11054 \end_layout
11056 \begin_layout Section
11057 \begin_inset CommandInset label
11058 LatexCommand label
11059 name "sec:Latex-Macros"
11061 \end_inset
11063 Latex Macros
11064 \end_layout
11066 \begin_layout Standard
11067 We require the 
11068 \noun on
11069 listings
11070 \noun default
11072 \noun on
11073 noweb
11074 \noun default
11075  and 
11076 \noun on
11077 xargs
11078 \noun default
11079  packages.
11080  As noweb defines it's own 
11081 \begin_inset Flex CharStyle:Code
11082 status collapsed
11084 \begin_layout Plain Layout
11086 \backslash
11087 code
11088 \end_layout
11090 \end_inset
11092  environment, we re-define the one that LyX logical markup module expects
11093  here.
11094 \end_layout
11096 \begin_layout Chunk
11097 ./newfangle.sty,language=tex,basicstyle=
11098 \backslash
11099 ttfamily
11100 \end_layout
11102 \begin_layout Standard
11103 \begin_inset listings
11104 inline false
11105 status open
11107 \begin_layout Plain Layout
11110 \backslash
11111 usepackage{listings}%
11112 \end_layout
11114 \begin_layout Plain Layout
11117 \backslash
11118 usepackage{noweb}%
11119 \end_layout
11121 \begin_layout Plain Layout
11124 \backslash
11125 usepackage{xargs}%
11126 \end_layout
11128 \begin_layout Plain Layout
11131 \backslash
11132 renewcommand{
11133 \backslash
11134 code}[1]{
11135 \backslash
11136 texttt{#1}}%
11137 \end_layout
11139 \end_inset
11142 \end_layout
11144 \begin_layout Standard
11145 We also define a 
11146 \begin_inset Flex CharStyle:Code
11147 status collapsed
11149 \begin_layout Plain Layout
11150 CChunk
11151 \end_layout
11153 \end_inset
11155  macro, for use as: 
11156 \begin_inset Flex CharStyle:Code
11157 status collapsed
11159 \begin_layout Plain Layout
11161 \backslash
11162 begin{CChunk}
11163 \end_layout
11165 \end_inset
11167  which will need renaming to 
11168 \begin_inset Flex CharStyle:Code
11169 status collapsed
11171 \begin_layout Plain Layout
11173 \backslash
11174 begin{Chunk}
11175 \end_layout
11177 \end_inset
11179  when I can do this without clashing with 
11180 \begin_inset Flex CharStyle:Code
11181 status collapsed
11183 \begin_layout Plain Layout
11185 \backslash
11186 Chunk
11187 \end_layout
11189 \end_inset
11192 \end_layout
11194 \begin_layout Standard
11195 \begin_inset listings
11196 inline false
11197 status open
11199 \begin_layout Plain Layout
11202 \backslash
11203 lstnewenvironment{Chunk}{
11204 \backslash
11205 relax}{
11206 \backslash
11207 relax}%
11208 \end_layout
11210 \end_inset
11213 \end_layout
11215 \begin_layout Standard
11216 We also define a suitable 
11217 \begin_inset Flex CharStyle:Code
11218 status collapsed
11220 \begin_layout Plain Layout
11222 \backslash
11223 lstset
11224 \end_layout
11226 \end_inset
11228  of parameters that suit the literate programming style after the fashion
11229  of 
11230 \noun on
11231 noweave
11232 \noun default
11234 \end_layout
11236 \begin_layout Standard
11237 \begin_inset listings
11238 inline false
11239 status open
11241 \begin_layout Plain Layout
11244 \backslash
11245 lstset{numbers=left, stepnumber=5, numbersep=5pt,
11246 \end_layout
11248 \begin_layout Plain Layout
11250         breaklines=false,basicstyle=
11251 \backslash
11252 ttfamily,
11253 \end_layout
11255 \begin_layout Plain Layout
11257         numberstyle=
11258 \backslash
11259 tiny, language=C}%
11260 \end_layout
11262 \end_inset
11265 \end_layout
11267 \begin_layout Standard
11268 We also define a notangle-like mechanism for 
11269 \emph on
11270 escaping
11271 \emph default
11272  to LaTeX from the listing, and by which we can refer to other listings.
11273  We declare the 
11274 \begin_inset Flex CharStyle:Code
11275 status collapsed
11277 \begin_layout Plain Layout
11278 =<\SpecialChar \ldots{}
11280 \end_layout
11282 \end_inset
11284  sequence to contain LaTeX code, and include another like this chunk: 
11285 \begin_inset Flex CharStyle:Code
11286 status collapsed
11288 \begin_layout Plain Layout
11290 \backslash
11291 chunkref{chunkname}>
11292 \end_layout
11294 \end_inset
11297  However, because 
11298 \begin_inset Flex CharStyle:Code
11299 status collapsed
11301 \begin_layout Plain Layout
11302 =<\SpecialChar \ldots{}
11304 \end_layout
11306 \end_inset
11308  is already defined to contain LaTeX code for this document --- this is
11309  a 
11310 \noun on
11311 newfangle
11312 \noun default
11313  document after all --- the code fragment below effectively contains the
11314  LaTeX code: 
11315 \begin_inset Flex CharStyle:Code
11316 status collapsed
11318 \begin_layout Plain Layout
11320 \end_layout
11322 \end_inset
11325  To avoid problems with document generation, I had to declare an lstlistings
11326  property: 
11327 \begin_inset Flex CharStyle:Code
11328 status collapsed
11330 \begin_layout Plain Layout
11331 escapeinside={}
11332 \end_layout
11334 \end_inset
11336  for this listing only; which in LyX was done by right-clicking the listings
11337  inset, choosing 
11338 \begin_inset Flex CharStyle:Code
11339 status collapsed
11341 \begin_layout Plain Layout
11342 settings
11343 \end_layout
11345 \end_inset
11347 \SpecialChar \menuseparator
11349 \begin_inset Flex CharStyle:Code
11350 status collapsed
11352 \begin_layout Plain Layout
11353 advanced
11354 \end_layout
11356 \end_inset
11359 \end_layout
11361 \begin_layout Standard
11362 \begin_inset Note Note
11363 status collapsed
11365 \begin_layout Plain Layout
11366 =< isn't enjoyed literally here, in a listing when the escape sequence is
11367  already defined as shown...
11368  we need to somehow escape this representation...
11369 \end_layout
11371 \end_inset
11374 \end_layout
11376 \begin_layout Standard
11377 \begin_inset listings
11378 lstparams "escapeinside={}"
11379 inline false
11380 status open
11382 \begin_layout Plain Layout
11385 \backslash
11386 lstset{escapeinside={=<}{>}}%
11387 \end_layout
11389 \end_inset
11392 \end_layout
11394 \begin_layout Standard
11395 Although our macros will contain the @ symbol, they will be included in
11396  a 
11397 \begin_inset Flex CharStyle:Code
11398 status collapsed
11400 \begin_layout Plain Layout
11402 \backslash
11403 makeatletter
11404 \end_layout
11406 \end_inset
11408  section by LyX; however we keep the commented out 
11409 \begin_inset Flex CharStyle:Code
11410 status collapsed
11412 \begin_layout Plain Layout
11414 \backslash
11415 makeatletter
11416 \end_layout
11418 \end_inset
11420  as a reminder.
11421  The listings package likes to centre the titles, but noweb titles are specially
11422  formatted and must be left aligned.
11423  The simplest way to do this turned out to be by removing the definition
11424  of 
11425 \begin_inset Flex CharStyle:Code
11426 status collapsed
11428 \begin_layout Plain Layout
11430 \backslash
11431 lst@maketitle
11432 \end_layout
11434 \end_inset
11437  This may interact badly if other listings want a regular title or caption.
11438  We remember the old maketitle in case we need it.
11439 \end_layout
11441 \begin_layout Standard
11442 \begin_inset listings
11443 inline false
11444 status open
11446 \begin_layout Plain Layout
11449 \backslash
11450 makeatletter
11451 \end_layout
11453 \begin_layout Plain Layout
11455 %somehow re-defining maketitle gives us a left-aligned title
11456 \end_layout
11458 \begin_layout Plain Layout
11460 %which is extactly what our specially formatted title needs!
11461 \end_layout
11463 \begin_layout Plain Layout
11466 \backslash
11467 global
11468 \backslash
11470 \backslash
11471 newfangle@lst@maketitle
11472 \backslash
11473 lst@maketitle%
11474 \end_layout
11476 \begin_layout Plain Layout
11479 \backslash
11480 global
11481 \backslash
11483 \backslash
11484 lst@maketitle{}%
11485 \end_layout
11487 \end_inset
11490 \end_layout
11492 \begin_layout Subsection
11493 \begin_inset CommandInset label
11494 LatexCommand label
11495 name "sub:The-chunk-command"
11497 \end_inset
11499 The chunk command
11500 \end_layout
11502 \begin_layout Standard
11503 Our chunk command accepts one argument, and calls 
11504 \begin_inset Flex CharStyle:Code
11505 status collapsed
11507 \begin_layout Plain Layout
11509 \backslash
11510 ltset
11511 \end_layout
11513 \end_inset
11516  Although 
11517 \begin_inset Flex CharStyle:Code
11518 status collapsed
11520 \begin_layout Plain Layout
11522 \backslash
11523 ltset
11524 \end_layout
11526 \end_inset
11528  will note the name, this is erased when the next 
11529 \begin_inset Flex CharStyle:Code
11530 status collapsed
11532 \begin_layout Plain Layout
11534 \backslash
11535 lstlisting
11536 \end_layout
11538 \end_inset
11540  starts, so we make a note of this in 
11541 \begin_inset Flex CharStyle:Code
11542 status collapsed
11544 \begin_layout Plain Layout
11546 \backslash
11547 lst@chunkname
11548 \end_layout
11550 \end_inset
11552  and restore in in lstlistings Init hook.
11553 \end_layout
11555 \begin_layout Standard
11556 \begin_inset listings
11557 inline false
11558 status open
11560 \begin_layout Plain Layout
11563 \backslash
11565 \backslash
11566 Chunk#1{%
11567 \end_layout
11569 \begin_layout Plain Layout
11571   
11572 \backslash
11573 lstset{title={
11574 \backslash
11575 newfanglecaption},name=#1}%
11576 \end_layout
11578 \begin_layout Plain Layout
11580   
11581 \backslash
11582 global
11583 \backslash
11584 edef
11585 \backslash
11586 lst@chunkname{
11587 \backslash
11588 lst@intname}%
11589 \end_layout
11591 \begin_layout Plain Layout
11594 \end_layout
11596 \begin_layout Plain Layout
11599 \backslash
11601 \backslash
11602 lst@chunkname{
11603 \backslash
11604 empty}%
11605 \end_layout
11607 \end_inset
11610 \end_layout
11612 \begin_layout Subsubsection
11613 Chunk parameters
11614 \end_layout
11616 \begin_layout Standard
11617 Newfangle permits parameterized chunks, and requires the paramters to be
11618  specified as listings options.
11619  The newfangle script uses this, and although we don't do anything with
11620  these in the LaTeX code right now, we need to stop the listings package
11621  complaining.
11622 \end_layout
11624 \begin_layout Standard
11625 \begin_inset listings
11626 inline false
11627 status open
11629 \begin_layout Plain Layout
11632 \backslash
11633 lst@Key{params}
11634 \backslash
11635 relax{
11636 \backslash
11638 \backslash
11639 newfangle@chunk@params{#1}}%
11640 \end_layout
11642 \end_inset
11645 \end_layout
11647 \begin_layout Standard
11648 As it is common to define a chunk which then needs appending to another
11649  chunk, and annoying to have to declare a single line chunk to manage the
11650  include, we support an 
11651 \begin_inset Flex CharStyle:Code
11652 status collapsed
11654 \begin_layout Plain Layout
11655 append=
11656 \end_layout
11658 \end_inset
11660  option.
11662 \end_layout
11664 \begin_layout Standard
11665 \begin_inset listings
11666 inline false
11667 status open
11669 \begin_layout Plain Layout
11672 \backslash
11673 lst@Key{append}
11674 \backslash
11675 relax{
11676 \backslash
11678 \backslash
11679 newfangle@chunk@append{#1}}%
11680 \end_layout
11682 \end_inset
11685 \end_layout
11687 \begin_layout Subsection
11688 The noweb styled caption
11689 \end_layout
11691 \begin_layout Standard
11692 We define a public macro 
11693 \begin_inset Flex CharStyle:Code
11694 status collapsed
11696 \begin_layout Plain Layout
11698 \backslash
11699 newfanglecaption
11700 \end_layout
11702 \end_inset
11704  which can be set as a regular title.
11705  By means of 
11706 \begin_inset Flex CharStyle:Code
11707 status collapsed
11709 \begin_layout Plain Layout
11711 \backslash
11712 protect
11713 \end_layout
11715 \end_inset
11717 , It expands to 
11718 \begin_inset Flex CharStyle:Code
11719 status collapsed
11721 \begin_layout Plain Layout
11723 \backslash
11724 newfangle@caption
11725 \end_layout
11727 \end_inset
11729  at the appriate time when the caption is emitted.
11730 \end_layout
11732 \begin_layout Standard
11733 \begin_inset listings
11734 inline false
11735 status open
11737 \begin_layout Plain Layout
11740 \backslash
11742 \backslash
11743 newfanglecaption{
11744 \backslash
11745 protect
11746 \backslash
11747 newfangle@caption}%
11748 \end_layout
11750 \end_inset
11753 \end_layout
11755 \begin_layout Standard
11756 \begin_inset Float figure
11757 placement H
11758 wide false
11759 sideways false
11760 status collapsed
11762 \begin_layout Plain Layout
11763 \begin_inset Box Boxed
11764 position "t"
11765 hor_pos "c"
11766 has_inner_box 1
11767 inner_pos "t"
11768 use_parbox 0
11769 width "100col%"
11770 special "none"
11771 height "1in"
11772 height_special "totalheight"
11773 status open
11775 \begin_layout Plain Layout
11777 \begin_inset space \qquad{}
11778 \end_inset
11781 \shape italic
11782 some-chunk
11783 \shape default
11784  19b⟩
11785 \begin_inset Formula $\equiv+$
11786 \end_inset
11789 \begin_inset space \qquad{}
11790 \end_inset
11793 \begin_inset space \qquad{}
11794 \end_inset
11797 \begin_inset space \qquad{}
11798 \end_inset
11801 \begin_inset Formula $\triangleleft$
11802 \end_inset
11805 \begin_inset space \quad{}
11806 \end_inset
11809 \begin_inset Formula $\triangleright$
11810 \end_inset
11813 \end_layout
11815 \begin_layout Plain Layout
11817 \size footnotesize
11818 In this example, the current chunk is 22c, and therefore the third chunk
11819  on page 22.
11820 \end_layout
11822 \begin_layout Plain Layout
11824 \size footnotesize
11825 It's name is 
11826 \emph on
11827 some-chunk
11828 \emph default
11831 \end_layout
11833 \begin_layout Plain Layout
11835 \size footnotesize
11836 The first chunk with this name (19b) occurs as the second chunk on page
11837  19.
11838 \end_layout
11840 \begin_layout Plain Layout
11842 \size footnotesize
11843 The previous chunk (22d) with the same name is the second chunk on page
11844  22.
11845 \end_layout
11847 \begin_layout Plain Layout
11849 \size footnotesize
11850 The next chunk (24d) is the fourth chunk on page 24.
11851 \end_layout
11853 \begin_layout Plain Layout
11854 \begin_inset Caption
11856 \begin_layout Plain Layout
11857 noweb heading
11858 \end_layout
11860 \end_inset
11863 \end_layout
11865 \end_inset
11868 \end_layout
11870 \end_inset
11872 The general noweb output format compactly identifies the current chunk,
11873  and references to the first chunk, and the previous and next chunks that
11874  have the same name.
11876 \end_layout
11878 \begin_layout Standard
11879 This means that we need to keep a counter for each chunk-name, that we use
11880  to count chunks of the same name.
11882 \end_layout
11884 \begin_layout Subsection
11885 The chunk counter
11886 \end_layout
11888 \begin_layout Standard
11889 It would be natural to have a counter for each chunk name, but TeX would
11890  soon run out of counters
11891 \begin_inset Foot
11892 status collapsed
11894 \begin_layout Plain Layout
11895 \SpecialChar \ldots{}
11896 soon 
11897 \emph on
11899 \emph default
11900  run out of counters and so I had to re-write the LaTeX macros to share
11901  a counter as described here
11902 \end_layout
11904 \end_inset
11906 , so we have one counter which we save at the end of a chunk and restore
11907  at the beginning of a chunk.
11908 \end_layout
11910 \begin_layout Standard
11911 \begin_inset listings
11912 inline false
11913 status open
11915 \begin_layout Plain Layout
11918 \backslash
11919 newcounter{newfangle@chunkcounter}%
11920 \end_layout
11922 \end_inset
11925 \end_layout
11927 \begin_layout Standard
11928 We construct the name of this variable to store the counter to be the text
11930 \begin_inset Flex CharStyle:Code
11931 status collapsed
11933 \begin_layout Plain Layout
11934 lst-chunk-
11935 \end_layout
11937 \end_inset
11939  prefixed onto the chunks own name, and store it in 
11940 \begin_inset Flex CharStyle:Code
11941 status collapsed
11943 \begin_layout Plain Layout
11945 \backslash
11946 chunkcount
11947 \end_layout
11949 \end_inset
11953 \end_layout
11955 \begin_layout Standard
11956 We save the counter like this:
11957 \end_layout
11959 \begin_layout Chunk
11960 save-counter
11961 \end_layout
11963 \begin_layout Standard
11964 \begin_inset listings
11965 inline false
11966 status open
11968 \begin_layout Plain Layout
11971 \backslash
11972 global
11973 \backslash
11974 expandafter
11975 \backslash
11976 edef
11977 \backslash
11978 csname 
11979 \backslash
11980 chunkcount
11981 \backslash
11982 endcsname{
11983 \backslash
11984 arabic{newfangle@chunkcounter}}%
11985 \end_layout
11987 \end_inset
11990 \end_layout
11992 \begin_layout Standard
11993 and restore the counter like this:
11994 \end_layout
11996 \begin_layout Chunk
11997 restore-counter
11998 \end_layout
12000 \begin_layout Standard
12001 \begin_inset listings
12002 inline false
12003 status open
12005 \begin_layout Plain Layout
12008 \backslash
12009 setcounter{newfangle@chunkcounter}{
12010 \backslash
12011 csname 
12012 \backslash
12013 chunkcount
12014 \backslash
12015 endcsname}%
12016 \end_layout
12018 \end_inset
12021 \end_layout
12023 \begin_layout Chunk
12024 ./newfangle.sty
12025 \end_layout
12027 \begin_layout Standard
12028 If there does not already exist a variable whose name is stored in 
12029 \begin_inset Flex CharStyle:Code
12030 status collapsed
12032 \begin_layout Plain Layout
12034 \backslash
12035 chunkcount
12036 \end_layout
12038 \end_inset
12040 , then we know we are the first chunk with this name, and then define a
12041  counter.
12043 \end_layout
12045 \begin_layout Standard
12046 Although chunks of the same name share a common counter, they must still
12047  be distinguished.
12048  We use is the internal name of the listing, suffixed by the counter value.
12049  So the first chunk might be 
12050 \begin_inset Flex CharStyle:Code
12051 status collapsed
12053 \begin_layout Plain Layout
12054 something-1
12055 \end_layout
12057 \end_inset
12059  and the second chunk be 
12060 \begin_inset Flex CharStyle:Code
12061 status collapsed
12063 \begin_layout Plain Layout
12064 something-2
12065 \end_layout
12067 \end_inset
12069 , etc.
12070 \end_layout
12072 \begin_layout Standard
12073 We also calculate the name of the previous chunk if we can (before we increment
12074  the chunk counter).
12075  If this is the first chunk of that name, then 
12076 \begin_inset Flex CharStyle:Code
12077 status collapsed
12079 \begin_layout Plain Layout
12081 \backslash
12082 prevchunkname
12083 \end_layout
12085 \end_inset
12087  is set to 
12088 \begin_inset Flex CharStyle:Code
12089 status collapsed
12091 \begin_layout Plain Layout
12093 \backslash
12094 relax
12095 \end_layout
12097 \end_inset
12099  which the noweb package will interpret as not existing.
12100 \end_layout
12102 \begin_layout Standard
12103 \begin_inset listings
12104 inline false
12105 status open
12107 \begin_layout Plain Layout
12110 \backslash
12112 \backslash
12113 newfangle@caption{%
12114 \end_layout
12116 \begin_layout Plain Layout
12118   
12119 \backslash
12120 edef
12121 \backslash
12122 chunkcount{lst-chunk-
12123 \backslash
12124 lst@intname}%
12125 \end_layout
12127 \begin_layout Plain Layout
12129   
12130 \backslash
12131 @ifundefined{
12132 \backslash
12133 chunkcount}{%
12134 \end_layout
12136 \begin_layout Plain Layout
12138     
12139 \backslash
12140 expandafter
12141 \backslash
12142 gdef
12143 \backslash
12144 csname 
12145 \backslash
12146 chunkcount
12147 \backslash
12148 endcsname{0}%
12149 \end_layout
12151 \begin_layout Plain Layout
12153     
12154 \backslash
12155 setcounter{newfangle@chunkcounter}{
12156 \backslash
12157 csname 
12158 \backslash
12159 chunkcount
12160 \backslash
12161 endcsname}%
12162 \end_layout
12164 \begin_layout Plain Layout
12166     
12167 \backslash
12169 \backslash
12170 prevchunkname
12171 \backslash
12172 relax%
12173 \end_layout
12175 \begin_layout Plain Layout
12177   }{%
12178 \end_layout
12180 \begin_layout Plain Layout
12182     
12183 \backslash
12184 setcounter{newfangle@chunkcounter}{
12185 \backslash
12186 csname 
12187 \backslash
12188 chunkcount
12189 \backslash
12190 endcsname}%
12191 \end_layout
12193 \begin_layout Plain Layout
12195     
12196 \backslash
12197 edef
12198 \backslash
12199 prevchunkname{
12200 \backslash
12201 lst@intname-
12202 \backslash
12203 arabic{newfangle@chunkcounter}}%
12204 \end_layout
12206 \begin_layout Plain Layout
12208   }%
12209 \end_layout
12211 \end_inset
12214 \end_layout
12216 \begin_layout Standard
12217 After incrementing the chunk counter, we then define the name of this chunk,
12218  as well as the name of the first chunk.
12219 \end_layout
12221 \begin_layout Standard
12222 \begin_inset listings
12223 inline false
12224 status open
12226 \begin_layout Plain Layout
12228   
12229 \backslash
12230 addtocounter{newfangle@chunkcounter}{1}%
12231 \end_layout
12233 \begin_layout Plain Layout
12235   
12236 \backslash
12237 global
12238 \backslash
12239 expandafter
12240 \backslash
12241 edef
12242 \backslash
12243 csname 
12244 \backslash
12245 chunkcount
12246 \backslash
12247 endcsname{
12248 \backslash
12249 arabic{newfangle@chunkcounter}}%
12250 \end_layout
12252 \begin_layout Plain Layout
12254   
12255 \backslash
12256 edef
12257 \backslash
12258 chunkname{
12259 \backslash
12260 lst@intname-
12261 \backslash
12262 arabic{newfangle@chunkcounter}}%
12263 \end_layout
12265 \begin_layout Plain Layout
12267   
12268 \backslash
12269 edef
12270 \backslash
12271 firstchunkname{
12272 \backslash
12273 lst@intname-1}%
12274 \end_layout
12276 \end_inset
12279 \end_layout
12281 \begin_layout Standard
12282 We now need to calculate the name of the next chunk.
12283  We do this by temporarily skipping the counter on by one; however there
12284  may not actually be another chunk with this name! We detect this by also
12285  defining a label for each chunk based on the chunkname.
12286  If there is a next chunkname then it will define a label with that name.
12287  As labels are persistent, we can at least tell the second time LaTeX is
12288  run.
12289  If we don't find such a defined label then we define 
12290 \begin_inset Flex CharStyle:Code
12291 status collapsed
12293 \begin_layout Plain Layout
12295 \backslash
12296 nextchunkname
12297 \end_layout
12299 \end_inset
12301  to 
12302 \begin_inset Flex CharStyle:Code
12303 status collapsed
12305 \begin_layout Plain Layout
12307 \backslash
12308 relax
12309 \end_layout
12311 \end_inset
12314 \end_layout
12316 \begin_layout Standard
12317 \begin_inset listings
12318 inline false
12319 status open
12321 \begin_layout Plain Layout
12323   
12324 \backslash
12325 addtocounter{newfangle@chunkcounter}{1}%
12326 \end_layout
12328 \begin_layout Plain Layout
12330   
12331 \backslash
12332 edef
12333 \backslash
12334 nextchunkname{
12335 \backslash
12336 lst@intname-
12337 \backslash
12338 arabic{newfangle@chunkcounter}}%
12339 \end_layout
12341 \begin_layout Plain Layout
12343   
12344 \backslash
12345 @ifundefined{r@label-
12346 \backslash
12347 nextchunkname}{
12348 \backslash
12350 \backslash
12351 nextchunkname
12352 \backslash
12353 relax}{}%
12354 \end_layout
12356 \end_inset
12359 \end_layout
12361 \begin_layout Standard
12362 The noweb package requires that we define a 
12363 \begin_inset Flex CharStyle:Code
12364 status collapsed
12366 \begin_layout Plain Layout
12368 \backslash
12369 sublabel
12370 \end_layout
12372 \end_inset
12374  for every chunk, with a unique name, which is then used to print out it's
12375  navigation hints.
12376 \end_layout
12378 \begin_layout Standard
12379 We also define a regular label for this chunk, as was mentioned above when
12380  we calculated 
12381 \begin_inset Flex CharStyle:Code
12382 status collapsed
12384 \begin_layout Plain Layout
12386 \backslash
12387 nextchunkname
12388 \end_layout
12390 \end_inset
12393  This requires LaTeX to be run at least twice after new chunk sections are
12394  added --- but noweb requried that anyway.
12395 \end_layout
12397 \begin_layout Standard
12398 \begin_inset listings
12399 inline false
12400 status open
12402 \begin_layout Plain Layout
12404   
12405 \backslash
12406 sublabel{
12407 \backslash
12408 chunkname}%
12409 \end_layout
12411 \begin_layout Plain Layout
12413 % define this label for every chunk instance, so we
12414 \end_layout
12416 \begin_layout Plain Layout
12418 % can tell when we are the last chunk of this name
12419 \end_layout
12421 \begin_layout Plain Layout
12423   
12424 \backslash
12425 label{label-
12426 \backslash
12427 chunkname}%
12428 \end_layout
12430 \end_inset
12433 \end_layout
12435 \begin_layout Standard
12436 We also try and add the chunk to the list of listings, but I'm afraid we
12437  don't do very well.
12438  We want each chunk name listing once, with all of it's references.
12439 \end_layout
12441 \begin_layout Standard
12442 \begin_inset listings
12443 inline false
12444 status open
12446 \begin_layout Plain Layout
12448   
12449 \backslash
12450 addcontentsline{lol}{lstlisting}{
12451 \backslash
12452 lst@name~[
12453 \backslash
12454 protect
12455 \backslash
12456 subpageref{
12457 \backslash
12458 chunkname}]}%
12459 \end_layout
12461 \end_inset
12464 \end_layout
12466 \begin_layout Standard
12467 We then call the noweb output macros in the same way that noweave generates
12468  them, except that we don't need to call 
12469 \begin_inset Flex CharStyle:Code
12470 status collapsed
12472 \begin_layout Plain Layout
12474 \backslash
12475 nwstartdeflinemarkup
12476 \end_layout
12478 \end_inset
12480  or 
12481 \begin_inset Flex CharStyle:Code
12482 status collapsed
12484 \begin_layout Plain Layout
12486 \backslash
12487 nwenddeflinemarkup
12488 \end_layout
12490 \end_inset
12492  -- and if we do it messes up the output somewhat.
12493 \end_layout
12495 \begin_layout Standard
12496 \begin_inset listings
12497 inline false
12498 status open
12500 \begin_layout Plain Layout
12502   
12503 \backslash
12504 nwmargintag{%
12505 \end_layout
12507 \begin_layout Plain Layout
12509     {%
12510 \end_layout
12512 \begin_layout Plain Layout
12514       
12515 \backslash
12516 nwtagstyle{}%
12517 \end_layout
12519 \begin_layout Plain Layout
12521       
12522 \backslash
12523 subpageref{
12524 \backslash
12525 chunkname}%
12526 \end_layout
12528 \begin_layout Plain Layout
12530     }%
12531 \end_layout
12533 \begin_layout Plain Layout
12535   }%
12536 \end_layout
12538 \begin_layout Plain Layout
12541 \end_layout
12543 \begin_layout Plain Layout
12545   
12546 \backslash
12547 moddef{%
12548 \end_layout
12550 \begin_layout Plain Layout
12552     {
12553 \backslash
12554 lst@name}%
12555 \end_layout
12557 \begin_layout Plain Layout
12559     {%
12560 \end_layout
12562 \begin_layout Plain Layout
12564       
12565 \backslash
12566 nwtagstyle{}
12567 \backslash
12569 \end_layout
12571 \begin_layout Plain Layout
12573       
12574 \backslash
12575 @ifundefined{newfangle@chunk@params}{}{%
12576 \end_layout
12578 \begin_layout Plain Layout
12580         (
12581 \backslash
12582 newfangle@chunk@params)%
12583 \end_layout
12585 \begin_layout Plain Layout
12587       }%
12588 \end_layout
12590 \begin_layout Plain Layout
12592       [
12593 \backslash
12594 csname 
12595 \backslash
12596 chunkcount
12597 \backslash
12598 endcsname]~%
12599 \end_layout
12601 \begin_layout Plain Layout
12603       
12604 \backslash
12605 subpageref{
12606 \backslash
12607 firstchunkname}%
12608 \end_layout
12610 \begin_layout Plain Layout
12612     }%
12613 \end_layout
12615 \begin_layout Plain Layout
12617     
12618 \backslash
12619 @ifundefined{newfangle@chunk@append}{}{%
12620 \end_layout
12622 \begin_layout Plain Layout
12624     
12625 \backslash
12626 ifx{}
12627 \backslash
12628 newfangle@chunk@append{x}
12629 \backslash
12630 else%
12631 \end_layout
12633 \begin_layout Plain Layout
12635         ,~add~to~
12636 \backslash
12637 newfangle@chunk@append%
12638 \end_layout
12640 \begin_layout Plain Layout
12642     
12643 \backslash
12645 \end_layout
12647 \begin_layout Plain Layout
12649     }%
12650 \end_layout
12652 \begin_layout Plain Layout
12655 \backslash
12656 global
12657 \backslash
12659 \backslash
12660 newfangle@chunk@append{}%
12661 \end_layout
12663 \begin_layout Plain Layout
12666 \backslash
12667 lstset{append=x}%
12668 \end_layout
12670 \begin_layout Plain Layout
12672   }%
12673 \end_layout
12675 \begin_layout Plain Layout
12678 \end_layout
12680 \begin_layout Plain Layout
12682   
12683 \backslash
12685 \backslash
12686 relax
12687 \backslash
12688 prevchunkname
12689 \backslash
12690 endmoddef
12691 \backslash
12692 else
12693 \backslash
12694 plusendmoddef
12695 \backslash
12697 \end_layout
12699 \begin_layout Plain Layout
12701 %  
12702 \backslash
12703 nwstartdeflinemarkup%
12704 \end_layout
12706 \begin_layout Plain Layout
12708   
12709 \backslash
12710 nwprevnextdefs{
12711 \backslash
12712 prevchunkname}{
12713 \backslash
12714 nextchunkname}%
12715 \end_layout
12717 \begin_layout Plain Layout
12719 %  
12720 \backslash
12721 nwenddeflinemarkup%
12722 \end_layout
12724 \begin_layout Plain Layout
12727 \end_layout
12729 \end_inset
12732 \end_layout
12734 \begin_layout Standard
12735 Originally this was developed as a 
12736 \begin_inset Flex CharStyle:Code
12737 status collapsed
12739 \begin_layout Plain Layout
12740 listings
12741 \end_layout
12743 \end_inset
12745  aspect, in the Init hook, but it was found easier to affect the title without
12746  using a hook --- 
12747 \begin_inset Flex CharStyle:Code
12748 status collapsed
12750 \begin_layout Plain Layout
12752 \backslash
12753 lst@AddToHookExe{PreSet}
12754 \end_layout
12756 \end_inset
12758  is still required to set the listings name to the name passed to the 
12759 \begin_inset Flex CharStyle:Code
12760 status collapsed
12762 \begin_layout Plain Layout
12764 \backslash
12765 Chunk
12766 \end_layout
12768 \end_inset
12770  command, though.
12771 \end_layout
12773 \begin_layout Standard
12774 \begin_inset listings
12775 inline false
12776 status open
12778 \begin_layout Plain Layout
12781 \backslash
12782 lst@BeginAspect{newfangle}
12783 \end_layout
12785 \begin_layout Plain Layout
12788 \backslash
12789 lst@Key{newfangle}{true}[t]{
12790 \backslash
12791 lstKV@SetIf{#1}{true}}
12792 \end_layout
12794 \begin_layout Plain Layout
12797 \backslash
12798 lst@AddToHookExe{PreSet}{
12799 \backslash
12800 global
12801 \backslash
12803 \backslash
12804 lst@intname
12805 \backslash
12806 lst@chunkname}
12807 \end_layout
12809 \begin_layout Plain Layout
12812 \backslash
12813 lst@AddToHook{Init}{}%
12814 \backslash
12815 newfangle@caption}
12816 \end_layout
12818 \begin_layout Plain Layout
12821 \backslash
12822 lst@EndAspect
12823 \end_layout
12825 \end_inset
12828 \end_layout
12830 \begin_layout Subsection
12831 Cross references
12832 \end_layout
12834 \begin_layout Standard
12835 We define the 
12836 \backslash
12837 chunkref command which makes it easy to generate visual references to different
12838  code chunks, e.g.
12839 \end_layout
12841 \begin_layout Standard
12842 \begin_inset Tabular
12843 <lyxtabular version="3" rows="4" columns="2">
12844 <features>
12845 <column alignment="center" valignment="top" width="0">
12846 <column alignment="center" valignment="top" width="0">
12847 <row>
12848 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
12849 \begin_inset Text
12851 \begin_layout Plain Layout
12852 Macro
12853 \end_layout
12855 \end_inset
12856 </cell>
12857 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
12858 \begin_inset Text
12860 \begin_layout Plain Layout
12861 Appearance
12862 \end_layout
12864 \end_inset
12865 </cell>
12866 </row>
12867 <row>
12868 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
12869 \begin_inset Text
12871 \begin_layout Plain Layout
12873 \backslash
12874 chunkref{preamble}
12875 \end_layout
12877 \end_inset
12878 </cell>
12879 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
12880 \begin_inset Text
12882 \begin_layout Plain Layout
12883 \begin_inset ERT
12884 status open
12886 \begin_layout Plain Layout
12889 \backslash
12890 chunkref{preamble}
12891 \end_layout
12893 \end_inset
12896 \end_layout
12898 \end_inset
12899 </cell>
12900 </row>
12901 <row>
12902 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
12903 \begin_inset Text
12905 \begin_layout Plain Layout
12907 \backslash
12908 chunkref[3]{preamble}
12909 \end_layout
12911 \end_inset
12912 </cell>
12913 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
12914 \begin_inset Text
12916 \begin_layout Plain Layout
12917 \begin_inset ERT
12918 status open
12920 \begin_layout Plain Layout
12923 \backslash
12924 chunkref[3]{preamble}
12925 \end_layout
12927 \end_inset
12930 \end_layout
12932 \end_inset
12933 </cell>
12934 </row>
12935 <row>
12936 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
12937 \begin_inset Text
12939 \begin_layout Plain Layout
12941 \backslash
12942 chunkref{preamble}[arg1, arg2]
12943 \end_layout
12945 \end_inset
12946 </cell>
12947 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
12948 \begin_inset Text
12950 \begin_layout Plain Layout
12951 \begin_inset ERT
12952 status open
12954 \begin_layout Plain Layout
12957 \backslash
12958 chunkref{preamble}[arg1, arg2]
12959 \end_layout
12961 \end_inset
12964 \end_layout
12966 \end_inset
12967 </cell>
12968 </row>
12969 </lyxtabular>
12971 \end_inset
12974 \end_layout
12976 \begin_layout Standard
12977 Chunkref can also be used within a code chunk to include another code chunk.
12978  The third optional parameter to chunkref is a comma sepatarated list of
12979  arguments, which will replace defined parameters in the chunkref.
12980 \begin_inset Note Note
12981 status open
12983 \begin_layout Plain Layout
12984 Darn it, if I have: =<
12985 \backslash
12986 chunkref{new-mode}[{chunks[chunk_name, "language"]},{mode}]> the inner braces
12987  (inside [ ]) cause _ to signify subscript even though we have lst@ReplaceIn
12988 \end_layout
12990 \end_inset
12993 \end_layout
12995 \begin_layout Standard
12996 \begin_inset listings
12997 inline false
12998 status open
13000 \begin_layout Plain Layout
13003 \backslash
13005 \backslash
13006 chunkref@args#1,{%
13007 \end_layout
13009 \begin_layout Plain Layout
13011   
13012 \backslash
13014 \backslash
13015 arg{#1}%
13016 \end_layout
13018 \begin_layout Plain Layout
13020   
13021 \backslash
13022 lst@ReplaceIn
13023 \backslash
13025 \backslash
13026 lst@filenamerpl%
13027 \end_layout
13029 \begin_layout Plain Layout
13031   
13032 \backslash
13033 arg%
13034 \end_layout
13036 \begin_layout Plain Layout
13038   
13039 \backslash
13040 @ifnextchar){
13041 \backslash
13042 relax}{, 
13043 \backslash
13044 chunkref@args}%
13045 \end_layout
13047 \begin_layout Plain Layout
13050 \end_layout
13052 \begin_layout Plain Layout
13055 \backslash
13056 newcommand
13057 \backslash
13058 chunkref[2][0]{%
13059 \end_layout
13061 \begin_layout Plain Layout
13063   
13064 \backslash
13065 @ifnextchar({
13066 \backslash
13067 chunkref@i{#1}{#2}}{
13068 \backslash
13069 chunkref@i{#1}{#2}()}%
13070 \end_layout
13072 \begin_layout Plain Layout
13075 \end_layout
13077 \begin_layout Plain Layout
13080 \backslash
13082 \backslash
13083 chunkref@i#1#2(#3){%
13084 \end_layout
13086 \begin_layout Plain Layout
13088   
13089 \backslash
13091 \backslash
13092 zero{0}%
13093 \end_layout
13095 \begin_layout Plain Layout
13097   
13098 \backslash
13100 \backslash
13101 chunk{#2}%
13102 \end_layout
13104 \begin_layout Plain Layout
13106   
13107 \backslash
13109 \backslash
13110 chunkno{#1}%
13111 \end_layout
13113 \begin_layout Plain Layout
13115   
13116 \backslash
13118 \backslash
13119 chunkargs{#3}%
13120 \end_layout
13122 \begin_layout Plain Layout
13124   
13125 \backslash
13127 \backslash
13128 chunkno
13129 \backslash
13130 zero%
13131 \end_layout
13133 \begin_layout Plain Layout
13135     
13136 \backslash
13138 \backslash
13139 chunkname{#2-1}%
13140 \end_layout
13142 \begin_layout Plain Layout
13144   
13145 \backslash
13146 else%
13147 \end_layout
13149 \begin_layout Plain Layout
13151     
13152 \backslash
13154 \backslash
13155 chunkname{#2-
13156 \backslash
13157 chunkno}%
13158 \end_layout
13160 \begin_layout Plain Layout
13162   
13163 \backslash
13165 \end_layout
13167 \begin_layout Plain Layout
13169   
13170 \backslash
13172 \backslash
13173 lst@arg
13174 \backslash
13175 chunk%
13176 \end_layout
13178 \begin_layout Plain Layout
13180   
13181 \backslash
13182 lst@ReplaceIn
13183 \backslash
13184 chunk
13185 \backslash
13186 lst@filenamerpl%
13187 \end_layout
13189 \begin_layout Plain Layout
13191   
13192 \backslash
13193 LA{%
13194 \backslash
13195 moddef{%
13196 \end_layout
13198 \begin_layout Plain Layout
13200     {
13201 \backslash
13202 chunk}%
13203 \end_layout
13205 \begin_layout Plain Layout
13207     {%
13208 \end_layout
13210 \begin_layout Plain Layout
13212       
13213 \backslash
13214 nwtagstyle{}
13215 \backslash
13217 \end_layout
13219 \begin_layout Plain Layout
13221       
13222 \backslash
13224 \backslash
13225 chunkno
13226 \backslash
13227 zero%
13228 \end_layout
13230 \begin_layout Plain Layout
13232       
13233 \backslash
13234 else%
13235 \end_layout
13237 \begin_layout Plain Layout
13239       [
13240 \backslash
13241 chunkno]%
13242 \end_layout
13244 \begin_layout Plain Layout
13246       
13247 \backslash
13249 \end_layout
13251 \begin_layout Plain Layout
13253       
13254 \backslash
13256 \backslash
13257 chunkargs
13258 \backslash
13259 empty%
13260 \end_layout
13262 \begin_layout Plain Layout
13264       
13265 \backslash
13266 else%
13267 \end_layout
13269 \begin_layout Plain Layout
13271         (
13272 \backslash
13273 chunkref@args #3,)%
13274 \end_layout
13276 \begin_layout Plain Layout
13278       
13279 \backslash
13281 \end_layout
13283 \begin_layout Plain Layout
13285       ~
13286 \backslash
13287 subpageref{
13288 \backslash
13289 chunkname}%
13290 \end_layout
13292 \begin_layout Plain Layout
13294     }%
13295 \end_layout
13297 \begin_layout Plain Layout
13299   }%
13300 \end_layout
13302 \begin_layout Plain Layout
13304   
13305 \backslash
13307 \backslash
13308 endmoddef%
13309 \end_layout
13311 \begin_layout Plain Layout
13314 \end_layout
13316 \end_inset
13319 \end_layout
13321 \begin_layout Subsection
13322 The end
13323 \end_layout
13325 \begin_layout Standard
13326 \begin_inset listings
13327 inline false
13328 status open
13330 \begin_layout Plain Layout
13333 \end_layout
13335 \begin_layout Plain Layout
13338 \backslash
13339 makeatother
13340 \end_layout
13342 \end_inset
13345 \end_layout
13347 \begin_layout Chapter
13348 Extracting newfangle
13349 \end_layout
13351 \begin_layout Section
13352 Extracting from Lyx
13353 \end_layout
13355 \begin_layout Standard
13356 To extract from LyX, you will need to configure LyX as explained in section
13358 \begin_inset CommandInset ref
13359 LatexCommand ref
13360 reference "sub:Configuring-the-build"
13362 \end_inset
13365 \end_layout
13367 \begin_layout Standard
13368 \begin_inset CommandInset label
13369 LatexCommand label
13370 name "lyx-build-script"
13372 \end_inset
13374 And this lyx-build scrap will extract newfangle for me.
13375 \end_layout
13377 \begin_layout Chunk
13378 lyx-build,language=sh
13379 \end_layout
13381 \begin_layout Standard
13382 \begin_inset listings
13383 inline false
13384 status open
13386 \begin_layout Plain Layout
13388 #! /bin/sh
13389 \end_layout
13391 \begin_layout Plain Layout
13393 set -x
13394 \end_layout
13396 \begin_layout Plain Layout
13398 \end_layout
13400 \begin_layout Plain Layout
13403 \backslash
13404 chunkref{lyx-build-helper}>
13405 \end_layout
13407 \begin_layout Plain Layout
13409 cd $PROJECT_DIR || exit 1
13410 \end_layout
13412 \begin_layout Plain Layout
13414 \end_layout
13416 \begin_layout Plain Layout
13418 /usr/local/bin/newfangle -R./newfangle $TEX_SRC > ./newfangle
13419 \end_layout
13421 \begin_layout Plain Layout
13423 /usr/local/bin/newfangle -R./newfangle.module $TEX_SRC > ./newfangle.module
13424 \end_layout
13426 \begin_layout Plain Layout
13428 \end_layout
13430 \begin_layout Plain Layout
13432 # run tests
13433 \end_layout
13435 \begin_layout Plain Layout
13437 ./newfangle -Rpca-test.awk $TEX_SRC | awk -f -
13438 \end_layout
13440 \end_inset
13443 \end_layout
13445 \begin_layout Standard
13446 With a lyx-build-helper
13447 \end_layout
13449 \begin_layout Chunk
13450 lyx-build-helper,language=sh
13451 \end_layout
13453 \begin_layout Standard
13454 \begin_inset listings
13455 inline false
13456 status open
13458 \begin_layout Plain Layout
13460 PROJECT_DIR="$LYX_r"
13461 \end_layout
13463 \begin_layout Plain Layout
13465 LYX_SRC="$PROJECT_DIR/${LYX_i%.tex}.lyx"
13466 \end_layout
13468 \begin_layout Plain Layout
13470 TEX_DIR="$LYX_p"
13471 \end_layout
13473 \begin_layout Plain Layout
13475 TEX_SRC="$TEX_DIR/$LYX_i"
13476 \end_layout
13478 \end_inset
13481 \end_layout
13483 \begin_layout Section
13484 Extracting from the command line
13485 \end_layout
13487 \begin_layout Standard
13488 First you will need the tex output, then you can extract:
13489 \end_layout
13491 \begin_layout Chunk
13492 lyx-build-manual,language=sh
13493 \end_layout
13495 \begin_layout Standard
13496 \begin_inset listings
13497 inline false
13498 status open
13500 \begin_layout Plain Layout
13502 lyx -e latex newfangle.lyx
13503 \end_layout
13505 \begin_layout Plain Layout
13507 newfangle -R./newfangle newfangle.tex > ./newfangle
13508 \end_layout
13510 \begin_layout Plain Layout
13512 newfangle -R./newfangle.module newfangle.tex > ./newfangle.module
13513 \end_layout
13515 \end_inset
13518 \end_layout
13520 \begin_layout Part
13521 Tests
13522 \end_layout
13524 \begin_layout Chapter
13525 Chunk Parameters
13526 \end_layout
13528 \begin_layout Chunk
13529 tests-sub,params=THING;colour
13530 \end_layout
13532 \begin_layout Standard
13533 \begin_inset listings
13534 inline false
13535 status open
13537 \begin_layout Plain Layout
13539 I see a ${THING} of 
13540 \end_layout
13542 \begin_layout Plain Layout
13544 colour ${colour}, 
13545 \end_layout
13547 \begin_layout Plain Layout
13549 looking closer =<
13550 \backslash
13551 chunkref{tests-sub-sub}(${colour})>
13552 \end_layout
13554 \end_inset
13557 \end_layout
13559 \begin_layout Chunk
13560 tests-sub-sub,params=colour
13561 \end_layout
13563 \begin_layout Standard
13564 \begin_inset listings
13565 inline false
13566 status open
13568 \begin_layout Plain Layout
13570 a funny shade of ${colour}
13571 \end_layout
13573 \end_inset
13576 \end_layout
13578 \begin_layout Chunk
13579 tests
13580 \end_layout
13582 \begin_layout Standard
13583 \begin_inset listings
13584 inline false
13585 status open
13587 \begin_layout Plain Layout
13589 What do you see? "=<
13590 \backslash
13591 chunkref{tests-sub}(joe, red)>"
13592 \end_layout
13594 \begin_layout Plain Layout
13596 Well, fancy!
13597 \end_layout
13599 \end_inset
13602 \end_layout
13604 \begin_layout Standard
13605 Should generate output:
13606 \end_layout
13608 \begin_layout Chunk
13609 tests-result
13610 \end_layout
13612 \begin_layout Standard
13613 \begin_inset listings
13614 inline false
13615 status open
13617 \begin_layout Plain Layout
13619 What do you see? "I see a joe of 
13620 \end_layout
13622 \begin_layout Plain Layout
13624                   colour red, 
13625 \end_layout
13627 \begin_layout Plain Layout
13629                   looking closer a funny shade of red"
13630 \end_layout
13632 \begin_layout Plain Layout
13634 Well, fancy!
13635 \end_layout
13637 \begin_layout Plain Layout
13639 \end_layout
13641 \end_inset
13644 \end_layout
13646 \end_body
13647 \end_document