Basic modes support working
[newfangle.git] / newfangle.lyx
blob6c12d9e8c5b8de0331cb5ff3ec032b05e6aad4e2
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.
4215  We also need to be able to parse a parameter list into an array of parameters.
4216 \end_layout
4218 \begin_layout Section
4219 Parsing argument lists
4220 \end_layout
4222 \begin_layout Standard
4223 An argument list may be as simple as in 
4224 \begin_inset Flex CharStyle:Code
4225 status collapsed
4227 \begin_layout Plain Layout
4229 \backslash
4230 chunkref{pull}(thing, otherthing)
4231 \end_layout
4233 \end_inset
4235  or as complex as:
4236 \end_layout
4238 \begin_layout LyX-Code
4240 \backslash
4241 chunkref{pull}(things[x, y], get_other_things(a, "all")) 
4242 \end_layout
4244 \begin_layout Standard
4245 --- which for all it's commas and quotes and parenthesis represents only
4246  two parameters.
4247 \end_layout
4249 \begin_layout Standard
4250 How do we stop the comma in 
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  from splitting it into two arguments 
4261 \begin_inset Flex CharStyle:Code
4262 status collapsed
4264 \begin_layout Plain Layout
4265 things[x
4266 \end_layout
4268 \end_inset
4270  and 
4271 \begin_inset Flex CharStyle:Code
4272 status collapsed
4274 \begin_layout Plain Layout
4276 \end_layout
4278 \end_inset
4280 --- neither of which make sense on their own? 
4281 \end_layout
4283 \begin_layout Standard
4284 One way it could be done is by refusing to split text between maching delimiters
4285 , such as 
4286 \begin_inset Flex CharStyle:Code
4287 status collapsed
4289 \begin_layout Plain Layout
4291 \end_layout
4293 \end_inset
4296 \begin_inset Flex CharStyle:Code
4297 status collapsed
4299 \begin_layout Plain Layout
4301 \end_layout
4303 \end_inset
4306 \begin_inset Flex CharStyle:Code
4307 status collapsed
4309 \begin_layout Plain Layout
4311 \end_layout
4313 \end_inset
4316 \begin_inset Flex CharStyle:Code
4317 status collapsed
4319 \begin_layout Plain Layout
4321 \end_layout
4323 \end_inset
4326 \begin_inset Flex CharStyle:Code
4327 status collapsed
4329 \begin_layout Plain Layout
4331 \end_layout
4333 \end_inset
4336 \begin_inset Flex CharStyle:Code
4337 status collapsed
4339 \begin_layout Plain Layout
4341 \end_layout
4343 \end_inset
4345  and most likely also 
4346 \begin_inset Flex CharStyle:Code
4347 status collapsed
4349 \begin_layout Plain Layout
4351 \end_layout
4353 \end_inset
4356 \begin_inset Flex CharStyle:Code
4357 status collapsed
4359 \begin_layout Plain Layout
4361 \end_layout
4363 \end_inset
4365  and 
4366 \begin_inset Flex CharStyle:Code
4367 status collapsed
4369 \begin_layout Plain Layout
4371 \end_layout
4373 \end_inset
4376 \begin_inset Flex CharStyle:Code
4377 status collapsed
4379 \begin_layout Plain Layout
4381 \end_layout
4383 \end_inset
4386  Of course this also makes it impossible to pass such mis-matched code fragments
4387  as parameters, but I don't think users could cope with people passing such
4388  code unbalanced fragments as chunk parameters
4389 \begin_inset Foot
4390 status collapsed
4392 \begin_layout Plain Layout
4393 I know that I couldn't cope with users doing such things, and although the
4394  GPL3 license prevents me from actually forbidding anyone from trying, if
4395  they want it to work they'll have to write the code themselves and not
4396  expect any support from me.
4397 \end_layout
4399 \end_inset
4402 \end_layout
4404 \begin_layout Standard
4405 Unfortunately, the full set of matching delimiters may vary from language
4406  to language.
4407  In certain C++ template contexts, 
4408 \begin_inset Flex CharStyle:Code
4409 status collapsed
4411 \begin_layout Plain Layout
4413 \end_layout
4415 \end_inset
4417  and 
4418 \begin_inset Flex CharStyle:Code
4419 status collapsed
4421 \begin_layout Plain Layout
4423 \end_layout
4425 \end_inset
4427  would count as delimiters, and yet in other contexts they would not.
4428 \end_layout
4430 \begin_layout Standard
4431 This puts me in the unfortunate position of having to parse-somewhat all
4432  programming languages without knowing what they are! Eventually this will
4433  be managed in the chunk modes in chapter 
4434 \begin_inset CommandInset ref
4435 LatexCommand ref
4436 reference "cha:modes"
4438 \end_inset
4441 \end_layout
4443 \begin_layout Standard
4444 Another way, inspired by LaTeX, is if the first character of the parameter
4445  is an opening-delimiter, to read up to the matching closing-delimiter wthout
4446  considering intervening commas; thus the above example could be expressed:
4447 \end_layout
4449 \begin_layout LyX-Code
4451 \backslash
4452 chunkref{pull}({things[x, y]}, [get_other_things(a, "all")])
4453 \end_layout
4455 \begin_layout Standard
4456 --- using 
4457 \begin_inset Flex CharStyle:Code
4458 status collapsed
4460 \begin_layout Plain Layout
4462 \end_layout
4464 \end_inset
4467 \begin_inset Flex CharStyle:Code
4468 status collapsed
4470 \begin_layout Plain Layout
4472 \end_layout
4474 \end_inset
4476  to wrap the first agument, and 
4477 \begin_inset Flex CharStyle:Code
4478 status collapsed
4480 \begin_layout Plain Layout
4482 \end_layout
4484 \end_inset
4487 \begin_inset Flex CharStyle:Code
4488 status collapsed
4490 \begin_layout Plain Layout
4492 \end_layout
4494 \end_inset
4496 to wrap the second argument and protect the comma.
4497 \end_layout
4499 \begin_layout Standard
4500 In the meantime, I'll work with the first method, and a fixed list of delimiters.
4501 \end_layout
4503 \begin_layout Standard
4504 -------
4505 \end_layout
4507 \begin_layout Chunk
4508 mode-definitions
4509 \end_layout
4511 \begin_layout Standard
4512 \begin_inset listings
4513 inline false
4514 status open
4516 \begin_layout Plain Layout
4518 modes["", "",  "submodes" ]="
4519 \backslash
4521 \backslash
4523 \backslash
4525 \backslash
4527 \backslash
4528 "|{|
4529 \backslash
4531 \backslash
4533 \backslash
4535 \backslash
4536 [|'|/
4537 \backslash
4539 \backslash
4541 \end_layout
4543 \begin_layout Plain Layout
4545 modes["", "",  "delimeters"]=" *, *";
4546 \end_layout
4548 \begin_layout Plain Layout
4550 modes["", "
4551 \backslash
4552 "", "submodes" ]="
4553 \backslash
4555 \end_layout
4557 \begin_layout Plain Layout
4559 modes["", "
4560 \backslash
4561 "", "terminators"]="
4562 \backslash
4564 \end_layout
4566 \begin_layout Plain Layout
4568 modes["", "{",  "submodes" ]="
4569 \backslash
4571 \backslash
4573 \backslash
4575 \backslash
4577 \backslash
4578 "|{|
4579 \backslash
4581 \backslash
4583 \backslash
4585 \backslash
4586 [|'|/
4587 \backslash
4589 \backslash
4591 \end_layout
4593 \begin_layout Plain Layout
4595 modes["", "{",  "delimeters"]=" *, *";
4596 \end_layout
4598 \begin_layout Plain Layout
4600 modes["", "{",  "terminators"]="}";
4601 \end_layout
4603 \begin_layout Plain Layout
4605 modes["", "[",  "submodes" ]="
4606 \backslash
4608 \backslash
4610 \backslash
4612 \backslash
4614 \backslash
4615 "|{|
4616 \backslash
4618 \backslash
4620 \backslash
4622 \backslash
4623 [|'|/
4624 \backslash
4626 \backslash
4628 \end_layout
4630 \begin_layout Plain Layout
4632 modes["", "[",  "delimiters"]=" *, *";
4633 \end_layout
4635 \begin_layout Plain Layout
4637 modes["", "[",  "terminators"]="
4638 \backslash
4640 \backslash
4642 \end_layout
4644 \begin_layout Plain Layout
4646 modes["", "(",  "submodes" ]="
4647 \backslash
4649 \backslash
4651 \backslash
4653 \backslash
4655 \backslash
4656 "|{|
4657 \backslash
4659 \backslash
4661 \backslash
4663 \backslash
4664 [|'|/
4665 \backslash
4667 \backslash
4669 \end_layout
4671 \begin_layout Plain Layout
4673 modes["", "(",  "delimiters"]=" *, *";
4674 \end_layout
4676 \begin_layout Plain Layout
4678 modes["", "(",  "terminators"]="
4679 \backslash
4681 \backslash
4683 \end_layout
4685 \begin_layout Plain Layout
4687 modes["", "'",  "submodes" ]="
4688 \backslash
4690 \backslash
4692 \backslash
4694 \backslash
4696 \end_layout
4698 \begin_layout Plain Layout
4700 modes["", "'",  "terminators"]="'";
4701 \end_layout
4703 \begin_layout Plain Layout
4705 modes["", "/*", "submodes"]="
4706 \backslash
4708 \backslash
4709 */";
4710 \end_layout
4712 \begin_layout Plain Layout
4714 modes["", "/*", "terminators"]="*/";
4715 \end_layout
4717 \begin_layout Plain Layout
4719 modes["", "//", "submodes"]="
4720 \backslash
4722 \end_layout
4724 \begin_layout Plain Layout
4726 modes["", "//", "terminators"]="
4727 \backslash
4729 \end_layout
4731 \begin_layout Plain Layout
4733 modes["", "",   "submodes" ]="
4734 \backslash
4736 \backslash
4738 \backslash
4740 \backslash
4742 \backslash
4743 "|{|
4744 \backslash
4746 \backslash
4748 \backslash
4750 \backslash
4751 [|'|/
4752 \backslash
4754 \backslash
4756 \end_layout
4758 \end_inset
4761 \end_layout
4763 \begin_layout Chunk
4764 parse_chunk_args
4765 \end_layout
4767 \begin_layout Standard
4768 \begin_inset listings
4769 inline false
4770 status open
4772 \begin_layout Plain Layout
4774 function parse_chunk_args(language, text, values,
4775 \end_layout
4777 \begin_layout Plain Layout
4779   # optional parameters
4780 \end_layout
4782 \begin_layout Plain Layout
4784   mode, 
4785 \end_layout
4787 \begin_layout Plain Layout
4789   path, # hierarchical precursors
4790 \end_layout
4792 \begin_layout Plain Layout
4794   stack, # delimiters to be matched
4795 \end_layout
4797 \begin_layout Plain Layout
4799   submodes,
4800 \end_layout
4802 \begin_layout Plain Layout
4804   # local vars
4805 \end_layout
4807 \begin_layout Plain Layout
4809   c, a, part, item, name, result, new_values, new_mode)
4810 \end_layout
4812 \begin_layout Plain Layout
4815 \end_layout
4817 \begin_layout Plain Layout
4819 #  split(chunklet_parts[2], call_chunk_args, " *, *");
4820 \end_layout
4822 \end_inset
4825 \end_layout
4827 \begin_layout Standard
4828 The strategy is to parse the name, and then look for a value.
4829  If the value begins with a brace 
4830 \begin_inset Flex CharStyle:Code
4831 status collapsed
4833 \begin_layout Plain Layout
4835 \end_layout
4837 \end_inset
4839 , then we recurse and consume as much of the text as necessary, returning
4840  the remaining text when we encounter a leading close-brace 
4841 \begin_inset Flex CharStyle:Code
4842 status collapsed
4844 \begin_layout Plain Layout
4846 \end_layout
4848 \end_inset
4851  This being the strategy --- and executed in a loop --- we realise that
4852  we must first look for the closing brace (perhaps preceded by white space)
4853  in order to terminate the recursion, and returning remaining text.
4854 \end_layout
4856 \begin_layout Standard
4857 \begin_inset listings
4858 inline false
4859 status open
4861 \begin_layout Plain Layout
4863   submodes=modes[language, mode, "submodes"];
4864 \end_layout
4866 \begin_layout Plain Layout
4868   if ((language, mode, "delimiters") in modes) {
4869 \end_layout
4871 \begin_layout Plain Layout
4873     submodes=submodes "|" modes[language, mode, "delimiters"];
4874 \end_layout
4876 \begin_layout Plain Layout
4878   }
4879 \end_layout
4881 \begin_layout Plain Layout
4883   if ((language, mode, "terminators") in modes) {
4884 \end_layout
4886 \begin_layout Plain Layout
4888     submodes=submodes "|" modes[language, mode, "terminators"];
4889 \end_layout
4891 \begin_layout Plain Layout
4893   }
4894 \end_layout
4896 \begin_layout Plain Layout
4898 \end_layout
4900 \begin_layout Plain Layout
4902   while(length(text)) {
4903 \end_layout
4905 \begin_layout Plain Layout
4907     if (match(text, "(" submodes ")", a)) {
4908 \end_layout
4910 \begin_layout Plain Layout
4912       part = substr(text, 1, RSTART -1);
4913 \end_layout
4915 \begin_layout Plain Layout
4917       item = item part;
4918 \end_layout
4920 \begin_layout Plain Layout
4922       if (match(a[1], "^" modes[language, mode, "terminators"] "$")) {
4923 \end_layout
4925 \begin_layout Plain Layout
4927        values[++c] = item;
4928 \end_layout
4930 \begin_layout Plain Layout
4932        return result item a[1];
4933 \end_layout
4935 \begin_layout Plain Layout
4937       }
4938 \end_layout
4940 \begin_layout Plain Layout
4942       if (match(a[1], "^" modes[language, mode, "delimiters"] "$")) {
4943 \end_layout
4945 \begin_layout Plain Layout
4947         values[++c] = item;
4948 \end_layout
4950 \begin_layout Plain Layout
4952         text = substr(text, 1 + length(part) + length(a[1]));
4953 \end_layout
4955 \begin_layout Plain Layout
4957         result = result item a[1];
4958 \end_layout
4960 \begin_layout Plain Layout
4962         item = "";
4963 \end_layout
4965 \begin_layout Plain Layout
4967       } else if ((language, a[1], "terminators") in modes) {
4968 \end_layout
4970 \begin_layout Plain Layout
4972         new_mode=a[1];
4973 \end_layout
4975 \begin_layout Plain Layout
4977         #check if new_mode is defined
4978 \end_layout
4980 \begin_layout Plain Layout
4982         text = substr(text, 1 + length(part) + length(a[1]));
4983 \end_layout
4985 \begin_layout Plain Layout
4987         s = parse_chunk_args(language, text,new_values,new_mode);
4988 \end_layout
4990 \begin_layout Plain Layout
4992         text = substr(text, length(s) +1);
4993 \end_layout
4995 \begin_layout Plain Layout
4997         item = item a[1] s;
4998 \end_layout
5000 \begin_layout Plain Layout
5002       } else {
5003 \end_layout
5005 \begin_layout Plain Layout
5007         error(sprintf("Submode '%s' set unknown mode in text: %s", new_mode,
5008  text));
5009 \end_layout
5011 \begin_layout Plain Layout
5013         text = substr(text, 1 + length(part) + length(a[1]));
5014 \end_layout
5016 \begin_layout Plain Layout
5018       }
5019 \end_layout
5021 \begin_layout Plain Layout
5023     } else {
5024 \end_layout
5026 \begin_layout Plain Layout
5028       result = result item text;
5029 \end_layout
5031 \begin_layout Plain Layout
5033       values[++c] = text;
5034 \end_layout
5036 \begin_layout Plain Layout
5038       text = "";
5039 \end_layout
5041 \begin_layout Plain Layout
5043       item = "";
5044 \end_layout
5046 \begin_layout Plain Layout
5048     }
5049 \end_layout
5051 \begin_layout Plain Layout
5053   }
5054 \end_layout
5056 \begin_layout Plain Layout
5058   if (length(item)) values[++c] = item;
5059 \end_layout
5061 \begin_layout Plain Layout
5063   return result item;
5064 \end_layout
5066 \begin_layout Plain Layout
5069 \end_layout
5071 \end_inset
5074 \end_layout
5076 \begin_layout Standard
5077 We can test this function like this:
5078 \end_layout
5080 \begin_layout Chunk
5081 pca-test.awk
5082 \end_layout
5084 \begin_layout Standard
5085 \begin_inset listings
5086 inline false
5087 status open
5089 \begin_layout Plain Layout
5092 \backslash
5093 chunkref{error()}>
5094 \end_layout
5096 \begin_layout Plain Layout
5099 \backslash
5100 chunkref{parse_chunk_args()}>
5101 \end_layout
5103 \begin_layout Plain Layout
5105 BEGIN {
5106 \end_layout
5108 \begin_layout Plain Layout
5110   SUBSEP=".";
5111 \end_layout
5113 \begin_layout Plain Layout
5115   =<
5116 \backslash
5117 chunkref{mode-definitions}>
5118 \end_layout
5120 \begin_layout Plain Layout
5122 \end_layout
5124 \begin_layout Plain Layout
5126 #  print parse_chunk_args("", "things[x, y], get_other_things(a, 
5127 \backslash
5128 "all
5129 \backslash
5130 "), 99", a, "(");
5131 \end_layout
5133 \begin_layout Plain Layout
5135 #  print parse_chunk_args("", "1,2,3)", a, "(");
5136 \end_layout
5138 \begin_layout Plain Layout
5140 #  print parse_chunk_args("", "joe, red", a, "(");
5141 \end_layout
5143 \begin_layout Plain Layout
5145   print parse_chunk_args("", "${colour}", a, "(");
5146 \end_layout
5148 \begin_layout Plain Layout
5150   for (b in a) {
5151 \end_layout
5153 \begin_layout Plain Layout
5155     print "a[" b "] => " a[b];
5156 \end_layout
5158 \begin_layout Plain Layout
5160   }
5161 \end_layout
5163 \begin_layout Plain Layout
5166 \end_layout
5168 \end_inset
5171 \end_layout
5173 \begin_layout Standard
5174 which should give this output:
5175 \end_layout
5177 \begin_layout Chunk
5178 pca-test.awk-results
5179 \end_layout
5181 \begin_layout Standard
5182 \begin_inset listings
5183 inline false
5184 status open
5186 \begin_layout Plain Layout
5188 a[foo.quux.quirk] => 
5189 \end_layout
5191 \begin_layout Plain Layout
5193 a[foo.quux.a] => fleeg
5194 \end_layout
5196 \begin_layout Plain Layout
5198 a[foo.bar] => baz
5199 \end_layout
5201 \begin_layout Plain Layout
5203 a[etc] => 
5204 \end_layout
5206 \begin_layout Plain Layout
5208 a[name] => freddie
5209 \end_layout
5211 \end_inset
5214 \end_layout
5216 \begin_layout Section
5217 Expanding parameters
5218 \end_layout
5220 \begin_layout Standard
5221 \begin_inset CommandInset label
5222 LatexCommand label
5223 name "Here-we-split"
5225 \end_inset
5227 Here we split the text on 
5228 \begin_inset Flex CharStyle:Code
5229 status collapsed
5231 \begin_layout Plain Layout
5233 \end_layout
5235 \end_inset
5237  which means that all parts except the first will begin with a parameter
5238  name.
5239  The split function will consume the literal 
5240 \begin_inset Flex CharStyle:Code
5241 status collapsed
5243 \begin_layout Plain Layout
5245 \end_layout
5247 \end_inset
5249  in each case.
5250 \end_layout
5252 \begin_layout Chunk
5253 expand_chunk_args()
5254 \end_layout
5256 \begin_layout Standard
5257 \begin_inset listings
5258 inline false
5259 status open
5261 \begin_layout Plain Layout
5263 function expand_chunk_args(text, params, args,  
5264 \end_layout
5266 \begin_layout Plain Layout
5268   p, text_array, next_text, v, t, l)
5269 \end_layout
5271 \begin_layout Plain Layout
5274 \end_layout
5276 \begin_layout Plain Layout
5278   if (split(text, text_array, "
5279 \backslash
5281 \backslash
5282 ${")) {
5283 \end_layout
5285 \begin_layout Plain Layout
5287     =<
5288 \backslash
5289 chunkref{substitute-chunk-args}>
5290 \end_layout
5292 \begin_layout Plain Layout
5294   }
5295 \end_layout
5297 \begin_layout Plain Layout
5299   return text;
5300 \end_layout
5302 \begin_layout Plain Layout
5305 \end_layout
5307 \end_inset
5310 \end_layout
5312 \begin_layout Standard
5313 First, we produce an associative array of substitution values indexed by
5314  parameter names
5315 \end_layout
5317 \begin_layout Chunk
5318 substitute-chunk-args
5319 \end_layout
5321 \begin_layout Standard
5322 \begin_inset listings
5323 inline false
5324 status open
5326 \begin_layout Plain Layout
5328 for(p in params) {
5329 \end_layout
5331 \begin_layout Plain Layout
5333   v[params[p]]=args[p];
5334 \end_layout
5336 \begin_layout Plain Layout
5339 \end_layout
5341 \end_inset
5344 \end_layout
5346 \begin_layout Standard
5347 We accumulate substituted text in the variable 
5348 \begin_inset Flex CharStyle:Code
5349 status collapsed
5351 \begin_layout Plain Layout
5352 text
5353 \end_layout
5355 \end_inset
5358  As the first part of the split function is the part before the delimiter
5359  --- which is 
5360 \begin_inset Flex CharStyle:Code
5361 status collapsed
5363 \begin_layout Plain Layout
5365 \end_layout
5367 \end_inset
5369  in our case --- this part will never contain a parameter reference, so
5370  we assign this directly to the result kept in 
5371 \begin_inset Flex CharStyle:Code
5372 status collapsed
5374 \begin_layout Plain Layout
5375 $text
5376 \end_layout
5378 \end_inset
5381 \begin_inset listings
5382 inline false
5383 status open
5385 \begin_layout Plain Layout
5387 text=text_array[1];
5388 \end_layout
5390 \end_inset
5393 \end_layout
5395 \begin_layout Standard
5396 We then iterate over the remaining values in the array
5397 \begin_inset Foot
5398 status collapsed
5400 \begin_layout Plain Layout
5401 I don't know why I think that it will enumerate the array in order, but
5402  it seems to work
5403 \end_layout
5405 \end_inset
5408 \begin_inset Note Note
5409 status collapsed
5411 \begin_layout Plain Layout
5412 So fix it or porve it
5413 \end_layout
5415 \end_inset
5417 , and substitute each reference for it's argument.
5418 \end_layout
5420 \begin_layout Standard
5421 \begin_inset listings
5422 inline false
5423 status open
5425 \begin_layout Plain Layout
5427 for(t in text_array) if (t>1) {
5428 \end_layout
5430 \begin_layout Plain Layout
5432   =<
5433 \backslash
5434 chunkref{substitute-chunk-arg}>
5435 \end_layout
5437 \begin_layout Plain Layout
5440 \end_layout
5442 \end_inset
5445 \end_layout
5447 \begin_layout Standard
5448 After the split on 
5449 \begin_inset Flex CharStyle:Code
5450 status collapsed
5452 \begin_layout Plain Layout
5454 \end_layout
5456 \end_inset
5458  a valid parameter reference will consist of valid parameter name terminated
5459  by a close-brace 
5460 \begin_inset Flex CharStyle:Code
5461 status collapsed
5463 \begin_layout Plain Layout
5465 \end_layout
5467 \end_inset
5470  A valid character name begins with the underscore or a letter, and may
5471  contain letters, digits or underscores.
5472 \end_layout
5474 \begin_layout Standard
5475 A valid looking reference that is not actually the name of a parameter will
5476  be and not substituted.
5477  This is good because there is nothing to substitute anyway, and it avoids
5478  clashes when writing code for languages where ${\SpecialChar \ldots{}
5479 } is a valid construct
5480  --- such constructs will not be interfered with unless the parameter name
5481  also matches.
5482 \end_layout
5484 \begin_layout Chunk
5485 substitute-chunk-arg
5486 \end_layout
5488 \begin_layout Standard
5489 \begin_inset listings
5490 inline false
5491 status open
5493 \begin_layout Plain Layout
5495 if (match(text_array[t], "^([a-zA-Z_][a-zA-Z0-9_]*)}", l) &&
5496 \end_layout
5498 \begin_layout Plain Layout
5500     l[1] in v) 
5501 \end_layout
5503 \begin_layout Plain Layout
5506 \end_layout
5508 \begin_layout Plain Layout
5510   text = text v[l[1]] substr(text_array[t], length(l[1])+2);
5511 \end_layout
5513 \begin_layout Plain Layout
5515 } else {
5516 \end_layout
5518 \begin_layout Plain Layout
5520   text = text "${" text_array[t];
5521 \end_layout
5523 \begin_layout Plain Layout
5526 \end_layout
5528 \end_inset
5531 \end_layout
5533 \begin_layout Chapter
5534 Recognizing Chunks
5535 \end_layout
5537 \begin_layout Standard
5538 Newfangle recognizes noweb chunks, but as we also want better LaTeX integration
5539  we will recognize any of these:
5540 \end_layout
5542 \begin_layout Itemize
5543 notangle chunks matching the pattern 
5544 \begin_inset Flex CharStyle:Code
5545 status collapsed
5547 \begin_layout Plain Layout
5549 \begin_inset space \hspace*{}
5550 \length 0in
5551 \end_inset
5553 <.*?>
5554 \begin_inset space \hspace*{}
5555 \length 0in
5556 \end_inset
5559 \end_layout
5561 \end_inset
5564 \end_layout
5566 \begin_layout Itemize
5567 a chunks beginning with 
5568 \begin_inset Flex CharStyle:Code
5569 status collapsed
5571 \begin_layout Plain Layout
5573 \backslash
5574 begin{lstlistings}
5575 \end_layout
5577 \end_inset
5579 , possibly with 
5580 \backslash
5581 Chunk{\SpecialChar \ldots{}
5582 } on the previous line
5583 \end_layout
5585 \begin_layout Itemize
5586 an older form I have used, beginning with 
5587 \begin_inset Flex CharStyle:Code
5588 status collapsed
5590 \begin_layout Plain Layout
5592 \backslash
5593 begin{Chunk}[options]
5594 \end_layout
5596 \end_inset
5598  --- also more suitable for plain LaTeX users
5599 \begin_inset Foot
5600 status collapsed
5602 \begin_layout Plain Layout
5603 Is there such a thing as plain LaTeX?
5604 \end_layout
5606 \end_inset
5609 \end_layout
5611 \begin_layout Section
5612 Chunk start
5613 \end_layout
5615 \begin_layout Standard
5616 The variable 
5617 \begin_inset Flex CharStyle:Code
5618 status collapsed
5620 \begin_layout Plain Layout
5621 chunking
5622 \end_layout
5624 \end_inset
5626  is used to signify that we are processing a code chunk and not document.
5627  In such a state, input lines will be assigned to the current chunk; otherwise
5628  they are ignored.
5629 \end_layout
5631 \begin_layout Subsection
5632 lstlistings
5633 \end_layout
5635 \begin_layout Standard
5636 Our current scheme is to recognize the new lstlisting chunks, but these
5637  may be preceded by a 
5638 \begin_inset Flex CharStyle:Code
5639 status collapsed
5641 \begin_layout Plain Layout
5643 \backslash
5644 Chunk
5645 \end_layout
5647 \end_inset
5649  command which in LyX is a more convenient way to pass the chunk name to
5650  the 
5651 \begin_inset Flex CharStyle:Code
5652 status collapsed
5654 \begin_layout Plain Layout
5656 \backslash
5657 begin{lstlistings}
5658 \end_layout
5660 \end_inset
5662  command, and a more visible way to specify other 
5663 \begin_inset Flex CharStyle:Code
5664 status collapsed
5666 \begin_layout Plain Layout
5667 lstset
5668 \end_layout
5670 \end_inset
5672  settings.
5673 \end_layout
5675 \begin_layout Standard
5676 The arguments to the 
5677 \begin_inset Flex CharStyle:Code
5678 status collapsed
5680 \begin_layout Plain Layout
5682 \backslash
5683 Chunk
5684 \end_layout
5686 \end_inset
5688  command are a name, and then a comma-seperated list of key-value pairs
5689  after the manner of 
5690 \begin_inset Flex CharStyle:Code
5691 status collapsed
5693 \begin_layout Plain Layout
5695 \backslash
5696 lstset
5697 \end_layout
5699 \end_inset
5702  (In fact within the LaTeX 
5703 \begin_inset Flex CharStyle:Code
5704 status collapsed
5706 \begin_layout Plain Layout
5708 \backslash
5709 Chunk
5710 \end_layout
5712 \end_inset
5714  macro (section 
5715 \begin_inset CommandInset ref
5716 LatexCommand ref
5717 reference "sub:The-chunk-command"
5719 \end_inset
5721 ) the text 
5722 \begin_inset Flex CharStyle:Code
5723 status collapsed
5725 \begin_layout Plain Layout
5726 name=
5727 \end_layout
5729 \end_inset
5731  is prefixed to the argument which is then literally passed to 
5732 \begin_inset Flex CharStyle:Code
5733 status collapsed
5735 \begin_layout Plain Layout
5737 \backslash
5738 lstset
5739 \end_layout
5741 \end_inset
5744 \end_layout
5746 \begin_layout Chunk
5747 recognize-chunk
5748 \end_layout
5750 \begin_layout Standard
5751 \begin_inset listings
5752 inline false
5753 status open
5755 \begin_layout Plain Layout
5758 \backslash
5760 \backslash
5761 Chunk{/ {
5762 \end_layout
5764 \begin_layout Plain Layout
5766   if (match($0, "^
5767 \backslash
5769 \backslash
5771 \backslash
5773 \backslash
5774 Chunk{ *([^ ,}]*),?(.*)}", line)) {
5775 \end_layout
5777 \begin_layout Plain Layout
5779     next_chunk_name = line[1];
5780 \end_layout
5782 \begin_layout Plain Layout
5784     get_chunk_args(line[2], next_chunk_args);
5785 \end_layout
5787 \begin_layout Plain Layout
5789   }
5790 \end_layout
5792 \begin_layout Plain Layout
5794   next;
5795 \end_layout
5797 \begin_layout Plain Layout
5800 \end_layout
5802 \end_inset
5805 \end_layout
5807 \begin_layout Standard
5808 We also make a basic attempt to parse the name out of the 
5809 \begin_inset Flex CharStyle:Code
5810 status collapsed
5812 \begin_layout Plain Layout
5814 \backslash
5815 lstlistings[name=
5816 \begin_inset space \hspace{}
5817 \length 0in
5818 \end_inset
5820 chunk-name]
5821 \end_layout
5823 \end_inset
5825  text, otherwise we fall back to the name found in the previous chunk command.
5826  This attempt is very basic and doesn't support commas or spaces or square
5827  brackets as part of the chunkname.
5828  We also recognize 
5829 \begin_inset Flex CharStyle:Code
5830 status collapsed
5832 \begin_layout Plain Layout
5834 \backslash
5835 begin{Chunk}
5836 \end_layout
5838 \end_inset
5840  which is convenient for some users
5841 \begin_inset Foot
5842 status open
5844 \begin_layout Plain Layout
5845 but not yet supported in the LaTeX macros
5846 \end_layout
5848 \end_inset
5851 \begin_inset Note Note
5852 status collapsed
5854 \begin_layout Plain Layout
5855 Add noweave support
5856 \end_layout
5858 \end_inset
5861 \end_layout
5863 \begin_layout Standard
5864 \begin_inset listings
5865 inline false
5866 status open
5868 \begin_layout Plain Layout
5871 \backslash
5873 \backslash
5874 begin{lstlisting}|^
5875 \backslash
5877 \backslash
5878 begin{Chunk}/ {
5879 \end_layout
5881 \begin_layout Plain Layout
5883   if (match($0, "}.*[[,] *name= *{? *([^], }]*)", line)) {
5884 \end_layout
5886 \begin_layout Plain Layout
5888     new_chunk(line[1]);
5889 \end_layout
5891 \begin_layout Plain Layout
5893   } else {
5894 \end_layout
5896 \begin_layout Plain Layout
5898     new_chunk(next_chunk_name, next_chunk_args);
5899 \end_layout
5901 \begin_layout Plain Layout
5903   }
5904 \end_layout
5906 \begin_layout Plain Layout
5908   chunking=1;
5909 \end_layout
5911 \begin_layout Plain Layout
5913   next;
5914 \end_layout
5916 \begin_layout Plain Layout
5919 \end_layout
5921 \end_inset
5924 \end_layout
5926 \begin_layout Subsection
5927 Noweb
5928 \end_layout
5930 \begin_layout Standard
5931 We recognize notangle style chunks too:
5932 \end_layout
5934 \begin_layout Chunk
5935 recognize-chunk
5936 \end_layout
5938 \begin_layout Standard
5939 \begin_inset listings
5940 inline false
5941 status open
5943 \begin_layout Plain Layout
5945 /^[<]<.*[>]>=/ {
5946 \end_layout
5948 \begin_layout Plain Layout
5950   if (match($0, "^[<]<(.*)[>]>= *$", line)) {
5951 \end_layout
5953 \begin_layout Plain Layout
5955     chunking=1;
5956 \end_layout
5958 \begin_layout Plain Layout
5960     notangle_mode=1;
5961 \end_layout
5963 \begin_layout Plain Layout
5965     new_chunk(line[1]);
5966 \end_layout
5968 \begin_layout Plain Layout
5970     next;
5971 \end_layout
5973 \begin_layout Plain Layout
5975   }
5976 \end_layout
5978 \begin_layout Plain Layout
5981 \end_layout
5983 \end_inset
5986 \end_layout
5988 \begin_layout Section
5989 Chunk end
5990 \end_layout
5992 \begin_layout Standard
5993 Likewise, we need to recognize when a chunk ends.
5994 \end_layout
5996 \begin_layout Subsection
5997 lstlistings
5998 \end_layout
6000 \begin_layout Standard
6001 The 
6002 \begin_inset Flex CharStyle:Code
6003 status collapsed
6005 \begin_layout Plain Layout
6007 \end_layout
6009 \end_inset
6011  in 
6012 \begin_inset Flex CharStyle:Code
6013 status collapsed
6015 \begin_layout Plain Layout
6016 [e]end{lislisting}
6017 \end_layout
6019 \end_inset
6021  is surrounded by square brackets so that when this document is processed,
6022  this chunk doesn't terminate early when the lstlistings package recognizes
6023  it's own end-string! 
6024 \begin_inset Note Greyedout
6025 status collapsed
6027 \begin_layout Plain Layout
6028 This doesn't make sense as the regex is anchored with ^, which this line
6029  does not begin with!
6030 \end_layout
6032 \end_inset
6035 \begin_inset Note Note
6036 status open
6038 \begin_layout Plain Layout
6039 No, it doesn't.
6040 \end_layout
6042 \end_inset
6045 \end_layout
6047 \begin_layout Chunk
6048 recognize-chunk
6049 \end_layout
6051 \begin_layout Standard
6052 \begin_inset listings
6053 inline false
6054 status open
6056 \begin_layout Plain Layout
6059 \backslash
6061 \backslash
6062 [e]nd{lstlisting}|^
6063 \backslash
6065 \backslash
6066 [e]nd{Chunk}/ {
6067 \end_layout
6069 \begin_layout Plain Layout
6071   chunking=0;
6072 \end_layout
6074 \begin_layout Plain Layout
6076   active_chunk="";
6077 \end_layout
6079 \begin_layout Plain Layout
6081   next;
6082 \end_layout
6084 \begin_layout Plain Layout
6087 \end_layout
6089 \end_inset
6092 \end_layout
6094 \begin_layout Subsection
6095 noweb
6096 \end_layout
6098 \begin_layout Chunk
6099 recognize-chunk
6100 \end_layout
6102 \begin_layout Standard
6103 \begin_inset listings
6104 inline false
6105 status open
6107 \begin_layout Plain Layout
6109 /^@ *$/ {
6110 \end_layout
6112 \begin_layout Plain Layout
6114   chunking=0;
6115 \end_layout
6117 \begin_layout Plain Layout
6119   active_chunk="";
6120 \end_layout
6122 \begin_layout Plain Layout
6125 \end_layout
6127 \end_inset
6130 \end_layout
6132 \begin_layout Standard
6133 All other recognizers are only of effect if we are chunking; there's no
6134  point in looking at lines if they aren't part of a chunk, so we just ignore
6135  them as efficiently as we can.
6136 \end_layout
6138 \begin_layout Chunk
6139 recognize-chunk
6140 \end_layout
6142 \begin_layout Standard
6143 \begin_inset listings
6144 inline false
6145 status open
6147 \begin_layout Plain Layout
6149 ! chunking { next; }
6150 \end_layout
6152 \end_inset
6155 \end_layout
6157 \begin_layout Section
6158 Chunk contents
6159 \end_layout
6161 \begin_layout Standard
6162 Chunk contents are any lines read while 
6163 \begin_inset Flex CharStyle:Code
6164 status collapsed
6166 \begin_layout Plain Layout
6167 chunking
6168 \end_layout
6170 \end_inset
6172  is true.
6173  Some chunk contents are special in that they refer to other chunks, and
6174  will be replaced by the contents of these chunks when the file is generated.
6175 \end_layout
6177 \begin_layout Standard
6178 \begin_inset CommandInset label
6179 LatexCommand label
6180 name "sub:ORS-chunk-text"
6182 \end_inset
6184 We add the output record separator 
6185 \begin_inset Flex CharStyle:Code
6186 status collapsed
6188 \begin_layout Plain Layout
6190 \end_layout
6192 \end_inset
6194  to the line now, because we will set 
6195 \begin_inset Flex CharStyle:Code
6196 status collapsed
6198 \begin_layout Plain Layout
6200 \end_layout
6202 \end_inset
6204  to the empty string when we generate the output
6205 \begin_inset Foot
6206 status collapsed
6208 \begin_layout Plain Layout
6209 So that we can print partial lines using 
6210 \begin_inset Flex CharStyle:Code
6211 status collapsed
6213 \begin_layout Plain Layout
6214 print
6215 \end_layout
6217 \end_inset
6219  instead of 
6220 \begin_inset Flex CharStyle:Code
6221 status collapsed
6223 \begin_layout Plain Layout
6224 printf
6225 \end_layout
6227 \end_inset
6230 \end_layout
6232 \end_inset
6235 \end_layout
6237 \begin_layout Chunk
6238 recognize-chunk
6239 \end_layout
6241 \begin_layout Standard
6242 \begin_inset listings
6243 inline false
6244 status open
6246 \begin_layout Plain Layout
6248 length(active_chunk) {
6249 \end_layout
6251 \begin_layout Plain Layout
6253   =<
6254 \backslash
6255 chunkref{process-chunk-tabs}>
6256 \end_layout
6258 \begin_layout Plain Layout
6260   =<
6261 \backslash
6262 chunkref{process-chunk}>
6263 \end_layout
6265 \begin_layout Plain Layout
6268 \end_layout
6270 \end_inset
6273 \end_layout
6275 \begin_layout Standard
6276 If a chunk just consisted of plain text, we could handle the chunk like
6277  this:
6278 \end_layout
6280 \begin_layout Chunk
6281 process-chunk-simple
6282 \end_layout
6284 \begin_layout Standard
6285 \begin_inset listings
6286 inline false
6287 status open
6289 \begin_layout Plain Layout
6291 chunk_line(active_chunk, $0 ORS);
6292 \end_layout
6294 \end_inset
6297 \end_layout
6299 \begin_layout Standard
6300 but in fact a chunk can include references to other chunks.
6301  Chunk includes are traditionally written as 
6302 \begin_inset Flex CharStyle:Code
6303 status collapsed
6305 \begin_layout Plain Layout
6306 <<chunk-name>>
6307 \end_layout
6309 \end_inset
6311 , but we support other variations.
6312 \end_layout
6314 \begin_layout Standard
6315 However, we also process tabs at this point, a tab at input can be replaced
6316  by a number of spaces defined by the 
6317 \begin_inset Flex CharStyle:Code
6318 status collapsed
6320 \begin_layout Plain Layout
6321 tabs
6322 \end_layout
6324 \end_inset
6326  variable, set by the 
6327 \begin_inset Flex CharStyle:Code
6328 status collapsed
6330 \begin_layout Plain Layout
6332 \end_layout
6334 \end_inset
6336  option.
6337  Of course this is poor tab behaviour, we should probably have the option
6338  to use proper counted tab-stops and process this on output.
6339 \end_layout
6341 \begin_layout Chunk
6342 process-chunk-tabs
6343 \end_layout
6345 \begin_layout Standard
6346 \begin_inset listings
6347 inline false
6348 status open
6350 \begin_layout Plain Layout
6352 if (length(tabs)) {
6353 \end_layout
6355 \begin_layout Plain Layout
6357   gsub("
6358 \backslash
6359 t", tabs);
6360 \end_layout
6362 \begin_layout Plain Layout
6365 \end_layout
6367 \end_inset
6370 \end_layout
6372 \begin_layout Subsection
6373 \begin_inset CommandInset label
6374 LatexCommand label
6375 name "sub:lstlistings-includes"
6377 \end_inset
6379 lstlistings
6380 \end_layout
6382 \begin_layout Standard
6383 If 
6384 \begin_inset Flex CharStyle:Code
6385 status collapsed
6387 \begin_layout Plain Layout
6389 \backslash
6390 lstset{escapeinside={=<}{>}}
6391 \end_layout
6393 \end_inset
6395  is set, then we can use 
6396 \begin_inset Flex CharStyle:Code
6397 status collapsed
6399 \begin_layout Plain Layout
6401 \backslash
6402 chunkref{
6403 \begin_inset space \hspace{}
6404 \length 0in
6405 \end_inset
6407 chunk-name}>
6408 \end_layout
6410 \end_inset
6412  in listings.
6413  The sequence 
6414 \begin_inset Flex CharStyle:Code
6415 status collapsed
6417 \begin_layout Plain Layout
6419 \end_layout
6421 \end_inset
6423  was chosen because:
6424 \end_layout
6426 \begin_layout Enumerate
6427 it is a better mnemonic than 
6428 \begin_inset Flex CharStyle:Code
6429 status collapsed
6431 \begin_layout Plain Layout
6432 <<chunk-name>>
6433 \end_layout
6435 \end_inset
6437  in that the = sign signifies equivalent or substitutability, 
6438 \end_layout
6440 \begin_layout Enumerate
6441 and because =< is not valid in C or in any language I can think of 
6442 \end_layout
6444 \begin_layout Enumerate
6445 and also because lstlistings doesn't like 
6446 \begin_inset Flex CharStyle:Code
6447 status collapsed
6449 \begin_layout Plain Layout
6451 \end_layout
6453 \end_inset
6455  as an end delimiter for the 
6456 \emph on
6457 texcl
6458 \emph default
6459  escape, so we must make do with a single 
6460 \begin_inset Flex CharStyle:Code
6461 status collapsed
6463 \begin_layout Plain Layout
6465 \end_layout
6467 \end_inset
6469 , which is better matched by 
6470 \begin_inset Flex CharStyle:Code
6471 status collapsed
6473 \begin_layout Plain Layout
6475 \end_layout
6477 \end_inset
6479  than 
6480 \begin_inset Flex CharStyle:Code
6481 status collapsed
6483 \begin_layout Plain Layout
6485 \end_layout
6487 \end_inset
6490 \end_layout
6492 \begin_layout Standard
6493 As each chunk line may contain more than one chunk include, we will split
6494  out chunk includes in an iterative fashion
6495 \begin_inset Foot
6496 status open
6498 \begin_layout Plain Layout
6499 Contrary to our use of 
6500 \begin_inset Flex CharStyle:Code
6501 status collapsed
6503 \begin_layout Plain Layout
6504 split
6505 \end_layout
6507 \end_inset
6509  when substituting parameters in chapter 
6510 \begin_inset CommandInset ref
6511 LatexCommand ref
6512 reference "Here-we-split"
6514 \end_inset
6517 \end_layout
6519 \end_inset
6522 \end_layout
6524 \begin_layout Standard
6525 First, as long as the chunk contains a 
6526 \begin_inset Flex CharStyle:Code
6527 status collapsed
6529 \begin_layout Plain Layout
6531 \backslash
6532 chunkref
6533 \end_layout
6535 \end_inset
6537  command we take as much as we can up to the first 
6538 \begin_inset Flex CharStyle:Code
6539 status collapsed
6541 \begin_layout Plain Layout
6543 \backslash
6544 chunkref
6545 \end_layout
6547 \end_inset
6549  command.
6550 \end_layout
6552 \begin_layout Chunk
6553 process-chunk
6554 \end_layout
6556 \begin_layout Standard
6557 \begin_inset listings
6558 inline false
6559 status open
6561 \begin_layout Plain Layout
6563 chunk = $0;
6564 \end_layout
6566 \begin_layout Plain Layout
6568 indent = 0;
6569 \end_layout
6571 \begin_layout Plain Layout
6573 while(match(chunk, 
6574 \end_layout
6576 \begin_layout Plain Layout
6578             "([=]<
6579 \backslash
6581 \backslash
6583 \backslash
6585 \backslash
6586 chunkref{([^}>]*)}(
6587 \backslash
6589 \backslash
6591 \backslash
6593 \backslash
6594 )|)>|<<([a-zA-Z_][-a-zA-Z0-9_]*)>>)", 
6595 \end_layout
6597 \begin_layout Plain Layout
6599             line)
6600 \backslash
6602 \end_layout
6604 \begin_layout Plain Layout
6606 ) {
6607 \end_layout
6609 \begin_layout Plain Layout
6611   chunklet = substr(chunk, 1, RSTART - 1);
6612 \end_layout
6614 \end_inset
6617 \end_layout
6619 \begin_layout Standard
6620 We keep track of the indent count, by counting the number of literal characters
6621  found.
6622  We can then preserve this indent on each output line when multi-line chunks
6623  are expanded.
6624 \end_layout
6626 \begin_layout Standard
6627 We then process this first part literal text, and set the chunk which is
6628  still to be processed to be the text after the 
6629 \begin_inset Flex CharStyle:Code
6630 status collapsed
6632 \begin_layout Plain Layout
6634 \backslash
6635 chunkref
6636 \end_layout
6638 \end_inset
6640  command, which we will process next as we continue around the loop.
6641 \end_layout
6643 \begin_layout Standard
6644 \begin_inset listings
6645 inline false
6646 status open
6648 \begin_layout Plain Layout
6650   indent += length(chunklet);
6651 \end_layout
6653 \begin_layout Plain Layout
6655   chunk_line(active_chunk, chunklet);
6656 \end_layout
6658 \begin_layout Plain Layout
6660   chunk = substr(chunk, RSTART + RLENGTH);
6661 \end_layout
6663 \end_inset
6666 \end_layout
6668 \begin_layout Standard
6669 We then consider the type of chunk command we have found, whether it is
6670  the newfangle style command beginning with 
6671 \begin_inset Flex CharStyle:Code
6672 status collapsed
6674 \begin_layout Plain Layout
6676 \end_layout
6678 \end_inset
6680  or the older notangle style beginning with 
6681 \begin_inset Flex CharStyle:Code
6682 status collapsed
6684 \begin_layout Plain Layout
6686 \end_layout
6688 \end_inset
6692 \end_layout
6694 \begin_layout Standard
6695 Newfangle chunks may have parameters contained within square brackets.
6696  These will be matched in 
6697 \begin_inset Flex CharStyle:Code
6698 status collapsed
6700 \begin_layout Plain Layout
6701 line[3]
6702 \end_layout
6704 \end_inset
6706  and are considered at this stage of processing to be part of the name of
6707  the chunk to be included.
6708 \end_layout
6710 \begin_layout Standard
6711 \begin_inset listings
6712 inline false
6713 status open
6715 \begin_layout Plain Layout
6717   if (substr(line[1], 1, 1) == "=") {
6718 \end_layout
6720 \begin_layout Plain Layout
6722     # chunk name up to }
6723 \end_layout
6725 \begin_layout Plain Layout
6727     chunk_include(active_chunk, line[2] line[3], indent);
6728 \end_layout
6730 \begin_layout Plain Layout
6732   } else if (substr(line[1], 1, 1) == "<") {
6733 \end_layout
6735 \begin_layout Plain Layout
6737     chunk_include(active_chunk, line[4], indent);
6738 \end_layout
6740 \begin_layout Plain Layout
6742   } else {
6743 \end_layout
6745 \begin_layout Plain Layout
6747     error("Unknown chunk fragment: " line[1]);
6748 \end_layout
6750 \begin_layout Plain Layout
6752   }
6753 \end_layout
6755 \end_inset
6758 \end_layout
6760 \begin_layout Standard
6761 The loop will continue until there are no more chunkref statements in the
6762  text, at which point we process the final part of the chunk.
6763 \end_layout
6765 \begin_layout Standard
6766 \begin_inset listings
6767 inline false
6768 status open
6770 \begin_layout Plain Layout
6773 \end_layout
6775 \begin_layout Plain Layout
6777 chunk_line(active_chunk, chunk);
6778 \end_layout
6780 \end_inset
6783 \end_layout
6785 \begin_layout Standard
6786 \begin_inset CommandInset label
6787 LatexCommand label
6788 name "lone-newline"
6790 \end_inset
6792 We add the newline character as a chunklet on it's own, to make it easier
6793  to detect new lines and thus manage indentation when processing the output.
6794 \end_layout
6796 \begin_layout Standard
6797 \begin_inset listings
6798 inline false
6799 status open
6801 \begin_layout Plain Layout
6803 chunk_line(active_chunk, "
6804 \backslash
6805 n");
6806 \end_layout
6808 \end_inset
6811 \end_layout
6813 \begin_layout Standard
6814 We will also permit a chunk-part number to follow in square brackets, so
6815  that 
6816 \begin_inset Flex CharStyle:Code
6817 status collapsed
6819 \begin_layout Plain Layout
6821 \backslash
6822 chunkref{chunk-name[1]}>
6823 \end_layout
6825 \end_inset
6827  will refer to the first part only.
6828  This can make it easy to include a C function prototype in a header file,
6829  if the first part of the chunk is just the function prototype without the
6830  trailing semi-colon.
6831  The header file would include the prototype with the trailing semi-colon,
6832  like this:
6833 \end_layout
6835 \begin_layout LyX-Code
6837 \backslash
6838 chunkref{chunk-name[1]}>;
6839 \end_layout
6841 \begin_layout Standard
6842 This is handled in section 
6843 \begin_inset CommandInset ref
6844 LatexCommand ref
6845 reference "sub:Chunk-parts"
6847 \end_inset
6850 \end_layout
6852 \begin_layout Standard
6853 We should perhaps introduce a notion of language specific chunk options;
6854  so that perhaps we could specify:
6855 \end_layout
6857 \begin_layout LyX-Code
6859 \backslash
6860 chunkref{chunk-name[function-declaration]}>;
6861 \end_layout
6863 \begin_layout Standard
6864 which applies a transform 
6865 \begin_inset Flex CharStyle:Code
6866 status collapsed
6868 \begin_layout Plain Layout
6869 function-declaration
6870 \end_layout
6872 \end_inset
6874  to the chunk --- which in this case would extract a function prototype
6875  from a function.
6876 \begin_inset Note Note
6877 status open
6879 \begin_layout Plain Layout
6880 So do it
6881 \end_layout
6883 \end_inset
6886 \end_layout
6888 \begin_layout Chapter
6889 Processing Options
6890 \end_layout
6892 \begin_layout Standard
6893 At the start, first we set the default options.
6894 \end_layout
6896 \begin_layout Chunk
6897 default-options
6898 \end_layout
6900 \begin_layout Standard
6901 \begin_inset listings
6902 inline false
6903 status open
6905 \begin_layout Plain Layout
6907 debug=0;
6908 \end_layout
6910 \begin_layout Plain Layout
6912 linenos=0;
6913 \end_layout
6915 \begin_layout Plain Layout
6917 notangle_mode=0;
6918 \end_layout
6920 \begin_layout Plain Layout
6922 root="*";
6923 \end_layout
6925 \begin_layout Plain Layout
6927 tabs = "";
6928 \end_layout
6930 \end_inset
6933 \end_layout
6935 \begin_layout Standard
6936 Then we use getopt the standard way, and null out ARGV afterwards in the
6937  normal AWK fashion.
6938 \end_layout
6940 \begin_layout Chunk
6941 read-options
6942 \end_layout
6944 \begin_layout Standard
6945 \begin_inset listings
6946 inline false
6947 status open
6949 \begin_layout Plain Layout
6951 Optind = 1    # skip ARGV[0]
6952 \end_layout
6954 \begin_layout Plain Layout
6956 while(getopt(ARGC, ARGV, "R:LdT:hr")!=-1) {
6957 \end_layout
6959 \begin_layout Plain Layout
6961   =<
6962 \backslash
6963 chunkref{handle-options}>
6964 \end_layout
6966 \begin_layout Plain Layout
6969 \end_layout
6971 \begin_layout Plain Layout
6973 for (i=1; i<Optind; i++) { ARGV[i]=""; }
6974 \end_layout
6976 \end_inset
6979 \end_layout
6981 \begin_layout Standard
6982 This is how we handle our options:
6983 \end_layout
6985 \begin_layout Chunk
6986 handle-options
6987 \end_layout
6989 \begin_layout Standard
6990 \begin_inset listings
6991 inline false
6992 status open
6994 \begin_layout Plain Layout
6996 if (Optopt == "R") root = Optarg;
6997 \end_layout
6999 \begin_layout Plain Layout
7001 else if (Optopt == "r") root="";
7002 \end_layout
7004 \begin_layout Plain Layout
7006 else if (Optopt == "L") linenos = 1;
7007 \end_layout
7009 \begin_layout Plain Layout
7011 else if (Optopt == "d") debug = 1;
7012 \end_layout
7014 \begin_layout Plain Layout
7016 else if (Optopt == "T") tabs = indent_string(Optarg+0);
7017 \end_layout
7019 \begin_layout Plain Layout
7021 else if (Optopt == "h") help();
7022 \end_layout
7024 \begin_layout Plain Layout
7026 else if (Optopt == "?") help();
7027 \end_layout
7029 \end_inset
7032 \end_layout
7034 \begin_layout Standard
7035 We do all of this at the beginning of the program
7036 \end_layout
7038 \begin_layout Chunk
7039 begin
7040 \end_layout
7042 \begin_layout Standard
7043 \begin_inset listings
7044 inline false
7045 status open
7047 \begin_layout Plain Layout
7049 BEGIN {
7050 \end_layout
7052 \begin_layout Plain Layout
7054   =<
7055 \backslash
7056 chunkref{constants}>
7057 \end_layout
7059 \begin_layout Plain Layout
7061   =<
7062 \backslash
7063 chunkref{mode-definitions}>
7064 \end_layout
7066 \begin_layout Plain Layout
7068   =<
7069 \backslash
7070 chunkref{default-options}>
7071 \end_layout
7073 \begin_layout Plain Layout
7075 \end_layout
7077 \begin_layout Plain Layout
7079   =<
7080 \backslash
7081 chunkref{read-options}>
7082 \end_layout
7084 \begin_layout Plain Layout
7087 \end_layout
7089 \end_inset
7092 \end_layout
7094 \begin_layout Standard
7095 And have a simple help function
7096 \end_layout
7098 \begin_layout Chunk
7099 help()
7100 \end_layout
7102 \begin_layout Standard
7103 \begin_inset listings
7104 inline false
7105 status open
7107 \begin_layout Plain Layout
7109 function help() {
7110 \end_layout
7112 \begin_layout Plain Layout
7114   print "Usage:"
7115 \end_layout
7117 \begin_layout Plain Layout
7119   print "  newfangle [-L] -R<rootname> [source.tex ...]"
7120 \end_layout
7122 \begin_layout Plain Layout
7124   print "  newfangle -r [source.tex ...]"
7125 \end_layout
7127 \begin_layout Plain Layout
7129   print "  If the filename, source.tex is not specified then stdin is used"
7130 \end_layout
7132 \begin_layout Plain Layout
7134   print
7135 \end_layout
7137 \begin_layout Plain Layout
7139   print "-L causes the C statement: #line <lineno> 
7140 \backslash
7141 "filename
7142 \backslash
7143 "" to be issued"
7144 \end_layout
7146 \begin_layout Plain Layout
7148   print "-R causes the named root to be written to stdout"
7149 \end_layout
7151 \begin_layout Plain Layout
7153   print "-r lists all roots in the file (even those used elsewhere)"
7154 \end_layout
7156 \begin_layout Plain Layout
7158   exit 1;
7159 \end_layout
7161 \begin_layout Plain Layout
7164 \end_layout
7166 \end_inset
7169 \end_layout
7171 \begin_layout Chapter
7172 Chunk Language Modes
7173 \end_layout
7175 \begin_layout Standard
7176 \begin_inset CommandInset label
7177 LatexCommand label
7178 name "cha:modes"
7180 \end_inset
7183 \begin_inset Note Greyedout
7184 status open
7186 \begin_layout Plain Layout
7187 This feature is in-development and does not work yet
7188 \end_layout
7190 \end_inset
7193 \begin_inset Note Note
7194 status open
7196 \begin_layout Plain Layout
7197 In Progress!
7198 \end_layout
7200 \end_inset
7203 \end_layout
7205 \begin_layout Standard
7206 lstlistings and newfangle both recognize source languages, and perform some
7207  basic parsing.
7208  lstlistings can detect strings and comments within a language definition
7209  and perform suitable rendering, such as italics for comments, and visible-space
7210 s within strings.
7211 \end_layout
7213 \begin_layout Standard
7214 Newfangle similarly can recognize strings, and comments, etc, within a language,
7215  so that any chunks included with 
7216 \begin_inset Flex CharStyle:Code
7217 status collapsed
7219 \begin_layout Plain Layout
7221 \backslash
7222 chunkref
7223 \end_layout
7225 \end_inset
7227  can be suitably quoted.
7228 \end_layout
7230 \begin_layout Standard
7231 For instance, consider this chunk with 
7232 \begin_inset Flex CharStyle:Code
7233 status collapsed
7235 \begin_layout Plain Layout
7236 language=perl
7237 \end_layout
7239 \end_inset
7242 \end_layout
7244 \begin_layout Chunk
7245 example-perl,language=perl
7246 \end_layout
7248 \begin_layout Standard
7249 \begin_inset listings
7250 inline false
7251 status open
7253 \begin_layout Plain Layout
7255 s/"$/'/;
7256 \end_layout
7258 \end_inset
7261 \end_layout
7263 \begin_layout Standard
7264 If it were included in a chunk with 
7265 \begin_inset Flex CharStyle:Code
7266 status collapsed
7268 \begin_layout Plain Layout
7269 language=sh
7270 \end_layout
7272 \end_inset
7274 , like this:
7275 \end_layout
7277 \begin_layout Chunk
7278 example-sh,language=sh
7279 \end_layout
7281 \begin_layout Standard
7282 \begin_inset listings
7283 inline false
7284 status open
7286 \begin_layout Plain Layout
7288 perl -pe "=<
7289 \backslash
7290 chunkref{example-perl}>"
7291 \end_layout
7293 \end_inset
7296 \end_layout
7298 \begin_layout Standard
7299 would need to generate output like this if it were to work: 
7300 \end_layout
7302 \begin_layout LyX-Code
7303 perl -pe "s/
7304 \backslash
7306 \backslash
7307 $/'/;"
7308 \end_layout
7310 \begin_layout Standard
7311 See that the double quote " as part of the regex has been quoted with a
7312  slash to protect it from shell interpretation.
7313 \end_layout
7315 \begin_layout Standard
7316 If that were then included in a chunk with 
7317 \begin_inset Flex CharStyle:Code
7318 status collapsed
7320 \begin_layout Plain Layout
7321 language=make
7322 \end_layout
7324 \end_inset
7326 , like this:
7327 \end_layout
7329 \begin_layout Chunk
7330 example-makefile,language=make
7331 \end_layout
7333 \begin_layout Standard
7334 \begin_inset listings
7335 inline false
7336 status open
7338 \begin_layout Plain Layout
7340 target: pre-req
7341 \end_layout
7343 \begin_layout Plain Layout
7345                 =<
7346 \backslash
7347 chunkref{example-sh}>
7348 \end_layout
7350 \end_inset
7353 \end_layout
7355 \begin_layout Standard
7356 We would need the output to look like this --- note the $$:
7357 \end_layout
7359 \begin_layout LyX-Code
7360 target: pre-req
7361 \end_layout
7363 \begin_layout LyX-Code
7364         perl -pe "s/
7365 \backslash
7367 \backslash
7368 $$/'/;"
7369 \end_layout
7371 \begin_layout Standard
7372 In order to make this work, we need to define a mode-tracker for each supported
7373  language, that can detect the various quoting modes, and provide a transformati
7374 on that must be applied to any included text so that included text will
7375  be interpreted correctly after the additional interpolation that it will
7376  be subject to at run-time.
7377 \end_layout
7379 \begin_layout Standard
7380 For example, the transformation for text to be inserted into sh double-quoted
7381  strings would be something like:
7382 \end_layout
7384 \begin_layout LyX-Code
7386 \backslash
7388 \backslash
7390 \backslash
7392 \backslash
7394 \backslash
7396 \backslash
7397 /g;s/$/
7398 \backslash
7400 \backslash
7401 $/g;s/"/
7402 \backslash
7404 \backslash
7405 "/g;
7406 \end_layout
7408 \begin_layout Standard
7409 which protects 
7410 \begin_inset Flex CharStyle:Code
7411 status collapsed
7413 \begin_layout Plain Layout
7415 \backslash
7416  $ "
7417 \end_layout
7419 \end_inset
7422 \end_layout
7424 \begin_layout Standard
7425 \begin_inset Note Note
7426 status collapsed
7428 \begin_layout Plain Layout
7429 I don't think this example is true
7430 \end_layout
7432 \end_inset
7434 The mode tracker must also track nested mode-changes, as in this 
7435 \begin_inset Flex CharStyle:Code
7436 status collapsed
7438 \begin_layout Plain Layout
7440 \end_layout
7442 \end_inset
7444  example.
7445 \end_layout
7447 \begin_layout LyX-Code
7448 echo "hello `id **`"
7449 \end_layout
7451 \begin_layout Standard
7452 Any literal text inserted at the point marked ** would need to be escaped
7453  in all kinds of ways, including 
7454 \begin_inset Flex CharStyle:Code
7455 status collapsed
7457 \begin_layout Plain Layout
7458 ` | *
7459 \end_layout
7461 \end_inset
7463  among others.
7464  First it would need escaping for the back-ticks `, and then for the double-quot
7465 es ".
7466 \end_layout
7468 \begin_layout Standard
7469 Escaping need not occur if the format and mode of the included chunk matches
7470  that of the including chunk, which would suggest that any back-ticks might
7471  need to be part of the included chunk and not including chunk
7472 \begin_inset Note Note
7473 status collapsed
7475 \begin_layout Plain Layout
7476 or is it the other way around?
7477 \end_layout
7479 \end_inset
7482 \end_layout
7484 \begin_layout Standard
7485 As each chunk is output a new mode tracker for that language is initialized
7486  in it's normal state.
7487  As text is output for that chunk the output mode is tracked.
7488  When a new chunk is included, a transformation appropriate to that mode
7489  is selected and pushed onto a stack of transformations.
7490  Any text to be output is first passed through this stack of transformations.
7491 \end_layout
7493 \begin_layout Standard
7494 It remains to consider if the chunk-include function should return it's
7495  generated text so that the caller can apply any transformations (and formatting
7496 ), or if it should apply the stack of transformations itself.
7497 \end_layout
7499 \begin_layout Standard
7500 Note that the transformed text should have the property of not being able
7501  to change the mode in the current chunk.
7502 \end_layout
7504 \begin_layout Standard
7505 \begin_inset Note Note
7506 status open
7508 \begin_layout Plain Layout
7509 Note chunk parameters should probably also be transformed
7510 \end_layout
7512 \end_inset
7515 \end_layout
7517 \begin_layout Chunk
7518 new_mode()
7519 \end_layout
7521 \begin_layout Standard
7522 \begin_inset listings
7523 inline false
7524 status open
7526 \begin_layout Plain Layout
7528 function new_mode(language, mode) {
7529 \end_layout
7531 \begin_layout Plain Layout
7533   mode["language"] = language;
7534 \end_layout
7536 \begin_layout Plain Layout
7538   mode["state"]="";
7539 \end_layout
7541 \begin_layout Plain Layout
7544 \end_layout
7546 \end_inset
7549 \end_layout
7551 \begin_layout Standard
7552 Because awk functions cannot return an array, we must create the array first
7553  and pass it in.
7554 \end_layout
7556 \begin_layout Chunk
7557 new-mode,params=language;mode
7558 \end_layout
7560 \begin_layout Standard
7561 \begin_inset listings
7562 inline false
7563 status open
7565 \begin_layout Plain Layout
7568 \backslash
7569 chunkref{awk-delete-array}(${mode})>
7570 \end_layout
7572 \begin_layout Plain Layout
7574 new_mode(${language}, ${mode});
7575 \end_layout
7577 \end_inset
7580 \end_layout
7582 \begin_layout Standard
7583 And for tracking modes, we dispatch to a mode-tracker action based on the
7584  current language
7585 \end_layout
7587 \begin_layout Chunk
7588 track_mode()
7589 \end_layout
7591 \begin_layout Standard
7592 \begin_inset listings
7593 inline false
7594 status open
7596 \begin_layout Plain Layout
7598 function track_mode(mode, text) {
7599 \end_layout
7601 \begin_layout Plain Layout
7603   if (mode["language"] == "C") {
7604 \end_layout
7606 \begin_layout Plain Layout
7608     =<
7609 \backslash
7610 chunkref{track-mode-C}>
7611 \end_layout
7613 \begin_layout Plain Layout
7615     return;
7616 \end_layout
7618 \begin_layout Plain Layout
7620   }
7621 \end_layout
7623 \begin_layout Plain Layout
7626 \end_layout
7628 \end_inset
7631 \end_layout
7633 \begin_layout Standard
7634 For each mode, we look for a character that has the power to change the
7635  mode.
7636 \end_layout
7638 \begin_layout Standard
7639 In plain mode:
7640 \end_layout
7642 \begin_layout List
7643 \labelwidthstring 00.00.0000
7644 \begin_inset Quotes eld
7645 \end_inset
7647  enters double-quote mode
7648 \end_layout
7650 \begin_layout List
7651 \labelwidthstring 00.00.0000
7652 ' enters single-quote mode
7653 \end_layout
7655 \begin_layout List
7656 \labelwidthstring 00.00.0000
7657 trailing-
7658 \backslash
7659  enters multi-line mode
7660 \end_layout
7662 \begin_layout List
7663 \labelwidthstring 00.00.0000
7664 # enters #define sub-mode, needs 
7665 \backslash
7666  escaping end of line too
7667 \end_layout
7669 \begin_layout List
7670 \labelwidthstring 00.00.0000
7671 /* enters comment mode
7672 \end_layout
7674 \begin_layout Standard
7675 In double-quote mode, escape 
7676 \backslash
7677  and 
7678 \begin_inset Quotes eld
7679 \end_inset
7681  and newline
7682 \end_layout
7684 \begin_layout Standard
7686 \backslash
7687  escapes prevents 
7688 \begin_inset Quotes eld
7689 \end_inset
7691  from leaving mode
7692 \end_layout
7694 \begin_layout Standard
7695 \begin_inset Quotes eld
7696 \end_inset
7698  leaves mode
7699 \end_layout
7701 \begin_layout Standard
7702 newline needs to close and re-open string or something
7703 \end_layout
7705 \begin_layout Standard
7706 in single-quote mode escape 
7707 \backslash
7708  and 
7709 \begin_inset Quotes eld
7710 \end_inset
7713 \end_layout
7715 \begin_layout Chunk
7716 track-mode-C
7717 \end_layout
7719 \begin_layout Standard
7720 \begin_inset listings
7721 inline false
7722 status open
7724 \begin_layout Plain Layout
7726 \end_layout
7728 \end_inset
7731 \end_layout
7733 \begin_layout Chunk
7734 mode-tracker
7735 \end_layout
7737 \begin_layout Standard
7738 \begin_inset listings
7739 inline false
7740 status open
7742 \begin_layout Plain Layout
7745 \backslash
7746 chunkref{new_mode()}>
7747 \end_layout
7749 \begin_layout Plain Layout
7752 \backslash
7753 chunkref{parse_chunk_args}>
7754 \end_layout
7756 \end_inset
7759 \end_layout
7761 \begin_layout Chapter
7762 Generating the output
7763 \end_layout
7765 \begin_layout Standard
7766 We generate output by calling output_chunk, or listing the chunk names.
7767 \end_layout
7769 \begin_layout Chunk
7770 generate-output
7771 \end_layout
7773 \begin_layout Standard
7774 \begin_inset listings
7775 inline false
7776 status open
7778 \begin_layout Plain Layout
7780 if (length(root)) output_chunk(root);
7781 \end_layout
7783 \begin_layout Plain Layout
7785 else output_chunk_names();
7786 \end_layout
7788 \end_inset
7791 \end_layout
7793 \begin_layout Standard
7794 We also have some other output debugging:
7795 \end_layout
7797 \begin_layout Chunk
7798 debug-output
7799 \end_layout
7801 \begin_layout Standard
7802 \begin_inset listings
7803 inline false
7804 status open
7806 \begin_layout Plain Layout
7808 if (debug) {
7809 \end_layout
7811 \begin_layout Plain Layout
7813   print "------ chunk names "
7814 \end_layout
7816 \begin_layout Plain Layout
7818   output_chunk_names();
7819 \end_layout
7821 \begin_layout Plain Layout
7823   print "====== chunks"
7824 \end_layout
7826 \begin_layout Plain Layout
7828   output_chunks();
7829 \end_layout
7831 \begin_layout Plain Layout
7833   print "++++++ debug"
7834 \end_layout
7836 \begin_layout Plain Layout
7838   for (a in chunks) {
7839 \end_layout
7841 \begin_layout Plain Layout
7843     print a "=" chunks[a];
7844 \end_layout
7846 \begin_layout Plain Layout
7848   }
7849 \end_layout
7851 \begin_layout Plain Layout
7854 \end_layout
7856 \end_inset
7859 \end_layout
7861 \begin_layout Standard
7862 We do both of these at the end.
7863  We also set 
7864 \begin_inset Flex CharStyle:Code
7865 status collapsed
7867 \begin_layout Plain Layout
7868 ORS=""
7869 \end_layout
7871 \end_inset
7873  because each chunklet is not necessarily a complete line, and we already
7874  added 
7875 \begin_inset Flex CharStyle:Code
7876 status collapsed
7878 \begin_layout Plain Layout
7880 \end_layout
7882 \end_inset
7884  to each input line in section 
7885 \begin_inset CommandInset ref
7886 LatexCommand ref
7887 reference "sub:ORS-chunk-text"
7889 \end_inset
7892 \end_layout
7894 \begin_layout Chunk
7896 \end_layout
7898 \begin_layout Standard
7899 \begin_inset listings
7900 inline false
7901 status open
7903 \begin_layout Plain Layout
7905 END {
7906 \end_layout
7908 \begin_layout Plain Layout
7910   =<
7911 \backslash
7912 chunkref{debug-output}>
7913 \end_layout
7915 \begin_layout Plain Layout
7917   ORS="";
7918 \end_layout
7920 \begin_layout Plain Layout
7922   =<
7923 \backslash
7924 chunkref{generate-output}>
7925 \end_layout
7927 \begin_layout Plain Layout
7930 \end_layout
7932 \end_inset
7935 \end_layout
7937 \begin_layout Standard
7938 We write chunk names like this.
7939  If we seem to be running in notangle compatibility mode, then we enclose
7940  the name like this 
7941 \begin_inset Flex CharStyle:Code
7942 status collapsed
7944 \begin_layout Plain Layout
7945 <<name>>
7946 \end_layout
7948 \end_inset
7950  the same way notangle does:
7951 \end_layout
7953 \begin_layout Chunk
7954 output_chunk_names()
7955 \end_layout
7957 \begin_layout Standard
7958 \begin_inset listings
7959 inline false
7960 status open
7962 \begin_layout Plain Layout
7964 function output_chunk_names(   c, prefix, suffix) 
7965 \end_layout
7967 \begin_layout Plain Layout
7970 \end_layout
7972 \begin_layout Plain Layout
7974   if (notangle_mode) {
7975 \end_layout
7977 \begin_layout Plain Layout
7979     prefix="<<";
7980 \end_layout
7982 \begin_layout Plain Layout
7984     suffix=">>";
7985 \end_layout
7987 \begin_layout Plain Layout
7989   }
7990 \end_layout
7992 \begin_layout Plain Layout
7994   for (c in chunk_names) {
7995 \end_layout
7997 \begin_layout Plain Layout
7999     print prefix c suffix "
8000 \backslash
8002 \end_layout
8004 \begin_layout Plain Layout
8006   }
8007 \end_layout
8009 \begin_layout Plain Layout
8012 \end_layout
8014 \end_inset
8017 \end_layout
8019 \begin_layout Standard
8020 This function would write out all chunks
8021 \end_layout
8023 \begin_layout Chunk
8024 output_chunks()
8025 \end_layout
8027 \begin_layout Standard
8028 \begin_inset listings
8029 inline false
8030 status open
8032 \begin_layout Plain Layout
8034 function output_chunks(  a) 
8035 \end_layout
8037 \begin_layout Plain Layout
8040 \end_layout
8042 \begin_layout Plain Layout
8044   for (a in chunk_names) {
8045 \end_layout
8047 \begin_layout Plain Layout
8049     output_chunk(chunk_names[a]);
8050 \end_layout
8052 \begin_layout Plain Layout
8054   }
8055 \end_layout
8057 \begin_layout Plain Layout
8060 \end_layout
8062 \begin_layout Plain Layout
8064 \end_layout
8066 \begin_layout Plain Layout
8068 function output_chunk(chunk) {
8069 \end_layout
8071 \begin_layout Plain Layout
8073   newline = 1;
8074 \end_layout
8076 \begin_layout Plain Layout
8078   lineno_needed = linenos;
8079 \end_layout
8081 \begin_layout Plain Layout
8083 \end_layout
8085 \begin_layout Plain Layout
8087   write_chunk(chunk);
8088 \end_layout
8090 \begin_layout Plain Layout
8093 \end_layout
8095 \begin_layout Plain Layout
8097 \end_layout
8099 \end_inset
8102 \end_layout
8104 \begin_layout Section
8105 Assembling the chunks
8106 \end_layout
8108 \begin_layout Standard
8109 \begin_inset Flex CharStyle:Code
8110 status collapsed
8112 \begin_layout Plain Layout
8113 chunk_path
8114 \end_layout
8116 \end_inset
8118  holds a string consisting of the names of all the chunks that resulted
8119  in this chunk being output.
8121 \begin_inset Note Note
8122 status collapsed
8124 \begin_layout Plain Layout
8125 Make sure it includes the line numbers too...
8127 \end_layout
8129 \end_inset
8131 It should probably also contain the source line numbers at which each inclusion
8132  also occured.
8133 \end_layout
8135 \begin_layout Chunk
8136 write_chunk(),emph={chunk_path}
8137 \end_layout
8139 \begin_layout Standard
8140 \begin_inset listings
8141 inline false
8142 status open
8144 \begin_layout Plain Layout
8146 function write_chunk(chunk_name, indent, tail,
8147 \end_layout
8149 \begin_layout Plain Layout
8151   # optional vars
8152 \end_layout
8154 \begin_layout Plain Layout
8156   chunk_path, chunk_args, 
8157 \end_layout
8159 \begin_layout Plain Layout
8161   # local vars
8162 \end_layout
8164 \begin_layout Plain Layout
8166   part, max_part, part_line, frag, max_frag, text, 
8167 \end_layout
8169 \begin_layout Plain Layout
8171   chunklet, only_part, call_chunk_args, mode)
8172 \end_layout
8174 \begin_layout Plain Layout
8177 \end_layout
8179 \end_inset
8182 \end_layout
8184 \begin_layout Subsection
8185 \begin_inset CommandInset label
8186 LatexCommand label
8187 name "sub:Chunk-parts"
8189 \end_inset
8191 Chunk parts
8192 \end_layout
8194 \begin_layout Standard
8195 As mentioned in section 
8196 \begin_inset CommandInset ref
8197 LatexCommand ref
8198 reference "sub:lstlistings-includes"
8200 \end_inset
8202 , a chunk name may contain a part specifier in square brackets, limiting
8203  the parts that should be emitted.
8204 \end_layout
8206 \begin_layout Standard
8207 \begin_inset listings
8208 inline false
8209 status open
8211 \begin_layout Plain Layout
8213   if (match(chunk_name, "^(.*)
8214 \backslash
8216 \backslash
8217 [([0-9]*)
8218 \backslash
8220 \backslash
8221 ]$", chunk_name_parts)) {
8222 \end_layout
8224 \begin_layout Plain Layout
8226     chunk_name = chunk_name_parts[1];
8227 \end_layout
8229 \begin_layout Plain Layout
8231     only_part = chunk_name_parts[2];
8232 \end_layout
8234 \begin_layout Plain Layout
8236   }
8237 \end_layout
8239 \end_inset
8242 \end_layout
8244 \begin_layout Standard
8245 We first create the mode tracker for this chunk.
8246 \end_layout
8248 \begin_layout Standard
8249 #  =<
8250 \backslash
8251 chunkref{awk-delete-array}(mode)>
8252 \end_layout
8254 \begin_layout Standard
8255 \begin_inset listings
8256 inline false
8257 status open
8259 \begin_layout Plain Layout
8261   split("", mode);
8262 \end_layout
8264 \begin_layout Plain Layout
8266   new_mode(chunks[chunk_name, "language"], mode);
8267 \end_layout
8269 \end_inset
8272 \end_layout
8274 \begin_layout Standard
8275 #  =<
8276 \backslash
8277 chunkref{new-mode}(chunks[chunk_name, "language"], mode)>
8278 \end_layout
8280 \begin_layout Standard
8281 We extract into 
8282 \begin_inset Flex CharStyle:Code
8283 status collapsed
8285 \begin_layout Plain Layout
8286 chunk_params
8287 \end_layout
8289 \end_inset
8291  the names of the parameters that this chunk accepts, whose values were
8292  (optionally) passed in 
8293 \begin_inset Flex CharStyle:Code
8294 status collapsed
8296 \begin_layout Plain Layout
8297 chunk_args
8298 \end_layout
8300 \end_inset
8303 \end_layout
8305 \begin_layout Standard
8306 \begin_inset listings
8307 inline false
8308 status open
8310 \begin_layout Plain Layout
8312   split(chunks[chunk_name, "params"], chunk_params, " *; *");
8313 \end_layout
8315 \end_inset
8318 \end_layout
8320 \begin_layout Standard
8321 To assemble a chunk, we write out each part.
8322 \end_layout
8324 \begin_layout Chunk
8325 write_chunk()
8326 \end_layout
8328 \begin_layout Standard
8329 \begin_inset listings
8330 inline false
8331 status open
8333 \begin_layout Plain Layout
8335   if (! (chunk_name in chunk_names)) {
8336 \end_layout
8338 \begin_layout Plain Layout
8340     error(sprintf(_"The root module <<%s>> was not defined.
8341 \backslash
8342 nUsed by: %s",
8343 \backslash
8345 \end_layout
8347 \begin_layout Plain Layout
8349                   chunk_name, chunk_path));
8350 \end_layout
8352 \begin_layout Plain Layout
8354   }
8355 \end_layout
8357 \begin_layout Plain Layout
8359 \end_layout
8361 \begin_layout Plain Layout
8363   max_part = chunks[chunk_name, "part"];
8364 \end_layout
8366 \begin_layout Plain Layout
8368   for(part = 1; part <= max_part; part++) {
8369 \end_layout
8371 \begin_layout Plain Layout
8373     if (! only_part || part == only_part) {
8374 \end_layout
8376 \begin_layout Plain Layout
8378       =<
8379 \backslash
8380 chunkref{write-part}>
8381 \end_layout
8383 \begin_layout Plain Layout
8385     }
8386 \end_layout
8388 \begin_layout Plain Layout
8390   }
8391 \end_layout
8393 \begin_layout Plain Layout
8396 \end_layout
8398 \end_inset
8401 \end_layout
8403 \begin_layout Standard
8404 A part can either be a chunklet of lines, or an include of another chunk.
8405 \end_layout
8407 \begin_layout Standard
8408 Chunks may also have parameters, specified in LaTeX style with braces after
8409  the chunk name --- looking like this in the document: 
8410 \begin_inset Flex CharStyle:Code
8411 status collapsed
8413 \begin_layout Plain Layout
8414 chunkname{param1, param2}
8415 \end_layout
8417 \end_inset
8420  Arguments are passed in square brackets: 
8421 \begin_inset Flex CharStyle:Code
8422 status collapsed
8424 \begin_layout Plain Layout
8426 \backslash
8427 chunkref{chunkname}[arg1, arg2]
8428 \end_layout
8430 \end_inset
8433 \end_layout
8435 \begin_layout Standard
8436 Before we process each part, we check that the source position hasn't changed
8437  unexpectedly, so that we can know if we need to output a new file-line
8438  directive.
8439 \end_layout
8441 \begin_layout Chunk
8442 write-part
8443 \end_layout
8445 \begin_layout Standard
8446 \begin_inset listings
8447 inline false
8448 status open
8450 \begin_layout Plain Layout
8453 \backslash
8454 chunkref{check-source-jump}>
8455 \end_layout
8457 \begin_layout Plain Layout
8459 \end_layout
8461 \begin_layout Plain Layout
8463 chunklet = chunks[chunk_name, "part", part];
8464 \end_layout
8466 \begin_layout Plain Layout
8468 if (chunks[chunk_name, "part", part, "type"] == part_type_chunk) {
8469 \end_layout
8471 \begin_layout Plain Layout
8473   =<
8474 \backslash
8475 chunkref{write-included-chunk}>
8476 \end_layout
8478 \begin_layout Plain Layout
8480 } else if (chunklet SUBSEP "line" in chunks) {
8481 \end_layout
8483 \begin_layout Plain Layout
8485   =<
8486 \backslash
8487 chunkref{write-chunklets}>
8488 \end_layout
8490 \begin_layout Plain Layout
8492 } else {
8493 \end_layout
8495 \begin_layout Plain Layout
8497   # empty last chunklet
8498 \end_layout
8500 \begin_layout Plain Layout
8503 \end_layout
8505 \end_inset
8508 \end_layout
8510 \begin_layout Standard
8511 To write an included chunk, we must detect any optional chunk arguments
8512  in parenthesis.
8513  Then we recurse calling 
8514 \begin_inset Flex Chunkref
8515 status collapsed
8517 \begin_layout Plain Layout
8518 write_chunk()
8519 \end_layout
8521 \end_inset
8524 \end_layout
8526 \begin_layout Chunk
8527 write-included-chunk
8528 \end_layout
8530 \begin_layout Standard
8531 \begin_inset listings
8532 inline false
8533 status open
8535 \begin_layout Plain Layout
8537 if (match(chunklet, "^([^
8538 \backslash
8540 \backslash
8541 []*)
8542 \backslash
8544 \backslash
8545 ((.*)
8546 \backslash
8548 \backslash
8549 )$", chunklet_parts)) {
8550 \end_layout
8552 \begin_layout Plain Layout
8554   chunklet = chunklet_parts[1];
8555 \end_layout
8557 \begin_layout Plain Layout
8559   parse_chunk_args("", chunklet_parts[2], call_chunk_args, "(");
8560 \end_layout
8562 \begin_layout Plain Layout
8564   for (c in call_chunk_args) {
8565 \end_layout
8567 \begin_layout Plain Layout
8569     call_chunk_args[c] = expand_chunk_args(call_chunk_args[c], chunk_params,
8570  chunk_args);
8571 \end_layout
8573 \begin_layout Plain Layout
8575   }
8576 \end_layout
8578 \begin_layout Plain Layout
8580 } else {
8581 \end_layout
8583 \begin_layout Plain Layout
8585   split("", call_chunk_args);
8586 \end_layout
8588 \begin_layout Plain Layout
8591 \end_layout
8593 \begin_layout Plain Layout
8595 write_chunk(chunklet,
8596 \end_layout
8598 \begin_layout Plain Layout
8600             chunks[chunk_name, "part", part, "indent"] indent,
8601 \end_layout
8603 \begin_layout Plain Layout
8605             chunks[chunk_name, "part", part, "tail"],
8606 \end_layout
8608 \begin_layout Plain Layout
8610             chunk_path "
8611 \backslash
8612 n         " chunk_name,
8613 \end_layout
8615 \begin_layout Plain Layout
8617             call_chunk_args);
8618 \end_layout
8620 \end_inset
8623 \end_layout
8625 \begin_layout Standard
8626 Before we output a chunklet of lines, we first emit the file and line number
8627  if we have one, and if it is safe to do so.
8629 \end_layout
8631 \begin_layout Standard
8632 Chunklets are generally broken up by includes, so the start of a chunklet
8633  is a good place to do this.
8634  Then we output each line of the chunklet.
8635 \end_layout
8637 \begin_layout Standard
8638 When it is not safe, such as in the middle of a multi-line macro definition,
8640 \begin_inset Flex CharStyle:Code
8641 status collapsed
8643 \begin_layout Plain Layout
8644 lineno_suppressed
8645 \end_layout
8647 \end_inset
8649  is set to true, and in such a case we note that we want to emit the line
8650  statement when it is next safe.
8651 \end_layout
8653 \begin_layout Chunk
8654 write-chunklets
8655 \end_layout
8657 \begin_layout Standard
8658 \begin_inset listings
8659 inline false
8660 status open
8662 \begin_layout Plain Layout
8664 max_frag = chunks[chunklet, "line"];
8665 \end_layout
8667 \begin_layout Plain Layout
8669 for(frag = 1; frag <= max_frag; frag++) {
8670 \end_layout
8672 \begin_layout Plain Layout
8674   =<
8675 \backslash
8676 chunkref{write-file-line}>
8677 \end_layout
8679 \end_inset
8682 \end_layout
8684 \begin_layout Standard
8685 We then extract the chunklet text and expand any arguments.
8686 \end_layout
8688 \begin_layout Standard
8689 \begin_inset listings
8690 inline false
8691 status open
8693 \begin_layout Plain Layout
8695 \end_layout
8697 \begin_layout Plain Layout
8699   text = chunks[chunklet, frag];
8700 \end_layout
8702 \begin_layout Plain Layout
8705 \end_layout
8707 \begin_layout Plain Layout
8709   /* check params */
8710 \end_layout
8712 \begin_layout Plain Layout
8714   text = expand_chunk_args(text, chunk_params, chunk_args);
8715 \end_layout
8717 \end_inset
8720 \end_layout
8722 \begin_layout Standard
8723 If the text is a single newline (which we keep separate - see 
8724 \begin_inset CommandInset ref
8725 LatexCommand ref
8726 reference "lone-newline"
8728 \end_inset
8730 ) then we increment the line number.
8731  In the case where this is the last line of a chunk and it is not a top-level
8732  chunk we replace the newline with an empty string --- because the chunk
8733  that included this chunk will have the newline at the end of the line that
8734  included this chunk.
8735 \end_layout
8737 \begin_layout Standard
8738 We also note by 
8739 \begin_inset Flex CharStyle:Code
8740 status collapsed
8742 \begin_layout Plain Layout
8743 newline = 1
8744 \end_layout
8746 \end_inset
8748  that we have started a new line, so that indentation can be managed with
8749  the following piece of text.
8750 \end_layout
8752 \begin_layout Standard
8753 \begin_inset listings
8754 inline false
8755 status open
8757 \begin_layout Plain Layout
8759 \end_layout
8761 \begin_layout Plain Layout
8763  if (text == "
8764 \backslash
8765 n") {
8766 \end_layout
8768 \begin_layout Plain Layout
8770     lineno++;
8771 \end_layout
8773 \begin_layout Plain Layout
8775     if (part == max_part && frag == max_frag && length(chunk_path)) {
8776 \end_layout
8778 \begin_layout Plain Layout
8780       text = "";
8781 \end_layout
8783 \begin_layout Plain Layout
8785       break;
8786 \end_layout
8788 \begin_layout Plain Layout
8790     } else {
8791 \end_layout
8793 \begin_layout Plain Layout
8795       newline = 1;
8796 \end_layout
8798 \begin_layout Plain Layout
8800     }
8801 \end_layout
8803 \end_inset
8806 \end_layout
8808 \begin_layout Standard
8809 If this text does not represent a newline, but we see that we are the first
8810  piece of text on a newline, then we prefix our text with the current indent.
8811  NOTE: 
8812 \begin_inset Flex CharStyle:Code
8813 status collapsed
8815 \begin_layout Plain Layout
8816 newline
8817 \end_layout
8819 \end_inset
8821  is a global output-state variable, but the 
8822 \begin_inset Flex CharStyle:Code
8823 status collapsed
8825 \begin_layout Plain Layout
8826 indent
8827 \end_layout
8829 \end_inset
8831  is not.
8833 \end_layout
8835 \begin_layout Standard
8836 \begin_inset listings
8837 inline false
8838 status open
8840 \begin_layout Plain Layout
8842   } else if (length(text) || length(tail)) {
8843 \end_layout
8845 \begin_layout Plain Layout
8847     if (newline) text = indent text;
8848 \end_layout
8850 \begin_layout Plain Layout
8852     newline = 0;
8853 \end_layout
8855 \begin_layout Plain Layout
8857   }
8858 \end_layout
8860 \begin_layout Plain Layout
8862 \end_layout
8864 \end_inset
8867 \end_layout
8869 \begin_layout Standard
8870 Tail will soon no longer be relevant once mode-detection is in place.
8871 \end_layout
8873 \begin_layout Standard
8874 \begin_inset listings
8875 inline false
8876 status open
8878 \begin_layout Plain Layout
8880   text = text tail;
8881 \end_layout
8883 \begin_layout Plain Layout
8885 #  track_mode(mode, text);
8886 \end_layout
8888 \begin_layout Plain Layout
8890   print text;
8891 \end_layout
8893 \end_inset
8896 \end_layout
8898 \begin_layout Standard
8899 If a line ends in a backslash --- suggesting continuation --- then we supress
8900  outputting file-line as it would probably break the continued lines.
8902 \end_layout
8904 \begin_layout Standard
8905 \begin_inset listings
8906 inline false
8907 status open
8909 \begin_layout Plain Layout
8911   if (linenos) {
8912 \end_layout
8914 \begin_layout Plain Layout
8916     lineno_suppressed = substr(lastline, length(lastline)) == "
8917 \backslash
8919 \backslash
8921 \end_layout
8923 \begin_layout Plain Layout
8925   }
8926 \end_layout
8928 \begin_layout Plain Layout
8931 \end_layout
8933 \end_inset
8936 \end_layout
8938 \begin_layout Standard
8939 Of course there is no point in actually outputting the source filename and
8940  line number (file-line) if they don't say anything new! We only need to
8941  emit them if they aren't what is expected, or if we we not able to emit
8942  one when they had changed.
8943 \end_layout
8945 \begin_layout Chunk
8946 write-file-line
8947 \end_layout
8949 \begin_layout Standard
8950 \begin_inset listings
8951 inline false
8952 status open
8954 \begin_layout Plain Layout
8956 if (newline && lineno_needed && ! lineno_suppressed) {
8957 \end_layout
8959 \begin_layout Plain Layout
8961   filename = a_filename;
8962 \end_layout
8964 \begin_layout Plain Layout
8966   lineno = a_lineno;
8967 \end_layout
8969 \begin_layout Plain Layout
8971   print "#line " lineno " 
8972 \backslash
8973 "" filename "
8974 \backslash
8976 \backslash
8978 \end_layout
8980 \begin_layout Plain Layout
8982   lineno_needed = 0;
8983 \end_layout
8985 \begin_layout Plain Layout
8988 \end_layout
8990 \end_inset
8993 \end_layout
8995 \begin_layout Standard
8996 We check if a new file-line is needed by checking if the source line matches
8997  what we (or a compiler) would expect.
8999 \end_layout
9001 \begin_layout Chunk
9002 check-source-jump
9003 \end_layout
9005 \begin_layout Standard
9006 \begin_inset listings
9007 inline false
9008 status open
9010 \begin_layout Plain Layout
9012 if (linenos && (chunk_name SUBSEP "part" SUBSEP part SUBSEP "FILENAME" in
9013  chunks)) {
9014 \end_layout
9016 \begin_layout Plain Layout
9018   a_filename = chunks[chunk_name, "part", part, "FILENAME"];
9019 \end_layout
9021 \begin_layout Plain Layout
9023   a_lineno = chunks[chunk_name, "part", part, "LINENO"];
9024 \end_layout
9026 \begin_layout Plain Layout
9028   if (a_filename != filename || a_lineno != lineno) {
9029 \end_layout
9031 \begin_layout Plain Layout
9033     lineno_needed++;
9034 \end_layout
9036 \begin_layout Plain Layout
9038   }
9039 \end_layout
9041 \begin_layout Plain Layout
9044 \end_layout
9046 \end_inset
9049 \end_layout
9051 \begin_layout Chapter
9052 Storing chunks
9053 \end_layout
9055 \begin_layout Standard
9056 Awk has pretty limited data structures, so we will use two main hashes.
9057  Uninterrupted sequences of a chunk will be stored in 
9058 \begin_inset Flex CharStyle:Code
9059 status collapsed
9061 \begin_layout Plain Layout
9062 chunklets
9063 \end_layout
9065 \end_inset
9067  and the chunklets used in a chunk will be stored in 
9068 \begin_inset Flex CharStyle:Code
9069 status collapsed
9071 \begin_layout Plain Layout
9072 chunks
9073 \end_layout
9075 \end_inset
9078 \end_layout
9080 \begin_layout Chunk
9081 constants
9082 \end_layout
9084 \begin_layout Standard
9085 \begin_inset listings
9086 inline false
9087 status open
9089 \begin_layout Plain Layout
9091 part_type_chunk=1;
9092 \end_layout
9094 \begin_layout Plain Layout
9096 SUBSEP=",";
9097 \end_layout
9099 \end_inset
9102 \end_layout
9104 \begin_layout Standard
9105 The 
9106 \begin_inset Flex CharStyle:Code
9107 status collapsed
9109 \begin_layout Plain Layout
9110 params
9111 \end_layout
9113 \end_inset
9115  mentioned are not chunk parameters for parameterized chunks, as mentioned
9116  in 
9117 \begin_inset CommandInset ref
9118 LatexCommand ref
9119 reference "cha:Chunk Arguments"
9121 \end_inset
9123 , but the lstlistings style parameters used in the 
9124 \begin_inset Flex CharStyle:Code
9125 status collapsed
9127 \begin_layout Plain Layout
9129 \backslash
9130 Chunk
9131 \end_layout
9133 \end_inset
9135  command
9136 \begin_inset Foot
9137 status collapsed
9139 \begin_layout Plain Layout
9140 The 
9141 \begin_inset Flex CharStyle:Code
9142 status collapsed
9144 \begin_layout Plain Layout
9145 params
9146 \end_layout
9148 \end_inset
9150  parameter is used to hold the parameters for parameterized chunks
9151 \end_layout
9153 \end_inset
9156 \end_layout
9158 \begin_layout Chunk
9159 chunk-storage-functions
9160 \end_layout
9162 \begin_layout Standard
9163 \begin_inset listings
9164 inline false
9165 status open
9167 \begin_layout Plain Layout
9169 function new_chunk(chunk_name, params,
9170 \end_layout
9172 \begin_layout Plain Layout
9174   # local vars
9175 \end_layout
9177 \begin_layout Plain Layout
9179   p, append )
9180 \end_layout
9182 \begin_layout Plain Layout
9185 \end_layout
9187 \begin_layout Plain Layout
9189   # HACK WHILE WE CHANGE TO ( ) for PARAM CHUNKS
9190 \end_layout
9192 \begin_layout Plain Layout
9194   gsub("
9195 \backslash
9197 \backslash
9199 \backslash
9201 \backslash
9202 )$", "", chunk_name);
9203 \end_layout
9205 \begin_layout Plain Layout
9207   if (! (chunk_name in chunk_names)) {
9208 \end_layout
9210 \begin_layout Plain Layout
9212     if (debug) print "New chunk " chunk_name;
9213 \end_layout
9215 \begin_layout Plain Layout
9217     chunk_names[chunk_name];
9218 \end_layout
9220 \begin_layout Plain Layout
9222     for (p in params) {
9223 \end_layout
9225 \begin_layout Plain Layout
9227       chunks[chunk_name, p] = params[p];
9228 \end_layout
9230 \begin_layout Plain Layout
9232     }
9233 \end_layout
9235 \begin_layout Plain Layout
9237     if ("append" in params) {
9238 \end_layout
9240 \begin_layout Plain Layout
9242       append=params["append"];
9243 \end_layout
9245 \begin_layout Plain Layout
9247       if (! (append in chunk_names)) {
9248 \end_layout
9250 \begin_layout Plain Layout
9252         warning("Chunk " chunk_name " is appended to chunk " append " which
9253  is not defined yet");
9254 \end_layout
9256 \begin_layout Plain Layout
9258         new_chunk(append);
9259 \end_layout
9261 \begin_layout Plain Layout
9263       }
9264 \end_layout
9266 \begin_layout Plain Layout
9268       chunk_include(append, chunk_name);
9269 \end_layout
9271 \begin_layout Plain Layout
9273       chunk_line(append, ORS);
9274 \end_layout
9276 \begin_layout Plain Layout
9278     }
9279 \end_layout
9281 \begin_layout Plain Layout
9283   }
9284 \end_layout
9286 \begin_layout Plain Layout
9288   active_chunk = chunk_name;
9289 \end_layout
9291 \begin_layout Plain Layout
9293   prime_chunk(chunk_name);
9294 \end_layout
9296 \begin_layout Plain Layout
9299 \end_layout
9301 \end_inset
9304 \end_layout
9306 \begin_layout Standard
9307 \begin_inset listings
9308 inline false
9309 status open
9311 \begin_layout Plain Layout
9313 \end_layout
9315 \begin_layout Plain Layout
9317 function prime_chunk(chunk_name)
9318 \end_layout
9320 \begin_layout Plain Layout
9323 \end_layout
9325 \begin_layout Plain Layout
9327   chunks[chunk_name, "part", ++chunks[chunk_name, "part"] ] = 
9328 \backslash
9330 \end_layout
9332 \begin_layout Plain Layout
9334          chunk_name SUBSEP "chunklet" SUBSEP "" ++chunks[chunk_name, "chunklet"]
9336 \end_layout
9338 \begin_layout Plain Layout
9340   chunks[chunk_name, "part", chunks[chunk_name, "part"], "FILENAME"] = FILENAME;
9341 \end_layout
9343 \begin_layout Plain Layout
9345   chunks[chunk_name, "part", chunks[chunk_name, "part"], "LINENO"] = FNR
9346  + 1;
9347 \end_layout
9349 \begin_layout Plain Layout
9352 \end_layout
9354 \begin_layout Plain Layout
9356 \end_layout
9358 \begin_layout Plain Layout
9360 function chunk_line(chunk_name, line){
9361 \end_layout
9363 \begin_layout Plain Layout
9365   chunks[chunk_name, "chunklet", chunks[chunk_name, "chunklet"],
9366 \end_layout
9368 \begin_layout Plain Layout
9370          ++chunks[chunk_name, "chunklet", chunks[chunk_name, "chunklet"],
9371  "line"]  ] = line;
9372 \end_layout
9374 \begin_layout Plain Layout
9377 \end_layout
9379 \begin_layout Plain Layout
9381 \end_layout
9383 \end_inset
9386 \end_layout
9388 \begin_layout Standard
9389 Chunk include represents a 
9390 \emph on
9391 chunkref
9392 \emph default
9393  statement, and stores the requirement to include another chunk.
9394  The parameter indent represents the quanity of literal text characters
9395  that preceded this 
9396 \emph on
9397 chunkref
9398 \emph default
9399  statement and therefore by how much additional lines of the included chunk
9400  should be indented.
9401 \end_layout
9403 \begin_layout Standard
9404 \begin_inset listings
9405 inline false
9406 status open
9408 \begin_layout Plain Layout
9410 function chunk_include(chunk_name, chunk_ref, indent, tail)
9411 \end_layout
9413 \begin_layout Plain Layout
9416 \end_layout
9418 \begin_layout Plain Layout
9420   chunks[chunk_name, "part", ++chunks[chunk_name, "part"] ] = chunk_ref;
9421 \end_layout
9423 \begin_layout Plain Layout
9425   chunks[chunk_name, "part", chunks[chunk_name, "part"], "type" ] = part_type_ch
9426 unk;
9427 \end_layout
9429 \begin_layout Plain Layout
9431   chunks[chunk_name, "part", chunks[chunk_name, "part"], "indent" ] = indent_str
9432 ing(indent);
9433 \end_layout
9435 \begin_layout Plain Layout
9437   chunks[chunk_name, "part", chunks[chunk_name, "part"], "tail" ] = tail;
9438 \end_layout
9440 \begin_layout Plain Layout
9442   prime_chunk(chunk_name);
9443 \end_layout
9445 \begin_layout Plain Layout
9448 \end_layout
9450 \begin_layout Plain Layout
9452 \end_layout
9454 \end_inset
9457 \end_layout
9459 \begin_layout Standard
9460 The indent is calculated by indent_string, which may in future convert some
9461  spaces into tab characters.
9462  This function works by generating a printf padded format string, like 
9463 \begin_inset Flex CharStyle:Code
9464 status collapsed
9466 \begin_layout Plain Layout
9467 %22s
9468 \end_layout
9470 \end_inset
9472  for an indent of 22, and then printing an empty string using that format.
9473 \end_layout
9475 \begin_layout Standard
9476 \begin_inset listings
9477 inline false
9478 status open
9480 \begin_layout Plain Layout
9482 function indent_string(indent) {
9483 \end_layout
9485 \begin_layout Plain Layout
9487   return sprintf("%" indent "s", "");
9488 \end_layout
9490 \begin_layout Plain Layout
9493 \end_layout
9495 \end_inset
9498 \end_layout
9500 \begin_layout Chapter
9501 \begin_inset CommandInset label
9502 LatexCommand label
9503 name "cha:getopt"
9505 \end_inset
9507 getopt
9508 \end_layout
9510 \begin_layout Standard
9511 I use Arnold Robbins public domain getopt (1993 revision).
9512  This is probably the same one that is covered in chapter 12 of 
9513 \begin_inset Quotes eld
9514 \end_inset
9516 Edition 3 of GAWK: Effective AWK Programming: A User's Guide for GNU Awk
9517 \begin_inset Quotes erd
9518 \end_inset
9520  but as that is licensed under the GNU Free Documentation License, Version
9521  1.3, which conflicts with the GPL3, I can't use it from there (or it's accompany
9522 ing explanations), so I do my best to explain how it works here.
9523 \end_layout
9525 \begin_layout Standard
9526 The getopt.awk header is:
9527 \end_layout
9529 \begin_layout Chunk
9530 getopt.awk-header,language=awk,morestring=[b]{/},morekeywords=else
9531 \end_layout
9533 \begin_layout Standard
9534 \begin_inset listings
9535 inline false
9536 status open
9538 \begin_layout Plain Layout
9540 # getopt.awk --- do C library getopt(3) function in awk
9541 \end_layout
9543 \begin_layout Plain Layout
9546 \end_layout
9548 \begin_layout Plain Layout
9550 # Arnold Robbins, arnold@skeeve.com, Public Domain
9551 \end_layout
9553 \begin_layout Plain Layout
9556 \end_layout
9558 \begin_layout Plain Layout
9560 # Initial version: March, 1991
9561 \end_layout
9563 \begin_layout Plain Layout
9565 # Revised: May, 1993
9566 \end_layout
9568 \end_inset
9571 \end_layout
9573 \begin_layout Standard
9574 The provided explanation is:
9575 \end_layout
9577 \begin_layout Chunk
9578 getopt.awk-notes
9579 \end_layout
9581 \begin_layout Standard
9582 \begin_inset listings
9583 inline false
9584 status open
9586 \begin_layout Plain Layout
9588 # External variables:
9589 \end_layout
9591 \begin_layout Plain Layout
9593 #    Optind -- index in ARGV of first nonoption argument
9594 \end_layout
9596 \begin_layout Plain Layout
9598 #    Optarg -- string value of argument to current option
9599 \end_layout
9601 \begin_layout Plain Layout
9603 #    Opterr -- if nonzero, print our own diagnostic
9604 \end_layout
9606 \begin_layout Plain Layout
9608 #    Optopt -- current option letter
9609 \end_layout
9611 \begin_layout Plain Layout
9613 \end_layout
9615 \begin_layout Plain Layout
9617 # Returns:
9618 \end_layout
9620 \begin_layout Plain Layout
9622 #    -1     at end of options
9623 \end_layout
9625 \begin_layout Plain Layout
9627 #    ?      for unrecognized option
9628 \end_layout
9630 \begin_layout Plain Layout
9632 #    <c>    a character representing the current option
9633 \end_layout
9635 \begin_layout Plain Layout
9637 \end_layout
9639 \begin_layout Plain Layout
9641 # Private Data:
9642 \end_layout
9644 \begin_layout Plain Layout
9646 #    _opti  -- index in multi-flag option, e.g., -abc
9647 \end_layout
9649 \end_inset
9652 \end_layout
9654 \begin_layout Standard
9655 The function follows.
9656  The final two parameters, 
9657 \begin_inset Flex CharStyle:Code
9658 status collapsed
9660 \begin_layout Plain Layout
9661 thisopt
9662 \end_layout
9664 \end_inset
9666  and 
9667 \begin_inset Flex CharStyle:Code
9668 status collapsed
9670 \begin_layout Plain Layout
9672 \end_layout
9674 \end_inset
9676  are local variables and not parameters --- as indicated by the multiple
9677  spaces preceding them.
9678  Awk doesn't care, the multiple spaces are a convention to help us humans.
9679 \end_layout
9681 \begin_layout Chunk
9682 getopt.awk-getopt()
9683 \end_layout
9685 \begin_layout Standard
9686 \begin_inset listings
9687 inline false
9688 status open
9690 \begin_layout Plain Layout
9692 function getopt(argc, argv, options,    thisopt, i)
9693 \end_layout
9695 \begin_layout Plain Layout
9698 \end_layout
9700 \begin_layout Plain Layout
9702     if (length(options) == 0)    # no options given
9703 \end_layout
9705 \begin_layout Plain Layout
9707         return -1
9708 \end_layout
9710 \begin_layout Plain Layout
9712     if (argv[Optind] == "--") {  # all done
9713 \end_layout
9715 \begin_layout Plain Layout
9717         Optind++
9718 \end_layout
9720 \begin_layout Plain Layout
9722         _opti = 0
9723 \end_layout
9725 \begin_layout Plain Layout
9727         return -1
9728 \end_layout
9730 \begin_layout Plain Layout
9732     } else if (argv[Optind] !~ /^-[^: 
9733 \backslash
9735 \backslash
9737 \backslash
9739 \backslash
9741 \backslash
9743 \backslash
9744 b]/) {
9745 \end_layout
9747 \begin_layout Plain Layout
9749         _opti = 0
9750 \end_layout
9752 \begin_layout Plain Layout
9754         return -1
9755 \end_layout
9757 \begin_layout Plain Layout
9759     }
9760 \end_layout
9762 \begin_layout Plain Layout
9764     if (_opti == 0)
9765 \end_layout
9767 \begin_layout Plain Layout
9769         _opti = 2
9770 \end_layout
9772 \begin_layout Plain Layout
9774     thisopt = substr(argv[Optind], _opti, 1)
9775 \end_layout
9777 \begin_layout Plain Layout
9779     Optopt = thisopt
9780 \end_layout
9782 \begin_layout Plain Layout
9784     i = index(options, thisopt)
9785 \end_layout
9787 \begin_layout Plain Layout
9789     if (i == 0) {
9790 \end_layout
9792 \begin_layout Plain Layout
9794         if (Opterr)
9795 \end_layout
9797 \begin_layout Plain Layout
9799             printf("%c -- invalid option
9800 \backslash
9802 \end_layout
9804 \begin_layout Plain Layout
9806                                   thisopt) > "/dev/stderr"
9807 \end_layout
9809 \begin_layout Plain Layout
9811         if (_opti >= length(argv[Optind])) {
9812 \end_layout
9814 \begin_layout Plain Layout
9816             Optind++
9817 \end_layout
9819 \begin_layout Plain Layout
9821             _opti = 0
9822 \end_layout
9824 \begin_layout Plain Layout
9826         } else
9827 \end_layout
9829 \begin_layout Plain Layout
9831             _opti++
9832 \end_layout
9834 \begin_layout Plain Layout
9836         return "?"
9837 \end_layout
9839 \begin_layout Plain Layout
9841     }
9842 \end_layout
9844 \end_inset
9847 \end_layout
9849 \begin_layout Standard
9850 At this point, the option has been found and we need to know if it takes
9851  any arguments.
9852 \end_layout
9854 \begin_layout Standard
9855 \begin_inset listings
9856 inline false
9857 status open
9859 \begin_layout Plain Layout
9861     if (substr(options, i + 1, 1) == ":") {
9862 \end_layout
9864 \begin_layout Plain Layout
9866         # get option argument
9867 \end_layout
9869 \begin_layout Plain Layout
9871         if (length(substr(argv[Optind], _opti + 1)) > 0)
9872 \end_layout
9874 \begin_layout Plain Layout
9876             Optarg = substr(argv[Optind], _opti + 1)
9877 \end_layout
9879 \begin_layout Plain Layout
9881         else
9882 \end_layout
9884 \begin_layout Plain Layout
9886             Optarg = argv[++Optind]
9887 \end_layout
9889 \begin_layout Plain Layout
9891         _opti = 0
9892 \end_layout
9894 \begin_layout Plain Layout
9896     } else
9897 \end_layout
9899 \begin_layout Plain Layout
9901         Optarg = ""
9902 \end_layout
9904 \begin_layout Plain Layout
9906     if (_opti == 0 || _opti >= length(argv[Optind])) {
9907 \end_layout
9909 \begin_layout Plain Layout
9911         Optind++
9912 \end_layout
9914 \begin_layout Plain Layout
9916         _opti = 0
9917 \end_layout
9919 \begin_layout Plain Layout
9921     } else
9922 \end_layout
9924 \begin_layout Plain Layout
9926         _opti++
9927 \end_layout
9929 \begin_layout Plain Layout
9931     return thisopt
9932 \end_layout
9934 \begin_layout Plain Layout
9937 \end_layout
9939 \end_inset
9941 A test program is built in, too
9942 \end_layout
9944 \begin_layout Chunk
9945 getopt.awk-begin
9946 \end_layout
9948 \begin_layout Standard
9949 \begin_inset listings
9950 inline false
9951 status open
9953 \begin_layout Plain Layout
9955 BEGIN {
9956 \end_layout
9958 \begin_layout Plain Layout
9960     Opterr = 1    # default is to diagnose
9961 \end_layout
9963 \begin_layout Plain Layout
9965     Optind = 1    # skip ARGV[0]
9966 \end_layout
9968 \begin_layout Plain Layout
9970     # test program
9971 \end_layout
9973 \begin_layout Plain Layout
9975     if (_getopt_test) {
9976 \end_layout
9978 \begin_layout Plain Layout
9980         while ((_go_c = getopt(ARGC, ARGV, "ab:cd")) != -1)
9981 \end_layout
9983 \begin_layout Plain Layout
9985             printf("c = <%c>, optarg = <%s>
9986 \backslash
9988 \end_layout
9990 \begin_layout Plain Layout
9992                                        _go_c, Optarg)
9993 \end_layout
9995 \begin_layout Plain Layout
9997         printf("non-option arguments:
9998 \backslash
10000 \end_layout
10002 \begin_layout Plain Layout
10004         for (; Optind < ARGC; Optind++)
10005 \end_layout
10007 \begin_layout Plain Layout
10009             printf("
10010 \backslash
10011 tARGV[%d] = <%s>
10012 \backslash
10014 \end_layout
10016 \begin_layout Plain Layout
10018                                     Optind, ARGV[Optind])
10019 \end_layout
10021 \begin_layout Plain Layout
10023     }
10024 \end_layout
10026 \begin_layout Plain Layout
10029 \end_layout
10031 \end_inset
10034 \end_layout
10036 \begin_layout Standard
10037 The entire getopt.awk is made out of these chunks in order
10038 \end_layout
10040 \begin_layout Chunk
10041 getopt.awk
10042 \end_layout
10044 \begin_layout Standard
10045 \begin_inset listings
10046 inline false
10047 status open
10049 \begin_layout Plain Layout
10052 \backslash
10053 chunkref{getopt.awk-header}>
10054 \end_layout
10056 \begin_layout Plain Layout
10058 \end_layout
10060 \begin_layout Plain Layout
10063 \backslash
10064 chunkref{getopt.awk-notes}>
10065 \end_layout
10067 \begin_layout Plain Layout
10070 \backslash
10071 chunkref{getopt.awk-getopt()}>
10072 \end_layout
10074 \begin_layout Plain Layout
10077 \backslash
10078 chunkref{getopt.awk-begin}>
10079 \end_layout
10081 \end_inset
10084 \end_layout
10086 \begin_layout Standard
10087 Although we only want the header and function:
10088 \end_layout
10090 \begin_layout Chunk
10091 getopt
10092 \end_layout
10094 \begin_layout Standard
10095 \begin_inset listings
10096 inline false
10097 status open
10099 \begin_layout Plain Layout
10101 # try: locate getopt.awk for the full original file
10102 \end_layout
10104 \begin_layout Plain Layout
10106 # as part of your standard awk installation
10107 \end_layout
10109 \begin_layout Plain Layout
10112 \backslash
10113 chunkref{getopt.awk-header}>
10114 \end_layout
10116 \begin_layout Plain Layout
10118 \end_layout
10120 \begin_layout Plain Layout
10123 \backslash
10124 chunkref{getopt.awk-getopt()}>
10125 \end_layout
10127 \end_inset
10130 \end_layout
10132 \begin_layout Chapter
10133 Newfangle LaTeX source code
10134 \end_layout
10136 \begin_layout Section
10137 newfangle module
10138 \end_layout
10140 \begin_layout Standard
10141 Here we define a Lyx .module file that makes it convenient to use LyX for
10142  writing such literate programs.
10143 \end_layout
10145 \begin_layout Standard
10146 This file 
10147 \begin_inset Flex CharStyle:Code
10148 status collapsed
10150 \begin_layout Plain Layout
10151 ./newfangle.module
10152 \end_layout
10154 \end_inset
10156  can be installed in your personal 
10157 \begin_inset Flex CharStyle:Code
10158 status collapsed
10160 \begin_layout Plain Layout
10161 .lyx/layouts folder
10162 \end_layout
10164 \end_inset
10167  You will need to Tools Reconfigure so that LyX notices it.
10168  It adds a new format Chunk, which should precede every listing and contain
10169  the chunk name.
10171 \end_layout
10173 \begin_layout Chunk
10174 ./newfangle.module,language=
10175 \end_layout
10177 \begin_layout Standard
10178 \begin_inset listings
10179 inline false
10180 status open
10182 \begin_layout Plain Layout
10185 \backslash
10186 DeclareLyXModule{Newfangle Literate Listings}
10187 \end_layout
10189 \begin_layout Plain Layout
10191 #DescriptionBegin
10192 \end_layout
10194 \begin_layout Plain Layout
10196 #  Newfangle literate listings allow one to write
10197 \end_layout
10199 \begin_layout Plain Layout
10201 #   literate programs after the fashion of noweb, but without having
10202 \end_layout
10204 \begin_layout Plain Layout
10206 #   to use noweave to generate the documentation.
10207  Instead the listings
10208 \end_layout
10210 \begin_layout Plain Layout
10212 #   package is extended in conjunction with the noweb package to implement
10213 \end_layout
10215 \begin_layout Plain Layout
10217 #   to code formating directly as latex.
10218 \end_layout
10220 \begin_layout Plain Layout
10222 #  The newfangle awk script
10223 \end_layout
10225 \begin_layout Plain Layout
10227 #DescriptionEnd
10228 \end_layout
10230 \begin_layout Plain Layout
10232 \end_layout
10234 \begin_layout Plain Layout
10236 Format 11
10237 \end_layout
10239 \begin_layout Plain Layout
10241 \end_layout
10243 \begin_layout Plain Layout
10245 AddToPreamble
10246 \end_layout
10248 \begin_layout Plain Layout
10251 \backslash
10252 chunkref{./newfangle.sty}>
10253 \end_layout
10255 \begin_layout Plain Layout
10257 EndPreamble
10258 \end_layout
10260 \begin_layout Plain Layout
10262 \end_layout
10264 \begin_layout Plain Layout
10267 \backslash
10268 chunkref{chunkstyle}>
10269 \end_layout
10271 \begin_layout Plain Layout
10273 \end_layout
10275 \begin_layout Plain Layout
10278 \backslash
10279 chunkref{chunkref}>
10280 \end_layout
10282 \end_inset
10285 \end_layout
10287 \begin_layout Subsection
10288 The Chunk style
10289 \end_layout
10291 \begin_layout Standard
10292 The purpose of the 
10293 \noun on
10294 chunk
10295 \noun default
10296  style is to make it easier for LyX users to provide the name to 
10297 \begin_inset Flex CharStyle:Code
10298 status collapsed
10300 \begin_layout Plain Layout
10302 \backslash
10303 lstlistings
10304 \end_layout
10306 \end_inset
10309  Normally this requires right-clicking on the listing, choosing settings,
10310  advanced, and then typing 
10311 \begin_inset Flex CharStyle:Code
10312 status collapsed
10314 \begin_layout Plain Layout
10315 name=chunk-name
10316 \end_layout
10318 \end_inset
10321  This has the further disadvantage that the name (and other options) are
10322  not generally visible during document editing.
10323 \end_layout
10325 \begin_layout Standard
10326 The chunk style is defined as a LaTeX command, so that all text on the same
10327  line is passed to the LaTeX command 
10328 \begin_inset Flex CharStyle:Code
10329 status collapsed
10331 \begin_layout Plain Layout
10332 Chunk
10333 \end_layout
10335 \end_inset
10338  This makes it easy to parse using 
10339 \begin_inset Flex CharStyle:Code
10340 status collapsed
10342 \begin_layout Plain Layout
10343 newfangle
10344 \end_layout
10346 \end_inset
10348 , and easy to pass these options on to the listings package.
10349  The first word in a chunk section should be the chunk name, and will have
10351 \begin_inset Flex CharStyle:Code
10352 status collapsed
10354 \begin_layout Plain Layout
10355 name=
10356 \end_layout
10358 \end_inset
10360  prepended to it.
10361  Any other words are accepted arguments to 
10362 \begin_inset Flex CharStyle:Code
10363 status collapsed
10365 \begin_layout Plain Layout
10367 \backslash
10368 lstset
10369 \end_layout
10371 \end_inset
10374 \end_layout
10376 \begin_layout Standard
10377 We set PassThru to 1 because the user is actually entering raw latex.
10378 \end_layout
10380 \begin_layout Chunk
10381 chunkstyle
10382 \end_layout
10384 \begin_layout Standard
10385 \begin_inset listings
10386 inline false
10387 status open
10389 \begin_layout Plain Layout
10391 Style Chunk
10392 \end_layout
10394 \begin_layout Plain Layout
10396   LatexType             Command
10397 \end_layout
10399 \begin_layout Plain Layout
10401   LatexName             Chunk
10402 \end_layout
10404 \begin_layout Plain Layout
10406   Margin                First_Dynamic
10407 \end_layout
10409 \begin_layout Plain Layout
10411   LeftMargin            Chunk:xxx
10412 \end_layout
10414 \begin_layout Plain Layout
10416   LabelSep              xx
10417 \end_layout
10419 \begin_layout Plain Layout
10421   LabelType             Static
10422 \end_layout
10424 \begin_layout Plain Layout
10426   LabelString           "Chunk:"
10427 \end_layout
10429 \begin_layout Plain Layout
10431   Align                 Left
10432 \end_layout
10434 \begin_layout Plain Layout
10436   PassThru              1
10437 \end_layout
10439 \begin_layout Plain Layout
10441 \end_layout
10443 \end_inset
10446 \end_layout
10448 \begin_layout Standard
10449 To make the label very visible we choose a larger font coloured red.
10450 \end_layout
10452 \begin_layout Standard
10453 \begin_inset listings
10454 inline false
10455 status open
10457 \begin_layout Plain Layout
10459   LabelFont
10460 \end_layout
10462 \begin_layout Plain Layout
10464     Family              Sans
10465 \end_layout
10467 \begin_layout Plain Layout
10469     Size                Large
10470 \end_layout
10472 \begin_layout Plain Layout
10474     Series              Bold
10475 \end_layout
10477 \begin_layout Plain Layout
10479     Shape               Italic
10480 \end_layout
10482 \begin_layout Plain Layout
10484     Color               red
10485 \end_layout
10487 \begin_layout Plain Layout
10489   EndFont
10490 \end_layout
10492 \begin_layout Plain Layout
10495 \end_layout
10497 \end_inset
10500 \end_layout
10502 \begin_layout Subsection
10503 The chunkref style
10504 \end_layout
10506 \begin_layout Standard
10507 We also define the Chunkref style which can be used to express cross references
10508  to chunks.
10509 \end_layout
10511 \begin_layout Chunk
10512 chunkref
10513 \end_layout
10515 \begin_layout Standard
10516 \begin_inset listings
10517 inline false
10518 status open
10520 \begin_layout Plain Layout
10522 InsetLayout Chunkref
10523 \end_layout
10525 \begin_layout Plain Layout
10527   LyxType               charstyle
10528 \end_layout
10530 \begin_layout Plain Layout
10532   LatexType             Command
10533 \end_layout
10535 \begin_layout Plain Layout
10537   LatexName             chunkref
10538 \end_layout
10540 \begin_layout Plain Layout
10542   PassThru              1
10543 \end_layout
10545 \begin_layout Plain Layout
10547   LabelFont             
10548 \end_layout
10550 \begin_layout Plain Layout
10552     Shape               Italic
10553 \end_layout
10555 \begin_layout Plain Layout
10557     Color               red
10558 \end_layout
10560 \begin_layout Plain Layout
10562   EndFont
10563 \end_layout
10565 \begin_layout Plain Layout
10568 \end_layout
10570 \end_inset
10573 \end_layout
10575 \begin_layout Section
10576 \begin_inset CommandInset label
10577 LatexCommand label
10578 name "sec:Latex-Macros"
10580 \end_inset
10582 Latex Macros
10583 \end_layout
10585 \begin_layout Standard
10586 We require the 
10587 \noun on
10588 listings
10589 \noun default
10591 \noun on
10592 noweb
10593 \noun default
10594  and 
10595 \noun on
10596 xargs
10597 \noun default
10598  packages.
10599  As noweb defines it's own 
10600 \begin_inset Flex CharStyle:Code
10601 status collapsed
10603 \begin_layout Plain Layout
10605 \backslash
10606 code
10607 \end_layout
10609 \end_inset
10611  environment, we re-define the one that LyX logical markup module expects
10612  here.
10613 \end_layout
10615 \begin_layout Chunk
10616 ./newfangle.sty,language=tex,basicstyle=
10617 \backslash
10618 ttfamily
10619 \end_layout
10621 \begin_layout Standard
10622 \begin_inset listings
10623 inline false
10624 status open
10626 \begin_layout Plain Layout
10629 \backslash
10630 usepackage{listings}%
10631 \end_layout
10633 \begin_layout Plain Layout
10636 \backslash
10637 usepackage{noweb}%
10638 \end_layout
10640 \begin_layout Plain Layout
10643 \backslash
10644 usepackage{xargs}%
10645 \end_layout
10647 \begin_layout Plain Layout
10650 \backslash
10651 renewcommand{
10652 \backslash
10653 code}[1]{
10654 \backslash
10655 texttt{#1}}%
10656 \end_layout
10658 \end_inset
10661 \end_layout
10663 \begin_layout Standard
10664 We also define a 
10665 \begin_inset Flex CharStyle:Code
10666 status collapsed
10668 \begin_layout Plain Layout
10669 CChunk
10670 \end_layout
10672 \end_inset
10674  macro, for use as: 
10675 \begin_inset Flex CharStyle:Code
10676 status collapsed
10678 \begin_layout Plain Layout
10680 \backslash
10681 begin{CChunk}
10682 \end_layout
10684 \end_inset
10686  which will need renaming to 
10687 \begin_inset Flex CharStyle:Code
10688 status collapsed
10690 \begin_layout Plain Layout
10692 \backslash
10693 begin{Chunk}
10694 \end_layout
10696 \end_inset
10698  when I can do this without clashing with 
10699 \begin_inset Flex CharStyle:Code
10700 status collapsed
10702 \begin_layout Plain Layout
10704 \backslash
10705 Chunk
10706 \end_layout
10708 \end_inset
10711 \end_layout
10713 \begin_layout Standard
10714 \begin_inset listings
10715 inline false
10716 status open
10718 \begin_layout Plain Layout
10721 \backslash
10722 lstnewenvironment{Chunk}{
10723 \backslash
10724 relax}{
10725 \backslash
10726 relax}%
10727 \end_layout
10729 \end_inset
10732 \end_layout
10734 \begin_layout Standard
10735 We also define a suitable 
10736 \begin_inset Flex CharStyle:Code
10737 status collapsed
10739 \begin_layout Plain Layout
10741 \backslash
10742 lstset
10743 \end_layout
10745 \end_inset
10747  of parameters that suit the literate programming style after the fashion
10748  of 
10749 \noun on
10750 noweave
10751 \noun default
10753 \end_layout
10755 \begin_layout Standard
10756 \begin_inset listings
10757 inline false
10758 status open
10760 \begin_layout Plain Layout
10763 \backslash
10764 lstset{numbers=left, stepnumber=5, numbersep=5pt,
10765 \end_layout
10767 \begin_layout Plain Layout
10769         breaklines=false,basicstyle=
10770 \backslash
10771 ttfamily,
10772 \end_layout
10774 \begin_layout Plain Layout
10776         numberstyle=
10777 \backslash
10778 tiny, language=C}%
10779 \end_layout
10781 \end_inset
10784 \end_layout
10786 \begin_layout Standard
10787 We also define a notangle-like mechanism for 
10788 \emph on
10789 escaping
10790 \emph default
10791  to LaTeX from the listing, and by which we can refer to other listings.
10792  We declare the 
10793 \begin_inset Flex CharStyle:Code
10794 status collapsed
10796 \begin_layout Plain Layout
10797 =<\SpecialChar \ldots{}
10799 \end_layout
10801 \end_inset
10803  sequence to contain LaTeX code, and include another like this chunk: 
10804 \begin_inset Flex CharStyle:Code
10805 status collapsed
10807 \begin_layout Plain Layout
10809 \backslash
10810 chunkref{chunkname}>
10811 \end_layout
10813 \end_inset
10816  However, because 
10817 \begin_inset Flex CharStyle:Code
10818 status collapsed
10820 \begin_layout Plain Layout
10821 =<\SpecialChar \ldots{}
10823 \end_layout
10825 \end_inset
10827  is already defined to contain LaTeX code for this document --- this is
10828  a 
10829 \noun on
10830 newfangle
10831 \noun default
10832  document after all --- the code fragment below effectively contains the
10833  LaTeX code: 
10834 \begin_inset Flex CharStyle:Code
10835 status collapsed
10837 \begin_layout Plain Layout
10839 \end_layout
10841 \end_inset
10844  To avoid problems with document generation, I had to declare an lstlistings
10845  property: 
10846 \begin_inset Flex CharStyle:Code
10847 status collapsed
10849 \begin_layout Plain Layout
10850 escapeinside={}
10851 \end_layout
10853 \end_inset
10855  for this listing only; which in LyX was done by right-clicking the listings
10856  inset, choosing 
10857 \begin_inset Flex CharStyle:Code
10858 status collapsed
10860 \begin_layout Plain Layout
10861 settings
10862 \end_layout
10864 \end_inset
10866 \SpecialChar \menuseparator
10868 \begin_inset Flex CharStyle:Code
10869 status collapsed
10871 \begin_layout Plain Layout
10872 advanced
10873 \end_layout
10875 \end_inset
10878 \end_layout
10880 \begin_layout Standard
10881 \begin_inset Note Note
10882 status collapsed
10884 \begin_layout Plain Layout
10885 =< isn't enjoyed literally here, in a listing when the escape sequence is
10886  already defined as shown...
10887  we need to somehow escape this representation...
10888 \end_layout
10890 \end_inset
10893 \end_layout
10895 \begin_layout Standard
10896 \begin_inset listings
10897 lstparams "escapeinside={}"
10898 inline false
10899 status open
10901 \begin_layout Plain Layout
10904 \backslash
10905 lstset{escapeinside={=<}{>}}%
10906 \end_layout
10908 \end_inset
10911 \end_layout
10913 \begin_layout Standard
10914 Although our macros will contain the @ symbol, they will be included in
10915  a 
10916 \begin_inset Flex CharStyle:Code
10917 status collapsed
10919 \begin_layout Plain Layout
10921 \backslash
10922 makeatletter
10923 \end_layout
10925 \end_inset
10927  section by LyX; however we keep the commented out 
10928 \begin_inset Flex CharStyle:Code
10929 status collapsed
10931 \begin_layout Plain Layout
10933 \backslash
10934 makeatletter
10935 \end_layout
10937 \end_inset
10939  as a reminder.
10940  The listings package likes to centre the titles, but noweb titles are specially
10941  formatted and must be left aligned.
10942  The simplest way to do this turned out to be by removing the definition
10943  of 
10944 \begin_inset Flex CharStyle:Code
10945 status collapsed
10947 \begin_layout Plain Layout
10949 \backslash
10950 lst@maketitle
10951 \end_layout
10953 \end_inset
10956  This may interact badly if other listings want a regular title or caption.
10957  We remember the old maketitle in case we need it.
10958 \end_layout
10960 \begin_layout Standard
10961 \begin_inset listings
10962 inline false
10963 status open
10965 \begin_layout Plain Layout
10968 \backslash
10969 makeatletter
10970 \end_layout
10972 \begin_layout Plain Layout
10974 %somehow re-defining maketitle gives us a left-aligned title
10975 \end_layout
10977 \begin_layout Plain Layout
10979 %which is extactly what our specially formatted title needs!
10980 \end_layout
10982 \begin_layout Plain Layout
10985 \backslash
10986 global
10987 \backslash
10989 \backslash
10990 newfangle@lst@maketitle
10991 \backslash
10992 lst@maketitle%
10993 \end_layout
10995 \begin_layout Plain Layout
10998 \backslash
10999 global
11000 \backslash
11002 \backslash
11003 lst@maketitle{}%
11004 \end_layout
11006 \end_inset
11009 \end_layout
11011 \begin_layout Subsection
11012 \begin_inset CommandInset label
11013 LatexCommand label
11014 name "sub:The-chunk-command"
11016 \end_inset
11018 The chunk command
11019 \end_layout
11021 \begin_layout Standard
11022 Our chunk command accepts one argument, and calls 
11023 \begin_inset Flex CharStyle:Code
11024 status collapsed
11026 \begin_layout Plain Layout
11028 \backslash
11029 ltset
11030 \end_layout
11032 \end_inset
11035  Although 
11036 \begin_inset Flex CharStyle:Code
11037 status collapsed
11039 \begin_layout Plain Layout
11041 \backslash
11042 ltset
11043 \end_layout
11045 \end_inset
11047  will note the name, this is erased when the next 
11048 \begin_inset Flex CharStyle:Code
11049 status collapsed
11051 \begin_layout Plain Layout
11053 \backslash
11054 lstlisting
11055 \end_layout
11057 \end_inset
11059  starts, so we make a note of this in 
11060 \begin_inset Flex CharStyle:Code
11061 status collapsed
11063 \begin_layout Plain Layout
11065 \backslash
11066 lst@chunkname
11067 \end_layout
11069 \end_inset
11071  and restore in in lstlistings Init hook.
11072 \end_layout
11074 \begin_layout Standard
11075 \begin_inset listings
11076 inline false
11077 status open
11079 \begin_layout Plain Layout
11082 \backslash
11084 \backslash
11085 Chunk#1{%
11086 \end_layout
11088 \begin_layout Plain Layout
11090   
11091 \backslash
11092 lstset{title={
11093 \backslash
11094 newfanglecaption},name=#1}%
11095 \end_layout
11097 \begin_layout Plain Layout
11099   
11100 \backslash
11101 global
11102 \backslash
11103 edef
11104 \backslash
11105 lst@chunkname{
11106 \backslash
11107 lst@intname}%
11108 \end_layout
11110 \begin_layout Plain Layout
11113 \end_layout
11115 \begin_layout Plain Layout
11118 \backslash
11120 \backslash
11121 lst@chunkname{
11122 \backslash
11123 empty}%
11124 \end_layout
11126 \end_inset
11129 \end_layout
11131 \begin_layout Subsubsection
11132 Chunk parameters
11133 \end_layout
11135 \begin_layout Standard
11136 Newfangle permits parameterized chunks, and requires the paramters to be
11137  specified as listings options.
11138  The newfangle script uses this, and although we don't do anything with
11139  these in the LaTeX code right now, we need to stop the listings package
11140  complaining.
11141 \end_layout
11143 \begin_layout Standard
11144 \begin_inset listings
11145 inline false
11146 status open
11148 \begin_layout Plain Layout
11151 \backslash
11152 lst@Key{params}
11153 \backslash
11154 relax{
11155 \backslash
11157 \backslash
11158 newfangle@chunk@params{#1}}%
11159 \end_layout
11161 \end_inset
11164 \end_layout
11166 \begin_layout Standard
11167 As it is common to define a chunk which then needs appending to another
11168  chunk, and annoying to have to declare a single line chunk to manage the
11169  include, we support an 
11170 \begin_inset Flex CharStyle:Code
11171 status collapsed
11173 \begin_layout Plain Layout
11174 append=
11175 \end_layout
11177 \end_inset
11179  option.
11181 \end_layout
11183 \begin_layout Standard
11184 \begin_inset listings
11185 inline false
11186 status open
11188 \begin_layout Plain Layout
11191 \backslash
11192 lst@Key{append}
11193 \backslash
11194 relax{
11195 \backslash
11197 \backslash
11198 newfangle@chunk@append{#1}}%
11199 \end_layout
11201 \end_inset
11204 \end_layout
11206 \begin_layout Subsection
11207 The noweb styled caption
11208 \end_layout
11210 \begin_layout Standard
11211 We define a public macro 
11212 \begin_inset Flex CharStyle:Code
11213 status collapsed
11215 \begin_layout Plain Layout
11217 \backslash
11218 newfanglecaption
11219 \end_layout
11221 \end_inset
11223  which can be set as a regular title.
11224  By means of 
11225 \begin_inset Flex CharStyle:Code
11226 status collapsed
11228 \begin_layout Plain Layout
11230 \backslash
11231 protect
11232 \end_layout
11234 \end_inset
11236 , It expands to 
11237 \begin_inset Flex CharStyle:Code
11238 status collapsed
11240 \begin_layout Plain Layout
11242 \backslash
11243 newfangle@caption
11244 \end_layout
11246 \end_inset
11248  at the appriate time when the caption is emitted.
11249 \end_layout
11251 \begin_layout Standard
11252 \begin_inset listings
11253 inline false
11254 status open
11256 \begin_layout Plain Layout
11259 \backslash
11261 \backslash
11262 newfanglecaption{
11263 \backslash
11264 protect
11265 \backslash
11266 newfangle@caption}%
11267 \end_layout
11269 \end_inset
11272 \end_layout
11274 \begin_layout Standard
11275 \begin_inset Float figure
11276 placement H
11277 wide false
11278 sideways false
11279 status collapsed
11281 \begin_layout Plain Layout
11282 \begin_inset Box Boxed
11283 position "t"
11284 hor_pos "c"
11285 has_inner_box 1
11286 inner_pos "t"
11287 use_parbox 0
11288 width "100col%"
11289 special "none"
11290 height "1in"
11291 height_special "totalheight"
11292 status open
11294 \begin_layout Plain Layout
11296 \begin_inset space \qquad{}
11297 \end_inset
11300 \shape italic
11301 some-chunk
11302 \shape default
11303  19b⟩
11304 \begin_inset Formula $\equiv+$
11305 \end_inset
11308 \begin_inset space \qquad{}
11309 \end_inset
11312 \begin_inset space \qquad{}
11313 \end_inset
11316 \begin_inset space \qquad{}
11317 \end_inset
11320 \begin_inset Formula $\triangleleft$
11321 \end_inset
11324 \begin_inset space \quad{}
11325 \end_inset
11328 \begin_inset Formula $\triangleright$
11329 \end_inset
11332 \end_layout
11334 \begin_layout Plain Layout
11336 \size footnotesize
11337 In this example, the current chunk is 22c, and therefore the third chunk
11338  on page 22.
11339 \end_layout
11341 \begin_layout Plain Layout
11343 \size footnotesize
11344 It's name is 
11345 \emph on
11346 some-chunk
11347 \emph default
11350 \end_layout
11352 \begin_layout Plain Layout
11354 \size footnotesize
11355 The first chunk with this name (19b) occurs as the second chunk on page
11356  19.
11357 \end_layout
11359 \begin_layout Plain Layout
11361 \size footnotesize
11362 The previous chunk (22d) with the same name is the second chunk on page
11363  22.
11364 \end_layout
11366 \begin_layout Plain Layout
11368 \size footnotesize
11369 The next chunk (24d) is the fourth chunk on page 24.
11370 \end_layout
11372 \begin_layout Plain Layout
11373 \begin_inset Caption
11375 \begin_layout Plain Layout
11376 noweb heading
11377 \end_layout
11379 \end_inset
11382 \end_layout
11384 \end_inset
11387 \end_layout
11389 \end_inset
11391 The general noweb output format compactly identifies the current chunk,
11392  and references to the first chunk, and the previous and next chunks that
11393  have the same name.
11395 \end_layout
11397 \begin_layout Standard
11398 This means that we need to keep a counter for each chunk-name, that we use
11399  to count chunks of the same name.
11401 \end_layout
11403 \begin_layout Subsection
11404 The chunk counter
11405 \end_layout
11407 \begin_layout Standard
11408 It would be natural to have a counter for each chunk name, but TeX would
11409  soon run out of counters
11410 \begin_inset Foot
11411 status collapsed
11413 \begin_layout Plain Layout
11414 \SpecialChar \ldots{}
11415 soon 
11416 \emph on
11418 \emph default
11419  run out of counters and so I had to re-write the LaTeX macros to share
11420  a counter as described here
11421 \end_layout
11423 \end_inset
11425 , so we have one counter which we save at the end of a chunk and restore
11426  at the beginning of a chunk.
11427 \end_layout
11429 \begin_layout Standard
11430 \begin_inset listings
11431 inline false
11432 status open
11434 \begin_layout Plain Layout
11437 \backslash
11438 newcounter{newfangle@chunkcounter}%
11439 \end_layout
11441 \end_inset
11444 \end_layout
11446 \begin_layout Standard
11447 We construct the name of this variable to store the counter to be the text
11449 \begin_inset Flex CharStyle:Code
11450 status collapsed
11452 \begin_layout Plain Layout
11453 lst-chunk-
11454 \end_layout
11456 \end_inset
11458  prefixed onto the chunks own name, and store it in 
11459 \begin_inset Flex CharStyle:Code
11460 status collapsed
11462 \begin_layout Plain Layout
11464 \backslash
11465 chunkcount
11466 \end_layout
11468 \end_inset
11472 \end_layout
11474 \begin_layout Standard
11475 We save the counter like this:
11476 \end_layout
11478 \begin_layout Chunk
11479 save-counter
11480 \end_layout
11482 \begin_layout Standard
11483 \begin_inset listings
11484 inline false
11485 status open
11487 \begin_layout Plain Layout
11490 \backslash
11491 global
11492 \backslash
11493 expandafter
11494 \backslash
11495 edef
11496 \backslash
11497 csname 
11498 \backslash
11499 chunkcount
11500 \backslash
11501 endcsname{
11502 \backslash
11503 arabic{newfangle@chunkcounter}}%
11504 \end_layout
11506 \end_inset
11509 \end_layout
11511 \begin_layout Standard
11512 and restore the counter like this:
11513 \end_layout
11515 \begin_layout Chunk
11516 restore-counter
11517 \end_layout
11519 \begin_layout Standard
11520 \begin_inset listings
11521 inline false
11522 status open
11524 \begin_layout Plain Layout
11527 \backslash
11528 setcounter{newfangle@chunkcounter}{
11529 \backslash
11530 csname 
11531 \backslash
11532 chunkcount
11533 \backslash
11534 endcsname}%
11535 \end_layout
11537 \end_inset
11540 \end_layout
11542 \begin_layout Chunk
11543 ./newfangle.sty
11544 \end_layout
11546 \begin_layout Standard
11547 If there does not already exist a variable whose name is stored in 
11548 \begin_inset Flex CharStyle:Code
11549 status collapsed
11551 \begin_layout Plain Layout
11553 \backslash
11554 chunkcount
11555 \end_layout
11557 \end_inset
11559 , then we know we are the first chunk with this name, and then define a
11560  counter.
11562 \end_layout
11564 \begin_layout Standard
11565 Although chunks of the same name share a common counter, they must still
11566  be distinguished.
11567  We use is the internal name of the listing, suffixed by the counter value.
11568  So the first chunk might be 
11569 \begin_inset Flex CharStyle:Code
11570 status collapsed
11572 \begin_layout Plain Layout
11573 something-1
11574 \end_layout
11576 \end_inset
11578  and the second chunk be 
11579 \begin_inset Flex CharStyle:Code
11580 status collapsed
11582 \begin_layout Plain Layout
11583 something-2
11584 \end_layout
11586 \end_inset
11588 , etc.
11589 \end_layout
11591 \begin_layout Standard
11592 We also calculate the name of the previous chunk if we can (before we increment
11593  the chunk counter).
11594  If this is the first chunk of that name, then 
11595 \begin_inset Flex CharStyle:Code
11596 status collapsed
11598 \begin_layout Plain Layout
11600 \backslash
11601 prevchunkname
11602 \end_layout
11604 \end_inset
11606  is set to 
11607 \begin_inset Flex CharStyle:Code
11608 status collapsed
11610 \begin_layout Plain Layout
11612 \backslash
11613 relax
11614 \end_layout
11616 \end_inset
11618  which the noweb package will interpret as not existing.
11619 \end_layout
11621 \begin_layout Standard
11622 \begin_inset listings
11623 inline false
11624 status open
11626 \begin_layout Plain Layout
11629 \backslash
11631 \backslash
11632 newfangle@caption{%
11633 \end_layout
11635 \begin_layout Plain Layout
11637   
11638 \backslash
11639 edef
11640 \backslash
11641 chunkcount{lst-chunk-
11642 \backslash
11643 lst@intname}%
11644 \end_layout
11646 \begin_layout Plain Layout
11648   
11649 \backslash
11650 @ifundefined{
11651 \backslash
11652 chunkcount}{%
11653 \end_layout
11655 \begin_layout Plain Layout
11657     
11658 \backslash
11659 expandafter
11660 \backslash
11661 gdef
11662 \backslash
11663 csname 
11664 \backslash
11665 chunkcount
11666 \backslash
11667 endcsname{0}%
11668 \end_layout
11670 \begin_layout Plain Layout
11672     
11673 \backslash
11674 setcounter{newfangle@chunkcounter}{
11675 \backslash
11676 csname 
11677 \backslash
11678 chunkcount
11679 \backslash
11680 endcsname}%
11681 \end_layout
11683 \begin_layout Plain Layout
11685     
11686 \backslash
11688 \backslash
11689 prevchunkname
11690 \backslash
11691 relax%
11692 \end_layout
11694 \begin_layout Plain Layout
11696   }{%
11697 \end_layout
11699 \begin_layout Plain Layout
11701     
11702 \backslash
11703 setcounter{newfangle@chunkcounter}{
11704 \backslash
11705 csname 
11706 \backslash
11707 chunkcount
11708 \backslash
11709 endcsname}%
11710 \end_layout
11712 \begin_layout Plain Layout
11714     
11715 \backslash
11716 edef
11717 \backslash
11718 prevchunkname{
11719 \backslash
11720 lst@intname-
11721 \backslash
11722 arabic{newfangle@chunkcounter}}%
11723 \end_layout
11725 \begin_layout Plain Layout
11727   }%
11728 \end_layout
11730 \end_inset
11733 \end_layout
11735 \begin_layout Standard
11736 After incrementing the chunk counter, we then define the name of this chunk,
11737  as well as the name of the first chunk.
11738 \end_layout
11740 \begin_layout Standard
11741 \begin_inset listings
11742 inline false
11743 status open
11745 \begin_layout Plain Layout
11747   
11748 \backslash
11749 addtocounter{newfangle@chunkcounter}{1}%
11750 \end_layout
11752 \begin_layout Plain Layout
11754   
11755 \backslash
11756 global
11757 \backslash
11758 expandafter
11759 \backslash
11760 edef
11761 \backslash
11762 csname 
11763 \backslash
11764 chunkcount
11765 \backslash
11766 endcsname{
11767 \backslash
11768 arabic{newfangle@chunkcounter}}%
11769 \end_layout
11771 \begin_layout Plain Layout
11773   
11774 \backslash
11775 edef
11776 \backslash
11777 chunkname{
11778 \backslash
11779 lst@intname-
11780 \backslash
11781 arabic{newfangle@chunkcounter}}%
11782 \end_layout
11784 \begin_layout Plain Layout
11786   
11787 \backslash
11788 edef
11789 \backslash
11790 firstchunkname{
11791 \backslash
11792 lst@intname-1}%
11793 \end_layout
11795 \end_inset
11798 \end_layout
11800 \begin_layout Standard
11801 We now need to calculate the name of the next chunk.
11802  We do this by temporarily skipping the counter on by one; however there
11803  may not actually be another chunk with this name! We detect this by also
11804  defining a label for each chunk based on the chunkname.
11805  If there is a next chunkname then it will define a label with that name.
11806  As labels are persistent, we can at least tell the second time LaTeX is
11807  run.
11808  If we don't find such a defined label then we define 
11809 \begin_inset Flex CharStyle:Code
11810 status collapsed
11812 \begin_layout Plain Layout
11814 \backslash
11815 nextchunkname
11816 \end_layout
11818 \end_inset
11820  to 
11821 \begin_inset Flex CharStyle:Code
11822 status collapsed
11824 \begin_layout Plain Layout
11826 \backslash
11827 relax
11828 \end_layout
11830 \end_inset
11833 \end_layout
11835 \begin_layout Standard
11836 \begin_inset listings
11837 inline false
11838 status open
11840 \begin_layout Plain Layout
11842   
11843 \backslash
11844 addtocounter{newfangle@chunkcounter}{1}%
11845 \end_layout
11847 \begin_layout Plain Layout
11849   
11850 \backslash
11851 edef
11852 \backslash
11853 nextchunkname{
11854 \backslash
11855 lst@intname-
11856 \backslash
11857 arabic{newfangle@chunkcounter}}%
11858 \end_layout
11860 \begin_layout Plain Layout
11862   
11863 \backslash
11864 @ifundefined{r@label-
11865 \backslash
11866 nextchunkname}{
11867 \backslash
11869 \backslash
11870 nextchunkname
11871 \backslash
11872 relax}{}%
11873 \end_layout
11875 \end_inset
11878 \end_layout
11880 \begin_layout Standard
11881 The noweb package requires that we define a 
11882 \begin_inset Flex CharStyle:Code
11883 status collapsed
11885 \begin_layout Plain Layout
11887 \backslash
11888 sublabel
11889 \end_layout
11891 \end_inset
11893  for every chunk, with a unique name, which is then used to print out it's
11894  navigation hints.
11895 \end_layout
11897 \begin_layout Standard
11898 We also define a regular label for this chunk, as was mentioned above when
11899  we calculated 
11900 \begin_inset Flex CharStyle:Code
11901 status collapsed
11903 \begin_layout Plain Layout
11905 \backslash
11906 nextchunkname
11907 \end_layout
11909 \end_inset
11912  This requires LaTeX to be run at least twice after new chunk sections are
11913  added --- but noweb requried that anyway.
11914 \end_layout
11916 \begin_layout Standard
11917 \begin_inset listings
11918 inline false
11919 status open
11921 \begin_layout Plain Layout
11923   
11924 \backslash
11925 sublabel{
11926 \backslash
11927 chunkname}%
11928 \end_layout
11930 \begin_layout Plain Layout
11932 % define this label for every chunk instance, so we
11933 \end_layout
11935 \begin_layout Plain Layout
11937 % can tell when we are the last chunk of this name
11938 \end_layout
11940 \begin_layout Plain Layout
11942   
11943 \backslash
11944 label{label-
11945 \backslash
11946 chunkname}%
11947 \end_layout
11949 \end_inset
11952 \end_layout
11954 \begin_layout Standard
11955 We also try and add the chunk to the list of listings, but I'm afraid we
11956  don't do very well.
11957  We want each chunk name listing once, with all of it's references.
11958 \end_layout
11960 \begin_layout Standard
11961 \begin_inset listings
11962 inline false
11963 status open
11965 \begin_layout Plain Layout
11967   
11968 \backslash
11969 addcontentsline{lol}{lstlisting}{
11970 \backslash
11971 lst@name~[
11972 \backslash
11973 protect
11974 \backslash
11975 subpageref{
11976 \backslash
11977 chunkname}]}%
11978 \end_layout
11980 \end_inset
11983 \end_layout
11985 \begin_layout Standard
11986 We then call the noweb output macros in the same way that noweave generates
11987  them, except that we don't need to call 
11988 \begin_inset Flex CharStyle:Code
11989 status collapsed
11991 \begin_layout Plain Layout
11993 \backslash
11994 nwstartdeflinemarkup
11995 \end_layout
11997 \end_inset
11999  or 
12000 \begin_inset Flex CharStyle:Code
12001 status collapsed
12003 \begin_layout Plain Layout
12005 \backslash
12006 nwenddeflinemarkup
12007 \end_layout
12009 \end_inset
12011  -- and if we do it messes up the output somewhat.
12012 \end_layout
12014 \begin_layout Standard
12015 \begin_inset listings
12016 inline false
12017 status open
12019 \begin_layout Plain Layout
12021   
12022 \backslash
12023 nwmargintag{%
12024 \end_layout
12026 \begin_layout Plain Layout
12028     {%
12029 \end_layout
12031 \begin_layout Plain Layout
12033       
12034 \backslash
12035 nwtagstyle{}%
12036 \end_layout
12038 \begin_layout Plain Layout
12040       
12041 \backslash
12042 subpageref{
12043 \backslash
12044 chunkname}%
12045 \end_layout
12047 \begin_layout Plain Layout
12049     }%
12050 \end_layout
12052 \begin_layout Plain Layout
12054   }%
12055 \end_layout
12057 \begin_layout Plain Layout
12060 \end_layout
12062 \begin_layout Plain Layout
12064   
12065 \backslash
12066 moddef{%
12067 \end_layout
12069 \begin_layout Plain Layout
12071     {
12072 \backslash
12073 lst@name}%
12074 \end_layout
12076 \begin_layout Plain Layout
12078     {%
12079 \end_layout
12081 \begin_layout Plain Layout
12083       
12084 \backslash
12085 nwtagstyle{}
12086 \backslash
12088 \end_layout
12090 \begin_layout Plain Layout
12092       
12093 \backslash
12094 @ifundefined{newfangle@chunk@params}{}{%
12095 \end_layout
12097 \begin_layout Plain Layout
12099         (
12100 \backslash
12101 newfangle@chunk@params)%
12102 \end_layout
12104 \begin_layout Plain Layout
12106       }%
12107 \end_layout
12109 \begin_layout Plain Layout
12111       [
12112 \backslash
12113 csname 
12114 \backslash
12115 chunkcount
12116 \backslash
12117 endcsname]~%
12118 \end_layout
12120 \begin_layout Plain Layout
12122       
12123 \backslash
12124 subpageref{
12125 \backslash
12126 firstchunkname}%
12127 \end_layout
12129 \begin_layout Plain Layout
12131     }%
12132 \end_layout
12134 \begin_layout Plain Layout
12136     
12137 \backslash
12138 @ifundefined{newfangle@chunk@append}{}{%
12139 \end_layout
12141 \begin_layout Plain Layout
12143     
12144 \backslash
12145 ifx{}
12146 \backslash
12147 newfangle@chunk@append{x}
12148 \backslash
12149 else%
12150 \end_layout
12152 \begin_layout Plain Layout
12154         ,~add~to~
12155 \backslash
12156 newfangle@chunk@append%
12157 \end_layout
12159 \begin_layout Plain Layout
12161     
12162 \backslash
12164 \end_layout
12166 \begin_layout Plain Layout
12168     }%
12169 \end_layout
12171 \begin_layout Plain Layout
12174 \backslash
12175 global
12176 \backslash
12178 \backslash
12179 newfangle@chunk@append{}%
12180 \end_layout
12182 \begin_layout Plain Layout
12185 \backslash
12186 lstset{append=x}%
12187 \end_layout
12189 \begin_layout Plain Layout
12191   }%
12192 \end_layout
12194 \begin_layout Plain Layout
12197 \end_layout
12199 \begin_layout Plain Layout
12201   
12202 \backslash
12204 \backslash
12205 relax
12206 \backslash
12207 prevchunkname
12208 \backslash
12209 endmoddef
12210 \backslash
12211 else
12212 \backslash
12213 plusendmoddef
12214 \backslash
12216 \end_layout
12218 \begin_layout Plain Layout
12220 %  
12221 \backslash
12222 nwstartdeflinemarkup%
12223 \end_layout
12225 \begin_layout Plain Layout
12227   
12228 \backslash
12229 nwprevnextdefs{
12230 \backslash
12231 prevchunkname}{
12232 \backslash
12233 nextchunkname}%
12234 \end_layout
12236 \begin_layout Plain Layout
12238 %  
12239 \backslash
12240 nwenddeflinemarkup%
12241 \end_layout
12243 \begin_layout Plain Layout
12246 \end_layout
12248 \end_inset
12251 \end_layout
12253 \begin_layout Standard
12254 Originally this was developed as a 
12255 \begin_inset Flex CharStyle:Code
12256 status collapsed
12258 \begin_layout Plain Layout
12259 listings
12260 \end_layout
12262 \end_inset
12264  aspect, in the Init hook, but it was found easier to affect the title without
12265  using a hook --- 
12266 \begin_inset Flex CharStyle:Code
12267 status collapsed
12269 \begin_layout Plain Layout
12271 \backslash
12272 lst@AddToHookExe{PreSet}
12273 \end_layout
12275 \end_inset
12277  is still required to set the listings name to the name passed to the 
12278 \begin_inset Flex CharStyle:Code
12279 status collapsed
12281 \begin_layout Plain Layout
12283 \backslash
12284 Chunk
12285 \end_layout
12287 \end_inset
12289  command, though.
12290 \end_layout
12292 \begin_layout Standard
12293 \begin_inset listings
12294 inline false
12295 status open
12297 \begin_layout Plain Layout
12300 \backslash
12301 lst@BeginAspect{newfangle}
12302 \end_layout
12304 \begin_layout Plain Layout
12307 \backslash
12308 lst@Key{newfangle}{true}[t]{
12309 \backslash
12310 lstKV@SetIf{#1}{true}}
12311 \end_layout
12313 \begin_layout Plain Layout
12316 \backslash
12317 lst@AddToHookExe{PreSet}{
12318 \backslash
12319 global
12320 \backslash
12322 \backslash
12323 lst@intname
12324 \backslash
12325 lst@chunkname}
12326 \end_layout
12328 \begin_layout Plain Layout
12331 \backslash
12332 lst@AddToHook{Init}{}%
12333 \backslash
12334 newfangle@caption}
12335 \end_layout
12337 \begin_layout Plain Layout
12340 \backslash
12341 lst@EndAspect
12342 \end_layout
12344 \end_inset
12347 \end_layout
12349 \begin_layout Subsection
12350 Cross references
12351 \end_layout
12353 \begin_layout Standard
12354 We define the 
12355 \backslash
12356 chunkref command which makes it easy to generate visual references to different
12357  code chunks, e.g.
12358 \end_layout
12360 \begin_layout Standard
12361 \begin_inset Tabular
12362 <lyxtabular version="3" rows="4" columns="2">
12363 <features>
12364 <column alignment="center" valignment="top" width="0">
12365 <column alignment="center" valignment="top" width="0">
12366 <row>
12367 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
12368 \begin_inset Text
12370 \begin_layout Plain Layout
12371 Macro
12372 \end_layout
12374 \end_inset
12375 </cell>
12376 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
12377 \begin_inset Text
12379 \begin_layout Plain Layout
12380 Appearance
12381 \end_layout
12383 \end_inset
12384 </cell>
12385 </row>
12386 <row>
12387 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
12388 \begin_inset Text
12390 \begin_layout Plain Layout
12392 \backslash
12393 chunkref{preamble}
12394 \end_layout
12396 \end_inset
12397 </cell>
12398 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
12399 \begin_inset Text
12401 \begin_layout Plain Layout
12402 \begin_inset ERT
12403 status open
12405 \begin_layout Plain Layout
12408 \backslash
12409 chunkref{preamble}
12410 \end_layout
12412 \end_inset
12415 \end_layout
12417 \end_inset
12418 </cell>
12419 </row>
12420 <row>
12421 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
12422 \begin_inset Text
12424 \begin_layout Plain Layout
12426 \backslash
12427 chunkref[3]{preamble}
12428 \end_layout
12430 \end_inset
12431 </cell>
12432 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
12433 \begin_inset Text
12435 \begin_layout Plain Layout
12436 \begin_inset ERT
12437 status open
12439 \begin_layout Plain Layout
12442 \backslash
12443 chunkref[3]{preamble}
12444 \end_layout
12446 \end_inset
12449 \end_layout
12451 \end_inset
12452 </cell>
12453 </row>
12454 <row>
12455 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
12456 \begin_inset Text
12458 \begin_layout Plain Layout
12460 \backslash
12461 chunkref{preamble}[arg1, arg2]
12462 \end_layout
12464 \end_inset
12465 </cell>
12466 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
12467 \begin_inset Text
12469 \begin_layout Plain Layout
12470 \begin_inset ERT
12471 status open
12473 \begin_layout Plain Layout
12476 \backslash
12477 chunkref{preamble}[arg1, arg2]
12478 \end_layout
12480 \end_inset
12483 \end_layout
12485 \end_inset
12486 </cell>
12487 </row>
12488 </lyxtabular>
12490 \end_inset
12493 \end_layout
12495 \begin_layout Standard
12496 Chunkref can also be used within a code chunk to include another code chunk.
12497  The third optional parameter to chunkref is a comma sepatarated list of
12498  arguments, which will replace defined parameters in the chunkref.
12499 \begin_inset Note Note
12500 status open
12502 \begin_layout Plain Layout
12503 Darn it, if I have: =<
12504 \backslash
12505 chunkref{new-mode}[{chunks[chunk_name, "language"]},{mode}]> the inner braces
12506  (inside [ ]) cause _ to signify subscript even though we have lst@ReplaceIn
12507 \end_layout
12509 \end_inset
12512 \end_layout
12514 \begin_layout Standard
12515 \begin_inset listings
12516 inline false
12517 status open
12519 \begin_layout Plain Layout
12522 \backslash
12524 \backslash
12525 chunkref@args#1,{%
12526 \end_layout
12528 \begin_layout Plain Layout
12530   
12531 \backslash
12533 \backslash
12534 arg{#1}%
12535 \end_layout
12537 \begin_layout Plain Layout
12539   
12540 \backslash
12541 lst@ReplaceIn
12542 \backslash
12544 \backslash
12545 lst@filenamerpl%
12546 \end_layout
12548 \begin_layout Plain Layout
12550   
12551 \backslash
12552 arg%
12553 \end_layout
12555 \begin_layout Plain Layout
12557   
12558 \backslash
12559 @ifnextchar){
12560 \backslash
12561 relax}{, 
12562 \backslash
12563 chunkref@args}%
12564 \end_layout
12566 \begin_layout Plain Layout
12569 \end_layout
12571 \begin_layout Plain Layout
12574 \backslash
12575 newcommand
12576 \backslash
12577 chunkref[2][0]{%
12578 \end_layout
12580 \begin_layout Plain Layout
12582   
12583 \backslash
12584 @ifnextchar({
12585 \backslash
12586 chunkref@i{#1}{#2}}{
12587 \backslash
12588 chunkref@i{#1}{#2}()}%
12589 \end_layout
12591 \begin_layout Plain Layout
12594 \end_layout
12596 \begin_layout Plain Layout
12599 \backslash
12601 \backslash
12602 chunkref@i#1#2(#3){%
12603 \end_layout
12605 \begin_layout Plain Layout
12607   
12608 \backslash
12610 \backslash
12611 zero{0}%
12612 \end_layout
12614 \begin_layout Plain Layout
12616   
12617 \backslash
12619 \backslash
12620 chunk{#2}%
12621 \end_layout
12623 \begin_layout Plain Layout
12625   
12626 \backslash
12628 \backslash
12629 chunkno{#1}%
12630 \end_layout
12632 \begin_layout Plain Layout
12634   
12635 \backslash
12637 \backslash
12638 chunkargs{#3}%
12639 \end_layout
12641 \begin_layout Plain Layout
12643   
12644 \backslash
12646 \backslash
12647 chunkno
12648 \backslash
12649 zero%
12650 \end_layout
12652 \begin_layout Plain Layout
12654     
12655 \backslash
12657 \backslash
12658 chunkname{#2-1}%
12659 \end_layout
12661 \begin_layout Plain Layout
12663   
12664 \backslash
12665 else%
12666 \end_layout
12668 \begin_layout Plain Layout
12670     
12671 \backslash
12673 \backslash
12674 chunkname{#2-
12675 \backslash
12676 chunkno}%
12677 \end_layout
12679 \begin_layout Plain Layout
12681   
12682 \backslash
12684 \end_layout
12686 \begin_layout Plain Layout
12688   
12689 \backslash
12691 \backslash
12692 lst@arg
12693 \backslash
12694 chunk%
12695 \end_layout
12697 \begin_layout Plain Layout
12699   
12700 \backslash
12701 lst@ReplaceIn
12702 \backslash
12703 chunk
12704 \backslash
12705 lst@filenamerpl%
12706 \end_layout
12708 \begin_layout Plain Layout
12710   
12711 \backslash
12712 LA{%
12713 \backslash
12714 moddef{%
12715 \end_layout
12717 \begin_layout Plain Layout
12719     {
12720 \backslash
12721 chunk}%
12722 \end_layout
12724 \begin_layout Plain Layout
12726     {%
12727 \end_layout
12729 \begin_layout Plain Layout
12731       
12732 \backslash
12733 nwtagstyle{}
12734 \backslash
12736 \end_layout
12738 \begin_layout Plain Layout
12740       
12741 \backslash
12743 \backslash
12744 chunkno
12745 \backslash
12746 zero%
12747 \end_layout
12749 \begin_layout Plain Layout
12751       
12752 \backslash
12753 else%
12754 \end_layout
12756 \begin_layout Plain Layout
12758       [
12759 \backslash
12760 chunkno]%
12761 \end_layout
12763 \begin_layout Plain Layout
12765       
12766 \backslash
12768 \end_layout
12770 \begin_layout Plain Layout
12772       
12773 \backslash
12775 \backslash
12776 chunkargs
12777 \backslash
12778 empty%
12779 \end_layout
12781 \begin_layout Plain Layout
12783       
12784 \backslash
12785 else%
12786 \end_layout
12788 \begin_layout Plain Layout
12790         (
12791 \backslash
12792 chunkref@args #3,)%
12793 \end_layout
12795 \begin_layout Plain Layout
12797       
12798 \backslash
12800 \end_layout
12802 \begin_layout Plain Layout
12804       ~
12805 \backslash
12806 subpageref{
12807 \backslash
12808 chunkname}%
12809 \end_layout
12811 \begin_layout Plain Layout
12813     }%
12814 \end_layout
12816 \begin_layout Plain Layout
12818   }%
12819 \end_layout
12821 \begin_layout Plain Layout
12823   
12824 \backslash
12826 \backslash
12827 endmoddef%
12828 \end_layout
12830 \begin_layout Plain Layout
12833 \end_layout
12835 \end_inset
12838 \end_layout
12840 \begin_layout Subsection
12841 The end
12842 \end_layout
12844 \begin_layout Standard
12845 \begin_inset listings
12846 inline false
12847 status open
12849 \begin_layout Plain Layout
12852 \end_layout
12854 \begin_layout Plain Layout
12857 \backslash
12858 makeatother
12859 \end_layout
12861 \end_inset
12864 \end_layout
12866 \begin_layout Chapter
12867 Extracting newfangle
12868 \end_layout
12870 \begin_layout Section
12871 Extracting from Lyx
12872 \end_layout
12874 \begin_layout Standard
12875 To extract from LyX, you will need to configure LyX as explained in section
12877 \begin_inset CommandInset ref
12878 LatexCommand ref
12879 reference "sub:Configuring-the-build"
12881 \end_inset
12884 \end_layout
12886 \begin_layout Standard
12887 \begin_inset CommandInset label
12888 LatexCommand label
12889 name "lyx-build-script"
12891 \end_inset
12893 And this lyx-build scrap will extract newfangle for me.
12894 \end_layout
12896 \begin_layout Chunk
12897 lyx-build,language=sh
12898 \end_layout
12900 \begin_layout Standard
12901 \begin_inset listings
12902 inline false
12903 status open
12905 \begin_layout Plain Layout
12907 #! /bin/sh
12908 \end_layout
12910 \begin_layout Plain Layout
12912 set -x
12913 \end_layout
12915 \begin_layout Plain Layout
12917 \end_layout
12919 \begin_layout Plain Layout
12922 \backslash
12923 chunkref{lyx-build-helper}>
12924 \end_layout
12926 \begin_layout Plain Layout
12928 cd $PROJECT_DIR || exit 1
12929 \end_layout
12931 \begin_layout Plain Layout
12933 \end_layout
12935 \begin_layout Plain Layout
12937 /usr/local/bin/newfangle -R./newfangle $TEX_SRC > ./newfangle
12938 \end_layout
12940 \begin_layout Plain Layout
12942 /usr/local/bin/newfangle -R./newfangle.module $TEX_SRC > ./newfangle.module
12943 \end_layout
12945 \end_inset
12948 \end_layout
12950 \begin_layout Standard
12951 With a lyx-build-helper
12952 \end_layout
12954 \begin_layout Chunk
12955 lyx-build-helper,language=sh
12956 \end_layout
12958 \begin_layout Standard
12959 \begin_inset listings
12960 inline false
12961 status open
12963 \begin_layout Plain Layout
12965 PROJECT_DIR="$LYX_r"
12966 \end_layout
12968 \begin_layout Plain Layout
12970 LYX_SRC="$PROJECT_DIR/${LYX_i%.tex}.lyx"
12971 \end_layout
12973 \begin_layout Plain Layout
12975 TEX_DIR="$LYX_p"
12976 \end_layout
12978 \begin_layout Plain Layout
12980 TEX_SRC="$TEX_DIR/$LYX_i"
12981 \end_layout
12983 \end_inset
12986 \end_layout
12988 \begin_layout Section
12989 Extracting from the command line
12990 \end_layout
12992 \begin_layout Standard
12993 First you will need the tex output, then you can extract:
12994 \end_layout
12996 \begin_layout Chunk
12997 lyx-build-manual,language=sh
12998 \end_layout
13000 \begin_layout Standard
13001 \begin_inset listings
13002 inline false
13003 status open
13005 \begin_layout Plain Layout
13007 lyx -e latex newfangle.lyx
13008 \end_layout
13010 \begin_layout Plain Layout
13012 newfangle -R./newfangle newfangle.tex > ./newfangle
13013 \end_layout
13015 \begin_layout Plain Layout
13017 newfangle -R./newfangle.module newfangle.tex > ./newfangle.module
13018 \end_layout
13020 \end_inset
13023 \end_layout
13025 \begin_layout Part
13026 Tests
13027 \end_layout
13029 \begin_layout Chapter
13030 Chunk Parameters
13031 \end_layout
13033 \begin_layout Chunk
13034 tests-sub,params=THING;colour
13035 \end_layout
13037 \begin_layout Standard
13038 \begin_inset listings
13039 inline false
13040 status open
13042 \begin_layout Plain Layout
13044 I see a ${THING} of 
13045 \end_layout
13047 \begin_layout Plain Layout
13049 colour ${colour}, 
13050 \end_layout
13052 \begin_layout Plain Layout
13054 looking closer =<
13055 \backslash
13056 chunkref{tests-sub-sub}(${colour})>
13057 \end_layout
13059 \end_inset
13062 \end_layout
13064 \begin_layout Chunk
13065 tests-sub-sub,params=colour
13066 \end_layout
13068 \begin_layout Standard
13069 \begin_inset listings
13070 inline false
13071 status open
13073 \begin_layout Plain Layout
13075 a funny shade of ${colour}
13076 \end_layout
13078 \end_inset
13081 \end_layout
13083 \begin_layout Chunk
13084 tests
13085 \end_layout
13087 \begin_layout Standard
13088 \begin_inset listings
13089 inline false
13090 status open
13092 \begin_layout Plain Layout
13094 What do you see? "=<
13095 \backslash
13096 chunkref{tests-sub}(joe, red)>"
13097 \end_layout
13099 \begin_layout Plain Layout
13101 Well, fancy!
13102 \end_layout
13104 \end_inset
13107 \end_layout
13109 \begin_layout Standard
13110 Should generate output:
13111 \end_layout
13113 \begin_layout Chunk
13114 tests-result
13115 \end_layout
13117 \begin_layout Standard
13118 \begin_inset listings
13119 inline false
13120 status open
13122 \begin_layout Plain Layout
13124 What do you see? "I see a joe of 
13125 \end_layout
13127 \begin_layout Plain Layout
13129                   colour red, 
13130 \end_layout
13132 \begin_layout Plain Layout
13134                   looking closer a funny shade of red"
13135 \end_layout
13137 \begin_layout Plain Layout
13139 Well, fancy!
13140 \end_layout
13142 \begin_layout Plain Layout
13144 \end_layout
13146 \end_inset
13149 \end_layout
13151 \end_body
13152 \end_document