Emit #line more eagerly
[newfangle.git] / newfangle.lyx
blobdbc9a0770a4d5ccb236047a631ed44f5f554085c
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
170  complications 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 indenting 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 wrong }
253 \end_layout
255 \begin_layout Chapter*
256 License
257 \end_layout
259 \begin_layout Standard
260 \begin_inset CommandInset label
261 LatexCommand label
262 name "cha:License"
264 \end_inset
266 Newfangle is licensed under the GPL 3
267 \begin_inset CommandInset citation
268 LatexCommand cite
269 key "gpl-licenses"
271 \end_inset
273  (or later).
274  This doesn't mean that you can't use or distribute newfangle with sources
275  of an incompatible license, but it means you must make the source of newfangle
276  available too.
277 \end_layout
279 \begin_layout Chunk
280 gpl3-copyright,language=
281 \end_layout
283 \begin_layout Standard
284 \begin_inset listings
285 inline false
286 status open
288 \begin_layout Plain Layout
290 #newfangle - fully featured notangle replacement in awk
291 \end_layout
293 \begin_layout Plain Layout
296 \end_layout
298 \begin_layout Plain Layout
300 #Copyright (C) Sam Liddicott 2009
301 \end_layout
303 \begin_layout Plain Layout
306 \end_layout
308 \begin_layout Plain Layout
310 #This program is free software: you can redistribute it and/or modify
311 \end_layout
313 \begin_layout Plain Layout
315 #it under the terms of the GNU General Public License as published by
316 \end_layout
318 \begin_layout Plain Layout
320 #the Free Software Foundation, either version 3 of the License, or
321 \end_layout
323 \begin_layout Plain Layout
325 #(at your option) any later version.
326 \end_layout
328 \begin_layout Plain Layout
331 \end_layout
333 \begin_layout Plain Layout
335 #This program is distributed in the hope that it will be useful,
336 \end_layout
338 \begin_layout Plain Layout
340 #but WITHOUT ANY WARRANTY; without even the implied warranty of
341 \end_layout
343 \begin_layout Plain Layout
345 #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
346   See the
347 \end_layout
349 \begin_layout Plain Layout
351 #GNU General Public License for more details.
352 \end_layout
354 \begin_layout Plain Layout
357 \end_layout
359 \begin_layout Plain Layout
361 #You should have received a copy of the GNU General Public License
362 \end_layout
364 \begin_layout Plain Layout
366 #along with this program.
367   If not, see <http://www.gnu.org/licenses/>.
368 \end_layout
370 \end_inset
373 \end_layout
375 \begin_layout Standard
376 \begin_inset CommandInset toc
377 LatexCommand tableofcontents
379 \end_inset
382 \end_layout
384 \begin_layout Part
385 Using Newfangle
386 \end_layout
388 \begin_layout Chapter
389 Running Newfangle
390 \end_layout
392 \begin_layout Standard
393 Newfangle is a replacement for noweb, which consists of 
394 \begin_inset Flex CharStyle:Code
395 status collapsed
397 \begin_layout Plain Layout
398 notangle
399 \end_layout
401 \end_inset
404 \begin_inset Flex CharStyle:Code
405 status collapsed
407 \begin_layout Plain Layout
408 noroots
409 \end_layout
411 \end_inset
413  and 
414 \begin_inset Flex CharStyle:Code
415 status collapsed
417 \begin_layout Plain Layout
418 noweave
419 \end_layout
421 \end_inset
424 \end_layout
426 \begin_layout Standard
427 Like 
428 \begin_inset Flex CharStyle:Code
429 status collapsed
431 \begin_layout Plain Layout
432 notangle
433 \end_layout
435 \end_inset
437  and 
438 \begin_inset Flex CharStyle:Code
439 status collapsed
441 \begin_layout Plain Layout
442 noroots
443 \end_layout
445 \end_inset
447  it can read multiple named files, or from stdin.
448 \end_layout
450 \begin_layout Section
451 Listing roots
452 \end_layout
454 \begin_layout Standard
455 The -r option causes newfangle to behave like noroots.
456 \end_layout
458 \begin_layout LyX-Code
459 newfangle -r filename.tex
460 \end_layout
462 \begin_layout Standard
463 will print out the newfangle roots of a tex file.
465 \end_layout
467 \begin_layout Standard
468 Unlike the 
469 \begin_inset Flex CharStyle:Code
470 status collapsed
472 \begin_layout Plain Layout
473 noroots
474 \end_layout
476 \end_inset
478  command, the roots are not enclosed in 
479 \begin_inset Flex CharStyle:Code
480 status collapsed
482 \begin_layout Plain Layout
483 <<name>>
484 \end_layout
486 \end_inset
488 , unless at least one of the roots is defined using the 
489 \begin_inset Flex CharStyle:Code
490 status collapsed
492 \begin_layout Plain Layout
493 notangle
494 \end_layout
496 \end_inset
498  style 
499 \begin_inset Flex CharStyle:Code
500 status collapsed
502 \begin_layout Plain Layout
503 <<name>>=
504 \end_layout
506 \end_inset
509 \end_layout
511 \begin_layout Standard
512 Also, unlike noroots, it prints out all roots --- not just those that are
513  not used elsewhere.
514  I find that a root not being used, doesn't make it particularly top level.
515  My convention is that top level roots to be extracted begin with 
516 \begin_inset Flex CharStyle:Code
517 status collapsed
519 \begin_layout Plain Layout
521 \end_layout
523 \end_inset
525  and have the form of a filename.
526 \end_layout
528 \begin_layout Section
529 Extracting roots
530 \end_layout
532 \begin_layout Standard
533 notangle's 
534 \begin_inset Flex CharStyle:Code
535 status collapsed
537 \begin_layout Plain Layout
539 \end_layout
541 \end_inset
543  and 
544 \begin_inset Flex CharStyle:Code
545 status collapsed
547 \begin_layout Plain Layout
549 \end_layout
551 \end_inset
553  options are supported.
554 \end_layout
556 \begin_layout Standard
557 The standard way to extract a file would be:
558 \end_layout
560 \begin_layout LyX-Code
561 newfangle -R./Makefile.inc newfangle.tex > ./Makefile.inc
562 \end_layout
564 \begin_layout Standard
565 Unlike the 
566 \begin_inset Flex CharStyle:Code
567 status collapsed
569 \begin_layout Plain Layout
570 noroots
571 \end_layout
573 \end_inset
575  command, the 
576 \begin_inset Flex CharStyle:Code
577 status collapsed
579 \begin_layout Plain Layout
581 \end_layout
583 \end_inset
585  option does not break indenting; also the 
586 \begin_inset Flex CharStyle:Code
587 status collapsed
589 \begin_layout Plain Layout
591 \end_layout
593 \end_inset
595  option does not interrupt (and break) multi-line C macros --- or indeed
596  any line ending with a backslash.
597  This does mean that sometimes the compiler might calculate the source line
598  wrongly when generating error messages in such cases, but there isn't any
599  other way around if multi-line macros include other chunks.
600 \end_layout
602 \begin_layout Section
603 Formatting source in LaTeX
604 \end_layout
606 \begin_layout Standard
607 The noweave replacement is a set of LaTeX macros dependant upon 
608 \emph on
609 noweb.sty
610 \emph default
611 , and which can be included with:
612 \end_layout
614 \begin_layout LyX-Code
616 \backslash
617 usepackage{newfangle.sty}
618 \end_layout
620 \begin_layout Standard
621 The LaTeX macros are shown in section 
622 \begin_inset CommandInset ref
623 LatexCommand ref
624 reference "sec:Latex-Macros"
626 \end_inset
628 , and are part of a LyX module file 
629 \begin_inset Flex CharStyle:Code
630 status collapsed
632 \begin_layout Plain Layout
633 newfangle.module
634 \end_layout
636 \end_inset
638 , which automatically includes the macros in the document pre-amble when
639  the newfangle LyX module is used.
640 \end_layout
642 \begin_layout Standard
643 Because the noweave replacement is impemented in LaTeX, there is no processing
644  stage required before running the 
645 \begin_inset Flex CharStyle:Code
646 status collapsed
648 \begin_layout Plain Layout
649 latex
650 \end_layout
652 \end_inset
654  command.
655  LaTeX may need running two or more times, so that the code chunk references
656  can be fully calculated.
657 \end_layout
659 \begin_layout Standard
660 The 
661 \begin_inset Flex CharStyle:Code
662 status collapsed
664 \begin_layout Plain Layout
665 noweb.sty
666 \end_layout
668 \end_inset
670  package is required as it is used for formatting the code chunk captions
671 \end_layout
673 \begin_layout Standard
674 The 
675 \begin_inset Flex CharStyle:Code
676 status collapsed
678 \begin_layout Plain Layout
679 listings.sty
680 \end_layout
682 \end_inset
684  package is also required, as it is used for formatting the code chunks
685  themselves.
686 \end_layout
688 \begin_layout Standard
689 The 
690 \begin_inset Flex CharStyle:Code
691 status collapsed
693 \begin_layout Plain Layout
694 xargs.sty
695 \end_layout
697 \end_inset
699  package is also required.
700 \end_layout
702 \begin_layout Chapter
703 Literate Programming with Newfangle
704 \end_layout
706 \begin_layout Standard
707 Todo.
708  Should really follow on from a part-0 explanation of what literate programming
709  is.
710 \end_layout
712 \begin_layout Chapter
713 Using Newfangle with LyX
714 \end_layout
716 \begin_layout Section
717 Setting up Lyx
718 \end_layout
720 \begin_layout Subsection
721 Installing the LyX module
722 \end_layout
724 \begin_layout Standard
725 Copy 
726 \begin_inset Flex CharStyle:Code
727 status collapsed
729 \begin_layout Plain Layout
730 newfangle.module
731 \end_layout
733 \end_inset
735  to your LyX layouts directory, which for unix users will be 
736 \begin_inset Flex CharStyle:Code
737 status collapsed
739 \begin_layout Plain Layout
740 ~/.lyx/layouts
741 \end_layout
743 \end_inset
746 \end_layout
748 \begin_layout Standard
749 You will need to reconfigure LyX by clicking Tools\SpecialChar \menuseparator
750 Reconfigure, and then
751  re-start LyX.
752 \end_layout
754 \begin_layout Subsection
755 \begin_inset CommandInset label
756 LatexCommand label
757 name "sub:Configuring-the-build"
759 \end_inset
761 Configuring the build script
762 \end_layout
764 \begin_layout Standard
765 Make sure you don't have a conversion defined for Lyx → Program
766 \end_layout
768 \begin_layout Standard
769 From the menu Tools\SpecialChar \menuseparator
770 Preferences, add a conversion from Latex(Plain) → Program
771  as:
772 \end_layout
774 \begin_layout LyX-Code
775 set -x ; newfangle -Rlyx-build $$i | 
776 \end_layout
778 \begin_layout LyX-Code
779   env LYX_b=$$b LYX_i=$$i LYX_o=$$o LYX_p=$$p LYX_r=$$r bash
780 \end_layout
782 \begin_layout Standard
783 (But don't cut-n-paste it from this document or you'll be pasting a multi-line
784  string which will break your lyx preferences file).
786 \end_layout
788 \begin_layout Standard
789 I hope that one day, LyX will set these into the environment when calling
790  the build script.
791 \end_layout
793 \begin_layout Standard
794 You may also want to consider adding options to this conversion\SpecialChar \ldots{}
796 \end_layout
798 \begin_layout LyX-Code
799 parselog=/usr/share/lyx/scripts/listerrors
800 \end_layout
802 \begin_layout Standard
803 \SpecialChar \ldots{}
804 but if you do you will lose your stderr
805 \begin_inset Foot
806 status collapsed
808 \begin_layout Plain Layout
809 There is some bash plumbing to get a copy of stderr but this footnote is
810  too small
811 \end_layout
813 \end_inset
816 \end_layout
818 \begin_layout Standard
819 Now, a shell script chunk called 
820 \begin_inset Flex CharStyle:Code
821 status collapsed
823 \begin_layout Plain Layout
824 lyx-build
825 \end_layout
827 \end_inset
829  will be extracted and run whenever you choose the Document\SpecialChar \menuseparator
830 Build Program
831  menu item.
832 \end_layout
834 \begin_layout Standard
835 The lyx-build script for this document is in section 
836 \begin_inset CommandInset ref
837 LatexCommand ref
838 reference "lyx-build-script"
840 \end_inset
842  and on a unix system will extract 
843 \begin_inset Flex CharStyle:Code
844 status collapsed
846 \begin_layout Plain Layout
847 newfangle.module
848 \end_layout
850 \end_inset
852  and the 
853 \begin_inset Flex CharStyle:Code
854 status collapsed
856 \begin_layout Plain Layout
857 newfangle
858 \end_layout
860 \end_inset
862  awk script.
863 \end_layout
865 \begin_layout Subsection
866 Preparing your Lyx document
867 \end_layout
869 \begin_layout Standard
870 It is not necessary to base your literate document on any of the original
871  LyX literate classes; so select a regular class for your document type.
872 \end_layout
874 \begin_layout Standard
875 Add the new module 
876 \emph on
877 Newfangle Literate
878 \emph default
880 \emph on
881 Listings
882 \emph default
883  and possibly also 
884 \emph on
885 Logical Markup
886 \emph default
888 \end_layout
890 \begin_layout Standard
891 In the drop-down style listbox you should notice a new style defined, called
893 \emph on
894 Chunk
895 \emph default
897 \end_layout
899 \begin_layout Standard
900 When you wish to insert a literate chunk, you enter it's plain name in the
901  Chunk style, instead of the older method that used 
902 \begin_inset Flex CharStyle:Code
903 status collapsed
905 \begin_layout Plain Layout
906 <<name>>=
907 \end_layout
909 \end_inset
911  type tags.
912  Following the chunk name, you insert a listing with: Insert\SpecialChar \menuseparator
913 Program Listing.
914 \end_layout
916 \begin_layout Standard
917 Inside the white listing box you can type (or paste using shift+ctrl+V)
918  your listing.
919  There is not need to use ctrl+enter at the end of lines as with some older
920  LyX literate techniques --- just press enter as normal.
921 \end_layout
923 \begin_layout Subsubsection
924 Customising the listing appearance
925 \end_layout
927 \begin_layout Standard
928 In the final document, the code is formatted using the 
929 \noun on
930 lstlistings
931 \noun default
932  package.
933  The chunk style doesn't just define the chunk name, but can also define
934  any other chunk options supported by the lstlistings package 
935 \begin_inset Flex CharStyle:Code
936 status collapsed
938 \begin_layout Plain Layout
940 \backslash
941 lstset
942 \end_layout
944 \end_inset
946  command.
947  In fact, what you type in the chunk style is raw latex.
948  If you want to set the chunk language without having to right-click the
949  listing, just add 
950 \begin_inset Flex CharStyle:Code
951 status collapsed
953 \begin_layout Plain Layout
954 ,lanuage=C
955 \end_layout
957 \end_inset
959  after the chunk name.
960 \end_layout
962 \begin_layout Standard
963 Of course you can do this by editing the listings box advanced properties
964  by right-clicking on the listings box, but that takes longer, and you can't
965  see at-a-glance what the advanced settings are while editing the document;
966  also advanced settings apply only to that box --- the chunk settings apply
967  through the rest of the document
968 \begin_inset Foot
969 status collapsed
971 \begin_layout Plain Layout
972 It ought to apply only to subsequent chunks of the same name.
973  I'll fix that later
974 \end_layout
976 \end_inset
979 \begin_inset Note Note
980 status collapsed
982 \begin_layout Plain Layout
983 So make sure they only apply to chunks of that name
984 \end_layout
986 \end_inset
989 \end_layout
991 \begin_layout Subsubsection
992 Global customisations
993 \end_layout
995 \begin_layout Standard
996 As 
997 \emph on
998 lstlistings
999 \emph default
1000  is used to set the code chunks, it's 
1001 \begin_inset Flex CharStyle:Code
1002 status collapsed
1004 \begin_layout Plain Layout
1006 \backslash
1007 lstset
1008 \end_layout
1010 \end_inset
1012  command can be used in the pre-amble to set some document wide settings.
1013 \end_layout
1015 \begin_layout Standard
1016 If your source has many words with long sequences of capital letters, then
1018 \begin_inset Flex CharStyle:Code
1019 status collapsed
1021 \begin_layout Plain Layout
1022 columns=fullflexible
1023 \end_layout
1025 \end_inset
1027  may be a good idea, or the capital letters will get crowded.
1028  (I think lstlistings ought to use a slightly smaller font for captial letters
1029  so that they still fit).
1030 \end_layout
1032 \begin_layout Standard
1033 The font family 
1034 \begin_inset Flex CharStyle:Code
1035 status collapsed
1037 \begin_layout Plain Layout
1039 \backslash
1040 ttfamily
1041 \end_layout
1043 \end_inset
1045  looks more normal for code, but has no bold (unless luximono is used, but
1046  it doesn't work for me); so I use 
1047 \begin_inset Flex CharStyle:Code
1048 status collapsed
1050 \begin_layout Plain Layout
1052 \backslash
1053 color{darkgreen}
1054 \end_layout
1056 \end_inset
1058  for my keywords.
1059  With 
1060 \begin_inset Flex CharStyle:Code
1061 status collapsed
1063 \begin_layout Plain Layout
1065 \backslash
1066 ttfamily
1067 \end_layout
1069 \end_inset
1072 \begin_inset Flex CharStyle:Code
1073 status collapsed
1075 \begin_layout Plain Layout
1076 columns=fullflexible
1077 \end_layout
1079 \end_inset
1081  is used or the wrong letter spacing is used.
1082 \end_layout
1084 \begin_layout Standard
1085 In my LeTeX pre-amble I usually specialise my code format with:
1086 \end_layout
1088 \begin_layout Chunk
1089 document-preamble,language=tex
1090 \end_layout
1092 \begin_layout Standard
1093 \begin_inset listings
1094 inline false
1095 status open
1097 \begin_layout Plain Layout
1100 \backslash
1101 usepackage{xcolor}
1102 \end_layout
1104 \begin_layout Plain Layout
1107 \backslash
1108 definecolor{darkgreen}{rgb}{0,0.5,0}
1109 \end_layout
1111 \begin_layout Plain Layout
1114 \backslash
1115 lstset{numbers=left, stepnumber=5, numbersep=5pt, breaklines=false,
1116 \end_layout
1118 \begin_layout Plain Layout
1120   basicstyle=
1121 \backslash
1122 footnotesize
1123 \backslash
1124 ttfamily,
1125 \end_layout
1127 \begin_layout Plain Layout
1129   keywordstyle=
1130 \backslash
1131 color{darkgreen},
1132 \end_layout
1134 \begin_layout Plain Layout
1136   numberstyle=
1137 \backslash
1138 tiny,language=C,columns=fullflexible,
1139 \end_layout
1141 \begin_layout Plain Layout
1143   numberfirstline=true
1144 \end_layout
1146 \begin_layout Plain Layout
1149 \end_layout
1151 \end_inset
1154 \end_layout
1156 \begin_layout Chapter
1157 Newfangle with Makefiles
1158 \end_layout
1160 \begin_layout Standard
1161 \begin_inset Note Note
1162 status open
1164 \begin_layout Plain Layout
1165 This chapter needs revising
1166 \end_layout
1168 \end_inset
1171 \begin_inset Note Greyedout
1172 status open
1174 \begin_layout Plain Layout
1175 This chapter needs revising
1176 \end_layout
1178 \end_inset
1180 Here we describe a Makefile.inc that you can include in your own Makefiles,
1181  or glue as a recursive make to other projects.
1182 \end_layout
1184 \begin_layout Standard
1185 The Makefile.inc described here was put together for a Samba4 vfs module,
1186  but can be used in any Make project, including automake projects.
1187 \end_layout
1189 \begin_layout Section
1190 A word about makefiles formats
1191 \end_layout
1193 \begin_layout Standard
1194 Whitespace formatting is very important in a Makefile.
1195  The first character of each command line must be a TAB.
1196 \end_layout
1198 \begin_layout LyX-Code
1199 target: pre-requisite
1200 \begin_inset Newline newline
1201 \end_inset
1203    →    action
1204 \begin_inset Newline newline
1205 \end_inset
1207    →    action
1208 \end_layout
1210 \begin_layout Standard
1211 But a TAB is pretty hard to enter into most of the Lyx formats and insets
1212  I've been using.
1213  An alternative is to use a semi-colon after the pre-requisite, and a backslash
1214  at the end of each line (except the last).
1215  Then any whitespace (or none) can prefix each action.
1216 \end_layout
1218 \begin_layout LyX-Code
1219 target: pre-requisite ; 
1220 \backslash
1222 \begin_inset Newline newline
1223 \end_inset
1225 ␣␣action 
1226 \backslash
1228 \begin_inset Newline newline
1229 \end_inset
1231 ␣␣action
1232 \end_layout
1234 \begin_layout Standard
1235 This is the style that we use and it works pretty well for GNU make at least.
1236 \end_layout
1238 \begin_layout Standard
1239 We also adopt a convention that code chunks whose names beginning with ./
1240  should always be automatically extracted from the document.
1241  Code chunks whose names do not begin with ./ are for internal reference.
1242  (This doesn't prevent such chunks from being extracted directly).
1243 \end_layout
1245 \begin_layout Section
1246 Boot-strapping the extraction
1247 \end_layout
1249 \begin_layout Subsection
1250 Using a Makefile
1251 \end_layout
1253 \begin_layout Standard
1254 \begin_inset CommandInset label
1255 LatexCommand label
1256 name "sub:Bootstrap-Using-a-Makefile"
1258 \end_inset
1260 It seems convenient to have the makefile extract or update the C source
1261  files as part of it's operation.
1262  It also seems convenient to have the makefile itself extracted from this
1263  document.
1264 \end_layout
1266 \begin_layout Standard
1267 It would also be convenient to have the code to extract the makefile from
1268  this document to also be part of this document, however we have to start
1269  somewhere and this unfortunately requires us to type at least a few words
1270  by hand to start things off.
1271 \end_layout
1273 \begin_layout Standard
1274 Therefore we will have a minimal root fragment, which, when extracted, can
1275  cope with extracting the rest of the source.
1276  perhaps with this shell script, which could be called 
1277 \emph on
1278 autoboot
1279 \emph default
1281 \begin_inset Note Note
1282 status open
1284 \begin_layout Plain Layout
1285 FIX THIS CHUNK AND TEST IT
1286 \end_layout
1288 \end_inset
1291 \end_layout
1293 \begin_layout Chunk
1295 \end_layout
1297 \begin_layout Standard
1298 \begin_inset listings
1299 inline false
1300 status open
1302 \begin_layout Plain Layout
1304 #! /bin/sh
1305 \end_layout
1307 \begin_layout Plain Layout
1309 \end_layout
1311 \begin_layout Plain Layout
1313 MAKE_SRC="${1:-${NW_LYX:-../../noweb-lyx/noweb-lyx3.lyx}}"
1314 \end_layout
1316 \begin_layout Plain Layout
1318 MAKE_SRC=`dirname "$MAKE_SRC"`/`basename "$MAKE_SRC" .lyx`
1319 \end_layout
1321 \begin_layout Plain Layout
1323 NOWEB_SRC="${2:-${NOWEB_SRC:-$MAKE_SRC.lyx}}"
1324 \end_layout
1326 \begin_layout Plain Layout
1328 lyx -e latex $MAKE_SRC
1329 \end_layout
1331 \begin_layout Plain Layout
1333 \end_layout
1335 \begin_layout Plain Layout
1337 newfangle -R./Makefile.inc ${MAKE_SRC}.tex 
1338 \backslash
1340 \end_layout
1342 \begin_layout Plain Layout
1344   | sed "/NEWFANGLE_SOURCE=/s/^/#/;T;aNOWEB_SOURCE=$NEWFANGLE_SRC" 
1345 \backslash
1347 \end_layout
1349 \begin_layout Plain Layout
1351   | cpif ./Makefile.inc
1352 \end_layout
1354 \begin_layout Plain Layout
1356 \end_layout
1358 \begin_layout Plain Layout
1360 make -f ./Makefile.inc newfangle_sources
1361 \end_layout
1363 \end_inset
1366 \end_layout
1368 \begin_layout Standard
1369 The general Makefile can be invoked with 
1370 \emph on
1371 ./autoboot
1372 \emph default
1373  and can also be included into any automake file to automatically re-generate
1374  the source files.
1375 \end_layout
1377 \begin_layout Standard
1378 The 
1379 \emph on
1380 autoboot
1381 \emph default
1382  can be extracted with this command:
1383 \end_layout
1385 \begin_layout LyX-Code
1386 lyx -e latex newfangle.lyx && 
1387 \backslash
1389 \end_layout
1391 \begin_layout LyX-Code
1392 newfangle newfangle.lyx > ./autoboot
1393 \end_layout
1395 \begin_layout Standard
1396 This looks simple enough, but as mentioned, newfangle has to be had from
1397  somewhere before it can be extracted.
1398 \end_layout
1400 \begin_layout Subsection
1401 \begin_inset Note Note
1402 status collapsed
1404 \begin_layout Plain Layout
1405 MERGE THIS WITH THE SECTIONS OF THIS DOCUMENT
1406 \end_layout
1408 \end_inset
1410 \SpecialChar \ldots{}
1412 \end_layout
1414 \begin_layout Standard
1415 When the lyx-build chunk is executed, the current directory will be a temporary
1416  directory, and 
1417 \begin_inset Flex CharStyle:Code
1418 status collapsed
1420 \begin_layout Plain Layout
1421 LYX_SOURCE
1422 \end_layout
1424 \end_inset
1426  will refer to the tex file in this temporary directory.
1427  This is unfortunate as our makefile wants to run from the project directory
1428  where the Lyx file is kept.
1429 \end_layout
1431 \begin_layout Standard
1432 We can extract the project directory from $$r, and derive the probable Lyx
1433  filename from the noweb file that Lyx generated.
1434 \end_layout
1436 \begin_layout Chunk
1437 lyx-build-helper
1438 \end_layout
1440 \begin_layout Standard
1441 \begin_inset listings
1442 inline false
1443 status open
1445 \begin_layout Plain Layout
1447 PROJECT_DIR="$LYX_r"
1448 \end_layout
1450 \begin_layout Plain Layout
1452 LYX_SRC="$PROJECT_DIR/${LYX_i%.tex}.lyx"
1453 \end_layout
1455 \begin_layout Plain Layout
1457 TEX_DIR="$LYX_p"
1458 \end_layout
1460 \begin_layout Plain Layout
1462 TEX_SRC="$TEX_DIR/$LYX_i"
1463 \end_layout
1465 \end_inset
1468 \end_layout
1470 \begin_layout Standard
1471 And then we can define a lyx-build fragment similar to the autoboot fragment
1472 \end_layout
1474 \begin_layout Chunk
1475 lyx-build
1476 \end_layout
1478 \begin_layout Standard
1479 \begin_inset listings
1480 inline false
1481 status open
1483 \begin_layout Plain Layout
1485 #! /bin/sh
1486 \end_layout
1488 \begin_layout Plain Layout
1491 \backslash
1492 chunkref{lyx-build-helper}>
1493 \end_layout
1495 \begin_layout Plain Layout
1497 cd $PROJECT_DIR || exit 1
1498 \end_layout
1500 \begin_layout Plain Layout
1502 \end_layout
1504 \begin_layout Plain Layout
1506 #/usr/bin/newfangle -filter ./notanglefix-filter 
1507 \backslash
1509 \end_layout
1511 \begin_layout Plain Layout
1513 #  -R./Makefile.inc "../../noweb-lyx/noweb-lyx3.lyx" 
1514 \backslash
1516 \end_layout
1518 \begin_layout Plain Layout
1520 #  | sed '/NOWEB_SOURCE=/s/=.*/=samba4-dfs.lyx/' 
1521 \backslash
1523 \end_layout
1525 \begin_layout Plain Layout
1527 #  > ./Makefile.inc
1528 \end_layout
1530 \begin_layout Plain Layout
1533 \end_layout
1535 \begin_layout Plain Layout
1537 #make -f ./Makefile.inc newfangle_sources
1538 \end_layout
1540 \end_inset
1543 \end_layout
1545 \begin_layout Section
1546 Extracting Sources
1547 \end_layout
1549 \begin_layout Subsection
1550 Including Makefile.inc
1551 \end_layout
1553 \begin_layout Standard
1554 \begin_inset CommandInset label
1555 LatexCommand label
1556 name "sub:Keeping-extracted-files"
1558 \end_inset
1560 Makefile.inc will cope with extracting all the other source files from this
1561  document and keeping them up to date.
1563 \end_layout
1565 \begin_layout Standard
1566 It may also be included by a Makefile or Makefile.am defined in a Lyx document
1567  to automatically deal with the extraction of source files and documents.
1568 \end_layout
1570 \begin_layout Standard
1571 A makefile has two parts; variables must be defined before the targets that
1572  use them.
1573 \end_layout
1575 \begin_layout Chunk
1576 ./Makefile.inc
1577 \end_layout
1579 \begin_layout Standard
1580 \begin_inset listings
1581 inline false
1582 status open
1584 \begin_layout Plain Layout
1587 \backslash
1588 chunkref{Makefile.inc-vars}>
1589 \end_layout
1591 \begin_layout Plain Layout
1594 \backslash
1595 chunkref{Makefile.inc-targets}>
1596 \end_layout
1598 \end_inset
1601 \end_layout
1603 \begin_layout Standard
1604 We first define 
1605 \begin_inset Flex CharStyle:Code
1606 status collapsed
1608 \begin_layout Plain Layout
1609 NOWEB_SOURCE
1610 \end_layout
1612 \end_inset
1614  to hold the name of this Lyx file.
1615 \end_layout
1617 \begin_layout Chunk
1618 Makefile.inc-vars
1619 \end_layout
1621 \begin_layout Standard
1622 \begin_inset listings
1623 inline false
1624 status open
1626 \begin_layout Plain Layout
1628 LYX_SOURCE=
1629 \end_layout
1631 \begin_layout Plain Layout
1633 LITERATE_SOURCE=$(LYX_SOURCE)
1634 \end_layout
1636 \end_inset
1639 \end_layout
1641 \begin_layout Subsection
1642 Recursive use of Makefile.inc
1643 \end_layout
1645 \begin_layout Standard
1646 The makefile glue described here is used when building Samba4 vfs modules.
1647 \end_layout
1649 \begin_layout Standard
1650 If you are defining a module of an existing program you may find it easier
1651  to use a slight recursive make instead of including the makefile directly.
1652  This way there is less chance of definitions in Makefile.inc interfering
1653  with definitions in the main makefile, or with definitions in other Makefile.inc
1654  from other noweb modules.
1655 \end_layout
1657 \begin_layout Standard
1658 The glue works by adding a .PHONY target to call the recursive make, and
1659  adding this target as an additional pre-requisite to the existing targets.
1660 \end_layout
1662 \begin_layout Standard
1663 In this example, the existing build system already has a build target for
1665 \begin_inset Flex CharStyle:Code
1666 status collapsed
1668 \begin_layout Plain Layout
1669 example.o
1670 \end_layout
1672 \end_inset
1674 , so we just add another pre-requisite to that.
1675  In this case we use 
1676 \begin_inset Flex CharStyle:Code
1677 status collapsed
1679 \begin_layout Plain Layout
1680 example.tex.stamp
1681 \end_layout
1683 \end_inset
1685  as a pre-requisite, the stamp file's modified time indicating when all
1686  sources were extracted.
1687 \end_layout
1689 \begin_layout Chunk
1690 makefile-glue
1691 \end_layout
1693 \begin_layout Standard
1694 \begin_inset listings
1695 inline false
1696 status open
1698 \begin_layout Plain Layout
1700 $(example_srcdir)/example.o: $(example_srcdir)/example.tex.stamp
1701 \end_layout
1703 \end_inset
1706 \end_layout
1708 \begin_layout Standard
1709 The target for this new pre-requisite is generated by a recursive make using
1710  Makefile.inc which will make sure that the source is up to date, before
1711  it is built by the main projects makefile.
1712 \end_layout
1714 \begin_layout Chunk
1715 makefile-glue
1716 \end_layout
1718 \begin_layout Standard
1719 \begin_inset listings
1720 inline false
1721 status open
1723 \begin_layout Plain Layout
1725 $(example_srcdir)/example.tex.stamp: $(example_srcdir)/example.tex ; 
1726 \backslash
1728 \end_layout
1730 \begin_layout Plain Layout
1732         cd $(example_srcdir) && 
1733 \backslash
1735 \end_layout
1737 \begin_layout Plain Layout
1739         $(MAKE) -f Makefile.inc newfangle_sources
1740 \end_layout
1742 \end_inset
1745 \end_layout
1747 \begin_layout Standard
1748 We can do similar glue for the docs, clean and distclean targets.
1749  In this example our build system is using a double colon for these targets,
1750  so we use the same in our glue.
1751 \end_layout
1753 \begin_layout Chunk
1754 makefile-glue
1755 \end_layout
1757 \begin_layout Standard
1758 \begin_inset listings
1759 inline false
1760 status open
1762 \begin_layout Plain Layout
1764 docs:: docs_example
1765 \end_layout
1767 \begin_layout Plain Layout
1769 .PHONY: docs_example
1770 \end_layout
1772 \begin_layout Plain Layout
1774 docs_example:: ; cd $(example_srcdir) && 
1775 \backslash
1777 \end_layout
1779 \begin_layout Plain Layout
1781         $(MAKE) -f Makefile.inc docs
1782 \end_layout
1784 \begin_layout Plain Layout
1786 \end_layout
1788 \begin_layout Plain Layout
1790 clean:: clean_example
1791 \end_layout
1793 \begin_layout Plain Layout
1795 .PHONEY: clean_example
1796 \end_layout
1798 \begin_layout Plain Layout
1800 clean_example: ; cd $(example_srcdir) && 
1801 \backslash
1803 \end_layout
1805 \begin_layout Plain Layout
1807         $(MAKE) -f Makefile.inc clean
1808 \end_layout
1810 \begin_layout Plain Layout
1812 \end_layout
1814 \begin_layout Plain Layout
1816 distclean:: distclean_example
1817 \end_layout
1819 \begin_layout Plain Layout
1821 .PHONY: distclean_example
1822 \end_layout
1824 \begin_layout Plain Layout
1826 distclean_example: ; cd $(example_srcdir) && 
1827 \backslash
1829 \end_layout
1831 \begin_layout Plain Layout
1833         $(MAKE) -f Makefile.inc distclean
1834 \end_layout
1836 \end_inset
1839 \end_layout
1841 \begin_layout Standard
1842 We could do similarly for install targets to install the generated docs.
1843 \end_layout
1845 \begin_layout Subsection
1846 \begin_inset CommandInset label
1847 LatexCommand label
1848 name "sub:Converting-from-Lyx"
1850 \end_inset
1852 Converting from Lyx to LaTeX
1853 \end_layout
1855 \begin_layout Standard
1856 The first stage will always be to convert the Lyx file to a LaTeX file;
1857  this must be so not only because newfangle needs to to run on a TeX file,
1858  but also because the Lyx command 
1859 \emph on
1860 server-goto-file-line
1861 \begin_inset Foot
1862 status collapsed
1864 \begin_layout Plain Layout
1865 The Lyx command 
1866 \emph on
1867 server-goto-file-line
1868 \emph default
1869  is used to position the Lyx cursor at the compiler errors.
1870 \end_layout
1872 \end_inset
1875 \emph default
1876  insists that the line number provided is a line in the TeX file, and always
1877  reverse maps this to derive the line in the Lyx docment.
1878 \begin_inset Note Note
1879 status collapsed
1881 \begin_layout Plain Layout
1882 The tex file should probably be an automake extra dist sources or something,
1883  so that it gets produced and packaged by make dist
1884 \end_layout
1886 \end_inset
1889 \end_layout
1891 \begin_layout Standard
1892 The command [[lyx -e literate noweb-lyx.lyx]] will produce [[noweb-lyx.nw]]
1893  a tex file, so we define the noweb target to be the same as the Lyx file
1894  but with the .nw extension.
1895 \end_layout
1897 \begin_layout Chunk
1898 Makefile.inc-vars
1899 \end_layout
1901 \begin_layout Standard
1902 \begin_inset listings
1903 inline false
1904 status open
1906 \begin_layout Plain Layout
1908 TEX_SOURCE=$(LYX_SOURCE:.lyx=.tex)
1909 \end_layout
1911 \end_inset
1914 \end_layout
1916 \begin_layout Chunk
1917 Makefile.inc-targets
1918 \end_layout
1920 \begin_layout Standard
1921 \begin_inset listings
1922 inline false
1923 status open
1925 \begin_layout Plain Layout
1927 $(TEX_SOURCE): $(LYX_SOURCE) ;
1928 \backslash
1930 \end_layout
1932 \begin_layout Plain Layout
1934         lyx -e latex $<
1935 \end_layout
1937 \begin_layout Plain Layout
1939 clean_tex: ; rm -f -- $(TEX_SOURCE)
1940 \end_layout
1942 \end_inset
1945 \end_layout
1947 \begin_layout Subsection
1948 Extracting Program Source
1949 \end_layout
1951 \begin_layout Standard
1952 The program source is extracted using newfangle, which is designed to operate
1953  on a LaTeX document.
1955 \end_layout
1957 \begin_layout Chunk
1958 Makefile.inc-vars
1959 \end_layout
1961 \begin_layout Standard
1962 \begin_inset listings
1963 inline false
1964 status open
1966 \begin_layout Plain Layout
1968 NEWFANGLE_SOURCE=$(TEX_SOURCE)
1969 \end_layout
1971 \end_inset
1974 \end_layout
1976 \begin_layout Standard
1977 The Lyx document can result in any number of source documents, but not all
1978  of these will be changed each time the Lyx document is updated.
1979  We certainly don't want to update the timestamps of these files and cause
1980  the whole source tree to be recompiled just because the Lyx document was
1981  edited.
1983 \end_layout
1985 \begin_layout Standard
1986 To solve this problem we use a stamp file which is always updated each time
1987  the sources are extracted from the LaTeX document.
1988  If the stamp file is older than the LaTeX document, then we can make an
1989  attempt to re-extract the sources.
1990 \end_layout
1992 \begin_layout Chunk
1993 Makefile.inc-vars
1994 \end_layout
1996 \begin_layout Standard
1997 \begin_inset listings
1998 inline false
1999 status open
2001 \begin_layout Plain Layout
2003 NEWFANGLE_SOURCE_STAMP=$(NEWFANGLE_SOURCE).stamp
2004 \end_layout
2006 \end_inset
2009 \end_layout
2011 \begin_layout Chunk
2012 Makefile.inc-targets
2013 \end_layout
2015 \begin_layout Standard
2016 \begin_inset listings
2017 inline false
2018 status open
2020 \begin_layout Plain Layout
2022 $(NEWFANGLE_SOURCE_STAMP): $(NEWFANGLE_SOURCE) 
2023 \backslash
2025 \end_layout
2027 \begin_layout Plain Layout
2029                            $(NEWFANGLE_SOURCES) ; 
2030 \backslash
2032 \end_layout
2034 \begin_layout Plain Layout
2036         echo > $(NEWFANGLE_SOURCE_STAMP)
2037 \end_layout
2039 \begin_layout Plain Layout
2041 clean_stamp: ; rm -f $(NEWFANGLE_SOURCE_STAMP)
2042 \end_layout
2044 \begin_layout Plain Layout
2046 clean: clean_stamp
2047 \end_layout
2049 \end_inset
2052 \end_layout
2054 \begin_layout Subsection
2055 Extracting C sources
2056 \end_layout
2058 \begin_layout Standard
2059 We compute 
2060 \begin_inset Flex CharStyle:Code
2061 status collapsed
2063 \begin_layout Plain Layout
2064 NEWFANGLE_SOURCES
2065 \end_layout
2067 \end_inset
2069  to hold the names of all the C source files defined in this document.
2070  We compute this only once, by means of := in assignent.
2071  The sed deletes the any <
2072 \begin_inset space \hspace*{}
2073 \length 0in
2074 \end_inset
2076 < and >
2077 \begin_inset space \hspace*{}
2078 \length 0in
2079 \end_inset
2081 > which may surround the roots names (for noroots compatibility).
2083 \end_layout
2085 \begin_layout Standard
2086 As we use chunk names beginning with ./ to denote top level fragments that
2087  should be extracted, we filter out all fragments that do not begin with
2088  ./
2089 \end_layout
2091 \begin_layout Chunk
2092 Makefile.inc-vars
2093 \end_layout
2095 \begin_layout Standard
2096 \begin_inset listings
2097 inline false
2098 status open
2100 \begin_layout Plain Layout
2102 NEWFANGLE_PREFIX:=
2103 \backslash
2105 \backslash
2107 \end_layout
2109 \begin_layout Plain Layout
2111 NEWFANGLE_SOURCES:=$(shell 
2112 \backslash
2114 \end_layout
2116 \begin_layout Plain Layout
2118   newfangle -r $(NEWFANGLE_SOURCE) |
2119 \backslash
2121 \end_layout
2123 \begin_layout Plain Layout
2125   sed -e 's/^[<][<]//;s/[>][>]$$//;/^$(NEWFANGLE_PREFIX)/!d' 
2126 \backslash
2128 \end_layout
2130 \begin_layout Plain Layout
2132       -e 's/^$(NEWFANGLE_PREFIX)/
2133 \backslash
2135 \backslash
2136 //' )
2137 \end_layout
2139 \begin_layout Plain Layout
2142 \end_layout
2144 \end_inset
2147 \end_layout
2149 \begin_layout Chunk
2150 Makefile.inc-targets
2151 \end_layout
2153 \begin_layout Standard
2154 \begin_inset listings
2155 inline false
2156 status open
2158 \begin_layout Plain Layout
2160 .PHONY: echo_newfangle_sources
2161 \end_layout
2163 \begin_layout Plain Layout
2165 echo_newfangle_sources: ; @echo $(NEWFANGLE_SOURCES)
2166 \end_layout
2168 \end_inset
2171 \end_layout
2173 \begin_layout Standard
2174 We define a convenient target called 
2175 \begin_inset Flex CharStyle:Code
2176 status collapsed
2178 \begin_layout Plain Layout
2179 newfangle_sources
2180 \end_layout
2182 \end_inset
2184  to re-extract the source if the LaTeX file has been updated.
2185 \end_layout
2187 \begin_layout Chunk
2188 Makefile.inc-targets
2189 \end_layout
2191 \begin_layout Standard
2192 \begin_inset listings
2193 inline false
2194 status open
2196 \begin_layout Plain Layout
2198 .PHONY: newfangle_sources
2199 \end_layout
2201 \begin_layout Plain Layout
2203 newfangle_sources: $(NEWFANGLE_SOURCE_STAMP)
2204 \end_layout
2206 \end_inset
2209 \end_layout
2211 \begin_layout Standard
2212 And also a convenient target to remove extracted sources.
2213 \end_layout
2215 \begin_layout Chunk
2216 Makefile.inc-targets
2217 \end_layout
2219 \begin_layout Standard
2220 \begin_inset listings
2221 inline false
2222 status open
2224 \begin_layout Plain Layout
2226 .PHONY: clean_newfangle_sources
2227 \end_layout
2229 \begin_layout Plain Layout
2231 clean_newfangle_sources: ; 
2232 \backslash
2234 \end_layout
2236 \begin_layout Plain Layout
2238         rm -f -- $(NEWFANGLE_SOURCE_STAMP) $(NEWFANGLE_SOURCES)
2239 \end_layout
2241 \end_inset
2244 \end_layout
2246 \begin_layout Standard
2247 This 
2248 \begin_inset Flex CharStyle:Code
2249 status collapsed
2251 \begin_layout Plain Layout
2252 if_extension
2253 \end_layout
2255 \end_inset
2257  macro takes 4 arguments: the filename (1), some extensions to match (2)
2258  and a some shell command to return if the filename matches the exentions
2259  (3), or not (4).
2260 \end_layout
2262 \begin_layout Chunk
2263 Makefile.inc-vars
2264 \end_layout
2266 \begin_layout Standard
2267 \begin_inset listings
2268 inline false
2269 status open
2271 \begin_layout Plain Layout
2273 if_extension=$(if $(findstring $(suffix $(1)),$(2)),$(3),$(4))
2274 \end_layout
2276 \end_inset
2279 \end_layout
2281 \begin_layout Standard
2282 For some source files like C files, we want to output the line number and
2283  filename of the original LaTeX document from which the source came.
2284 \end_layout
2286 \begin_layout Standard
2287 To make this easier we define the file extensions for which we want to do
2288  this.
2289 \end_layout
2291 \begin_layout Chunk
2292 Makefile.inc-vars
2293 \end_layout
2295 \begin_layout Standard
2296 \begin_inset listings
2297 inline false
2298 status open
2300 \begin_layout Plain Layout
2302 C_EXTENSIONS=.c .h
2303 \end_layout
2305 \end_inset
2308 \end_layout
2310 \begin_layout Standard
2311 We can then use the if_extensions macro to define a macro which expands
2312  out to the 
2313 \begin_inset Flex CharStyle:Code
2314 status collapsed
2316 \begin_layout Plain Layout
2318 \end_layout
2320 \end_inset
2322  option if newfangle is being invoked in a C source file, so that C compile
2323  errors will refer to the line number in the Lyx document.
2325 \end_layout
2327 \begin_layout Chunk
2328 Makefile.inc-vars
2329 \end_layout
2331 \begin_layout Standard
2332 \begin_inset listings
2333 inline false
2334 status open
2336 \begin_layout Plain Layout
2338 TABS=8
2339 \end_layout
2341 \begin_layout Plain Layout
2343 nf_line=-L -T$(TABS)
2344 \end_layout
2346 \begin_layout Plain Layout
2348 newfangle=newfangle 
2349 \backslash
2351 \end_layout
2353 \begin_layout Plain Layout
2355   $(call if_extension,$(2),$(C_EXTENSIONS),$(nf_line)) 
2356 \backslash
2358 \end_layout
2360 \begin_layout Plain Layout
2362     -R"$(2)" $(1)
2363 \end_layout
2365 \end_inset
2368 \end_layout
2370 \begin_layout Standard
2371 We can use a similar trick to define an 
2372 \emph on
2373 indent
2374 \emph default
2375  macro which takes just the filename as an argument and can return a pipeline
2376  stage calling the indent command.
2377  Indent can be turned off with 
2378 \begin_inset Flex CharStyle:Code
2379 status collapsed
2381 \begin_layout Plain Layout
2382 make newfangle_sources indent=
2383 \end_layout
2385 \end_inset
2388 \end_layout
2390 \begin_layout Chunk
2391 Makefile.inc-vars
2392 \end_layout
2394 \begin_layout Standard
2395 \begin_inset listings
2396 inline false
2397 status open
2399 \begin_layout Plain Layout
2401 indent_options=-npro -kr -i8 -ts8 -sob -l80 -ss -ncs
2402 \end_layout
2404 \begin_layout Plain Layout
2406 indent=$(call if_extension,$(1),$(C_EXTENSIONS),
2407 \backslash
2409 \end_layout
2411 \begin_layout Plain Layout
2413               | indent $(indent_options))
2414 \end_layout
2416 \end_inset
2419 \end_layout
2421 \begin_layout Standard
2422 We now define the pattern for extracting a file.
2423  The files are written using noweb's 
2424 \emph on
2425 cpif
2426 \begin_inset Foot
2427 status collapsed
2429 \begin_layout Plain Layout
2431 \emph on
2432 So you still need noweb installed in order to use cpif
2433 \end_layout
2435 \end_inset
2438 \begin_inset Note Note
2439 status collapsed
2441 \begin_layout Plain Layout
2443 \emph on
2444 Write an awk version
2445 \end_layout
2447 \end_inset
2450 \emph default
2451  so that the file timestamp will not be touched if the contents haven't
2452  changed.
2453  This avoids the need to rebuild the entire project because of a typographical
2454  change in the documentation, or if only a few C source files have changed.
2455 \end_layout
2457 \begin_layout Chunk
2458 Makefile.inc-vars
2459 \end_layout
2461 \begin_layout Standard
2462 \begin_inset listings
2463 inline false
2464 status open
2466 \begin_layout Plain Layout
2468 newfangle_extract=@mkdir -p $(dir $(1)) && 
2469 \backslash
2471 \end_layout
2473 \begin_layout Plain Layout
2475   $(call newfangle,$(2),$(1)) > "$(1).tmp" && 
2476 \backslash
2478 \end_layout
2480 \begin_layout Plain Layout
2482   cat "$(1).tmp" $(indent) | cpif "$(1)" 
2483 \backslash
2485 \end_layout
2487 \begin_layout Plain Layout
2489   && rm -- "$(1).tmp" || 
2490 \backslash
2492 \end_layout
2494 \begin_layout Plain Layout
2496   (echo error newfangling $(1) from $(2) ; exit 1)
2497 \end_layout
2499 \end_inset
2502 \end_layout
2504 \begin_layout Standard
2505 We define a target which will extract or update all sources.
2506  To do this we first defined a makefile template that can do this for any
2507  source file in the LaTeX document.
2508 \end_layout
2510 \begin_layout Chunk
2511 Makefile.inc-vars
2512 \end_layout
2514 \begin_layout Standard
2515 \begin_inset listings
2516 inline false
2517 status open
2519 \begin_layout Plain Layout
2521 define NEWFANGLE_template
2522 \end_layout
2524 \begin_layout Plain Layout
2526   $(1): $(2); 
2527 \backslash
2529 \end_layout
2531 \begin_layout Plain Layout
2533     $$(call newfangle_extract,$(1),$(2))
2534 \end_layout
2536 \begin_layout Plain Layout
2538   NEWFANGLE_TARGETS+=$(1)
2539 \end_layout
2541 \begin_layout Plain Layout
2543 endef
2544 \end_layout
2546 \end_inset
2549 \end_layout
2551 \begin_layout Standard
2552 We then enumerate the discovered 
2553 \begin_inset Flex CharStyle:Code
2554 status collapsed
2556 \begin_layout Plain Layout
2557 NEWTANGLE_SOURCES
2558 \end_layout
2560 \end_inset
2562  to generate a makefile rule for each one using the makefile template we
2563  defined above.
2564 \end_layout
2566 \begin_layout Chunk
2567 Makefile.inc-targets
2568 \end_layout
2570 \begin_layout Standard
2571 \begin_inset listings
2572 inline false
2573 status open
2575 \begin_layout Plain Layout
2577 $(foreach source,$(NEWFANGLE_SOURCES),
2578 \backslash
2580 \end_layout
2582 \begin_layout Plain Layout
2584   $(eval $(call NEWFANGLE_template,$(source),$(NEWFANGLE_SOURCE))) 
2585 \backslash
2587 \end_layout
2589 \begin_layout Plain Layout
2592 \end_layout
2594 \end_inset
2597 \end_layout
2599 \begin_layout Standard
2600 These will all be built with NEWFANGLE_SOURCE_STAMP.
2601 \end_layout
2603 \begin_layout Standard
2604 We also remove the generated sources on a 
2605 \emph on
2606 make distclean
2607 \emph default
2609 \end_layout
2611 \begin_layout Chunk
2612 Makefile.inc-targets
2613 \end_layout
2615 \begin_layout Standard
2616 \begin_inset listings
2617 inline false
2618 status open
2620 \begin_layout Plain Layout
2622 _distclean: clean_newfangle_sources
2623 \end_layout
2625 \end_inset
2628 \end_layout
2630 \begin_layout Subsection
2631 Extracting Documentation
2632 \end_layout
2634 \begin_layout Standard
2635 We then identify the intermediate stages of the documentation and their
2636  build and clean targets.
2637 \end_layout
2639 \begin_layout Subsubsection
2640 Running pdflatex
2641 \end_layout
2643 \begin_layout Standard
2644 We produce a pdf file from the tex file.
2645 \end_layout
2647 \begin_layout Chunk
2648 Makefile.inc-vars
2649 \end_layout
2651 \begin_layout Standard
2652 \begin_inset listings
2653 inline false
2654 status open
2656 \begin_layout Plain Layout
2658 NEWFANGLE_PDF=$(TEX_SOURCE:.tex=.pdf)
2659 \end_layout
2661 \end_inset
2664 \end_layout
2666 \begin_layout Standard
2667 We run pdflatex twice to be sure that the contents and aux files are up
2668  to date.
2669  We certainly are required to run pdflatex twice if these files do not exist!
2670 \end_layout
2672 \begin_layout Chunk
2673 Makefile.inc-targets
2674 \end_layout
2676 \begin_layout Standard
2677 \begin_inset listings
2678 inline false
2679 status open
2681 \begin_layout Plain Layout
2683 $(NEWFANGLE_PDF): $(TEX_SOURCE); pdflatex $< && pdflatex $<
2684 \end_layout
2686 \begin_layout Plain Layout
2688 clean_pdf: ; rm -f -- $(NEWFANGLE_PDF) 
2689 \backslash
2691 \end_layout
2693 \begin_layout Plain Layout
2695                       $(TEX_SOURCE:.tex=.toc) 
2696 \backslash
2698 \end_layout
2700 \begin_layout Plain Layout
2702                       $(TEX_SOURCE:.tex=.log) 
2703 \backslash
2705 \end_layout
2707 \begin_layout Plain Layout
2709                       $(TEX_SOURCE:.tex=.aux)
2710 \end_layout
2712 \end_inset
2715 \end_layout
2717 \begin_layout Subsubsection
2718 The docs as a whole
2719 \end_layout
2721 \begin_layout Standard
2722 Currently we only build pdf as a final format, but NEWFANGLE_DOCS may later
2723  hold other output formats.
2724 \end_layout
2726 \begin_layout Chunk
2727 Makefile.inc-vars
2728 \end_layout
2730 \begin_layout Standard
2731 \begin_inset listings
2732 inline false
2733 status open
2735 \begin_layout Plain Layout
2737 NEWFANGLE_DOCS=$(NEWFANGLE_PDF)
2738 \end_layout
2740 \end_inset
2743 \end_layout
2745 \begin_layout Standard
2746 We also define newfangle_docs as a convenient phony target<
2747 \end_layout
2749 \begin_layout Chunk
2750 Makefile.inc-targets
2751 \end_layout
2753 \begin_layout Standard
2754 \begin_inset listings
2755 inline false
2756 status open
2758 \begin_layout Plain Layout
2760 .PHONY: newfangle_docs
2761 \end_layout
2763 \begin_layout Plain Layout
2765 newfangle_docs: $(NEWFANGLE_DOCS)
2766 \end_layout
2768 \begin_layout Plain Layout
2770 docs: newfangle_docs
2771 \end_layout
2773 \end_inset
2776 \end_layout
2778 \begin_layout Standard
2779 And define a convenient clean_noweb_docs which we add to the regular clean
2780  target
2781 \end_layout
2783 \begin_layout Chunk
2784 Makefile.inc-targets
2785 \end_layout
2787 \begin_layout Standard
2788 \begin_inset listings
2789 inline false
2790 status open
2792 \begin_layout Plain Layout
2794 .PHONEY: clean_newfangle_docs
2795 \end_layout
2797 \begin_layout Plain Layout
2799 clean_newfangle_docs: clean_tex clean_pdf
2800 \end_layout
2802 \begin_layout Plain Layout
2804 clean: clean_newfangle_docs
2805 \end_layout
2807 \begin_layout Plain Layout
2809 \end_layout
2811 \begin_layout Plain Layout
2813 distclean_newfangle_docs: clean_tex clean_newfangle_docs
2814 \end_layout
2816 \begin_layout Plain Layout
2818 distclean: clean distclean_newfangle_docs
2819 \end_layout
2821 \end_inset
2824 \end_layout
2826 \begin_layout Subsection
2827 Other helpers
2828 \end_layout
2830 \begin_layout Standard
2831 If Makefile.inc is included into Makefile, then extracted files can be updated
2832  with this command:
2833 \end_layout
2835 \begin_layout LyX-Code
2836 make newfangle_sources
2837 \end_layout
2839 \begin_layout Standard
2840 otherwise, with:
2841 \end_layout
2843 \begin_layout LyX-Code
2844 make -f Makefile.inc newfangle_sources
2845 \end_layout
2847 \begin_layout Part
2848 Source Code
2849 \end_layout
2851 \begin_layout Chapter
2852 Newfangle awk source code
2853 \end_layout
2855 \begin_layout Standard
2856 We use the copyright notice from chapter 
2857 \begin_inset CommandInset ref
2858 LatexCommand ref
2859 reference "cha:License"
2861 \end_inset
2864 \end_layout
2866 \begin_layout Chunk
2867 ./newfangle,language=awk,morestring=[b]{/},morekeywords=else
2868 \end_layout
2870 \begin_layout Standard
2871 \begin_inset listings
2872 inline false
2873 status open
2875 \begin_layout Plain Layout
2877 #! /usr/bin/awk -f
2878 \end_layout
2880 \begin_layout Plain Layout
2883 \backslash
2884 chunkref{gpl3-copyright}>
2885 \end_layout
2887 \end_inset
2890 \end_layout
2892 \begin_layout Standard
2893 We also use code from Arnold Robbins public domain getopt (1993 revision)
2894  defined in chapter 
2895 \begin_inset CommandInset ref
2896 LatexCommand ref
2897 reference "cha:getopt"
2899 \end_inset
2901 , and naturally want to attribute this appropriately.
2902 \end_layout
2904 \begin_layout Standard
2905 \begin_inset listings
2906 inline false
2907 status open
2909 \begin_layout Plain Layout
2911 \end_layout
2913 \begin_layout Plain Layout
2915 # NOTE: Arnold Robbins public domain getopt for awk is also used:
2916 \end_layout
2918 \begin_layout Plain Layout
2921 \backslash
2922 chunkref{getopt.awk-header}>
2923 \end_layout
2925 \begin_layout Plain Layout
2927 \end_layout
2929 \begin_layout Plain Layout
2932 \backslash
2933 chunkref{getopt.awk-getopt()}>
2934 \end_layout
2936 \begin_layout Plain Layout
2938 \end_layout
2940 \end_inset
2943 \end_layout
2945 \begin_layout Standard
2946 And include the following chunks
2947 \end_layout
2949 \begin_layout Chunk
2950 ./newfangle
2951 \end_layout
2953 \begin_layout Standard
2954 \begin_inset listings
2955 inline false
2956 status open
2958 \begin_layout Plain Layout
2961 \backslash
2962 chunkref{helper-functions}>
2963 \end_layout
2965 \begin_layout Plain Layout
2968 \backslash
2969 chunkref{mode-tracker}>
2970 \end_layout
2972 \begin_layout Plain Layout
2975 \backslash
2976 chunkref{chunk-storage-functions}>
2977 \end_layout
2979 \begin_layout Plain Layout
2982 \backslash
2983 chunkref{output_chunk_names()}>
2984 \end_layout
2986 \begin_layout Plain Layout
2989 \backslash
2990 chunkref{output_chunks()}>
2991 \end_layout
2993 \begin_layout Plain Layout
2996 \backslash
2997 chunkref{write_chunk()}>
2998 \end_layout
3000 \begin_layout Plain Layout
3003 \backslash
3004 chunkref{expand_chunk_args()}>
3005 \end_layout
3007 \begin_layout Plain Layout
3010 \backslash
3011 chunkref{begin}>
3012 \end_layout
3014 \begin_layout Plain Layout
3017 \backslash
3018 chunkref{recognize-chunk}>
3019 \end_layout
3021 \begin_layout Plain Layout
3024 \backslash
3025 chunkref{end}>
3026 \end_layout
3028 \end_inset
3031 \end_layout
3033 \begin_layout Section
3034 AWK tricks
3035 \end_layout
3037 \begin_layout Standard
3038 The portable way to erase an array in awk is to split the empty string,
3039  like this:
3040 \end_layout
3042 \begin_layout Chunk
3043 awk-delete-array,params=ARRAY
3044 \end_layout
3046 \begin_layout Standard
3047 \begin_inset listings
3048 inline false
3049 status open
3051 \begin_layout Plain Layout
3053 split("", ${ARRAY});
3054 \end_layout
3056 \end_inset
3059 \end_layout
3061 \begin_layout Chunk
3062 ,params=
3063 \end_layout
3065 \begin_layout Section
3066 Catching errors
3067 \end_layout
3069 \begin_layout Standard
3070 Fatal errors are issued with the error function:
3071 \end_layout
3073 \begin_layout Chunk
3074 error()
3075 \end_layout
3077 \begin_layout Standard
3078 \begin_inset listings
3079 inline false
3080 status open
3082 \begin_layout Plain Layout
3084 function error(message)
3085 \end_layout
3087 \begin_layout Plain Layout
3090 \end_layout
3092 \begin_layout Plain Layout
3094   print message > "/dev/stderr";
3095 \end_layout
3097 \begin_layout Plain Layout
3099   exit 1;
3100 \end_layout
3102 \begin_layout Plain Layout
3105 \end_layout
3107 \end_inset
3110 \end_layout
3112 \begin_layout Standard
3113 This is one of the helper functions.
3114 \end_layout
3116 \begin_layout Chunk
3117 helper-functions
3118 \end_layout
3120 \begin_layout Standard
3121 \begin_inset listings
3122 inline false
3123 status open
3125 \begin_layout Plain Layout
3128 \backslash
3129 chunkref{error()}>
3130 \end_layout
3132 \end_inset
3135 \end_layout
3137 \begin_layout Chapter
3138 lstlistings
3139 \end_layout
3141 \begin_layout Standard
3142 LaTeX arguments to lstlistings macros are a comma seperated list of key-value
3143  pairs.
3144  Values containing commas are enclosed in { braces }.
3145 \end_layout
3147 \begin_layout Standard
3148 We need a function that can parse such an expression and assign the values
3149  to an 
3150 \noun on
3152 \noun default
3153  associated array.
3154 \end_layout
3156 \begin_layout Standard
3157 A sample expressions is:
3158 \end_layout
3160 \begin_layout LyX-Code
3161 name=thomas, params={a, b}, something, something-else
3162 \end_layout
3164 \begin_layout Standard
3165 but we see that this is just a simpler form of this expression:
3166 \end_layout
3168 \begin_layout LyX-Code
3169 name=freddie, foo={bar=baz, quux={quirk, a=fleeg}}, etc
3170 \end_layout
3172 \begin_layout Standard
3173 And that it would be a good idea to use a recursive parser into a multi-dimensio
3174 nal hash
3175 \begin_inset Foot
3176 status collapsed
3178 \begin_layout Plain Layout
3179 as AWK doesn't have nested-hash support
3180 \end_layout
3182 \end_inset
3184 , resulting in:
3185 \end_layout
3187 \begin_layout Standard
3188 \begin_inset Tabular
3189 <lyxtabular version="3" rows="6" columns="2">
3190 <features>
3191 <column alignment="left" valignment="top" width="0">
3192 <column alignment="left" valignment="top" width="0">
3193 <row>
3194 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
3195 \begin_inset Text
3197 \begin_layout Plain Layout
3199 \end_layout
3201 \end_inset
3202 </cell>
3203 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
3204 \begin_inset Text
3206 \begin_layout Plain Layout
3207 value
3208 \end_layout
3210 \end_inset
3211 </cell>
3212 </row>
3213 <row>
3214 <cell alignment="left" valignment="top" topline="true" leftline="true" usebox="none">
3215 \begin_inset Text
3217 \begin_layout Plain Layout
3218 a[name]
3219 \end_layout
3221 \end_inset
3222 </cell>
3223 <cell alignment="left" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
3224 \begin_inset Text
3226 \begin_layout Plain Layout
3227 freddie
3228 \end_layout
3230 \end_inset
3231 </cell>
3232 </row>
3233 <row>
3234 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
3235 \begin_inset Text
3237 \begin_layout Plain Layout
3238 a[foo, bar]
3239 \end_layout
3241 \end_inset
3242 </cell>
3243 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
3244 \begin_inset Text
3246 \begin_layout Plain Layout
3248 \end_layout
3250 \end_inset
3251 </cell>
3252 </row>
3253 <row>
3254 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
3255 \begin_inset Text
3257 \begin_layout Plain Layout
3258 a[foo, quux, quirk]
3259 \end_layout
3261 \end_inset
3262 </cell>
3263 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
3264 \begin_inset Text
3266 \begin_layout Plain Layout
3268 \end_layout
3270 \end_inset
3271 </cell>
3272 </row>
3273 <row>
3274 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
3275 \begin_inset Text
3277 \begin_layout Plain Layout
3278 a[foo, quux, a]
3279 \end_layout
3281 \end_inset
3282 </cell>
3283 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
3284 \begin_inset Text
3286 \begin_layout Plain Layout
3287 fleeg
3288 \end_layout
3290 \end_inset
3291 </cell>
3292 </row>
3293 <row>
3294 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
3295 \begin_inset Text
3297 \begin_layout Plain Layout
3298 a[etc]
3299 \end_layout
3301 \end_inset
3302 </cell>
3303 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
3304 \begin_inset Text
3306 \begin_layout Plain Layout
3308 \end_layout
3310 \end_inset
3311 </cell>
3312 </row>
3313 </lyxtabular>
3315 \end_inset
3318 \end_layout
3320 \begin_layout Standard
3321 On reflection it seems that sometimes such nesting is not desirable, as
3322  the braces are also used to delimit values that contain commas --- we may
3323  consider that
3324 \end_layout
3326 \begin_layout LyX-Code
3327 name={williamson, freddie}
3328 \end_layout
3330 \begin_layout Standard
3331 should assign 
3332 \begin_inset Flex CharStyle:Code
3333 status collapsed
3335 \begin_layout Plain Layout
3336 williamson, freddie
3337 \end_layout
3339 \end_inset
3341  to 
3342 \begin_inset Flex CharStyle:Code
3343 status collapsed
3345 \begin_layout Plain Layout
3346 name
3347 \end_layout
3349 \end_inset
3351  --- so I may change this behaviour.
3352 \begin_inset Note Note
3353 status collapsed
3355 \begin_layout Plain Layout
3356 So change it
3357 \end_layout
3359 \end_inset
3362 \end_layout
3364 \begin_layout Standard
3365 Function 
3366 \begin_inset Flex Chunkref
3367 status collapsed
3369 \begin_layout Plain Layout
3370 get_chunk_args()
3371 \end_layout
3373 \end_inset
3375  will accept two paramters, 
3376 \begin_inset Flex CharStyle:Code
3377 status collapsed
3379 \begin_layout Plain Layout
3380 text
3381 \end_layout
3383 \end_inset
3385  being the text to parse, and 
3386 \begin_inset Flex CharStyle:Code
3387 status collapsed
3389 \begin_layout Plain Layout
3390 values
3391 \end_layout
3393 \end_inset
3395  being an array to receive the parsed values as described above.
3396  The optional parameter 
3397 \begin_inset Flex CharStyle:Code
3398 status collapsed
3400 \begin_layout Plain Layout
3401 path
3402 \end_layout
3404 \end_inset
3406  is used during recursion to build up the multi-dimensional array path.
3407 \end_layout
3409 \begin_layout Chunk
3410 ./newfangle
3411 \end_layout
3413 \begin_layout Standard
3414 \begin_inset listings
3415 inline false
3416 status open
3418 \begin_layout Plain Layout
3421 \backslash
3422 chunkref{get_chunk_args()}>
3423 \end_layout
3425 \end_inset
3428 \end_layout
3430 \begin_layout Chunk
3431 get_chunk_args()
3432 \end_layout
3434 \begin_layout Standard
3435 \begin_inset listings
3436 inline false
3437 status open
3439 \begin_layout Plain Layout
3441 function get_chunk_args(text, values,
3442 \end_layout
3444 \begin_layout Plain Layout
3446   # optional parameters
3447 \end_layout
3449 \begin_layout Plain Layout
3451   path, # hierarchical precursors
3452 \end_layout
3454 \begin_layout Plain Layout
3456   # local vars
3457 \end_layout
3459 \begin_layout Plain Layout
3461   a, name)
3462 \end_layout
3464 \end_inset
3467 \end_layout
3469 \begin_layout Standard
3470 The strategy is to parse the name, and then look for a value.
3471  If the value begins with a brace 
3472 \begin_inset Flex CharStyle:Code
3473 status collapsed
3475 \begin_layout Plain Layout
3477 \end_layout
3479 \end_inset
3481 , then we recurse and consume as much of the text as necessary, returning
3482  the remaining text when we encounter a leading close-brace 
3483 \begin_inset Flex CharStyle:Code
3484 status collapsed
3486 \begin_layout Plain Layout
3488 \end_layout
3490 \end_inset
3493  This being the strategy --- and executed in a loop --- we realise that
3494  we must first look for the closing brace (perhaps preceded by white space)
3495  in order to terminate the recursion, and returning remaining text.
3496 \end_layout
3498 \begin_layout Standard
3499 \begin_inset listings
3500 inline false
3501 status open
3503 \begin_layout Plain Layout
3506 \end_layout
3508 \begin_layout Plain Layout
3510   while(length(text)) {
3511 \end_layout
3513 \begin_layout Plain Layout
3515     if (match(text, "^ *}(.*)", a)) {
3516 \end_layout
3518 \begin_layout Plain Layout
3520       return a[1];
3521 \end_layout
3523 \begin_layout Plain Layout
3525     }
3526 \end_layout
3528 \begin_layout Plain Layout
3530     =<
3531 \backslash
3532 chunkref{parse-chunk-args}>
3533 \end_layout
3535 \begin_layout Plain Layout
3537   }
3538 \end_layout
3540 \begin_layout Plain Layout
3542   return text;
3543 \end_layout
3545 \begin_layout Plain Layout
3548 \end_layout
3550 \end_inset
3553 \end_layout
3555 \begin_layout Standard
3556 \begin_inset Note Note
3557 status collapsed
3559 \begin_layout Plain Layout
3560 Use BNF package here
3561 \end_layout
3563 \end_inset
3565 We can see that the text could be inspected with this regex:
3566 \end_layout
3568 \begin_layout Chunk
3569 parse-chunk-args
3570 \end_layout
3572 \begin_layout Standard
3573 \begin_inset listings
3574 inline false
3575 status open
3577 \begin_layout Plain Layout
3579 if (! match(text, " *([^,=]*[^,= ]) *(([,=]) *(([^,}]*) *,* *(.*))|)$", a))
3581 \end_layout
3583 \begin_layout Plain Layout
3585   return text;
3586 \end_layout
3588 \begin_layout Plain Layout
3591 \end_layout
3593 \end_inset
3596 \end_layout
3598 \begin_layout Standard
3599 and that 
3600 \begin_inset Flex CharStyle:Code
3601 status collapsed
3603 \begin_layout Plain Layout
3605 \end_layout
3607 \end_inset
3609  will have the following values:
3610 \end_layout
3612 \begin_layout Standard
3613 \begin_inset Tabular
3614 <lyxtabular version="3" rows="7" columns="2">
3615 <features>
3616 <column alignment="center" valignment="top" width="0">
3617 <column alignment="left" valignment="top" width="0">
3618 <row>
3619 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
3620 \begin_inset Text
3622 \begin_layout Plain Layout
3623 a[n]
3624 \end_layout
3626 \end_inset
3627 </cell>
3628 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
3629 \begin_inset Text
3631 \begin_layout Plain Layout
3632 assigned text
3633 \end_layout
3635 \end_inset
3636 </cell>
3637 </row>
3638 <row>
3639 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
3640 \begin_inset Text
3642 \begin_layout Plain Layout
3644 \end_layout
3646 \end_inset
3647 </cell>
3648 <cell alignment="left" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
3649 \begin_inset Text
3651 \begin_layout Plain Layout
3652 freddie
3653 \end_layout
3655 \end_inset
3656 </cell>
3657 </row>
3658 <row>
3659 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
3660 \begin_inset Text
3662 \begin_layout Plain Layout
3664 \end_layout
3666 \end_inset
3667 </cell>
3668 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
3669 \begin_inset Text
3671 \begin_layout Plain Layout
3672 =freddie, foo={bar=baz, quux={quirk, a=fleeg}}, etc
3673 \end_layout
3675 \end_inset
3676 </cell>
3677 </row>
3678 <row>
3679 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
3680 \begin_inset Text
3682 \begin_layout Plain Layout
3684 \end_layout
3686 \end_inset
3687 </cell>
3688 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
3689 \begin_inset Text
3691 \begin_layout Plain Layout
3693 \end_layout
3695 \end_inset
3696 </cell>
3697 </row>
3698 <row>
3699 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
3700 \begin_inset Text
3702 \begin_layout Plain Layout
3704 \end_layout
3706 \end_inset
3707 </cell>
3708 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
3709 \begin_inset Text
3711 \begin_layout Plain Layout
3712 freddie, foo={bar=baz, quux={quirk, a=fleeg}}, etc
3713 \end_layout
3715 \end_inset
3716 </cell>
3717 </row>
3718 <row>
3719 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
3720 \begin_inset Text
3722 \begin_layout Plain Layout
3724 \end_layout
3726 \end_inset
3727 </cell>
3728 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
3729 \begin_inset Text
3731 \begin_layout Plain Layout
3732 freddie
3733 \end_layout
3735 \end_inset
3736 </cell>
3737 </row>
3738 <row>
3739 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
3740 \begin_inset Text
3742 \begin_layout Plain Layout
3744 \end_layout
3746 \end_inset
3747 </cell>
3748 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
3749 \begin_inset Text
3751 \begin_layout Plain Layout
3752 , foo={bar=baz, quux={quirk, a=fleeg}}, etc
3753 \end_layout
3755 \end_inset
3756 </cell>
3757 </row>
3758 </lyxtabular>
3760 \end_inset
3763 \end_layout
3765 \begin_layout Standard
3766 a[3] will be either 
3767 \begin_inset Flex CharStyle:Code
3768 status collapsed
3770 \begin_layout Plain Layout
3772 \end_layout
3774 \end_inset
3776  or 
3777 \begin_inset Flex CharStyle:Code
3778 status collapsed
3780 \begin_layout Plain Layout
3782 \end_layout
3784 \end_inset
3786  and signify whether the option named in 
3787 \begin_inset Flex CharStyle:Code
3788 status collapsed
3790 \begin_layout Plain Layout
3791 a[1]
3792 \end_layout
3794 \end_inset
3796  has a value or not (respectively).
3797 \end_layout
3799 \begin_layout Standard
3800 If the option does have a value, then if the expression 
3801 \begin_inset Flex CharStyle:Code
3802 status collapsed
3804 \begin_layout Plain Layout
3805 substr(a[4],1,1)
3806 \end_layout
3808 \end_inset
3810  returns a brace 
3811 \begin_inset Flex CharStyle:Code
3812 status collapsed
3814 \begin_layout Plain Layout
3816 \end_layout
3818 \end_inset
3820  it will signify that we need to recurse:
3821 \end_layout
3823 \begin_layout Standard
3824 \begin_inset listings
3825 inline false
3826 status open
3828 \begin_layout Plain Layout
3830 name=a[1];
3831 \end_layout
3833 \begin_layout Plain Layout
3835 if (a[3] == "=") {
3836 \end_layout
3838 \begin_layout Plain Layout
3840   if (substr(a[4],1,1) == "{") {
3841 \end_layout
3843 \begin_layout Plain Layout
3845     text = get_chunk_args(substr(a[4],2), values, path name SUBSEP);
3846 \end_layout
3848 \begin_layout Plain Layout
3850   } else {
3851 \end_layout
3853 \begin_layout Plain Layout
3855     values[path name]=a[5];
3856 \end_layout
3858 \begin_layout Plain Layout
3860     text = a[6];
3861 \end_layout
3863 \begin_layout Plain Layout
3865   }
3866 \end_layout
3868 \begin_layout Plain Layout
3870 } else {
3871 \end_layout
3873 \begin_layout Plain Layout
3875   values[path name]="";
3876 \end_layout
3878 \begin_layout Plain Layout
3880   text = a[2];
3881 \end_layout
3883 \begin_layout Plain Layout
3886 \end_layout
3888 \end_inset
3891 \end_layout
3893 \begin_layout Standard
3894 We can test this function like this:
3895 \end_layout
3897 \begin_layout Chunk
3898 gca-test.awk
3899 \end_layout
3901 \begin_layout Standard
3902 \begin_inset listings
3903 inline false
3904 status open
3906 \begin_layout Plain Layout
3909 \backslash
3910 chunkref{get_chunk_args()}>
3911 \end_layout
3913 \begin_layout Plain Layout
3915 BEGIN {
3916 \end_layout
3918 \begin_layout Plain Layout
3920   SUBSEP=".";
3921 \end_layout
3923 \begin_layout Plain Layout
3925 \end_layout
3927 \begin_layout Plain Layout
3929   print get_chunk_args("name=freddie, foo={bar=baz, quux={quirk, a=fleeg}},
3930  etc", a);
3931 \end_layout
3933 \begin_layout Plain Layout
3935   for (b in a) {
3936 \end_layout
3938 \begin_layout Plain Layout
3940     print "a[" b "] => " a[b];
3941 \end_layout
3943 \begin_layout Plain Layout
3945   }
3946 \end_layout
3948 \begin_layout Plain Layout
3951 \end_layout
3953 \end_inset
3956 \end_layout
3958 \begin_layout Standard
3959 which should give this output:
3960 \end_layout
3962 \begin_layout Chunk
3963 gca-test.awk-results
3964 \end_layout
3966 \begin_layout Standard
3967 \begin_inset listings
3968 inline false
3969 status open
3971 \begin_layout Plain Layout
3973 a[foo.quux.quirk] => 
3974 \end_layout
3976 \begin_layout Plain Layout
3978 a[foo.quux.a] => fleeg
3979 \end_layout
3981 \begin_layout Plain Layout
3983 a[foo.bar] => baz
3984 \end_layout
3986 \begin_layout Plain Layout
3988 a[etc] => 
3989 \end_layout
3991 \begin_layout Plain Layout
3993 a[name] => freddie
3994 \end_layout
3996 \end_inset
3999 \end_layout
4001 \begin_layout Chapter
4002 Expanding chunk arguments
4003 \end_layout
4005 \begin_layout Standard
4006 \begin_inset CommandInset label
4007 LatexCommand label
4008 name "cha:Chunk Arguments"
4010 \end_inset
4013 \begin_inset Note Note
4014 status open
4016 \begin_layout Plain Layout
4017 Explain this in the documentation section too
4018 \end_layout
4020 \end_inset
4022 As an extension to many literate-programming styles, newfangle permits code
4023  chunks to take parameters and thus operate somewhat like C pre-processor
4024  macros, or like C++ templates.
4025 \end_layout
4027 \begin_layout Standard
4028 Chunk parameters are declared with a chunk argument called 
4029 \begin_inset Flex CharStyle:Code
4030 status collapsed
4032 \begin_layout Plain Layout
4033 params
4034 \end_layout
4036 \end_inset
4038 , which holds a semi-colon separated list of parameters, like this:
4039 \end_layout
4041 \begin_layout LyX-Code
4042 achunk,language=C,params=name;address
4043 \end_layout
4045 \begin_layout Standard
4046 When such a chunk is included the arguments are expressed thus, in square
4047  brackets as optional arguments separated by a comma
4048 \begin_inset Note Note
4049 status open
4051 \begin_layout Plain Layout
4052 We ought to support qouting in {} like ({Jones, John}, Jones@example.com)
4053 \end_layout
4055 \end_inset
4058 \end_layout
4060 \begin_layout LyX-Code
4062 \backslash
4063 chunkref{achunk}(John Jones, jones@example.com)
4064 \end_layout
4066 \begin_layout Standard
4067 Within the body a chunk, parameters are expressed as: 
4068 \begin_inset Flex CharStyle:Code
4069 status collapsed
4071 \begin_layout Plain Layout
4072 ${name}
4073 \end_layout
4075 \end_inset
4077  and 
4078 \begin_inset Flex CharStyle:Code
4079 status collapsed
4081 \begin_layout Plain Layout
4082 ${address}
4083 \end_layout
4085 \end_inset
4088  There is a strong case that a LaTeX style notation should be used, like
4090 \backslash
4091 param{name} --- =<
4092 \backslash
4093 param{name}> as it would appear in the lstlisting.
4094  Such notation would make me go blind, but I do intend to adopt it.
4095 \end_layout
4097 \begin_layout Standard
4098 We therefore need a function 
4099 \begin_inset Flex CharStyle:Code
4100 status collapsed
4102 \begin_layout Plain Layout
4103 expand_chunk_args
4104 \end_layout
4106 \end_inset
4108  which will take a block of text, a list of permitted parameters and the
4109  arguments which must substitute for the parameters.
4110  We also need to be able to parse a parameter list into an array of parameters.
4111 \end_layout
4113 \begin_layout Section
4114 Parsing argument lists
4115 \end_layout
4117 \begin_layout Standard
4118 An argument list may be as simple as in 
4119 \begin_inset Flex CharStyle:Code
4120 status collapsed
4122 \begin_layout Plain Layout
4124 \backslash
4125 chunkref{pull}(thing, otherthing)
4126 \end_layout
4128 \end_inset
4130  or as complex as:
4131 \end_layout
4133 \begin_layout LyX-Code
4135 \backslash
4136 chunkref{pull}(things[x, y], get_other_things(a, "all")) 
4137 \end_layout
4139 \begin_layout Standard
4140 --- which for all it's commas and quotes and parenthesis represents only
4141  two parameters.
4142 \end_layout
4144 \begin_layout Standard
4145 How do we stop the comma in 
4146 \begin_inset Flex CharStyle:Code
4147 status collapsed
4149 \begin_layout Plain Layout
4150 things[x,y]
4151 \end_layout
4153 \end_inset
4155  from splitting it into two arguments 
4156 \begin_inset Flex CharStyle:Code
4157 status collapsed
4159 \begin_layout Plain Layout
4160 things[x
4161 \end_layout
4163 \end_inset
4165  and 
4166 \begin_inset Flex CharStyle:Code
4167 status collapsed
4169 \begin_layout Plain Layout
4171 \end_layout
4173 \end_inset
4175 --- neither of which make sense on their own? 
4176 \end_layout
4178 \begin_layout Standard
4179 One way it could be done is by refusing to split text between maching delimiters
4180 , such as 
4181 \begin_inset Flex CharStyle:Code
4182 status collapsed
4184 \begin_layout Plain Layout
4186 \end_layout
4188 \end_inset
4191 \begin_inset Flex CharStyle:Code
4192 status collapsed
4194 \begin_layout Plain Layout
4196 \end_layout
4198 \end_inset
4201 \begin_inset Flex CharStyle:Code
4202 status collapsed
4204 \begin_layout Plain Layout
4206 \end_layout
4208 \end_inset
4211 \begin_inset Flex CharStyle:Code
4212 status collapsed
4214 \begin_layout Plain Layout
4216 \end_layout
4218 \end_inset
4221 \begin_inset Flex CharStyle:Code
4222 status collapsed
4224 \begin_layout Plain Layout
4226 \end_layout
4228 \end_inset
4231 \begin_inset Flex CharStyle:Code
4232 status collapsed
4234 \begin_layout Plain Layout
4236 \end_layout
4238 \end_inset
4240 and most likely also 
4241 \begin_inset Flex CharStyle:Code
4242 status collapsed
4244 \begin_layout Plain Layout
4246 \end_layout
4248 \end_inset
4251 \begin_inset Flex CharStyle:Code
4252 status collapsed
4254 \begin_layout Plain Layout
4256 \end_layout
4258 \end_inset
4260  and 
4261 \begin_inset Flex CharStyle:Code
4262 status collapsed
4264 \begin_layout Plain Layout
4266 \end_layout
4268 \end_inset
4271 \begin_inset Flex CharStyle:Code
4272 status collapsed
4274 \begin_layout Plain Layout
4276 \end_layout
4278 \end_inset
4281  Of course this also makes it impossible to pass such mis-matched code fragments
4282  as parameters, but I don't think users could cope with people passing such
4283  code unbalanced fragments as chunk parameters
4284 \begin_inset Foot
4285 status collapsed
4287 \begin_layout Plain Layout
4288 I know that I couldn't cope with users doing such things, and although the
4289  GPL3 license prevents me from actually forbidding anyone from trying, if
4290  they wan't it to work they'll have to write the code themselves and not
4291  expect any support from me.
4292 \end_layout
4294 \end_inset
4297 \end_layout
4299 \begin_layout Standard
4300 Unfortunately, the full set of matching delimiters may vary from language
4301  to language.
4302  In certain C++ template contexts, 
4303 \begin_inset Flex CharStyle:Code
4304 status collapsed
4306 \begin_layout Plain Layout
4308 \end_layout
4310 \end_inset
4312  and 
4313 \begin_inset Flex CharStyle:Code
4314 status collapsed
4316 \begin_layout Plain Layout
4318 \end_layout
4320 \end_inset
4322  would count as delimiters, and yet in other contexts they would not.
4323 \end_layout
4325 \begin_layout Standard
4326 This puts me in the unfortunate position of having to parse-somewhat all
4327  programming languages without knowing what they are! Eventually this will
4328  be managed in the chunk modes in chapter 
4329 \begin_inset CommandInset ref
4330 LatexCommand ref
4331 reference "cha:modes"
4333 \end_inset
4336 \end_layout
4338 \begin_layout Standard
4339 Another way, inspired by LaTeX, is if the first character of the parameter
4340  is an opening-delimiter, to read up to the matching closing-delimiter wthout
4341  considering intervening commas; thus the above example could be expressed:
4342 \end_layout
4344 \begin_layout LyX-Code
4346 \backslash
4347 chunkref{pull}({things[x, y]}, [get_other_things(a, "all")])
4348 \end_layout
4350 \begin_layout Standard
4351 --- using 
4352 \begin_inset Flex CharStyle:Code
4353 status collapsed
4355 \begin_layout Plain Layout
4357 \end_layout
4359 \end_inset
4362 \begin_inset Flex CharStyle:Code
4363 status collapsed
4365 \begin_layout Plain Layout
4367 \end_layout
4369 \end_inset
4371  to wrap the first agument, and 
4372 \begin_inset Flex CharStyle:Code
4373 status collapsed
4375 \begin_layout Plain Layout
4377 \end_layout
4379 \end_inset
4382 \begin_inset Flex CharStyle:Code
4383 status collapsed
4385 \begin_layout Plain Layout
4387 \end_layout
4389 \end_inset
4391 to wrap the second argument and protect the comma.
4392 \end_layout
4394 \begin_layout Standard
4395 In the meantime, I'll work with the first method, and a fixed list of delimiters.
4396 \end_layout
4398 \begin_layout Standard
4399 -------
4400 \end_layout
4402 \begin_layout Chunk
4403 parse_chunk_args
4404 \end_layout
4406 \begin_layout Standard
4407 \begin_inset listings
4408 inline false
4409 status open
4411 \begin_layout Plain Layout
4413 function parse_chunk_args(text, values,
4414 \end_layout
4416 \begin_layout Plain Layout
4418   # optional parameters
4419 \end_layout
4421 \begin_layout Plain Layout
4423   path, # hierarchical precursors
4424 \end_layout
4426 \begin_layout Plain Layout
4428   stack, # delimiters to be matched
4429 \end_layout
4431 \begin_layout Plain Layout
4433   delimiters,
4434 \end_layout
4436 \begin_layout Plain Layout
4438   # local vars
4439 \end_layout
4441 \begin_layout Plain Layout
4443   a, name)
4444 \end_layout
4446 \begin_layout Plain Layout
4449 \end_layout
4451 \begin_layout Plain Layout
4453   split(chunklet_parts[2], call_chunk_args, " *, *");
4454 \end_layout
4456 \begin_layout Plain Layout
4459 \end_layout
4461 \end_inset
4464 \end_layout
4466 \begin_layout Standard
4467 The strategy is to parse the name, and then look for a value.
4468  If the value begins with a brace 
4469 \begin_inset Flex CharStyle:Code
4470 status collapsed
4472 \begin_layout Plain Layout
4474 \end_layout
4476 \end_inset
4478 , then we recurse and consume as much of the text as necessary, returning
4479  the remaining text when we encounter a leading close-brace 
4480 \begin_inset Flex CharStyle:Code
4481 status collapsed
4483 \begin_layout Plain Layout
4485 \end_layout
4487 \end_inset
4490  This being the strategy --- and executed in a loop --- we realise that
4491  we must first look for the closing brace (perhaps preceded by white space)
4492  in order to terminate the recursion, and returning remaining text.
4493 \end_layout
4495 \begin_layout Standard
4496 \begin_inset listings
4497 inline false
4498 status open
4500 \begin_layout Plain Layout
4503 \end_layout
4505 \begin_layout Plain Layout
4507   modes["
4508 \backslash
4509 "", "delimiters" ]="
4510 \backslash
4511 "" "|
4512 \backslash
4514 \end_layout
4516 \begin_layout Plain Layout
4518   modes["
4519 \backslash
4520 "", "terminators"]="
4521 \backslash
4523 \end_layout
4525 \begin_layout Plain Layout
4527   modes["{",  "delimiters" ]="
4528 \backslash
4530 \backslash
4532 \backslash
4533 "|{|}|(|)|
4534 \backslash
4536 \backslash
4538 \backslash
4540 \backslash
4541 ]|'|/*" "|}";
4542 \end_layout
4544 \begin_layout Plain Layout
4546   modes["{",  "terminators"]="}";
4547 \end_layout
4549 \begin_layout Plain Layout
4551   modes["[",  "delimiters" ]="
4552 \backslash
4554 \backslash
4556 \backslash
4557 "|{|}|(|)|
4558 \backslash
4560 \backslash
4562 \backslash
4564 \backslash
4565 ]|'|/*" "|
4566 \backslash
4568 \backslash
4570 \end_layout
4572 \begin_layout Plain Layout
4574   modes["[",  "terminators"]="]";
4575 \end_layout
4577 \begin_layout Plain Layout
4579   modes["(",  "delimiters" ]="
4580 \backslash
4582 \backslash
4584 \backslash
4585 "|{|}|(|)|
4586 \backslash
4588 \backslash
4590 \backslash
4592 \backslash
4593 ]|'|/*" "|)";
4594 \end_layout
4596 \begin_layout Plain Layout
4598   modes["(",  "terminators"]=")";
4599 \end_layout
4601 \begin_layout Plain Layout
4603   modes["'",  "delimiters" ]="
4604 \backslash
4606 \backslash
4608 \end_layout
4610 \begin_layout Plain Layout
4612   modes["'",  "terminators"]="'";
4613 \end_layout
4615 \begin_layout Plain Layout
4617   modes["/*", "terminators"]="*/";
4618 \end_layout
4620 \begin_layout Plain Layout
4622   modes["//", "terminators"]="
4623 \backslash
4625 \end_layout
4627 \begin_layout Plain Layout
4629   modes["",   "delimiters" ]="
4630 \backslash
4632 \backslash
4634 \backslash
4635 "|{|}|(|)|
4636 \backslash
4638 \backslash
4640 \backslash
4642 \backslash
4643 ]|'|/*";
4644 \end_layout
4646 \begin_layout Plain Layout
4648   mode="";
4649 \end_layout
4651 \begin_layout Plain Layout
4653 \end_layout
4655 \begin_layout Plain Layout
4657   delimiters=modes[mode, "delimiters"];
4658 \end_layout
4660 \begin_layout Plain Layout
4662 \end_layout
4664 \begin_layout Plain Layout
4666   while(length(text)) {
4667 \end_layout
4669 \begin_layout Plain Layout
4671     if match(text, "(" delimiters ")", a) {
4672 \end_layout
4674 \begin_layout Plain Layout
4676       if (a[1] == modes[mode, "terminator"]) return result a[1];
4677 \end_layout
4679 \begin_layout Plain Layout
4681       new_mode=a[1];
4682 \end_layout
4684 \begin_layout Plain Layout
4686       #check if new_mode is defined
4687 \end_layout
4689 \begin_layout Plain Layout
4691       if (! (new_mode, "terminators") in modes) {
4692 \end_layout
4694 \begin_layout Plain Layout
4696         error("Delimiter %s set unknown mode in text: %s", new_mode, text);
4697 \end_layout
4699 \begin_layout Plain Layout
4701       }
4702 \end_layout
4704 \begin_layout Plain Layout
4706       text = substr(text, RSTART));
4707 \end_layout
4709 \begin_layout Plain Layout
4711       result = result substr(text, 1, RSTART -1) RECURSE(text,,new_mode);
4712 \end_layout
4714 \begin_layout Plain Layout
4716     }
4717 \end_layout
4719 \begin_layout Plain Layout
4721     result = result text;
4722 \end_layout
4724 \begin_layout Plain Layout
4726     text = "";
4727 \end_layout
4729 \begin_layout Plain Layout
4731   }
4732 \end_layout
4734 \begin_layout Plain Layout
4736   return result;
4737 \end_layout
4739 \begin_layout Plain Layout
4742 \end_layout
4744 \end_inset
4747 \end_layout
4749 \begin_layout Standard
4750 We can test this function like this:
4751 \end_layout
4753 \begin_layout Chunk
4754 pca-test.awk
4755 \end_layout
4757 \begin_layout Standard
4758 \begin_inset listings
4759 inline false
4760 status open
4762 \begin_layout Plain Layout
4765 \backslash
4766 chunkref{get_chunk_args()}>
4767 \end_layout
4769 \begin_layout Plain Layout
4771 BEGIN {
4772 \end_layout
4774 \begin_layout Plain Layout
4776   SUBSEP=".";
4777 \end_layout
4779 \begin_layout Plain Layout
4781 \end_layout
4783 \begin_layout Plain Layout
4785   print parse_chunk_args("things[x, y], get_other_things(a, 
4786 \backslash
4787 "all
4788 \backslash
4789 ")", a);
4790 \end_layout
4792 \begin_layout Plain Layout
4794   for (b in a) {
4795 \end_layout
4797 \begin_layout Plain Layout
4799     print "a[" b "] => " a[b];
4800 \end_layout
4802 \begin_layout Plain Layout
4804   }
4805 \end_layout
4807 \begin_layout Plain Layout
4810 \end_layout
4812 \end_inset
4815 \end_layout
4817 \begin_layout Standard
4818 which should give this output:
4819 \end_layout
4821 \begin_layout Chunk
4822 pca-test.awk-results
4823 \end_layout
4825 \begin_layout Standard
4826 \begin_inset listings
4827 inline false
4828 status open
4830 \begin_layout Plain Layout
4832 a[foo.quux.quirk] => 
4833 \end_layout
4835 \begin_layout Plain Layout
4837 a[foo.quux.a] => fleeg
4838 \end_layout
4840 \begin_layout Plain Layout
4842 a[foo.bar] => baz
4843 \end_layout
4845 \begin_layout Plain Layout
4847 a[etc] => 
4848 \end_layout
4850 \begin_layout Plain Layout
4852 a[name] => freddie
4853 \end_layout
4855 \end_inset
4858 \end_layout
4860 \begin_layout Section
4861 Expanding parameters
4862 \end_layout
4864 \begin_layout Standard
4865 \begin_inset CommandInset label
4866 LatexCommand label
4867 name "Here-we-split"
4869 \end_inset
4871 Here we split the text on 
4872 \begin_inset Flex CharStyle:Code
4873 status collapsed
4875 \begin_layout Plain Layout
4877 \end_layout
4879 \end_inset
4881  which means that all parts except the first will begin with a parameter
4882  name.
4883  The split function will consume the literal 
4884 \begin_inset Flex CharStyle:Code
4885 status collapsed
4887 \begin_layout Plain Layout
4889 \end_layout
4891 \end_inset
4893  in each case.
4894 \end_layout
4896 \begin_layout Chunk
4897 expand_chunk_args()
4898 \end_layout
4900 \begin_layout Standard
4901 \begin_inset listings
4902 inline false
4903 status open
4905 \begin_layout Plain Layout
4907 function expand_chunk_args(text, params, args,  
4908 \end_layout
4910 \begin_layout Plain Layout
4912   p, text_array, next_text, v, t, l)
4913 \end_layout
4915 \begin_layout Plain Layout
4918 \end_layout
4920 \begin_layout Plain Layout
4922   if (split(text, text_array, "
4923 \backslash
4925 \backslash
4926 ${")) {
4927 \end_layout
4929 \begin_layout Plain Layout
4931     =<
4932 \backslash
4933 chunkref{substitute-chunk-args}>
4934 \end_layout
4936 \begin_layout Plain Layout
4938   }
4939 \end_layout
4941 \begin_layout Plain Layout
4943   return text;
4944 \end_layout
4946 \begin_layout Plain Layout
4949 \end_layout
4951 \end_inset
4954 \end_layout
4956 \begin_layout Standard
4957 First, we produce an associative array of substitution values indexed by
4958  parameter names
4959 \end_layout
4961 \begin_layout Chunk
4962 substitute-chunk-args
4963 \end_layout
4965 \begin_layout Standard
4966 \begin_inset listings
4967 inline false
4968 status open
4970 \begin_layout Plain Layout
4972 for(p in params) {
4973 \end_layout
4975 \begin_layout Plain Layout
4977   v[params[p]]=args[p];
4978 \end_layout
4980 \begin_layout Plain Layout
4983 \end_layout
4985 \end_inset
4988 \end_layout
4990 \begin_layout Standard
4991 We accumulate substituted text in the variable 
4992 \begin_inset Flex CharStyle:Code
4993 status collapsed
4995 \begin_layout Plain Layout
4996 text
4997 \end_layout
4999 \end_inset
5002  As the first part of the split function is the part before the delimiter
5003  --- which is 
5004 \begin_inset Flex CharStyle:Code
5005 status collapsed
5007 \begin_layout Plain Layout
5009 \end_layout
5011 \end_inset
5013  in our case --- this part will never contain a parameter reference, so
5014  we assign this directly to the result kept in 
5015 \begin_inset Flex CharStyle:Code
5016 status collapsed
5018 \begin_layout Plain Layout
5019 $text
5020 \end_layout
5022 \end_inset
5025 \begin_inset listings
5026 inline false
5027 status open
5029 \begin_layout Plain Layout
5031 text=text_array[1];
5032 \end_layout
5034 \end_inset
5037 \end_layout
5039 \begin_layout Standard
5040 We then iterate over the remaining values in the array
5041 \begin_inset Foot
5042 status collapsed
5044 \begin_layout Plain Layout
5045 I don't know why I think that it will enumerate the array in order, but
5046  it seems to work
5047 \end_layout
5049 \end_inset
5052 \begin_inset Note Note
5053 status collapsed
5055 \begin_layout Plain Layout
5056 So fix it or porve it
5057 \end_layout
5059 \end_inset
5061 , and substitute each reference for it's argument.
5062 \end_layout
5064 \begin_layout Standard
5065 \begin_inset listings
5066 inline false
5067 status open
5069 \begin_layout Plain Layout
5071 for(t in text_array) if (t>1) {
5072 \end_layout
5074 \begin_layout Plain Layout
5076   =<
5077 \backslash
5078 chunkref{substitute-chunk-arg}>
5079 \end_layout
5081 \begin_layout Plain Layout
5084 \end_layout
5086 \end_inset
5089 \end_layout
5091 \begin_layout Standard
5092 After the split on 
5093 \begin_inset Flex CharStyle:Code
5094 status collapsed
5096 \begin_layout Plain Layout
5098 \end_layout
5100 \end_inset
5102  a valid parameter reference will consist of valid parameter name terminated
5103  by a close-brace 
5104 \begin_inset Flex CharStyle:Code
5105 status collapsed
5107 \begin_layout Plain Layout
5109 \end_layout
5111 \end_inset
5114  A valid character name begins with the underscore or a letter, and may
5115  contain letters, digits or underscores.
5116 \end_layout
5118 \begin_layout Standard
5119 A valid looking reference that is not actually the name of a parameter will
5120  be and not substituted.
5121  This is good because there is nothing to substitute anyway, and it avoids
5122  clashes when writing code for languages where ${\SpecialChar \ldots{}
5123 } is a valid construct
5124  --- such constructs will not be interfered with unless the parameter name
5125  also matches.
5126 \end_layout
5128 \begin_layout Chunk
5129 substitute-chunk-arg
5130 \end_layout
5132 \begin_layout Standard
5133 \begin_inset listings
5134 inline false
5135 status open
5137 \begin_layout Plain Layout
5139 if (match(text_array[t], "^([a-zA-Z_][a-zA-Z0-9_]*)}", l) &&
5140 \end_layout
5142 \begin_layout Plain Layout
5144     l[1] in v) 
5145 \end_layout
5147 \begin_layout Plain Layout
5150 \end_layout
5152 \begin_layout Plain Layout
5154   text = text v[l[1]] substr(text_array[t], length(l[1])+2);
5155 \end_layout
5157 \begin_layout Plain Layout
5159 } else {
5160 \end_layout
5162 \begin_layout Plain Layout
5164   text = text "${" text_array[t];
5165 \end_layout
5167 \begin_layout Plain Layout
5170 \end_layout
5172 \end_inset
5175 \end_layout
5177 \begin_layout Chapter
5178 Recognizing Chunks
5179 \end_layout
5181 \begin_layout Standard
5182 Newfangle recognizes noweb chunks, but as we also want better LaTeX integration
5183  we will recognize any of these:
5184 \end_layout
5186 \begin_layout Itemize
5187 notangle chunks matching the pattern 
5188 \begin_inset Flex CharStyle:Code
5189 status collapsed
5191 \begin_layout Plain Layout
5193 \begin_inset space \hspace*{}
5194 \length 0in
5195 \end_inset
5197 <.*?>
5198 \begin_inset space \hspace*{}
5199 \length 0in
5200 \end_inset
5203 \end_layout
5205 \end_inset
5208 \end_layout
5210 \begin_layout Itemize
5211 a chunks beginning with 
5212 \begin_inset Flex CharStyle:Code
5213 status collapsed
5215 \begin_layout Plain Layout
5217 \backslash
5218 begin{lstlistings}
5219 \end_layout
5221 \end_inset
5223 , possibly with 
5224 \backslash
5225 Chunk{\SpecialChar \ldots{}
5226 } on the previous line
5227 \end_layout
5229 \begin_layout Itemize
5230 an older form I have used, beginning with 
5231 \begin_inset Flex CharStyle:Code
5232 status collapsed
5234 \begin_layout Plain Layout
5236 \backslash
5237 begin{Chunk}[options]
5238 \end_layout
5240 \end_inset
5242  --- also more suitable for plain LaTeX users
5243 \begin_inset Foot
5244 status collapsed
5246 \begin_layout Plain Layout
5247 Is there such a thing as plain LaTeX?
5248 \end_layout
5250 \end_inset
5253 \end_layout
5255 \begin_layout Section
5256 Chunk start
5257 \end_layout
5259 \begin_layout Standard
5260 The variable 
5261 \begin_inset Flex CharStyle:Code
5262 status collapsed
5264 \begin_layout Plain Layout
5265 chunking
5266 \end_layout
5268 \end_inset
5270  is used to signify that we are processing a code chunk and not document.
5271  In such a state, input lines will be assigned to the current chunk; otherwise
5272  they are ignored.
5273 \end_layout
5275 \begin_layout Subsection
5276 lstlistings
5277 \end_layout
5279 \begin_layout Standard
5280 Our current scheme is to recognize the new lstlisting chunks, but these
5281  may be preceded by a 
5282 \begin_inset Flex CharStyle:Code
5283 status collapsed
5285 \begin_layout Plain Layout
5287 \backslash
5288 Chunk
5289 \end_layout
5291 \end_inset
5293  command which in LyX is a more convenient way to pass the chunk name to
5294  the 
5295 \begin_inset Flex CharStyle:Code
5296 status collapsed
5298 \begin_layout Plain Layout
5300 \backslash
5301 begin{lstlistings}
5302 \end_layout
5304 \end_inset
5306  command, and a more visible way to specify other 
5307 \begin_inset Flex CharStyle:Code
5308 status collapsed
5310 \begin_layout Plain Layout
5311 lstset
5312 \end_layout
5314 \end_inset
5316  settings.
5317 \end_layout
5319 \begin_layout Standard
5320 The arguments to the 
5321 \begin_inset Flex CharStyle:Code
5322 status collapsed
5324 \begin_layout Plain Layout
5326 \backslash
5327 Chunk
5328 \end_layout
5330 \end_inset
5332  command are a name, and then a comma-seperated list of key-value pairs
5333  after the manner of 
5334 \begin_inset Flex CharStyle:Code
5335 status collapsed
5337 \begin_layout Plain Layout
5339 \backslash
5340 lstset
5341 \end_layout
5343 \end_inset
5346  (In fact within the LaTeX 
5347 \begin_inset Flex CharStyle:Code
5348 status collapsed
5350 \begin_layout Plain Layout
5352 \backslash
5353 Chunk
5354 \end_layout
5356 \end_inset
5358  macro (section 
5359 \begin_inset CommandInset ref
5360 LatexCommand ref
5361 reference "sub:The-chunk-command"
5363 \end_inset
5365 ) the text 
5366 \begin_inset Flex CharStyle:Code
5367 status collapsed
5369 \begin_layout Plain Layout
5370 name=
5371 \end_layout
5373 \end_inset
5375  is prefixed to the argument which is then literally passed to 
5376 \begin_inset Flex CharStyle:Code
5377 status collapsed
5379 \begin_layout Plain Layout
5381 \backslash
5382 lstset
5383 \end_layout
5385 \end_inset
5388 \end_layout
5390 \begin_layout Chunk
5391 recognize-chunk
5392 \end_layout
5394 \begin_layout Standard
5395 \begin_inset listings
5396 inline false
5397 status open
5399 \begin_layout Plain Layout
5402 \backslash
5404 \backslash
5405 Chunk{/ {
5406 \end_layout
5408 \begin_layout Plain Layout
5410   if (match($0, "^
5411 \backslash
5413 \backslash
5415 \backslash
5417 \backslash
5418 Chunk{ *([^ ,}]*),?(.*)}", line)) {
5419 \end_layout
5421 \begin_layout Plain Layout
5423     next_chunk_name = line[1];
5424 \end_layout
5426 \begin_layout Plain Layout
5428     get_chunk_args(line[2], next_chunk_args);
5429 \end_layout
5431 \begin_layout Plain Layout
5433   }
5434 \end_layout
5436 \begin_layout Plain Layout
5438   next;
5439 \end_layout
5441 \begin_layout Plain Layout
5444 \end_layout
5446 \end_inset
5449 \end_layout
5451 \begin_layout Standard
5452 We also make a basic attempt to parse the name out of the 
5453 \begin_inset Flex CharStyle:Code
5454 status collapsed
5456 \begin_layout Plain Layout
5458 \backslash
5459 lstlistings[name=
5460 \begin_inset space \hspace{}
5461 \length 0in
5462 \end_inset
5464 chunk-name]
5465 \end_layout
5467 \end_inset
5469  text, otherwise we fall back to the name found in the previous chunk command.
5470  This attempt is very basic and doesn't support commas or spaces or square
5471  brackets as part of the chunkname.
5472  We also recognize 
5473 \begin_inset Flex CharStyle:Code
5474 status collapsed
5476 \begin_layout Plain Layout
5478 \backslash
5479 begin{Chunk}
5480 \end_layout
5482 \end_inset
5484  which is convenient for some users
5485 \begin_inset Foot
5486 status open
5488 \begin_layout Plain Layout
5489 but not yet supported in the LaTeX macros
5490 \end_layout
5492 \end_inset
5495 \begin_inset Note Note
5496 status collapsed
5498 \begin_layout Plain Layout
5499 Add noweave support
5500 \end_layout
5502 \end_inset
5505 \end_layout
5507 \begin_layout Standard
5508 \begin_inset listings
5509 inline false
5510 status open
5512 \begin_layout Plain Layout
5515 \backslash
5517 \backslash
5518 begin{lstlisting}|^
5519 \backslash
5521 \backslash
5522 begin{Chunk}/ {
5523 \end_layout
5525 \begin_layout Plain Layout
5527   if (match($0, "}.*[[,] *name= *{? *([^], }]*)", line)) {
5528 \end_layout
5530 \begin_layout Plain Layout
5532     new_chunk(line[1]);
5533 \end_layout
5535 \begin_layout Plain Layout
5537   } else {
5538 \end_layout
5540 \begin_layout Plain Layout
5542     new_chunk(next_chunk_name, next_chunk_args);
5543 \end_layout
5545 \begin_layout Plain Layout
5547   }
5548 \end_layout
5550 \begin_layout Plain Layout
5552   chunking=1;
5553 \end_layout
5555 \begin_layout Plain Layout
5557   next;
5558 \end_layout
5560 \begin_layout Plain Layout
5563 \end_layout
5565 \end_inset
5568 \end_layout
5570 \begin_layout Subsection
5571 Noweb
5572 \end_layout
5574 \begin_layout Standard
5575 We recognize notangle style chunks too:
5576 \end_layout
5578 \begin_layout Chunk
5579 recognize-chunk
5580 \end_layout
5582 \begin_layout Standard
5583 \begin_inset listings
5584 inline false
5585 status open
5587 \begin_layout Plain Layout
5589 /^[<]<.*[>]>=/ {
5590 \end_layout
5592 \begin_layout Plain Layout
5594   if (match($0, "^[<]<(.*)[>]>= *$", line)) {
5595 \end_layout
5597 \begin_layout Plain Layout
5599     chunking=1;
5600 \end_layout
5602 \begin_layout Plain Layout
5604     notangle_mode=1;
5605 \end_layout
5607 \begin_layout Plain Layout
5609     new_chunk(line[1]);
5610 \end_layout
5612 \begin_layout Plain Layout
5614     next;
5615 \end_layout
5617 \begin_layout Plain Layout
5619   }
5620 \end_layout
5622 \begin_layout Plain Layout
5625 \end_layout
5627 \end_inset
5630 \end_layout
5632 \begin_layout Section
5633 Chunk end
5634 \end_layout
5636 \begin_layout Standard
5637 Likewise, we need to recognize when a chunk ends.
5638 \end_layout
5640 \begin_layout Subsection
5641 lstlistings
5642 \end_layout
5644 \begin_layout Standard
5645 The 
5646 \begin_inset Flex CharStyle:Code
5647 status collapsed
5649 \begin_layout Plain Layout
5651 \end_layout
5653 \end_inset
5655  in 
5656 \begin_inset Flex CharStyle:Code
5657 status collapsed
5659 \begin_layout Plain Layout
5660 [e]end{lislisting}
5661 \end_layout
5663 \end_inset
5665  is surrounded by square brackets so that when this document is processed,
5666  this chunk doesn't terminate early when the lstlistings package recognizes
5667  it's own end-string! 
5668 \begin_inset Note Greyedout
5669 status collapsed
5671 \begin_layout Plain Layout
5672 This doesn't make sense as the regex is anchored with ^, which this line
5673  does not begin with!
5674 \end_layout
5676 \end_inset
5679 \begin_inset Note Note
5680 status open
5682 \begin_layout Plain Layout
5683 No, it doesn't.
5684 \end_layout
5686 \end_inset
5689 \end_layout
5691 \begin_layout Chunk
5692 recognize-chunk
5693 \end_layout
5695 \begin_layout Standard
5696 \begin_inset listings
5697 inline false
5698 status open
5700 \begin_layout Plain Layout
5703 \backslash
5705 \backslash
5706 [e]nd{lstlisting}|^
5707 \backslash
5709 \backslash
5710 [e]nd{Chunk}/ {
5711 \end_layout
5713 \begin_layout Plain Layout
5715   chunking=0;
5716 \end_layout
5718 \begin_layout Plain Layout
5720   active_chunk="";
5721 \end_layout
5723 \begin_layout Plain Layout
5725   next;
5726 \end_layout
5728 \begin_layout Plain Layout
5731 \end_layout
5733 \end_inset
5736 \end_layout
5738 \begin_layout Subsection
5739 noweb
5740 \end_layout
5742 \begin_layout Chunk
5743 recognize-chunk
5744 \end_layout
5746 \begin_layout Standard
5747 \begin_inset listings
5748 inline false
5749 status open
5751 \begin_layout Plain Layout
5753 /^@ *$/ {
5754 \end_layout
5756 \begin_layout Plain Layout
5758   chunking=0;
5759 \end_layout
5761 \begin_layout Plain Layout
5763   active_chunk="";
5764 \end_layout
5766 \begin_layout Plain Layout
5769 \end_layout
5771 \end_inset
5774 \end_layout
5776 \begin_layout Standard
5777 All other recognizers are only of effect if we are chunking; there's no
5778  point in looking at lines if they aren't part of a chunk, so we just ignore
5779  them as efficiently as we can.
5780 \end_layout
5782 \begin_layout Chunk
5783 recognize-chunk
5784 \end_layout
5786 \begin_layout Standard
5787 \begin_inset listings
5788 inline false
5789 status open
5791 \begin_layout Plain Layout
5793 ! chunking { next; }
5794 \end_layout
5796 \end_inset
5799 \end_layout
5801 \begin_layout Section
5802 Chunk contents
5803 \end_layout
5805 \begin_layout Standard
5806 Chunk contents are any lines read while 
5807 \begin_inset Flex CharStyle:Code
5808 status collapsed
5810 \begin_layout Plain Layout
5811 chunking
5812 \end_layout
5814 \end_inset
5816  is true.
5817  Some chunk contents are special in that they refer to other chunks, and
5818  will be replaced by the contents of these chunks when the file is generated.
5819 \end_layout
5821 \begin_layout Standard
5822 \begin_inset CommandInset label
5823 LatexCommand label
5824 name "sub:ORS-chunk-text"
5826 \end_inset
5828 We add the output record separator 
5829 \begin_inset Flex CharStyle:Code
5830 status collapsed
5832 \begin_layout Plain Layout
5834 \end_layout
5836 \end_inset
5838  to the line now, because we will set 
5839 \begin_inset Flex CharStyle:Code
5840 status collapsed
5842 \begin_layout Plain Layout
5844 \end_layout
5846 \end_inset
5848  to the empty string when we generate the output
5849 \begin_inset Foot
5850 status collapsed
5852 \begin_layout Plain Layout
5853 So that we can print partial lines using 
5854 \begin_inset Flex CharStyle:Code
5855 status collapsed
5857 \begin_layout Plain Layout
5858 print
5859 \end_layout
5861 \end_inset
5863  instead of 
5864 \begin_inset Flex CharStyle:Code
5865 status collapsed
5867 \begin_layout Plain Layout
5868 printf
5869 \end_layout
5871 \end_inset
5874 \end_layout
5876 \end_inset
5879 \end_layout
5881 \begin_layout Chunk
5882 recognize-chunk
5883 \end_layout
5885 \begin_layout Standard
5886 \begin_inset listings
5887 inline false
5888 status open
5890 \begin_layout Plain Layout
5892 length(active_chunk) {
5893 \end_layout
5895 \begin_layout Plain Layout
5897   =<
5898 \backslash
5899 chunkref{process-chunk-tabs}>
5900 \end_layout
5902 \begin_layout Plain Layout
5904   =<
5905 \backslash
5906 chunkref{process-chunk}>
5907 \end_layout
5909 \begin_layout Plain Layout
5912 \end_layout
5914 \end_inset
5917 \end_layout
5919 \begin_layout Standard
5920 If a chunk just consisted of plain text, we could handle the chunk like
5921  this:
5922 \end_layout
5924 \begin_layout Chunk
5925 process-chunk-simple
5926 \end_layout
5928 \begin_layout Standard
5929 \begin_inset listings
5930 inline false
5931 status open
5933 \begin_layout Plain Layout
5935 chunk_line(active_chunk, $0 ORS);
5936 \end_layout
5938 \end_inset
5941 \end_layout
5943 \begin_layout Standard
5944 but in fact a chunk can include references to other chunks.
5945  Chunk includes are traditionally written as 
5946 \begin_inset Flex CharStyle:Code
5947 status collapsed
5949 \begin_layout Plain Layout
5950 <<chunk-name>>
5951 \end_layout
5953 \end_inset
5955 , but we support other variations.
5956 \end_layout
5958 \begin_layout Standard
5959 However, we also process tabs at this point, a tab at input can be replaced
5960  by a number of spaces defined by the 
5961 \begin_inset Flex CharStyle:Code
5962 status collapsed
5964 \begin_layout Plain Layout
5965 tabs
5966 \end_layout
5968 \end_inset
5970  variable, set by the 
5971 \begin_inset Flex CharStyle:Code
5972 status collapsed
5974 \begin_layout Plain Layout
5976 \end_layout
5978 \end_inset
5980  option.
5981  Of course this is poor tab behaviour, we should probably have the option
5982  to use proper counted tab-stops and process this on output.
5983 \end_layout
5985 \begin_layout Chunk
5986 process-chunk-tabs
5987 \end_layout
5989 \begin_layout Standard
5990 \begin_inset listings
5991 inline false
5992 status open
5994 \begin_layout Plain Layout
5996 if (length(tabs)) {
5997 \end_layout
5999 \begin_layout Plain Layout
6001   gsub("
6002 \backslash
6003 t", tabs);
6004 \end_layout
6006 \begin_layout Plain Layout
6009 \end_layout
6011 \end_inset
6014 \end_layout
6016 \begin_layout Subsection
6017 \begin_inset CommandInset label
6018 LatexCommand label
6019 name "sub:lstlistings-includes"
6021 \end_inset
6023 lstlistings
6024 \end_layout
6026 \begin_layout Standard
6027 If 
6028 \begin_inset Flex CharStyle:Code
6029 status collapsed
6031 \begin_layout Plain Layout
6033 \backslash
6034 lstset{escapeinside={=<}{>}}
6035 \end_layout
6037 \end_inset
6039  is set, then we can use 
6040 \begin_inset Flex CharStyle:Code
6041 status collapsed
6043 \begin_layout Plain Layout
6045 \backslash
6046 chunkref{
6047 \begin_inset space \hspace{}
6048 \length 0in
6049 \end_inset
6051 chunk-name}>
6052 \end_layout
6054 \end_inset
6056  in listings.
6057  The sequence 
6058 \begin_inset Flex CharStyle:Code
6059 status collapsed
6061 \begin_layout Plain Layout
6063 \end_layout
6065 \end_inset
6067  was chosen because:
6068 \end_layout
6070 \begin_layout Enumerate
6071 it is a better mnemonic than 
6072 \begin_inset Flex CharStyle:Code
6073 status collapsed
6075 \begin_layout Plain Layout
6076 <<chunk-name>>
6077 \end_layout
6079 \end_inset
6081  in that the = sign signifies equivalent or substitutability, 
6082 \end_layout
6084 \begin_layout Enumerate
6085 and because =< is not valid in C or in any language I can think of 
6086 \end_layout
6088 \begin_layout Enumerate
6089 and also because lstlistings doesn't like 
6090 \begin_inset Flex CharStyle:Code
6091 status collapsed
6093 \begin_layout Plain Layout
6095 \end_layout
6097 \end_inset
6099  as an end delimiter for the 
6100 \emph on
6101 texcl
6102 \emph default
6103  escape, so we must make do with a single 
6104 \begin_inset Flex CharStyle:Code
6105 status collapsed
6107 \begin_layout Plain Layout
6109 \end_layout
6111 \end_inset
6113 , which is better matched by 
6114 \begin_inset Flex CharStyle:Code
6115 status collapsed
6117 \begin_layout Plain Layout
6119 \end_layout
6121 \end_inset
6123  than 
6124 \begin_inset Flex CharStyle:Code
6125 status collapsed
6127 \begin_layout Plain Layout
6129 \end_layout
6131 \end_inset
6134 \end_layout
6136 \begin_layout Standard
6137 As each chunk line may contain more than one chunk include, we will split
6138  out chunk includes in an iterative fashion
6139 \begin_inset Foot
6140 status open
6142 \begin_layout Plain Layout
6143 Contrary to our use of 
6144 \begin_inset Flex CharStyle:Code
6145 status collapsed
6147 \begin_layout Plain Layout
6148 split
6149 \end_layout
6151 \end_inset
6153  when substituting parameters in chapter 
6154 \begin_inset CommandInset ref
6155 LatexCommand ref
6156 reference "Here-we-split"
6158 \end_inset
6161 \end_layout
6163 \end_inset
6166 \end_layout
6168 \begin_layout Standard
6169 First, as long as the chunk contains a 
6170 \begin_inset Flex CharStyle:Code
6171 status collapsed
6173 \begin_layout Plain Layout
6175 \backslash
6176 chunkref
6177 \end_layout
6179 \end_inset
6181  command we take as much as we can up to the first 
6182 \begin_inset Flex CharStyle:Code
6183 status collapsed
6185 \begin_layout Plain Layout
6187 \backslash
6188 chunkref
6189 \end_layout
6191 \end_inset
6193  command.
6194 \end_layout
6196 \begin_layout Chunk
6197 process-chunk
6198 \end_layout
6200 \begin_layout Standard
6201 \begin_inset listings
6202 inline false
6203 status open
6205 \begin_layout Plain Layout
6207 chunk = $0;
6208 \end_layout
6210 \begin_layout Plain Layout
6212 indent = 0;
6213 \end_layout
6215 \begin_layout Plain Layout
6217 while(match(chunk, 
6218 \end_layout
6220 \begin_layout Plain Layout
6222             "([=]<
6223 \backslash
6225 \backslash
6227 \backslash
6229 \backslash
6230 chunkref{([^}>]*)}(
6231 \backslash
6233 \backslash
6235 \backslash
6237 \backslash
6238 )|)>|<<([a-zA-Z_][-a-zA-Z0-9_]*)>>)", 
6239 \end_layout
6241 \begin_layout Plain Layout
6243             line)
6244 \backslash
6246 \end_layout
6248 \begin_layout Plain Layout
6250 ) {
6251 \end_layout
6253 \begin_layout Plain Layout
6255   chunklet = substr(chunk, 1, RSTART - 1);
6256 \end_layout
6258 \end_inset
6261 \end_layout
6263 \begin_layout Standard
6264 We keep track of the indent count, by counting the number of literal characters
6265  found.
6266  We can then preserve this indent on each output line when multi-line chunks
6267  are expanded.
6268 \end_layout
6270 \begin_layout Standard
6271 We then process this first part literal text, and set the chunk which is
6272  still to be processed to be the text after the 
6273 \begin_inset Flex CharStyle:Code
6274 status collapsed
6276 \begin_layout Plain Layout
6278 \backslash
6279 chunkref
6280 \end_layout
6282 \end_inset
6284  command, which we will process next as we continue around the loop.
6285 \end_layout
6287 \begin_layout Standard
6288 \begin_inset listings
6289 inline false
6290 status open
6292 \begin_layout Plain Layout
6294   indent += length(chunklet);
6295 \end_layout
6297 \begin_layout Plain Layout
6299   chunk_line(active_chunk, chunklet);
6300 \end_layout
6302 \begin_layout Plain Layout
6304   chunk = substr(chunk, RSTART + RLENGTH);
6305 \end_layout
6307 \end_inset
6310 \end_layout
6312 \begin_layout Standard
6313 We then consider the type of chunk command we have found, whether it is
6314  the newfangle style command beginning with 
6315 \begin_inset Flex CharStyle:Code
6316 status collapsed
6318 \begin_layout Plain Layout
6320 \end_layout
6322 \end_inset
6324  or the older notangle style beginning with 
6325 \begin_inset Flex CharStyle:Code
6326 status collapsed
6328 \begin_layout Plain Layout
6330 \end_layout
6332 \end_inset
6336 \end_layout
6338 \begin_layout Standard
6339 Newfangle chunks may have parameters contained within square brackets.
6340  These will be matched in 
6341 \begin_inset Flex CharStyle:Code
6342 status collapsed
6344 \begin_layout Plain Layout
6345 line[3]
6346 \end_layout
6348 \end_inset
6350  and are considered at this stage of processing to be part of the name of
6351  the chunk to be included.
6352 \end_layout
6354 \begin_layout Standard
6355 \begin_inset listings
6356 inline false
6357 status open
6359 \begin_layout Plain Layout
6361   if (substr(line[1], 1, 1) == "=") {
6362 \end_layout
6364 \begin_layout Plain Layout
6366     # chunk name up to }
6367 \end_layout
6369 \begin_layout Plain Layout
6371     chunk_include(active_chunk, line[2] line[3], indent);
6372 \end_layout
6374 \begin_layout Plain Layout
6376   } else if (substr(line[1], 1, 1) == "<") {
6377 \end_layout
6379 \begin_layout Plain Layout
6381     chunk_include(active_chunk, line[4], indent);
6382 \end_layout
6384 \begin_layout Plain Layout
6386   } else {
6387 \end_layout
6389 \begin_layout Plain Layout
6391     error("Unknown chunk fragment: " line[1]);
6392 \end_layout
6394 \begin_layout Plain Layout
6396   }
6397 \end_layout
6399 \end_inset
6402 \end_layout
6404 \begin_layout Standard
6405 The loop will continue until there are no more chunkref statements in the
6406  text, at which point we process the final part of the chunk.
6407 \end_layout
6409 \begin_layout Standard
6410 \begin_inset listings
6411 inline false
6412 status open
6414 \begin_layout Plain Layout
6417 \end_layout
6419 \begin_layout Plain Layout
6421 chunk_line(active_chunk, chunk);
6422 \end_layout
6424 \end_inset
6427 \end_layout
6429 \begin_layout Standard
6430 \begin_inset CommandInset label
6431 LatexCommand label
6432 name "lone-newline"
6434 \end_inset
6436 We add the newline character as a chunklet on it's own, to make it easier
6437  to detect new lines and thus manage indentation when processing the output.
6438 \end_layout
6440 \begin_layout Standard
6441 \begin_inset listings
6442 inline false
6443 status open
6445 \begin_layout Plain Layout
6447 chunk_line(active_chunk, "
6448 \backslash
6449 n");
6450 \end_layout
6452 \end_inset
6455 \end_layout
6457 \begin_layout Standard
6458 We will also permit a chunk-part number to follow in square brackets, so
6459  that 
6460 \begin_inset Flex CharStyle:Code
6461 status collapsed
6463 \begin_layout Plain Layout
6465 \backslash
6466 chunkref{chunk-name[1]}>
6467 \end_layout
6469 \end_inset
6471  will refer to the first part only.
6472  This can make it easy to include a C function prototype in a header file,
6473  if the first part of the chunk is just the function prototype without the
6474  trailing semi-colon.
6475  The header file would include the prototype with the trailing semi-colon,
6476  like this:
6477 \end_layout
6479 \begin_layout LyX-Code
6481 \backslash
6482 chunkref{chunk-name[1]}>;
6483 \end_layout
6485 \begin_layout Standard
6486 This is handled in section 
6487 \begin_inset CommandInset ref
6488 LatexCommand ref
6489 reference "sub:Chunk-parts"
6491 \end_inset
6494 \end_layout
6496 \begin_layout Standard
6497 We should perhaps introduce a notion of language specific chunk options;
6498  so that perhaps we could specify:
6499 \end_layout
6501 \begin_layout LyX-Code
6503 \backslash
6504 chunkref{chunk-name[function-declaration]}>;
6505 \end_layout
6507 \begin_layout Standard
6508 which applies a transform 
6509 \begin_inset Flex CharStyle:Code
6510 status collapsed
6512 \begin_layout Plain Layout
6513 function-declaration
6514 \end_layout
6516 \end_inset
6518  to the chunk --- which in this case would extract a function prototype
6519  from a function.
6520 \begin_inset Note Note
6521 status open
6523 \begin_layout Plain Layout
6524 So do it
6525 \end_layout
6527 \end_inset
6530 \end_layout
6532 \begin_layout Chapter
6533 Processing Options
6534 \end_layout
6536 \begin_layout Standard
6537 At the start, first we set the default options.
6538 \end_layout
6540 \begin_layout Chunk
6541 default-options
6542 \end_layout
6544 \begin_layout Standard
6545 \begin_inset listings
6546 inline false
6547 status open
6549 \begin_layout Plain Layout
6551 debug=0;
6552 \end_layout
6554 \begin_layout Plain Layout
6556 linenos=0;
6557 \end_layout
6559 \begin_layout Plain Layout
6561 notangle_mode=0;
6562 \end_layout
6564 \begin_layout Plain Layout
6566 SUBSEP=",";
6567 \end_layout
6569 \begin_layout Plain Layout
6571 root="*";
6572 \end_layout
6574 \begin_layout Plain Layout
6576 tabs = "";
6577 \end_layout
6579 \end_inset
6582 \end_layout
6584 \begin_layout Standard
6585 Then we use getopt the standard way, and null out ARGV afterwards in the
6586  normal AWK fashion.
6587 \end_layout
6589 \begin_layout Chunk
6590 read-options
6591 \end_layout
6593 \begin_layout Standard
6594 \begin_inset listings
6595 inline false
6596 status open
6598 \begin_layout Plain Layout
6600 Optind = 1    # skip ARGV[0]
6601 \end_layout
6603 \begin_layout Plain Layout
6605 while(getopt(ARGC, ARGV, "R:LdT:hr")!=-1) {
6606 \end_layout
6608 \begin_layout Plain Layout
6610   =<
6611 \backslash
6612 chunkref{handle-options}>
6613 \end_layout
6615 \begin_layout Plain Layout
6618 \end_layout
6620 \begin_layout Plain Layout
6622 for (i=1; i<Optind; i++) { ARGV[i]=""; }
6623 \end_layout
6625 \end_inset
6628 \end_layout
6630 \begin_layout Standard
6631 This is how we handle our options:
6632 \end_layout
6634 \begin_layout Chunk
6635 handle-options
6636 \end_layout
6638 \begin_layout Standard
6639 \begin_inset listings
6640 inline false
6641 status open
6643 \begin_layout Plain Layout
6645 if (Optopt == "R") root = Optarg;
6646 \end_layout
6648 \begin_layout Plain Layout
6650 else if (Optopt == "r") root="";
6651 \end_layout
6653 \begin_layout Plain Layout
6655 else if (Optopt == "L") linenos = 1;
6656 \end_layout
6658 \begin_layout Plain Layout
6660 else if (Optopt == "d") debug = 1;
6661 \end_layout
6663 \begin_layout Plain Layout
6665 else if (Optopt == "T") tabs = indent_string(Optarg+0);
6666 \end_layout
6668 \begin_layout Plain Layout
6670 else if (Optopt == "h") help();
6671 \end_layout
6673 \begin_layout Plain Layout
6675 else if (Optopt == "?") help();
6676 \end_layout
6678 \end_inset
6681 \end_layout
6683 \begin_layout Standard
6684 We do all of this at the beginning of the program
6685 \end_layout
6687 \begin_layout Chunk
6688 begin
6689 \end_layout
6691 \begin_layout Standard
6692 \begin_inset listings
6693 inline false
6694 status open
6696 \begin_layout Plain Layout
6698 BEGIN {
6699 \end_layout
6701 \begin_layout Plain Layout
6703   =<
6704 \backslash
6705 chunkref{constants}>
6706 \end_layout
6708 \begin_layout Plain Layout
6710   =<
6711 \backslash
6712 chunkref{default-options}>
6713 \end_layout
6715 \begin_layout Plain Layout
6717 \end_layout
6719 \begin_layout Plain Layout
6721   =<
6722 \backslash
6723 chunkref{read-options}>
6724 \end_layout
6726 \begin_layout Plain Layout
6729 \end_layout
6731 \end_inset
6734 \end_layout
6736 \begin_layout Standard
6737 And have a simple help function
6738 \end_layout
6740 \begin_layout Chunk
6741 help()
6742 \end_layout
6744 \begin_layout Standard
6745 \begin_inset listings
6746 inline false
6747 status open
6749 \begin_layout Plain Layout
6751 function help() {
6752 \end_layout
6754 \begin_layout Plain Layout
6756   print "Usage:"
6757 \end_layout
6759 \begin_layout Plain Layout
6761   print "  newfangle [-L] -R<rootname> [source.tex ...]"
6762 \end_layout
6764 \begin_layout Plain Layout
6766   print "  newfangle -r [source.tex ...]"
6767 \end_layout
6769 \begin_layout Plain Layout
6771   print "  If the filename, source.tex is not specified then stdin is used"
6772 \end_layout
6774 \begin_layout Plain Layout
6776   print
6777 \end_layout
6779 \begin_layout Plain Layout
6781   print "-L causes the C statement: #line <lineno> 
6782 \backslash
6783 "filename
6784 \backslash
6785 "" to be issued"
6786 \end_layout
6788 \begin_layout Plain Layout
6790   print "-R causes the named root to be written to stdout"
6791 \end_layout
6793 \begin_layout Plain Layout
6795   print "-r lists all roots in the file (even those used elsewhere)"
6796 \end_layout
6798 \begin_layout Plain Layout
6800   exit 1;
6801 \end_layout
6803 \begin_layout Plain Layout
6806 \end_layout
6808 \end_inset
6811 \end_layout
6813 \begin_layout Chapter
6814 Chunk Language Modes
6815 \end_layout
6817 \begin_layout Standard
6818 \begin_inset CommandInset label
6819 LatexCommand label
6820 name "cha:modes"
6822 \end_inset
6825 \begin_inset Note Greyedout
6826 status open
6828 \begin_layout Plain Layout
6829 This feature is in-development and does not work yet
6830 \end_layout
6832 \end_inset
6835 \begin_inset Note Note
6836 status open
6838 \begin_layout Plain Layout
6839 In Progress!
6840 \end_layout
6842 \end_inset
6845 \end_layout
6847 \begin_layout Standard
6848 lstlistings and newfangle both recognize source languages, and perform some
6849  basic parsing.
6850  lstlistings can detect strings and comments within a language definition
6851  and perform suitable rendering, such as italics for comments, and visible-space
6852 s within strings.
6853 \end_layout
6855 \begin_layout Standard
6856 Newfangle similarly can recognize strings, and comments, etc, within a language,
6857  so that any chunks included with 
6858 \begin_inset Flex CharStyle:Code
6859 status collapsed
6861 \begin_layout Plain Layout
6863 \backslash
6864 chunkref
6865 \end_layout
6867 \end_inset
6869  can be suitably quoted.
6870 \end_layout
6872 \begin_layout Standard
6873 For instance, consider this chunk with 
6874 \begin_inset Flex CharStyle:Code
6875 status collapsed
6877 \begin_layout Plain Layout
6878 language=perl
6879 \end_layout
6881 \end_inset
6884 \end_layout
6886 \begin_layout Chunk
6887 example-perl,language=perl
6888 \end_layout
6890 \begin_layout Standard
6891 \begin_inset listings
6892 inline false
6893 status open
6895 \begin_layout Plain Layout
6897 s/"$/'/;
6898 \end_layout
6900 \end_inset
6903 \end_layout
6905 \begin_layout Standard
6906 If it were included in a chunk with 
6907 \begin_inset Flex CharStyle:Code
6908 status collapsed
6910 \begin_layout Plain Layout
6911 language=sh
6912 \end_layout
6914 \end_inset
6916 , like this:
6917 \end_layout
6919 \begin_layout Chunk
6920 example-sh,language=sh
6921 \end_layout
6923 \begin_layout Standard
6924 \begin_inset listings
6925 inline false
6926 status open
6928 \begin_layout Plain Layout
6930 perl -pe "=<
6931 \backslash
6932 chunkref{example-perl}>"
6933 \end_layout
6935 \end_inset
6938 \end_layout
6940 \begin_layout Standard
6941 would need to generate output like this if it were to work: 
6942 \end_layout
6944 \begin_layout LyX-Code
6945 perl -pe "s/
6946 \backslash
6948 \backslash
6949 $/'/;"
6950 \end_layout
6952 \begin_layout Standard
6953 See that the double quote " as part of the regex has been quoted with a
6954  slash to protect it from shell interpretation.
6955 \end_layout
6957 \begin_layout Standard
6958 If that were then included in a chunk with 
6959 \begin_inset Flex CharStyle:Code
6960 status collapsed
6962 \begin_layout Plain Layout
6963 language=make
6964 \end_layout
6966 \end_inset
6968 , like this:
6969 \end_layout
6971 \begin_layout Chunk
6972 example-makefile,language=make
6973 \end_layout
6975 \begin_layout Standard
6976 \begin_inset listings
6977 inline false
6978 status open
6980 \begin_layout Plain Layout
6982 target: pre-req
6983 \end_layout
6985 \begin_layout Plain Layout
6987                 =<
6988 \backslash
6989 chunkref{example-sh}>
6990 \end_layout
6992 \end_inset
6995 \end_layout
6997 \begin_layout Standard
6998 We would need the output to look like this --- note the $$:
6999 \end_layout
7001 \begin_layout LyX-Code
7002 target: pre-req
7003 \end_layout
7005 \begin_layout LyX-Code
7006         perl -pe "s/
7007 \backslash
7009 \backslash
7010 $$/'/;"
7011 \end_layout
7013 \begin_layout Standard
7014 In order to make this work, we need to define a mode-tracker for each supported
7015  language, that can detect the various quoting modes, and provide a transformati
7016 on that must be applied to any included text so that included text will
7017  be interpreted correctly after the additional interpolation that it will
7018  be subject to at run-time.
7019 \end_layout
7021 \begin_layout Standard
7022 For example, the transformation for text to be inserted into sh double-quoted
7023  strings would be something like:
7024 \end_layout
7026 \begin_layout LyX-Code
7028 \backslash
7030 \backslash
7032 \backslash
7034 \backslash
7036 \backslash
7038 \backslash
7039 /g;s/$/
7040 \backslash
7042 \backslash
7043 $/g;s/"/
7044 \backslash
7046 \backslash
7047 "/g;
7048 \end_layout
7050 \begin_layout Standard
7051 which protects 
7052 \begin_inset Flex CharStyle:Code
7053 status collapsed
7055 \begin_layout Plain Layout
7057 \backslash
7058  $ "
7059 \end_layout
7061 \end_inset
7064 \end_layout
7066 \begin_layout Standard
7067 \begin_inset Note Note
7068 status collapsed
7070 \begin_layout Plain Layout
7071 I don't think this example is true
7072 \end_layout
7074 \end_inset
7076 The mode tracker must also track nested mode-changes, as in this 
7077 \begin_inset Flex CharStyle:Code
7078 status collapsed
7080 \begin_layout Plain Layout
7082 \end_layout
7084 \end_inset
7086  example.
7087 \end_layout
7089 \begin_layout LyX-Code
7090 echo "hello `id **`"
7091 \end_layout
7093 \begin_layout Standard
7094 Any literal text inserted at the point marked ** would need to be escaped
7095  in all kinds of ways, including 
7096 \begin_inset Flex CharStyle:Code
7097 status collapsed
7099 \begin_layout Plain Layout
7100 ` | *
7101 \end_layout
7103 \end_inset
7105  among others.
7106  First it would need escaping for the back-ticks `, and then for the double-quot
7107 es ".
7108 \end_layout
7110 \begin_layout Standard
7111 Escaping need not occur if the format and mode of the included chunk matches
7112  that of the including chunk, which would suggest that any back-ticks might
7113  need to be part of the included chunk and not including chunk
7114 \begin_inset Note Note
7115 status collapsed
7117 \begin_layout Plain Layout
7118 or is it the other way around?
7119 \end_layout
7121 \end_inset
7124 \end_layout
7126 \begin_layout Standard
7127 As each chunk is output a new mode tracker for that language is initialized
7128  in it's normal state.
7129  As text is output for that chunk the output mode is tracked.
7130  When a new chunk is included, a transformation appropriate to that mode
7131  is selected and pushed onto a stack of transformations.
7132  Any text to be output is first passed through this stack of transformations.
7133 \end_layout
7135 \begin_layout Standard
7136 It remains to consider if the chunk-include function should return it's
7137  generated text so that the caller can apply any transformations (and formatting
7138 ), or if it should apply the stack of transformations itself.
7139 \end_layout
7141 \begin_layout Standard
7142 Note that the transformed text should have the property of not being able
7143  to change the mode in the current chunk.
7144 \end_layout
7146 \begin_layout Standard
7147 \begin_inset Note Note
7148 status open
7150 \begin_layout Plain Layout
7151 Note chunk parameters should probably also be transformed
7152 \end_layout
7154 \end_inset
7157 \end_layout
7159 \begin_layout Chunk
7160 new_mode()
7161 \end_layout
7163 \begin_layout Standard
7164 \begin_inset listings
7165 inline false
7166 status open
7168 \begin_layout Plain Layout
7170 function new_mode(language, mode) {
7171 \end_layout
7173 \begin_layout Plain Layout
7175   mode["language"] = language;
7176 \end_layout
7178 \begin_layout Plain Layout
7180   mode["state"]="";
7181 \end_layout
7183 \begin_layout Plain Layout
7186 \end_layout
7188 \end_inset
7191 \end_layout
7193 \begin_layout Standard
7194 Because awk functions cannot return an array, we must create the array first
7195  and pass it in.
7196 \end_layout
7198 \begin_layout Chunk
7199 new-mode,params=language;mode
7200 \end_layout
7202 \begin_layout Standard
7203 \begin_inset listings
7204 inline false
7205 status open
7207 \begin_layout Plain Layout
7210 \backslash
7211 chunkref{awk-delete-array}(${mode})>
7212 \end_layout
7214 \begin_layout Plain Layout
7216 new_mode(${language}, ${mode});
7217 \end_layout
7219 \end_inset
7222 \end_layout
7224 \begin_layout Standard
7225 And for tracking modes, we dispatch to a mode-tracker action based on the
7226  current language
7227 \end_layout
7229 \begin_layout Chunk
7230 track_mode()
7231 \end_layout
7233 \begin_layout Standard
7234 \begin_inset listings
7235 inline false
7236 status open
7238 \begin_layout Plain Layout
7240 function track_mode(mode, text) {
7241 \end_layout
7243 \begin_layout Plain Layout
7245   if (mode["language"] == "C") {
7246 \end_layout
7248 \begin_layout Plain Layout
7250     =<
7251 \backslash
7252 chunkref{track-mode-C}>
7253 \end_layout
7255 \begin_layout Plain Layout
7257     return;
7258 \end_layout
7260 \begin_layout Plain Layout
7262   }
7263 \end_layout
7265 \begin_layout Plain Layout
7268 \end_layout
7270 \end_inset
7273 \end_layout
7275 \begin_layout Standard
7276 For each mode, we look for a character that has the power to change the
7277  mode.
7278 \end_layout
7280 \begin_layout Standard
7281 In plain mode:
7282 \end_layout
7284 \begin_layout List
7285 \labelwidthstring 00.00.0000
7286 \begin_inset Quotes eld
7287 \end_inset
7289  enters double-quote mode
7290 \end_layout
7292 \begin_layout List
7293 \labelwidthstring 00.00.0000
7294 ' enters single-quote mode
7295 \end_layout
7297 \begin_layout List
7298 \labelwidthstring 00.00.0000
7299 trailing-
7300 \backslash
7301  enters multi-line mode
7302 \end_layout
7304 \begin_layout List
7305 \labelwidthstring 00.00.0000
7306 # enters #define sub-mode, needs 
7307 \backslash
7308  escaping end of line too
7309 \end_layout
7311 \begin_layout List
7312 \labelwidthstring 00.00.0000
7313 /* enters comment mode
7314 \end_layout
7316 \begin_layout Standard
7317 In double-quote mode, escape 
7318 \backslash
7319  and 
7320 \begin_inset Quotes eld
7321 \end_inset
7323  and newline
7324 \end_layout
7326 \begin_layout Standard
7328 \backslash
7329  escapes prevents 
7330 \begin_inset Quotes eld
7331 \end_inset
7333  from leaving mode
7334 \end_layout
7336 \begin_layout Standard
7337 \begin_inset Quotes eld
7338 \end_inset
7340  leaves mode
7341 \end_layout
7343 \begin_layout Standard
7344 newline needs to close and re-open string or something
7345 \end_layout
7347 \begin_layout Standard
7348 in single-quote mode escape 
7349 \backslash
7350  and 
7351 \begin_inset Quotes eld
7352 \end_inset
7355 \end_layout
7357 \begin_layout Chunk
7358 track-mode-C
7359 \end_layout
7361 \begin_layout Standard
7362 \begin_inset listings
7363 inline false
7364 status open
7366 \begin_layout Plain Layout
7368 \end_layout
7370 \end_inset
7373 \end_layout
7375 \begin_layout Chunk
7376 mode-tracker
7377 \end_layout
7379 \begin_layout Standard
7380 \begin_inset listings
7381 inline false
7382 status open
7384 \begin_layout Plain Layout
7387 \backslash
7388 chunkref{new_mode()}>
7389 \end_layout
7391 \end_inset
7394 \end_layout
7396 \begin_layout Chapter
7397 Generating the output
7398 \end_layout
7400 \begin_layout Standard
7401 We generate output by calling output_chunk, or listing the chunk names.
7402 \end_layout
7404 \begin_layout Chunk
7405 generate-output
7406 \end_layout
7408 \begin_layout Standard
7409 \begin_inset listings
7410 inline false
7411 status open
7413 \begin_layout Plain Layout
7415 if (length(root)) output_chunk(root);
7416 \end_layout
7418 \begin_layout Plain Layout
7420 else output_chunk_names();
7421 \end_layout
7423 \end_inset
7426 \end_layout
7428 \begin_layout Standard
7429 We also have some other output debugging:
7430 \end_layout
7432 \begin_layout Chunk
7433 debug-output
7434 \end_layout
7436 \begin_layout Standard
7437 \begin_inset listings
7438 inline false
7439 status open
7441 \begin_layout Plain Layout
7443 if (debug) {
7444 \end_layout
7446 \begin_layout Plain Layout
7448   print "------ chunk names "
7449 \end_layout
7451 \begin_layout Plain Layout
7453   output_chunk_names();
7454 \end_layout
7456 \begin_layout Plain Layout
7458   print "====== chunks"
7459 \end_layout
7461 \begin_layout Plain Layout
7463   output_chunks();
7464 \end_layout
7466 \begin_layout Plain Layout
7468   print "++++++ debug"
7469 \end_layout
7471 \begin_layout Plain Layout
7473   for (a in chunks) {
7474 \end_layout
7476 \begin_layout Plain Layout
7478     print a "=" chunks[a];
7479 \end_layout
7481 \begin_layout Plain Layout
7483   }
7484 \end_layout
7486 \begin_layout Plain Layout
7489 \end_layout
7491 \end_inset
7494 \end_layout
7496 \begin_layout Standard
7497 We do both of these at the end.
7498  We also set 
7499 \begin_inset Flex CharStyle:Code
7500 status collapsed
7502 \begin_layout Plain Layout
7503 ORS=""
7504 \end_layout
7506 \end_inset
7508  because each chunklet is not necessarily a complete line, and we already
7509  added 
7510 \begin_inset Flex CharStyle:Code
7511 status collapsed
7513 \begin_layout Plain Layout
7515 \end_layout
7517 \end_inset
7519  to each input line in section 
7520 \begin_inset CommandInset ref
7521 LatexCommand ref
7522 reference "sub:ORS-chunk-text"
7524 \end_inset
7527 \end_layout
7529 \begin_layout Chunk
7531 \end_layout
7533 \begin_layout Standard
7534 \begin_inset listings
7535 inline false
7536 status open
7538 \begin_layout Plain Layout
7540 END {
7541 \end_layout
7543 \begin_layout Plain Layout
7545   =<
7546 \backslash
7547 chunkref{debug-output}>
7548 \end_layout
7550 \begin_layout Plain Layout
7552   ORS="";
7553 \end_layout
7555 \begin_layout Plain Layout
7557   =<
7558 \backslash
7559 chunkref{generate-output}>
7560 \end_layout
7562 \begin_layout Plain Layout
7565 \end_layout
7567 \end_inset
7570 \end_layout
7572 \begin_layout Standard
7573 We write chunk names like this.
7574  If we seem to be running in notangle compatibility mode, then we enclose
7575  the name like this 
7576 \begin_inset Flex CharStyle:Code
7577 status collapsed
7579 \begin_layout Plain Layout
7580 <<name>>
7581 \end_layout
7583 \end_inset
7585  the same way notangle does:
7586 \end_layout
7588 \begin_layout Chunk
7589 output_chunk_names()
7590 \end_layout
7592 \begin_layout Standard
7593 \begin_inset listings
7594 inline false
7595 status open
7597 \begin_layout Plain Layout
7599 function output_chunk_names(   c, prefix, suffix) 
7600 \end_layout
7602 \begin_layout Plain Layout
7605 \end_layout
7607 \begin_layout Plain Layout
7609   if (notangle_mode) {
7610 \end_layout
7612 \begin_layout Plain Layout
7614     prefix="<<";
7615 \end_layout
7617 \begin_layout Plain Layout
7619     suffix=">>";
7620 \end_layout
7622 \begin_layout Plain Layout
7624   }
7625 \end_layout
7627 \begin_layout Plain Layout
7629   for (c in chunk_names) {
7630 \end_layout
7632 \begin_layout Plain Layout
7634     print prefix c suffix "
7635 \backslash
7637 \end_layout
7639 \begin_layout Plain Layout
7641   }
7642 \end_layout
7644 \begin_layout Plain Layout
7647 \end_layout
7649 \end_inset
7652 \end_layout
7654 \begin_layout Standard
7655 This function would write out all chunks
7656 \end_layout
7658 \begin_layout Chunk
7659 output_chunks()
7660 \end_layout
7662 \begin_layout Standard
7663 \begin_inset listings
7664 inline false
7665 status open
7667 \begin_layout Plain Layout
7669 function output_chunks(  a) 
7670 \end_layout
7672 \begin_layout Plain Layout
7675 \end_layout
7677 \begin_layout Plain Layout
7679   for (a in chunk_names) {
7680 \end_layout
7682 \begin_layout Plain Layout
7684     output_chunk(chunk_names[a]);
7685 \end_layout
7687 \begin_layout Plain Layout
7689   }
7690 \end_layout
7692 \begin_layout Plain Layout
7695 \end_layout
7697 \begin_layout Plain Layout
7699 \end_layout
7701 \begin_layout Plain Layout
7703 function output_chunk(chunk) {
7704 \end_layout
7706 \begin_layout Plain Layout
7708   newline = 1;
7709 \end_layout
7711 \begin_layout Plain Layout
7713   lineno_needed = linenos;
7714 \end_layout
7716 \begin_layout Plain Layout
7718 \end_layout
7720 \begin_layout Plain Layout
7722   write_chunk(chunk);
7723 \end_layout
7725 \begin_layout Plain Layout
7728 \end_layout
7730 \begin_layout Plain Layout
7732 \end_layout
7734 \end_inset
7737 \end_layout
7739 \begin_layout Section
7740 Assembling the chunks
7741 \end_layout
7743 \begin_layout Standard
7744 \begin_inset Flex CharStyle:Code
7745 status collapsed
7747 \begin_layout Plain Layout
7748 chunk_path
7749 \end_layout
7751 \end_inset
7753  holds a string consisting of the names of all the chunks that resulted
7754  in this chunk being output.
7756 \begin_inset Note Note
7757 status collapsed
7759 \begin_layout Plain Layout
7760 Make sure it includes the line numbers too...
7762 \end_layout
7764 \end_inset
7766 It should probably also contain the source line numbers at which each inclusion
7767  also occured.
7768 \end_layout
7770 \begin_layout Chunk
7771 write_chunk(),emph={chunk_path}
7772 \end_layout
7774 \begin_layout Standard
7775 \begin_inset listings
7776 inline false
7777 status open
7779 \begin_layout Plain Layout
7781 function write_chunk(chunk_name, indent, tail,
7782 \end_layout
7784 \begin_layout Plain Layout
7786   # optional vars
7787 \end_layout
7789 \begin_layout Plain Layout
7791   chunk_path, chunk_args, 
7792 \end_layout
7794 \begin_layout Plain Layout
7796   # local vars
7797 \end_layout
7799 \begin_layout Plain Layout
7801   part, max_part, part_line, frag, max_frag, text, 
7802 \end_layout
7804 \begin_layout Plain Layout
7806   chunklet, only_part, call_chunk_args, mode)
7807 \end_layout
7809 \begin_layout Plain Layout
7812 \end_layout
7814 \end_inset
7817 \end_layout
7819 \begin_layout Subsection
7820 \begin_inset CommandInset label
7821 LatexCommand label
7822 name "sub:Chunk-parts"
7824 \end_inset
7826 Chunk parts
7827 \end_layout
7829 \begin_layout Standard
7830 As mentioned in section 
7831 \begin_inset CommandInset ref
7832 LatexCommand ref
7833 reference "sub:lstlistings-includes"
7835 \end_inset
7837 , a chunk name may contain a part specifier in square brackets, limiting
7838  the parts that should be emitted.
7839 \end_layout
7841 \begin_layout Standard
7842 \begin_inset listings
7843 inline false
7844 status open
7846 \begin_layout Plain Layout
7848   if (match(chunk_name, "^(.*)
7849 \backslash
7851 \backslash
7852 [([0-9]*)
7853 \backslash
7855 \backslash
7856 ]$", chunk_name_parts)) {
7857 \end_layout
7859 \begin_layout Plain Layout
7861     chunk_name = chunk_name_parts[1];
7862 \end_layout
7864 \begin_layout Plain Layout
7866     only_part = chunk_name_parts[2];
7867 \end_layout
7869 \begin_layout Plain Layout
7871   }
7872 \end_layout
7874 \end_inset
7877 \end_layout
7879 \begin_layout Standard
7880 We first create the mode tracker for this chunk.
7881 \end_layout
7883 \begin_layout Standard
7884 #  =<
7885 \backslash
7886 chunkref{awk-delete-array}(mode)>
7887 \end_layout
7889 \begin_layout Standard
7890 \begin_inset listings
7891 inline false
7892 status open
7894 \begin_layout Plain Layout
7896   split("", mode);
7897 \end_layout
7899 \begin_layout Plain Layout
7901   new_mode(chunks[chunk_name, "language"], mode);
7902 \end_layout
7904 \end_inset
7907 \end_layout
7909 \begin_layout Standard
7910 #  =<
7911 \backslash
7912 chunkref{new-mode}(chunks[chunk_name, "language"], mode)>
7913 \end_layout
7915 \begin_layout Standard
7916 We extract into 
7917 \begin_inset Flex CharStyle:Code
7918 status collapsed
7920 \begin_layout Plain Layout
7921 chunk_params
7922 \end_layout
7924 \end_inset
7926  the names of the parameters that this chunk accepts, whose values were
7927  (optionally) passed in 
7928 \begin_inset Flex CharStyle:Code
7929 status collapsed
7931 \begin_layout Plain Layout
7932 chunk_args
7933 \end_layout
7935 \end_inset
7938 \end_layout
7940 \begin_layout Standard
7941 \begin_inset listings
7942 inline false
7943 status open
7945 \begin_layout Plain Layout
7947   split(chunks[chunk_name, "params"], chunk_params, " *; *");
7948 \end_layout
7950 \end_inset
7953 \end_layout
7955 \begin_layout Standard
7956 To assemble a chunk, we write out each part.
7957 \end_layout
7959 \begin_layout Chunk
7960 write_chunk()
7961 \end_layout
7963 \begin_layout Standard
7964 \begin_inset listings
7965 inline false
7966 status open
7968 \begin_layout Plain Layout
7970   if (! (chunk_name in chunk_names)) {
7971 \end_layout
7973 \begin_layout Plain Layout
7975     error(sprintf(_"The root module <<%s>> was not defined.
7976 \backslash
7977 nUsed by: %s",
7978 \backslash
7980 \end_layout
7982 \begin_layout Plain Layout
7984                   chunk_name, chunk_path));
7985 \end_layout
7987 \begin_layout Plain Layout
7989   }
7990 \end_layout
7992 \begin_layout Plain Layout
7994 \end_layout
7996 \begin_layout Plain Layout
7998   max_part = chunks[chunk_name, "part"];
7999 \end_layout
8001 \begin_layout Plain Layout
8003   for(part = 1; part <= max_part; part++) {
8004 \end_layout
8006 \begin_layout Plain Layout
8008     if (! only_part || part == only_part) {
8009 \end_layout
8011 \begin_layout Plain Layout
8013       =<
8014 \backslash
8015 chunkref{write-part}>
8016 \end_layout
8018 \begin_layout Plain Layout
8020     }
8021 \end_layout
8023 \begin_layout Plain Layout
8025   }
8026 \end_layout
8028 \begin_layout Plain Layout
8031 \end_layout
8033 \end_inset
8036 \end_layout
8038 \begin_layout Standard
8039 A part can either be a chunklet of lines, or an include of another chunk.
8040 \end_layout
8042 \begin_layout Standard
8043 Chunks may also have parameters, specified in LaTeX style with braces after
8044  the chunk name --- looking like this in the document: 
8045 \begin_inset Flex CharStyle:Code
8046 status collapsed
8048 \begin_layout Plain Layout
8049 chunkname{param1, param2}
8050 \end_layout
8052 \end_inset
8055  Arguments are passed in square brackets: 
8056 \begin_inset Flex CharStyle:Code
8057 status collapsed
8059 \begin_layout Plain Layout
8061 \backslash
8062 chunkref{chunkname}[arg1, arg2]
8063 \end_layout
8065 \end_inset
8068 \end_layout
8070 \begin_layout Standard
8071 Before we process each part, we check that the source position hasn't changed
8072  unexpectedly, so that we can know if we need to output a new file-line
8073  directive.
8074 \end_layout
8076 \begin_layout Chunk
8077 write-part
8078 \end_layout
8080 \begin_layout Standard
8081 \begin_inset listings
8082 inline false
8083 status open
8085 \begin_layout Plain Layout
8088 \backslash
8089 chunkref{check-source-jump}>
8090 \end_layout
8092 \begin_layout Plain Layout
8094 \end_layout
8096 \begin_layout Plain Layout
8098 chunklet = chunks[chunk_name, "part", part];
8099 \end_layout
8101 \begin_layout Plain Layout
8103 if (chunks[chunk_name, "part", part, "type"] == part_type_chunk) {
8104 \end_layout
8106 \begin_layout Plain Layout
8108   =<
8109 \backslash
8110 chunkref{write-included-chunk}>
8111 \end_layout
8113 \begin_layout Plain Layout
8115 } else if (chunklet SUBSEP "line" in chunks) {
8116 \end_layout
8118 \begin_layout Plain Layout
8120   =<
8121 \backslash
8122 chunkref{write-chunklets}>
8123 \end_layout
8125 \begin_layout Plain Layout
8127 } else {
8128 \end_layout
8130 \begin_layout Plain Layout
8132   # empty last chunklet
8133 \end_layout
8135 \begin_layout Plain Layout
8138 \end_layout
8140 \end_inset
8143 \end_layout
8145 \begin_layout Standard
8146 To write an included chunk, we must detect any optional chunk arguments
8147  in parenthesis.
8148  Then we recurse calling 
8149 \begin_inset Flex Chunkref
8150 status collapsed
8152 \begin_layout Plain Layout
8153 write_chunk()
8154 \end_layout
8156 \end_inset
8159 \end_layout
8161 \begin_layout Chunk
8162 write-included-chunk
8163 \end_layout
8165 \begin_layout Standard
8166 \begin_inset listings
8167 inline false
8168 status open
8170 \begin_layout Plain Layout
8172 if (match(chunklet, "^([^
8173 \backslash
8175 \backslash
8176 []*)
8177 \backslash
8179 \backslash
8180 ((.*)
8181 \backslash
8183 \backslash
8184 )$", chunklet_parts)) {
8185 \end_layout
8187 \begin_layout Plain Layout
8189   chunklet = chunklet_parts[1];
8190 \end_layout
8192 \begin_layout Plain Layout
8194 #  parse_chunk_args(chunklet_parts[2], chunk_args);
8195 \end_layout
8197 \begin_layout Plain Layout
8199 # TO BE parse_chunk_args SOON
8200 \end_layout
8202 \begin_layout Plain Layout
8204   split(chunklet_parts[2], call_chunk_args, " *, *");
8205 \end_layout
8207 \begin_layout Plain Layout
8209   for (c in call_chunk_args) {
8210 \end_layout
8212 \begin_layout Plain Layout
8214     call_chunk_args[c] = expand_chunk_args(call_chunk_args[c], chunk_params,
8215  chunk_args);
8216 \end_layout
8218 \begin_layout Plain Layout
8220   }
8221 \end_layout
8223 \begin_layout Plain Layout
8225 } else {
8226 \end_layout
8228 \begin_layout Plain Layout
8230   split("", call_chunk_args);
8231 \end_layout
8233 \begin_layout Plain Layout
8236 \end_layout
8238 \begin_layout Plain Layout
8240 write_chunk(chunklet,
8241 \end_layout
8243 \begin_layout Plain Layout
8245             chunks[chunk_name, "part", part, "indent"] indent,
8246 \end_layout
8248 \begin_layout Plain Layout
8250             chunks[chunk_name, "part", part, "tail"],
8251 \end_layout
8253 \begin_layout Plain Layout
8255             chunk_path "
8256 \backslash
8257 n         " chunk_name,
8258 \end_layout
8260 \begin_layout Plain Layout
8262             call_chunk_args);
8263 \end_layout
8265 \end_inset
8268 \end_layout
8270 \begin_layout Standard
8271 Before we output a chunklet of lines, we first emit the file and line number
8272  if we have one, and if it is safe to do so.
8274 \end_layout
8276 \begin_layout Standard
8277 Chunklets are generally broken up by includes, so the start of a chunklet
8278  is a good place to do this.
8279  Then we output each line of the chunklet.
8280 \end_layout
8282 \begin_layout Standard
8283 When it is not safe, such as in the middle of a multi-line macro definition,
8285 \begin_inset Flex CharStyle:Code
8286 status collapsed
8288 \begin_layout Plain Layout
8289 lineno_suppressed
8290 \end_layout
8292 \end_inset
8294  is set to true, and in such a case we note that we want to emit the line
8295  statement when it is next safe.
8296 \end_layout
8298 \begin_layout Chunk
8299 write-chunklets
8300 \end_layout
8302 \begin_layout Standard
8303 \begin_inset listings
8304 inline false
8305 status open
8307 \begin_layout Plain Layout
8309 max_frag = chunks[chunklet, "line"];
8310 \end_layout
8312 \begin_layout Plain Layout
8314 for(frag = 1; frag <= max_frag; frag++) {
8315 \end_layout
8317 \begin_layout Plain Layout
8319   =<
8320 \backslash
8321 chunkref{write-file-line}>
8322 \end_layout
8324 \end_inset
8327 \end_layout
8329 \begin_layout Standard
8330 We then extract the chunklet text and expand any arguments.
8331 \end_layout
8333 \begin_layout Standard
8334 \begin_inset listings
8335 inline false
8336 status open
8338 \begin_layout Plain Layout
8340 \end_layout
8342 \begin_layout Plain Layout
8344   text = chunks[chunklet, frag];
8345 \end_layout
8347 \begin_layout Plain Layout
8350 \end_layout
8352 \begin_layout Plain Layout
8354   /* check params */
8355 \end_layout
8357 \begin_layout Plain Layout
8359   text = expand_chunk_args(text, chunk_params, chunk_args);
8360 \end_layout
8362 \end_inset
8365 \end_layout
8367 \begin_layout Standard
8368 If the text is a single newline (which we keep separate - see 
8369 \begin_inset CommandInset ref
8370 LatexCommand ref
8371 reference "lone-newline"
8373 \end_inset
8375 ) then we increment the line number.
8376  In the case where this is the last line of a chunk and it is not a top-level
8377  chunk we replace the newline with an empty string --- because the chunk
8378  that included this chunk will have the newline at the end of the line that
8379  included this chunk.
8380 \end_layout
8382 \begin_layout Standard
8383 We also note by 
8384 \begin_inset Flex CharStyle:Code
8385 status collapsed
8387 \begin_layout Plain Layout
8388 newline = 1
8389 \end_layout
8391 \end_inset
8393  that we have started a new line, so that indentation can be managed with
8394  the following piece of text.
8395 \end_layout
8397 \begin_layout Standard
8398 \begin_inset listings
8399 inline false
8400 status open
8402 \begin_layout Plain Layout
8404 \end_layout
8406 \begin_layout Plain Layout
8408  if (text == "
8409 \backslash
8410 n") {
8411 \end_layout
8413 \begin_layout Plain Layout
8415     lineno++;
8416 \end_layout
8418 \begin_layout Plain Layout
8420     if (part == max_part && frag == max_frag && length(chunk_path)) {
8421 \end_layout
8423 \begin_layout Plain Layout
8425       text = "";
8426 \end_layout
8428 \begin_layout Plain Layout
8430       break;
8431 \end_layout
8433 \begin_layout Plain Layout
8435     } else {
8436 \end_layout
8438 \begin_layout Plain Layout
8440       newline = 1;
8441 \end_layout
8443 \begin_layout Plain Layout
8445     }
8446 \end_layout
8448 \end_inset
8451 \end_layout
8453 \begin_layout Standard
8454 If this text does not represent a newline, but we see that we are the first
8455  piece of text on a newline, then we prefix our text with the current indent.
8456  NOTE: 
8457 \begin_inset Flex CharStyle:Code
8458 status collapsed
8460 \begin_layout Plain Layout
8461 newline
8462 \end_layout
8464 \end_inset
8466  is a global output-state variable, but the 
8467 \begin_inset Flex CharStyle:Code
8468 status collapsed
8470 \begin_layout Plain Layout
8471 indent
8472 \end_layout
8474 \end_inset
8476  is not.
8478 \end_layout
8480 \begin_layout Standard
8481 \begin_inset listings
8482 inline false
8483 status open
8485 \begin_layout Plain Layout
8487   } else if (length(text) || length(tail)) {
8488 \end_layout
8490 \begin_layout Plain Layout
8492     if (newline) text = indent text;
8493 \end_layout
8495 \begin_layout Plain Layout
8497     newline = 0;
8498 \end_layout
8500 \begin_layout Plain Layout
8502   }
8503 \end_layout
8505 \begin_layout Plain Layout
8507 \end_layout
8509 \end_inset
8512 \end_layout
8514 \begin_layout Standard
8515 Tail will soon no longer be relevant once mode-detection is in place.
8516 \end_layout
8518 \begin_layout Standard
8519 \begin_inset listings
8520 inline false
8521 status open
8523 \begin_layout Plain Layout
8525   text = text tail;
8526 \end_layout
8528 \begin_layout Plain Layout
8530 #  track_mode(mode, text);
8531 \end_layout
8533 \begin_layout Plain Layout
8535   print text;
8536 \end_layout
8538 \end_inset
8541 \end_layout
8543 \begin_layout Standard
8544 If a line ends in a backslash --- suggesting continuation --- then we supress
8545  outputting file-line as it would probably break the continued lines.
8547 \end_layout
8549 \begin_layout Standard
8550 \begin_inset listings
8551 inline false
8552 status open
8554 \begin_layout Plain Layout
8556   if (linenos) {
8557 \end_layout
8559 \begin_layout Plain Layout
8561     lineno_suppressed = substr(lastline, length(lastline)) == "
8562 \backslash
8564 \backslash
8566 \end_layout
8568 \begin_layout Plain Layout
8570   }
8571 \end_layout
8573 \begin_layout Plain Layout
8576 \end_layout
8578 \end_inset
8581 \end_layout
8583 \begin_layout Standard
8584 Of course there is no point in actually outputting the source filename and
8585  line number (file-line) if they don't say anything new! We only need to
8586  emit them if they aren't what is expected, or if we we not able to emit
8587  one when they had changed.
8588 \end_layout
8590 \begin_layout Chunk
8591 write-file-line
8592 \end_layout
8594 \begin_layout Standard
8595 \begin_inset listings
8596 inline false
8597 status open
8599 \begin_layout Plain Layout
8601 if (newline && lineno_needed && ! lineno_suppressed) {
8602 \end_layout
8604 \begin_layout Plain Layout
8606   filename = a_filename;
8607 \end_layout
8609 \begin_layout Plain Layout
8611   lineno = a_lineno;
8612 \end_layout
8614 \begin_layout Plain Layout
8616   print "#line " lineno " 
8617 \backslash
8618 "" filename "
8619 \backslash
8621 \backslash
8623 \end_layout
8625 \begin_layout Plain Layout
8627   lineno_needed = 0;
8628 \end_layout
8630 \begin_layout Plain Layout
8633 \end_layout
8635 \end_inset
8638 \end_layout
8640 \begin_layout Standard
8641 We check if a new file-line is needed by checking if the source line matches
8642  what we (or a compiler) would expect.
8644 \end_layout
8646 \begin_layout Chunk
8647 check-source-jump
8648 \end_layout
8650 \begin_layout Standard
8651 \begin_inset listings
8652 inline false
8653 status open
8655 \begin_layout Plain Layout
8657 if (linenos && (chunk_name SUBSEP "part" SUBSEP part SUBSEP "FILENAME" in
8658  chunks)) {
8659 \end_layout
8661 \begin_layout Plain Layout
8663   a_filename = chunks[chunk_name, "part", part, "FILENAME"];
8664 \end_layout
8666 \begin_layout Plain Layout
8668   a_lineno = chunks[chunk_name, "part", part, "LINENO"];
8669 \end_layout
8671 \begin_layout Plain Layout
8673   if (a_filename != filename || a_lineno != lineno) {
8674 \end_layout
8676 \begin_layout Plain Layout
8678     lineno_needed++;
8679 \end_layout
8681 \begin_layout Plain Layout
8683   }
8684 \end_layout
8686 \begin_layout Plain Layout
8689 \end_layout
8691 \end_inset
8694 \end_layout
8696 \begin_layout Chapter
8697 Storing chunks
8698 \end_layout
8700 \begin_layout Standard
8701 Awk has pretty limited data structures, so we will use two main hashes.
8702  Uninterrupted sequences of a chunk will be stored in 
8703 \begin_inset Flex CharStyle:Code
8704 status collapsed
8706 \begin_layout Plain Layout
8707 chunklets
8708 \end_layout
8710 \end_inset
8712  and the chunklets used in a chunk will be stored in 
8713 \begin_inset Flex CharStyle:Code
8714 status collapsed
8716 \begin_layout Plain Layout
8717 chunks
8718 \end_layout
8720 \end_inset
8723 \end_layout
8725 \begin_layout Chunk
8726 constants
8727 \end_layout
8729 \begin_layout Standard
8730 \begin_inset listings
8731 inline false
8732 status open
8734 \begin_layout Plain Layout
8736 part_type_chunk=1;
8737 \end_layout
8739 \end_inset
8742 \end_layout
8744 \begin_layout Standard
8745 The 
8746 \begin_inset Flex CharStyle:Code
8747 status collapsed
8749 \begin_layout Plain Layout
8750 params
8751 \end_layout
8753 \end_inset
8755  mentioned are not chunk parameters for parameterized chunks, as mentioned
8756  in 
8757 \begin_inset CommandInset ref
8758 LatexCommand ref
8759 reference "cha:Chunk Arguments"
8761 \end_inset
8763 , but the lstlistings style parameters used in the 
8764 \begin_inset Flex CharStyle:Code
8765 status collapsed
8767 \begin_layout Plain Layout
8769 \backslash
8770 Chunk
8771 \end_layout
8773 \end_inset
8775  command
8776 \begin_inset Foot
8777 status collapsed
8779 \begin_layout Plain Layout
8780 The 
8781 \begin_inset Flex CharStyle:Code
8782 status collapsed
8784 \begin_layout Plain Layout
8785 params
8786 \end_layout
8788 \end_inset
8790  parameter is used to hold the parameters for parameterized chunks
8791 \end_layout
8793 \end_inset
8796 \end_layout
8798 \begin_layout Chunk
8799 chunk-storage-functions
8800 \end_layout
8802 \begin_layout Standard
8803 \begin_inset listings
8804 inline false
8805 status open
8807 \begin_layout Plain Layout
8809 function new_chunk(chunk_name, params,
8810 \end_layout
8812 \begin_layout Plain Layout
8814   # local vars
8815 \end_layout
8817 \begin_layout Plain Layout
8819   p )
8820 \end_layout
8822 \begin_layout Plain Layout
8825 \end_layout
8827 \begin_layout Plain Layout
8829   # HACK WHILE WE CHANGE TO ( ) for PARAM CHUNKS
8830 \end_layout
8832 \begin_layout Plain Layout
8834   gsub("
8835 \backslash
8837 \backslash
8839 \backslash
8841 \backslash
8842 )$", "", chunk_name);
8843 \end_layout
8845 \begin_layout Plain Layout
8847   active_chunk = chunk_name;
8848 \end_layout
8850 \begin_layout Plain Layout
8852   if (! (chunk_name in chunk_names)) {
8853 \end_layout
8855 \begin_layout Plain Layout
8857     if (debug) print "New chunk " chunk_name;
8858 \end_layout
8860 \begin_layout Plain Layout
8862     chunk_names[chunk_name];
8863 \end_layout
8865 \begin_layout Plain Layout
8867     for (p in params) {
8868 \end_layout
8870 \begin_layout Plain Layout
8872       chunks[chunk_name, p] = params[p];
8873 \end_layout
8875 \begin_layout Plain Layout
8877     }
8878 \end_layout
8880 \begin_layout Plain Layout
8882   }
8883 \end_layout
8885 \begin_layout Plain Layout
8887   prime_chunk(chunk_name);
8888 \end_layout
8890 \begin_layout Plain Layout
8893 \end_layout
8895 \end_inset
8898 \end_layout
8900 \begin_layout Standard
8901 \begin_inset listings
8902 inline false
8903 status open
8905 \begin_layout Plain Layout
8907 \end_layout
8909 \begin_layout Plain Layout
8911 function prime_chunk(chunk_name)
8912 \end_layout
8914 \begin_layout Plain Layout
8917 \end_layout
8919 \begin_layout Plain Layout
8921   chunks[chunk_name, "part", ++chunks[chunk_name, "part"] ] = 
8922 \backslash
8924 \end_layout
8926 \begin_layout Plain Layout
8928          chunk_name SUBSEP "chunklet" SUBSEP "" ++chunks[chunk_name, "chunklet"]
8930 \end_layout
8932 \begin_layout Plain Layout
8934   chunks[chunk_name, "part", chunks[chunk_name, "part"], "FILENAME"] = FILENAME;
8935 \end_layout
8937 \begin_layout Plain Layout
8939   chunks[chunk_name, "part", chunks[chunk_name, "part"], "LINENO"] = FNR
8940  + 1;
8941 \end_layout
8943 \begin_layout Plain Layout
8946 \end_layout
8948 \begin_layout Plain Layout
8950 \end_layout
8952 \begin_layout Plain Layout
8954 function chunk_line(chunk_name, line){
8955 \end_layout
8957 \begin_layout Plain Layout
8959   chunks[chunk_name, "chunklet", chunks[chunk_name, "chunklet"],
8960 \end_layout
8962 \begin_layout Plain Layout
8964          ++chunks[chunk_name, "chunklet", chunks[chunk_name, "chunklet"],
8965  "line"]  ] = line;
8966 \end_layout
8968 \begin_layout Plain Layout
8971 \end_layout
8973 \begin_layout Plain Layout
8975 \end_layout
8977 \end_inset
8980 \end_layout
8982 \begin_layout Standard
8983 Chunk include represents a 
8984 \emph on
8985 chunkref
8986 \emph default
8987  statement, and stores the requirement to include another chunk.
8988  The parameter indent represents the quanity of literal text characters
8989  that preceded this 
8990 \emph on
8991 chunkref
8992 \emph default
8993  statement and therefore by how much additional lines of the included chunk
8994  should be indented.
8995 \end_layout
8997 \begin_layout Standard
8998 \begin_inset listings
8999 inline false
9000 status open
9002 \begin_layout Plain Layout
9004 function chunk_include(chunk_name, chunk_ref, indent, tail)
9005 \end_layout
9007 \begin_layout Plain Layout
9010 \end_layout
9012 \begin_layout Plain Layout
9014   chunks[chunk_name, "part", ++chunks[chunk_name, "part"] ] = chunk_ref;
9015 \end_layout
9017 \begin_layout Plain Layout
9019   chunks[chunk_name, "part", chunks[chunk_name, "part"], "type" ] = part_type_ch
9020 unk;
9021 \end_layout
9023 \begin_layout Plain Layout
9025   chunks[chunk_name, "part", chunks[chunk_name, "part"], "indent" ] = indent_str
9026 ing(indent);
9027 \end_layout
9029 \begin_layout Plain Layout
9031   chunks[chunk_name, "part", chunks[chunk_name, "part"], "tail" ] = tail;
9032 \end_layout
9034 \begin_layout Plain Layout
9036   prime_chunk(chunk_name);
9037 \end_layout
9039 \begin_layout Plain Layout
9042 \end_layout
9044 \begin_layout Plain Layout
9046 \end_layout
9048 \end_inset
9051 \end_layout
9053 \begin_layout Standard
9054 The indent is calculated by indent_string, which may in future convert some
9055  spaces into tab characters.
9056  This function works by generating a printf padded format string, like 
9057 \begin_inset Flex CharStyle:Code
9058 status collapsed
9060 \begin_layout Plain Layout
9061 %22s
9062 \end_layout
9064 \end_inset
9066  for an indent of 22, and then printing an empty string using that format.
9067 \end_layout
9069 \begin_layout Standard
9070 \begin_inset listings
9071 inline false
9072 status open
9074 \begin_layout Plain Layout
9076 function indent_string(indent) {
9077 \end_layout
9079 \begin_layout Plain Layout
9081   return sprintf("%" indent "s", "");
9082 \end_layout
9084 \begin_layout Plain Layout
9087 \end_layout
9089 \end_inset
9092 \end_layout
9094 \begin_layout Chapter
9095 \begin_inset CommandInset label
9096 LatexCommand label
9097 name "cha:getopt"
9099 \end_inset
9101 getopt
9102 \end_layout
9104 \begin_layout Standard
9105 I use Arnold Robbins public domain getopt (1993 revision).
9106  This is probably the same one that is covered in chapter 12 of 
9107 \begin_inset Quotes eld
9108 \end_inset
9110 Edition 3 of GAWK: Effective AWK Programming: A User's Guide for GNU Awk
9111 \begin_inset Quotes erd
9112 \end_inset
9114  but as that is licensed under the GNU Free Documentation License, Version
9115  1.3, which conflicts with the GPL3, I can't use it from there (or it's accompany
9116 ing explanations), so I do my best to explain how it works here.
9117 \end_layout
9119 \begin_layout Standard
9120 The getopt.awk header is:
9121 \end_layout
9123 \begin_layout Chunk
9124 getopt.awk-header,language=awk,morestring=[b]{/},morekeywords=else
9125 \end_layout
9127 \begin_layout Standard
9128 \begin_inset listings
9129 inline false
9130 status open
9132 \begin_layout Plain Layout
9134 # getopt.awk --- do C library getopt(3) function in awk
9135 \end_layout
9137 \begin_layout Plain Layout
9140 \end_layout
9142 \begin_layout Plain Layout
9144 # Arnold Robbins, arnold@skeeve.com, Public Domain
9145 \end_layout
9147 \begin_layout Plain Layout
9150 \end_layout
9152 \begin_layout Plain Layout
9154 # Initial version: March, 1991
9155 \end_layout
9157 \begin_layout Plain Layout
9159 # Revised: May, 1993
9160 \end_layout
9162 \end_inset
9165 \end_layout
9167 \begin_layout Standard
9168 The provided explanation is:
9169 \end_layout
9171 \begin_layout Chunk
9172 getopt.awk-notes
9173 \end_layout
9175 \begin_layout Standard
9176 \begin_inset listings
9177 inline false
9178 status open
9180 \begin_layout Plain Layout
9182 # External variables:
9183 \end_layout
9185 \begin_layout Plain Layout
9187 #    Optind -- index in ARGV of first nonoption argument
9188 \end_layout
9190 \begin_layout Plain Layout
9192 #    Optarg -- string value of argument to current option
9193 \end_layout
9195 \begin_layout Plain Layout
9197 #    Opterr -- if nonzero, print our own diagnostic
9198 \end_layout
9200 \begin_layout Plain Layout
9202 #    Optopt -- current option letter
9203 \end_layout
9205 \begin_layout Plain Layout
9207 \end_layout
9209 \begin_layout Plain Layout
9211 # Returns:
9212 \end_layout
9214 \begin_layout Plain Layout
9216 #    -1     at end of options
9217 \end_layout
9219 \begin_layout Plain Layout
9221 #    ?      for unrecognized option
9222 \end_layout
9224 \begin_layout Plain Layout
9226 #    <c>    a character representing the current option
9227 \end_layout
9229 \begin_layout Plain Layout
9231 \end_layout
9233 \begin_layout Plain Layout
9235 # Private Data:
9236 \end_layout
9238 \begin_layout Plain Layout
9240 #    _opti  -- index in multi-flag option, e.g., -abc
9241 \end_layout
9243 \end_inset
9246 \end_layout
9248 \begin_layout Standard
9249 The function follows.
9250  The final two parameters, 
9251 \begin_inset Flex CharStyle:Code
9252 status collapsed
9254 \begin_layout Plain Layout
9255 thisopt
9256 \end_layout
9258 \end_inset
9260  and 
9261 \begin_inset Flex CharStyle:Code
9262 status collapsed
9264 \begin_layout Plain Layout
9266 \end_layout
9268 \end_inset
9270  are local variables and not parameters --- as indicated by the multiple
9271  spaces preceding them.
9272  Awk doesn't care, the multiple spaces are a convention to help us humans.
9273 \end_layout
9275 \begin_layout Chunk
9276 getopt.awk-getopt()
9277 \end_layout
9279 \begin_layout Standard
9280 \begin_inset listings
9281 inline false
9282 status open
9284 \begin_layout Plain Layout
9286 function getopt(argc, argv, options,    thisopt, i)
9287 \end_layout
9289 \begin_layout Plain Layout
9292 \end_layout
9294 \begin_layout Plain Layout
9296     if (length(options) == 0)    # no options given
9297 \end_layout
9299 \begin_layout Plain Layout
9301         return -1
9302 \end_layout
9304 \begin_layout Plain Layout
9306     if (argv[Optind] == "--") {  # all done
9307 \end_layout
9309 \begin_layout Plain Layout
9311         Optind++
9312 \end_layout
9314 \begin_layout Plain Layout
9316         _opti = 0
9317 \end_layout
9319 \begin_layout Plain Layout
9321         return -1
9322 \end_layout
9324 \begin_layout Plain Layout
9326     } else if (argv[Optind] !~ /^-[^: 
9327 \backslash
9329 \backslash
9331 \backslash
9333 \backslash
9335 \backslash
9337 \backslash
9338 b]/) {
9339 \end_layout
9341 \begin_layout Plain Layout
9343         _opti = 0
9344 \end_layout
9346 \begin_layout Plain Layout
9348         return -1
9349 \end_layout
9351 \begin_layout Plain Layout
9353     }
9354 \end_layout
9356 \begin_layout Plain Layout
9358     if (_opti == 0)
9359 \end_layout
9361 \begin_layout Plain Layout
9363         _opti = 2
9364 \end_layout
9366 \begin_layout Plain Layout
9368     thisopt = substr(argv[Optind], _opti, 1)
9369 \end_layout
9371 \begin_layout Plain Layout
9373     Optopt = thisopt
9374 \end_layout
9376 \begin_layout Plain Layout
9378     i = index(options, thisopt)
9379 \end_layout
9381 \begin_layout Plain Layout
9383     if (i == 0) {
9384 \end_layout
9386 \begin_layout Plain Layout
9388         if (Opterr)
9389 \end_layout
9391 \begin_layout Plain Layout
9393             printf("%c -- invalid option
9394 \backslash
9396 \end_layout
9398 \begin_layout Plain Layout
9400                                   thisopt) > "/dev/stderr"
9401 \end_layout
9403 \begin_layout Plain Layout
9405         if (_opti >= length(argv[Optind])) {
9406 \end_layout
9408 \begin_layout Plain Layout
9410             Optind++
9411 \end_layout
9413 \begin_layout Plain Layout
9415             _opti = 0
9416 \end_layout
9418 \begin_layout Plain Layout
9420         } else
9421 \end_layout
9423 \begin_layout Plain Layout
9425             _opti++
9426 \end_layout
9428 \begin_layout Plain Layout
9430         return "?"
9431 \end_layout
9433 \begin_layout Plain Layout
9435     }
9436 \end_layout
9438 \end_inset
9441 \end_layout
9443 \begin_layout Standard
9444 At this point, the option has been found and we need to know if it takes
9445  any arguments.
9446 \end_layout
9448 \begin_layout Standard
9449 \begin_inset listings
9450 inline false
9451 status open
9453 \begin_layout Plain Layout
9455     if (substr(options, i + 1, 1) == ":") {
9456 \end_layout
9458 \begin_layout Plain Layout
9460         # get option argument
9461 \end_layout
9463 \begin_layout Plain Layout
9465         if (length(substr(argv[Optind], _opti + 1)) > 0)
9466 \end_layout
9468 \begin_layout Plain Layout
9470             Optarg = substr(argv[Optind], _opti + 1)
9471 \end_layout
9473 \begin_layout Plain Layout
9475         else
9476 \end_layout
9478 \begin_layout Plain Layout
9480             Optarg = argv[++Optind]
9481 \end_layout
9483 \begin_layout Plain Layout
9485         _opti = 0
9486 \end_layout
9488 \begin_layout Plain Layout
9490     } else
9491 \end_layout
9493 \begin_layout Plain Layout
9495         Optarg = ""
9496 \end_layout
9498 \begin_layout Plain Layout
9500     if (_opti == 0 || _opti >= length(argv[Optind])) {
9501 \end_layout
9503 \begin_layout Plain Layout
9505         Optind++
9506 \end_layout
9508 \begin_layout Plain Layout
9510         _opti = 0
9511 \end_layout
9513 \begin_layout Plain Layout
9515     } else
9516 \end_layout
9518 \begin_layout Plain Layout
9520         _opti++
9521 \end_layout
9523 \begin_layout Plain Layout
9525     return thisopt
9526 \end_layout
9528 \begin_layout Plain Layout
9531 \end_layout
9533 \end_inset
9535 A test program is built in, too
9536 \end_layout
9538 \begin_layout Chunk
9539 getopt.awk-begin
9540 \end_layout
9542 \begin_layout Standard
9543 \begin_inset listings
9544 inline false
9545 status open
9547 \begin_layout Plain Layout
9549 BEGIN {
9550 \end_layout
9552 \begin_layout Plain Layout
9554     Opterr = 1    # default is to diagnose
9555 \end_layout
9557 \begin_layout Plain Layout
9559     Optind = 1    # skip ARGV[0]
9560 \end_layout
9562 \begin_layout Plain Layout
9564     # test program
9565 \end_layout
9567 \begin_layout Plain Layout
9569     if (_getopt_test) {
9570 \end_layout
9572 \begin_layout Plain Layout
9574         while ((_go_c = getopt(ARGC, ARGV, "ab:cd")) != -1)
9575 \end_layout
9577 \begin_layout Plain Layout
9579             printf("c = <%c>, optarg = <%s>
9580 \backslash
9582 \end_layout
9584 \begin_layout Plain Layout
9586                                        _go_c, Optarg)
9587 \end_layout
9589 \begin_layout Plain Layout
9591         printf("non-option arguments:
9592 \backslash
9594 \end_layout
9596 \begin_layout Plain Layout
9598         for (; Optind < ARGC; Optind++)
9599 \end_layout
9601 \begin_layout Plain Layout
9603             printf("
9604 \backslash
9605 tARGV[%d] = <%s>
9606 \backslash
9608 \end_layout
9610 \begin_layout Plain Layout
9612                                     Optind, ARGV[Optind])
9613 \end_layout
9615 \begin_layout Plain Layout
9617     }
9618 \end_layout
9620 \begin_layout Plain Layout
9623 \end_layout
9625 \end_inset
9628 \end_layout
9630 \begin_layout Standard
9631 The entire getopt.awk is made out of these chunks in order
9632 \end_layout
9634 \begin_layout Chunk
9635 getopt.awk
9636 \end_layout
9638 \begin_layout Standard
9639 \begin_inset listings
9640 inline false
9641 status open
9643 \begin_layout Plain Layout
9646 \backslash
9647 chunkref{getopt.awk-header}>
9648 \end_layout
9650 \begin_layout Plain Layout
9652 \end_layout
9654 \begin_layout Plain Layout
9657 \backslash
9658 chunkref{getopt.awk-notes}>
9659 \end_layout
9661 \begin_layout Plain Layout
9664 \backslash
9665 chunkref{getopt.awk-getopt()}>
9666 \end_layout
9668 \begin_layout Plain Layout
9671 \backslash
9672 chunkref{getopt.awk-begin}>
9673 \end_layout
9675 \end_inset
9678 \end_layout
9680 \begin_layout Standard
9681 Although we only want the header and function:
9682 \end_layout
9684 \begin_layout Chunk
9685 getopt
9686 \end_layout
9688 \begin_layout Standard
9689 \begin_inset listings
9690 inline false
9691 status open
9693 \begin_layout Plain Layout
9695 # try: locate getopt.awk for the full original file
9696 \end_layout
9698 \begin_layout Plain Layout
9700 # as part of your standard awk installation
9701 \end_layout
9703 \begin_layout Plain Layout
9706 \backslash
9707 chunkref{getopt.awk-header}>
9708 \end_layout
9710 \begin_layout Plain Layout
9712 \end_layout
9714 \begin_layout Plain Layout
9717 \backslash
9718 chunkref{getopt.awk-getopt()}>
9719 \end_layout
9721 \end_inset
9724 \end_layout
9726 \begin_layout Chapter
9727 Newfangle LaTeX source code
9728 \end_layout
9730 \begin_layout Section
9731 newfangle module
9732 \end_layout
9734 \begin_layout Standard
9735 Here we define a Lyx .module file that makes it convenient to use LyX for
9736  writing such literate programs.
9737 \end_layout
9739 \begin_layout Standard
9740 This file 
9741 \begin_inset Flex CharStyle:Code
9742 status collapsed
9744 \begin_layout Plain Layout
9745 ./newfangle.module
9746 \end_layout
9748 \end_inset
9750  can be installed in your personal 
9751 \begin_inset Flex CharStyle:Code
9752 status collapsed
9754 \begin_layout Plain Layout
9755 .lyx/layouts folder
9756 \end_layout
9758 \end_inset
9761  You will need to Tools Reconfigure so that LyX notices it.
9762  It adds a new format Chunk, which should precede every listing and contain
9763  the chunk name.
9765 \end_layout
9767 \begin_layout Chunk
9768 ./newfangle.module,language=
9769 \end_layout
9771 \begin_layout Standard
9772 \begin_inset listings
9773 inline false
9774 status open
9776 \begin_layout Plain Layout
9779 \backslash
9780 DeclareLyXModule{Newfangle Literate Listings}
9781 \end_layout
9783 \begin_layout Plain Layout
9785 #DescriptionBegin
9786 \end_layout
9788 \begin_layout Plain Layout
9790 #  Newfangle literate listings allow one to write
9791 \end_layout
9793 \begin_layout Plain Layout
9795 #   literate programs after the fashion of noweb, but without having
9796 \end_layout
9798 \begin_layout Plain Layout
9800 #   to use noweave to generate the documentation.
9801  Instead the listings
9802 \end_layout
9804 \begin_layout Plain Layout
9806 #   package is extended in conjunction with the noweb package to implement
9807 \end_layout
9809 \begin_layout Plain Layout
9811 #   to code formating directly as latex.
9812 \end_layout
9814 \begin_layout Plain Layout
9816 #  The newfangle awk script
9817 \end_layout
9819 \begin_layout Plain Layout
9821 #DescriptionEnd
9822 \end_layout
9824 \begin_layout Plain Layout
9826 \end_layout
9828 \begin_layout Plain Layout
9830 Format 11
9831 \end_layout
9833 \begin_layout Plain Layout
9835 \end_layout
9837 \begin_layout Plain Layout
9839 AddToPreamble
9840 \end_layout
9842 \begin_layout Plain Layout
9845 \backslash
9846 chunkref{./newfangle.sty}>
9847 \end_layout
9849 \begin_layout Plain Layout
9851 EndPreamble
9852 \end_layout
9854 \begin_layout Plain Layout
9856 \end_layout
9858 \begin_layout Plain Layout
9861 \backslash
9862 chunkref{chunkstyle}>
9863 \end_layout
9865 \begin_layout Plain Layout
9867 \end_layout
9869 \begin_layout Plain Layout
9872 \backslash
9873 chunkref{chunkref}>
9874 \end_layout
9876 \end_inset
9879 \end_layout
9881 \begin_layout Subsection
9882 The Chunk style
9883 \end_layout
9885 \begin_layout Standard
9886 The purpose of the 
9887 \noun on
9888 chunk
9889 \noun default
9890  style is to make it easier for LyX users to provide the name to 
9891 \begin_inset Flex CharStyle:Code
9892 status collapsed
9894 \begin_layout Plain Layout
9896 \backslash
9897 lstlistings
9898 \end_layout
9900 \end_inset
9903  Normally this requires right-clicking on the listing, choosing settings,
9904  advanced, and then typing 
9905 \begin_inset Flex CharStyle:Code
9906 status collapsed
9908 \begin_layout Plain Layout
9909 name=chunk-name
9910 \end_layout
9912 \end_inset
9915  This has the further disadvantage that the name (and other options) are
9916  not generally visible during document editing.
9917 \end_layout
9919 \begin_layout Standard
9920 The chunk style is defined as a LaTeX command, so that all text on the same
9921  line is passed to the LaTeX command 
9922 \begin_inset Flex CharStyle:Code
9923 status collapsed
9925 \begin_layout Plain Layout
9926 Chunk
9927 \end_layout
9929 \end_inset
9932  This makes it easy to parse using 
9933 \begin_inset Flex CharStyle:Code
9934 status collapsed
9936 \begin_layout Plain Layout
9937 newfangle
9938 \end_layout
9940 \end_inset
9942 , and easy to pass these options on to the listings package.
9943  The first word in a chunk section should be the chunk name, and will have
9945 \begin_inset Flex CharStyle:Code
9946 status collapsed
9948 \begin_layout Plain Layout
9949 name=
9950 \end_layout
9952 \end_inset
9954  prepended to it.
9955  Any other words are accepted arguments to 
9956 \begin_inset Flex CharStyle:Code
9957 status collapsed
9959 \begin_layout Plain Layout
9961 \backslash
9962 lstset
9963 \end_layout
9965 \end_inset
9968 \end_layout
9970 \begin_layout Standard
9971 We set PassThru to 1 because the user is actually entering raw latex.
9972 \end_layout
9974 \begin_layout Chunk
9975 chunkstyle
9976 \end_layout
9978 \begin_layout Standard
9979 \begin_inset listings
9980 inline false
9981 status open
9983 \begin_layout Plain Layout
9985 Style Chunk
9986 \end_layout
9988 \begin_layout Plain Layout
9990   LatexType             Command
9991 \end_layout
9993 \begin_layout Plain Layout
9995   LatexName             Chunk
9996 \end_layout
9998 \begin_layout Plain Layout
10000   Margin                First_Dynamic
10001 \end_layout
10003 \begin_layout Plain Layout
10005   LeftMargin            Chunk:xxx
10006 \end_layout
10008 \begin_layout Plain Layout
10010   LabelSep              xx
10011 \end_layout
10013 \begin_layout Plain Layout
10015   LabelType             Static
10016 \end_layout
10018 \begin_layout Plain Layout
10020   LabelString           "Chunk:"
10021 \end_layout
10023 \begin_layout Plain Layout
10025   Align                 Left
10026 \end_layout
10028 \begin_layout Plain Layout
10030   PassThru              1
10031 \end_layout
10033 \begin_layout Plain Layout
10035 \end_layout
10037 \end_inset
10040 \end_layout
10042 \begin_layout Standard
10043 To make the label very visible we choose a larger font coloured red.
10044 \end_layout
10046 \begin_layout Standard
10047 \begin_inset listings
10048 inline false
10049 status open
10051 \begin_layout Plain Layout
10053   LabelFont
10054 \end_layout
10056 \begin_layout Plain Layout
10058     Family              Sans
10059 \end_layout
10061 \begin_layout Plain Layout
10063     Size                Large
10064 \end_layout
10066 \begin_layout Plain Layout
10068     Series              Bold
10069 \end_layout
10071 \begin_layout Plain Layout
10073     Shape               Italic
10074 \end_layout
10076 \begin_layout Plain Layout
10078     Color               red
10079 \end_layout
10081 \begin_layout Plain Layout
10083   EndFont
10084 \end_layout
10086 \begin_layout Plain Layout
10089 \end_layout
10091 \end_inset
10094 \end_layout
10096 \begin_layout Subsection
10097 The chunkref style
10098 \end_layout
10100 \begin_layout Standard
10101 We also define the Chunkref style which can be used to express cross references
10102  to chunks.
10103 \end_layout
10105 \begin_layout Chunk
10106 chunkref
10107 \end_layout
10109 \begin_layout Standard
10110 \begin_inset listings
10111 inline false
10112 status open
10114 \begin_layout Plain Layout
10116 InsetLayout Chunkref
10117 \end_layout
10119 \begin_layout Plain Layout
10121   LyxType               charstyle
10122 \end_layout
10124 \begin_layout Plain Layout
10126   LatexType             Command
10127 \end_layout
10129 \begin_layout Plain Layout
10131   LatexName             chunkref
10132 \end_layout
10134 \begin_layout Plain Layout
10136   PassThru              1
10137 \end_layout
10139 \begin_layout Plain Layout
10141   LabelFont             
10142 \end_layout
10144 \begin_layout Plain Layout
10146     Shape               Italic
10147 \end_layout
10149 \begin_layout Plain Layout
10151     Color               red
10152 \end_layout
10154 \begin_layout Plain Layout
10156   EndFont
10157 \end_layout
10159 \begin_layout Plain Layout
10162 \end_layout
10164 \end_inset
10167 \end_layout
10169 \begin_layout Section
10170 \begin_inset CommandInset label
10171 LatexCommand label
10172 name "sec:Latex-Macros"
10174 \end_inset
10176 Latex Macros
10177 \end_layout
10179 \begin_layout Standard
10180 We require the 
10181 \noun on
10182 listings
10183 \noun default
10185 \noun on
10186 noweb
10187 \noun default
10188  and 
10189 \noun on
10190 xargs
10191 \noun default
10192  packages.
10193  As noweb defines it's own 
10194 \begin_inset Flex CharStyle:Code
10195 status collapsed
10197 \begin_layout Plain Layout
10199 \backslash
10200 code
10201 \end_layout
10203 \end_inset
10205  environment, we re-define the one that LyX logical markup module expects
10206  here.
10207 \end_layout
10209 \begin_layout Chunk
10210 ./newfangle.sty,language=tex,basicstyle=
10211 \backslash
10212 ttfamily
10213 \end_layout
10215 \begin_layout Standard
10216 \begin_inset listings
10217 inline false
10218 status open
10220 \begin_layout Plain Layout
10223 \backslash
10224 usepackage{listings}%
10225 \end_layout
10227 \begin_layout Plain Layout
10230 \backslash
10231 usepackage{noweb}%
10232 \end_layout
10234 \begin_layout Plain Layout
10237 \backslash
10238 usepackage{xargs}%
10239 \end_layout
10241 \begin_layout Plain Layout
10244 \backslash
10245 renewcommand{
10246 \backslash
10247 code}[1]{
10248 \backslash
10249 texttt{#1}}%
10250 \end_layout
10252 \end_inset
10255 \end_layout
10257 \begin_layout Standard
10258 We also define a 
10259 \begin_inset Flex CharStyle:Code
10260 status collapsed
10262 \begin_layout Plain Layout
10263 CChunk
10264 \end_layout
10266 \end_inset
10268  macro, for use as: 
10269 \begin_inset Flex CharStyle:Code
10270 status collapsed
10272 \begin_layout Plain Layout
10274 \backslash
10275 begin{CChunk}
10276 \end_layout
10278 \end_inset
10280  which will need renaming to 
10281 \begin_inset Flex CharStyle:Code
10282 status collapsed
10284 \begin_layout Plain Layout
10286 \backslash
10287 begin{Chunk}
10288 \end_layout
10290 \end_inset
10292  when I can do this without clashing with 
10293 \begin_inset Flex CharStyle:Code
10294 status collapsed
10296 \begin_layout Plain Layout
10298 \backslash
10299 Chunk
10300 \end_layout
10302 \end_inset
10305 \end_layout
10307 \begin_layout Standard
10308 \begin_inset listings
10309 inline false
10310 status open
10312 \begin_layout Plain Layout
10315 \backslash
10316 lstnewenvironment{Chunk}{
10317 \backslash
10318 relax}{
10319 \backslash
10320 relax}%
10321 \end_layout
10323 \end_inset
10326 \end_layout
10328 \begin_layout Standard
10329 We also define a suitable 
10330 \begin_inset Flex CharStyle:Code
10331 status collapsed
10333 \begin_layout Plain Layout
10335 \backslash
10336 lstset
10337 \end_layout
10339 \end_inset
10341  of parameters that suit the literate programming style after the fashion
10342  of 
10343 \noun on
10344 noweave
10345 \noun default
10347 \end_layout
10349 \begin_layout Standard
10350 \begin_inset listings
10351 inline false
10352 status open
10354 \begin_layout Plain Layout
10357 \backslash
10358 lstset{numbers=left, stepnumber=5, numbersep=5pt,
10359 \end_layout
10361 \begin_layout Plain Layout
10363         breaklines=false,basicstyle=
10364 \backslash
10365 ttfamily,
10366 \end_layout
10368 \begin_layout Plain Layout
10370         numberstyle=
10371 \backslash
10372 tiny, language=C}%
10373 \end_layout
10375 \end_inset
10378 \end_layout
10380 \begin_layout Standard
10381 We also define a notangle-like mechanism for 
10382 \emph on
10383 escaping
10384 \emph default
10385  to LaTeX from the listing, and by which we can refer to other listings.
10386  We declare the 
10387 \begin_inset Flex CharStyle:Code
10388 status collapsed
10390 \begin_layout Plain Layout
10391 =<\SpecialChar \ldots{}
10393 \end_layout
10395 \end_inset
10397  sequence to contain LaTeX code, and include another like this chunk: 
10398 \begin_inset Flex CharStyle:Code
10399 status collapsed
10401 \begin_layout Plain Layout
10403 \backslash
10404 chunkref{chunkname}>
10405 \end_layout
10407 \end_inset
10410  However, because 
10411 \begin_inset Flex CharStyle:Code
10412 status collapsed
10414 \begin_layout Plain Layout
10415 =<\SpecialChar \ldots{}
10417 \end_layout
10419 \end_inset
10421  is already defined to contain LaTeX code for this document --- this is
10422  a 
10423 \noun on
10424 newfangle
10425 \noun default
10426  document after all --- the code fragment below effectively contains the
10427  LaTeX code: 
10428 \begin_inset Flex CharStyle:Code
10429 status collapsed
10431 \begin_layout Plain Layout
10433 \end_layout
10435 \end_inset
10438  To avoid problems with document generation, I had to declare an lstlistings
10439  property: 
10440 \begin_inset Flex CharStyle:Code
10441 status collapsed
10443 \begin_layout Plain Layout
10444 escapeinside={}
10445 \end_layout
10447 \end_inset
10449  for this listing only; which in LyX was done by right-clicking the listings
10450  inset, choosing 
10451 \begin_inset Flex CharStyle:Code
10452 status collapsed
10454 \begin_layout Plain Layout
10455 settings
10456 \end_layout
10458 \end_inset
10460 \SpecialChar \menuseparator
10462 \begin_inset Flex CharStyle:Code
10463 status collapsed
10465 \begin_layout Plain Layout
10466 advanced
10467 \end_layout
10469 \end_inset
10472 \end_layout
10474 \begin_layout Standard
10475 \begin_inset Note Note
10476 status collapsed
10478 \begin_layout Plain Layout
10479 =< isn't enjoyed literally here, in a listing when the escape sequence is
10480  already defined as shown...
10481  we need to somehow escape this representation...
10482 \end_layout
10484 \end_inset
10487 \end_layout
10489 \begin_layout Standard
10490 \begin_inset listings
10491 lstparams "escapeinside={}"
10492 inline false
10493 status open
10495 \begin_layout Plain Layout
10498 \backslash
10499 lstset{escapeinside={=<}{>}}%
10500 \end_layout
10502 \end_inset
10505 \end_layout
10507 \begin_layout Standard
10508 Although our macros will contain the @ symbol, they will be included in
10509  a 
10510 \begin_inset Flex CharStyle:Code
10511 status collapsed
10513 \begin_layout Plain Layout
10515 \backslash
10516 makeatletter
10517 \end_layout
10519 \end_inset
10521  section by LyX; however we keep the commented out 
10522 \begin_inset Flex CharStyle:Code
10523 status collapsed
10525 \begin_layout Plain Layout
10527 \backslash
10528 makeatletter
10529 \end_layout
10531 \end_inset
10533  as a reminder.
10534  The listings package likes to centre the titles, but noweb titles are specially
10535  formatted and must be left aligned.
10536  The simplest way to do this turned out to be by removing the definition
10537  of 
10538 \begin_inset Flex CharStyle:Code
10539 status collapsed
10541 \begin_layout Plain Layout
10543 \backslash
10544 lst@maketitle
10545 \end_layout
10547 \end_inset
10550  This may interact badly if other listings want a regular title or caption.
10551  We remember the old maketitle in case we need it.
10552 \end_layout
10554 \begin_layout Standard
10555 \begin_inset listings
10556 inline false
10557 status open
10559 \begin_layout Plain Layout
10562 \backslash
10563 makeatletter
10564 \end_layout
10566 \begin_layout Plain Layout
10568 %somehow re-defining maketitle gives us a left-aligned title
10569 \end_layout
10571 \begin_layout Plain Layout
10573 %which is extactly what our specially formatted title needs!
10574 \end_layout
10576 \begin_layout Plain Layout
10579 \backslash
10580 global
10581 \backslash
10583 \backslash
10584 newfangle@lst@maketitle
10585 \backslash
10586 lst@maketitle%
10587 \end_layout
10589 \begin_layout Plain Layout
10592 \backslash
10593 global
10594 \backslash
10596 \backslash
10597 lst@maketitle{}%
10598 \end_layout
10600 \end_inset
10603 \end_layout
10605 \begin_layout Subsection
10606 \begin_inset CommandInset label
10607 LatexCommand label
10608 name "sub:The-chunk-command"
10610 \end_inset
10612 The chunk command
10613 \end_layout
10615 \begin_layout Standard
10616 Our chunk command accepts one argument, and calls 
10617 \begin_inset Flex CharStyle:Code
10618 status collapsed
10620 \begin_layout Plain Layout
10622 \backslash
10623 ltset
10624 \end_layout
10626 \end_inset
10629  Although 
10630 \begin_inset Flex CharStyle:Code
10631 status collapsed
10633 \begin_layout Plain Layout
10635 \backslash
10636 ltset
10637 \end_layout
10639 \end_inset
10641  will note the name, this is erased when the next 
10642 \begin_inset Flex CharStyle:Code
10643 status collapsed
10645 \begin_layout Plain Layout
10647 \backslash
10648 lstlisting
10649 \end_layout
10651 \end_inset
10653  starts, so we make a note of this in 
10654 \begin_inset Flex CharStyle:Code
10655 status collapsed
10657 \begin_layout Plain Layout
10659 \backslash
10660 lst@chunkname
10661 \end_layout
10663 \end_inset
10665  and restore in in lstlistings Init hook.
10666 \end_layout
10668 \begin_layout Standard
10669 \begin_inset listings
10670 inline false
10671 status open
10673 \begin_layout Plain Layout
10676 \backslash
10678 \backslash
10679 Chunk#1{%
10680 \end_layout
10682 \begin_layout Plain Layout
10684   
10685 \backslash
10686 lstset{title={
10687 \backslash
10688 newfanglecaption},name=#1}%
10689 \end_layout
10691 \begin_layout Plain Layout
10693   
10694 \backslash
10695 global
10696 \backslash
10697 edef
10698 \backslash
10699 lst@chunkname{
10700 \backslash
10701 lst@intname}%
10702 \end_layout
10704 \begin_layout Plain Layout
10707 \end_layout
10709 \begin_layout Plain Layout
10712 \backslash
10714 \backslash
10715 lst@chunkname{
10716 \backslash
10717 empty}%
10718 \end_layout
10720 \end_inset
10723 \end_layout
10725 \begin_layout Subsubsection
10726 Chunk parameters
10727 \end_layout
10729 \begin_layout Standard
10730 Newfangle permits parameterized chunks, and requires the paramters to be
10731  specified as listings options.
10732  The newfangle script uses this, and although we don't do anything with
10733  these in the LaTeX code right now, we need to stop the listings package
10734  complaining.
10735 \end_layout
10737 \begin_layout Standard
10738 \begin_inset listings
10739 inline false
10740 status open
10742 \begin_layout Plain Layout
10745 \backslash
10746 lst@Key{params}
10747 \backslash
10748 relax{
10749 \backslash
10751 \backslash
10752 newfangle@chunk@params{#1}}%
10753 \end_layout
10755 \end_inset
10758 \end_layout
10760 \begin_layout Subsection
10761 The noweb styled caption
10762 \end_layout
10764 \begin_layout Standard
10765 We define a public macro 
10766 \begin_inset Flex CharStyle:Code
10767 status collapsed
10769 \begin_layout Plain Layout
10771 \backslash
10772 newfanglecaption
10773 \end_layout
10775 \end_inset
10777  which can be set as a regular title.
10778  By means of 
10779 \begin_inset Flex CharStyle:Code
10780 status collapsed
10782 \begin_layout Plain Layout
10784 \backslash
10785 protect
10786 \end_layout
10788 \end_inset
10790 , It expands to 
10791 \begin_inset Flex CharStyle:Code
10792 status collapsed
10794 \begin_layout Plain Layout
10796 \backslash
10797 newfangle@caption
10798 \end_layout
10800 \end_inset
10802  at the appriate time when the caption is emitted.
10803 \end_layout
10805 \begin_layout Standard
10806 \begin_inset listings
10807 inline false
10808 status open
10810 \begin_layout Plain Layout
10813 \backslash
10815 \backslash
10816 newfanglecaption{
10817 \backslash
10818 protect
10819 \backslash
10820 newfangle@caption}%
10821 \end_layout
10823 \end_inset
10826 \end_layout
10828 \begin_layout Standard
10829 \begin_inset Float figure
10830 placement H
10831 wide false
10832 sideways false
10833 status collapsed
10835 \begin_layout Plain Layout
10836 \begin_inset Box Boxed
10837 position "t"
10838 hor_pos "c"
10839 has_inner_box 1
10840 inner_pos "t"
10841 use_parbox 0
10842 width "100col%"
10843 special "none"
10844 height "1in"
10845 height_special "totalheight"
10846 status open
10848 \begin_layout Plain Layout
10850 \begin_inset space \qquad{}
10851 \end_inset
10854 \shape italic
10855 some-chunk
10856 \shape default
10857  19b⟩
10858 \begin_inset Formula $\equiv+$
10859 \end_inset
10862 \begin_inset space \qquad{}
10863 \end_inset
10866 \begin_inset space \qquad{}
10867 \end_inset
10870 \begin_inset space \qquad{}
10871 \end_inset
10874 \begin_inset Formula $\triangleleft$
10875 \end_inset
10878 \begin_inset space \quad{}
10879 \end_inset
10882 \begin_inset Formula $\triangleright$
10883 \end_inset
10886 \end_layout
10888 \begin_layout Plain Layout
10890 \size footnotesize
10891 In this example, the current chunk is 22c, and therefore the third chunk
10892  on page 22.
10893 \end_layout
10895 \begin_layout Plain Layout
10897 \size footnotesize
10898 It's name is 
10899 \emph on
10900 some-chunk
10901 \emph default
10904 \end_layout
10906 \begin_layout Plain Layout
10908 \size footnotesize
10909 The first chunk with this name (19b) occurs as the second chunk on page
10910  19.
10911 \end_layout
10913 \begin_layout Plain Layout
10915 \size footnotesize
10916 The previous chunk (22d) with the same name is the second chunk on page
10917  22.
10918 \end_layout
10920 \begin_layout Plain Layout
10922 \size footnotesize
10923 The next chunk (24d) is the fourth chunk on page 24.
10924 \end_layout
10926 \begin_layout Plain Layout
10927 \begin_inset Caption
10929 \begin_layout Plain Layout
10930 noweb heading
10931 \end_layout
10933 \end_inset
10936 \end_layout
10938 \end_inset
10941 \end_layout
10943 \end_inset
10945 The general noweb output format compactly identifies the current chunk,
10946  and references to the first chunk, and the previous and next chunks that
10947  have the same name.
10949 \end_layout
10951 \begin_layout Standard
10952 This means that we need to keep a counter for each chunk-name, that we use
10953  to count chunks of the same name.
10955 \end_layout
10957 \begin_layout Subsection
10958 The chunk counter
10959 \end_layout
10961 \begin_layout Standard
10962 It would be natural to have a counter for each chunk name, but TeX would
10963  soon run out of counters
10964 \begin_inset Foot
10965 status collapsed
10967 \begin_layout Plain Layout
10968 \SpecialChar \ldots{}
10969 soon 
10970 \emph on
10972 \emph default
10973  run out of counters and so I had to re-write the LaTeX macros to share
10974  a counter as described here
10975 \end_layout
10977 \end_inset
10979 , so we have one counter which we save at the end of a chunk and restore
10980  at the beginning of a chunk.
10981 \end_layout
10983 \begin_layout Standard
10984 \begin_inset listings
10985 inline false
10986 status open
10988 \begin_layout Plain Layout
10991 \backslash
10992 newcounter{newfangle@chunkcounter}%
10993 \end_layout
10995 \end_inset
10998 \end_layout
11000 \begin_layout Standard
11001 We construct the name of this variable to store the counter to be the text
11003 \begin_inset Flex CharStyle:Code
11004 status collapsed
11006 \begin_layout Plain Layout
11007 lst-chunk-
11008 \end_layout
11010 \end_inset
11012  prefixed onto the chunks own name, and store it in 
11013 \begin_inset Flex CharStyle:Code
11014 status collapsed
11016 \begin_layout Plain Layout
11018 \backslash
11019 chunkcount
11020 \end_layout
11022 \end_inset
11026 \end_layout
11028 \begin_layout Standard
11029 We save the counter like this:
11030 \end_layout
11032 \begin_layout Chunk
11033 save-counter
11034 \end_layout
11036 \begin_layout Standard
11037 \begin_inset listings
11038 inline false
11039 status open
11041 \begin_layout Plain Layout
11044 \backslash
11045 global
11046 \backslash
11047 expandafter
11048 \backslash
11049 edef
11050 \backslash
11051 csname 
11052 \backslash
11053 chunkcount
11054 \backslash
11055 endcsname{
11056 \backslash
11057 arabic{newfangle@chunkcounter}}%
11058 \end_layout
11060 \end_inset
11063 \end_layout
11065 \begin_layout Standard
11066 and restore the counter like this:
11067 \end_layout
11069 \begin_layout Chunk
11070 restore-counter
11071 \end_layout
11073 \begin_layout Standard
11074 \begin_inset listings
11075 inline false
11076 status open
11078 \begin_layout Plain Layout
11081 \backslash
11082 setcounter{newfangle@chunkcounter}{
11083 \backslash
11084 csname 
11085 \backslash
11086 chunkcount
11087 \backslash
11088 endcsname}%
11089 \end_layout
11091 \end_inset
11094 \end_layout
11096 \begin_layout Chunk
11097 ./newfangle.sty
11098 \end_layout
11100 \begin_layout Standard
11101 If there does not already exist a variable whose name is stored in 
11102 \begin_inset Flex CharStyle:Code
11103 status collapsed
11105 \begin_layout Plain Layout
11107 \backslash
11108 chunkcount
11109 \end_layout
11111 \end_inset
11113 , then we know we are the first chunk with this name, and then define a
11114  counter.
11116 \end_layout
11118 \begin_layout Standard
11119 Although chunks of the same name share a common counter, they must still
11120  be distinguished.
11121  We use is the internal name of the listing, suffixed by the counter value.
11122  So the first chunk might be 
11123 \begin_inset Flex CharStyle:Code
11124 status collapsed
11126 \begin_layout Plain Layout
11127 something-1
11128 \end_layout
11130 \end_inset
11132  and the second chunk be 
11133 \begin_inset Flex CharStyle:Code
11134 status collapsed
11136 \begin_layout Plain Layout
11137 something-2
11138 \end_layout
11140 \end_inset
11142 , etc.
11143 \end_layout
11145 \begin_layout Standard
11146 We also calculate the name of the previous chunk if we can (before we increment
11147  the chunk counter).
11148  If this is the first chunk of that name, then 
11149 \begin_inset Flex CharStyle:Code
11150 status collapsed
11152 \begin_layout Plain Layout
11154 \backslash
11155 prevchunkname
11156 \end_layout
11158 \end_inset
11160  is set to 
11161 \begin_inset Flex CharStyle:Code
11162 status collapsed
11164 \begin_layout Plain Layout
11166 \backslash
11167 relax
11168 \end_layout
11170 \end_inset
11172  which the noweb package will interpret as not existing.
11173 \end_layout
11175 \begin_layout Standard
11176 \begin_inset listings
11177 inline false
11178 status open
11180 \begin_layout Plain Layout
11183 \backslash
11185 \backslash
11186 newfangle@caption{%
11187 \end_layout
11189 \begin_layout Plain Layout
11191   
11192 \backslash
11193 edef
11194 \backslash
11195 chunkcount{lst-chunk-
11196 \backslash
11197 lst@intname}%
11198 \end_layout
11200 \begin_layout Plain Layout
11202   
11203 \backslash
11204 @ifundefined{
11205 \backslash
11206 chunkcount}{%
11207 \end_layout
11209 \begin_layout Plain Layout
11211     
11212 \backslash
11213 expandafter
11214 \backslash
11215 gdef
11216 \backslash
11217 csname 
11218 \backslash
11219 chunkcount
11220 \backslash
11221 endcsname{0}%
11222 \end_layout
11224 \begin_layout Plain Layout
11226     
11227 \backslash
11228 setcounter{newfangle@chunkcounter}{
11229 \backslash
11230 csname 
11231 \backslash
11232 chunkcount
11233 \backslash
11234 endcsname}%
11235 \end_layout
11237 \begin_layout Plain Layout
11239     
11240 \backslash
11242 \backslash
11243 prevchunkname
11244 \backslash
11245 relax%
11246 \end_layout
11248 \begin_layout Plain Layout
11250   }{%
11251 \end_layout
11253 \begin_layout Plain Layout
11255     
11256 \backslash
11257 setcounter{newfangle@chunkcounter}{
11258 \backslash
11259 csname 
11260 \backslash
11261 chunkcount
11262 \backslash
11263 endcsname}%
11264 \end_layout
11266 \begin_layout Plain Layout
11268     
11269 \backslash
11270 edef
11271 \backslash
11272 prevchunkname{
11273 \backslash
11274 lst@intname-
11275 \backslash
11276 arabic{newfangle@chunkcounter}}%
11277 \end_layout
11279 \begin_layout Plain Layout
11281   }%
11282 \end_layout
11284 \end_inset
11287 \end_layout
11289 \begin_layout Standard
11290 After incrementing the chunk counter, we then define the name of this chunk,
11291  as well as the name of the first chunk.
11292 \end_layout
11294 \begin_layout Standard
11295 \begin_inset listings
11296 inline false
11297 status open
11299 \begin_layout Plain Layout
11301   
11302 \backslash
11303 addtocounter{newfangle@chunkcounter}{1}%
11304 \end_layout
11306 \begin_layout Plain Layout
11308   
11309 \backslash
11310 global
11311 \backslash
11312 expandafter
11313 \backslash
11314 edef
11315 \backslash
11316 csname 
11317 \backslash
11318 chunkcount
11319 \backslash
11320 endcsname{
11321 \backslash
11322 arabic{newfangle@chunkcounter}}%
11323 \end_layout
11325 \begin_layout Plain Layout
11327   
11328 \backslash
11329 edef
11330 \backslash
11331 chunkname{
11332 \backslash
11333 lst@intname-
11334 \backslash
11335 arabic{newfangle@chunkcounter}}%
11336 \end_layout
11338 \begin_layout Plain Layout
11340   
11341 \backslash
11342 edef
11343 \backslash
11344 firstchunkname{
11345 \backslash
11346 lst@intname-1}%
11347 \end_layout
11349 \end_inset
11352 \end_layout
11354 \begin_layout Standard
11355 We now need to calculate the name of the next chunk.
11356  We do this by temporarily skipping the counter on by one; however there
11357  may not actually be another chunk with this name! We detect this by also
11358  defining a label for each chunk based on the chunkname.
11359  If there is a next chunkname then it will define a label with that name.
11360  As labels are persistent, we can at least tell the second time LaTeX is
11361  run.
11362  If we don't find such a defined label then we define 
11363 \begin_inset Flex CharStyle:Code
11364 status collapsed
11366 \begin_layout Plain Layout
11368 \backslash
11369 nextchunkname
11370 \end_layout
11372 \end_inset
11374  to 
11375 \begin_inset Flex CharStyle:Code
11376 status collapsed
11378 \begin_layout Plain Layout
11380 \backslash
11381 relax
11382 \end_layout
11384 \end_inset
11387 \end_layout
11389 \begin_layout Standard
11390 \begin_inset listings
11391 inline false
11392 status open
11394 \begin_layout Plain Layout
11396   
11397 \backslash
11398 addtocounter{newfangle@chunkcounter}{1}%
11399 \end_layout
11401 \begin_layout Plain Layout
11403   
11404 \backslash
11405 edef
11406 \backslash
11407 nextchunkname{
11408 \backslash
11409 lst@intname-
11410 \backslash
11411 arabic{newfangle@chunkcounter}}%
11412 \end_layout
11414 \begin_layout Plain Layout
11416   
11417 \backslash
11418 @ifundefined{r@label-
11419 \backslash
11420 nextchunkname}{
11421 \backslash
11423 \backslash
11424 nextchunkname
11425 \backslash
11426 relax}{}%
11427 \end_layout
11429 \end_inset
11432 \end_layout
11434 \begin_layout Standard
11435 The noweb package requires that we define a 
11436 \begin_inset Flex CharStyle:Code
11437 status collapsed
11439 \begin_layout Plain Layout
11441 \backslash
11442 sublabel
11443 \end_layout
11445 \end_inset
11447  for every chunk, with a unique name, which is then used to print out it's
11448  navigation hints.
11449 \end_layout
11451 \begin_layout Standard
11452 We also define a regular label for this chunk, as was mentioned above when
11453  we calculated 
11454 \begin_inset Flex CharStyle:Code
11455 status collapsed
11457 \begin_layout Plain Layout
11459 \backslash
11460 nextchunkname
11461 \end_layout
11463 \end_inset
11466  This requires LaTeX to be run at least twice after new chunk sections are
11467  added --- but noweb requried that anyway.
11468 \end_layout
11470 \begin_layout Standard
11471 \begin_inset listings
11472 inline false
11473 status open
11475 \begin_layout Plain Layout
11477   
11478 \backslash
11479 sublabel{
11480 \backslash
11481 chunkname}%
11482 \end_layout
11484 \begin_layout Plain Layout
11486 % define this label for every chunk instance, so we
11487 \end_layout
11489 \begin_layout Plain Layout
11491 % can tell when we are the last chunk of this name
11492 \end_layout
11494 \begin_layout Plain Layout
11496   
11497 \backslash
11498 label{label-
11499 \backslash
11500 chunkname}%
11501 \end_layout
11503 \end_inset
11506 \end_layout
11508 \begin_layout Standard
11509 We also try and add the chunk to the list of listings, but I'm afraid we
11510  don't do very well.
11511  We want each chunk name listing once, with all of it's references.
11512 \end_layout
11514 \begin_layout Standard
11515 \begin_inset listings
11516 inline false
11517 status open
11519 \begin_layout Plain Layout
11521   
11522 \backslash
11523 addcontentsline{lol}{lstlisting}{
11524 \backslash
11525 lst@name~[
11526 \backslash
11527 protect
11528 \backslash
11529 subpageref{
11530 \backslash
11531 chunkname}]}%
11532 \end_layout
11534 \end_inset
11537 \end_layout
11539 \begin_layout Standard
11540 We then call the noweb output macros in the same way that noweave generates
11541  them, except that we don't need to call 
11542 \begin_inset Flex CharStyle:Code
11543 status collapsed
11545 \begin_layout Plain Layout
11547 \backslash
11548 nwstartdeflinemarkup
11549 \end_layout
11551 \end_inset
11553  or 
11554 \begin_inset Flex CharStyle:Code
11555 status collapsed
11557 \begin_layout Plain Layout
11559 \backslash
11560 nwenddeflinemarkup
11561 \end_layout
11563 \end_inset
11565  -- and if we do it messes up the output somewhat.
11566 \end_layout
11568 \begin_layout Standard
11569 \begin_inset listings
11570 inline false
11571 status open
11573 \begin_layout Plain Layout
11575   
11576 \backslash
11577 nwmargintag{%
11578 \end_layout
11580 \begin_layout Plain Layout
11582     {%
11583 \end_layout
11585 \begin_layout Plain Layout
11587       
11588 \backslash
11589 nwtagstyle{}%
11590 \end_layout
11592 \begin_layout Plain Layout
11594       
11595 \backslash
11596 subpageref{
11597 \backslash
11598 chunkname}%
11599 \end_layout
11601 \begin_layout Plain Layout
11603     }%
11604 \end_layout
11606 \begin_layout Plain Layout
11608   }%
11609 \end_layout
11611 \begin_layout Plain Layout
11614 \end_layout
11616 \begin_layout Plain Layout
11618   
11619 \backslash
11620 moddef{%
11621 \end_layout
11623 \begin_layout Plain Layout
11625     {
11626 \backslash
11627 lst@name}%
11628 \end_layout
11630 \begin_layout Plain Layout
11632     {%
11633 \end_layout
11635 \begin_layout Plain Layout
11637       
11638 \backslash
11639 nwtagstyle{}
11640 \backslash
11642 \end_layout
11644 \begin_layout Plain Layout
11646       
11647 \backslash
11648 @ifundefined{newfangle@chunk@params}{}{%
11649 \end_layout
11651 \begin_layout Plain Layout
11653         (
11654 \backslash
11655 newfangle@chunk@params)%
11656 \end_layout
11658 \begin_layout Plain Layout
11660       }%
11661 \end_layout
11663 \begin_layout Plain Layout
11665       [
11666 \backslash
11667 csname 
11668 \backslash
11669 chunkcount
11670 \backslash
11671 endcsname]~%%
11672 \end_layout
11674 \begin_layout Plain Layout
11676       
11677 \backslash
11678 subpageref{
11679 \backslash
11680 firstchunkname}%
11681 \end_layout
11683 \begin_layout Plain Layout
11685     }%
11686 \end_layout
11688 \begin_layout Plain Layout
11690   }%
11691 \end_layout
11693 \begin_layout Plain Layout
11696 \end_layout
11698 \begin_layout Plain Layout
11700   
11701 \backslash
11703 \backslash
11704 relax
11705 \backslash
11706 prevchunkname
11707 \backslash
11708 endmoddef
11709 \backslash
11710 else
11711 \backslash
11712 plusendmoddef
11713 \backslash
11715 \end_layout
11717 \begin_layout Plain Layout
11719 %  
11720 \backslash
11721 nwstartdeflinemarkup%
11722 \end_layout
11724 \begin_layout Plain Layout
11726   
11727 \backslash
11728 nwprevnextdefs{
11729 \backslash
11730 prevchunkname}{
11731 \backslash
11732 nextchunkname}%
11733 \end_layout
11735 \begin_layout Plain Layout
11737 %  
11738 \backslash
11739 nwenddeflinemarkup%
11740 \end_layout
11742 \begin_layout Plain Layout
11745 \end_layout
11747 \end_inset
11750 \end_layout
11752 \begin_layout Standard
11753 Originally this was developed as a 
11754 \begin_inset Flex CharStyle:Code
11755 status collapsed
11757 \begin_layout Plain Layout
11758 listings
11759 \end_layout
11761 \end_inset
11763  aspect, in the Init hook, but it was found easier to affect the title without
11764  using a hook --- 
11765 \begin_inset Flex CharStyle:Code
11766 status collapsed
11768 \begin_layout Plain Layout
11770 \backslash
11771 lst@AddToHookExe{PreSet}
11772 \end_layout
11774 \end_inset
11776  is still required to set the listings name to the name passed to the 
11777 \begin_inset Flex CharStyle:Code
11778 status collapsed
11780 \begin_layout Plain Layout
11782 \backslash
11783 Chunk
11784 \end_layout
11786 \end_inset
11788  command, though.
11789 \end_layout
11791 \begin_layout Standard
11792 \begin_inset listings
11793 inline false
11794 status open
11796 \begin_layout Plain Layout
11799 \backslash
11800 lst@BeginAspect{newfangle}
11801 \end_layout
11803 \begin_layout Plain Layout
11806 \backslash
11807 lst@Key{newfangle}{true}[t]{
11808 \backslash
11809 lstKV@SetIf{#1}{true}}
11810 \end_layout
11812 \begin_layout Plain Layout
11815 \backslash
11816 lst@AddToHookExe{PreSet}{
11817 \backslash
11818 global
11819 \backslash
11821 \backslash
11822 lst@intname
11823 \backslash
11824 lst@chunkname}
11825 \end_layout
11827 \begin_layout Plain Layout
11830 \backslash
11831 lst@AddToHook{Init}{}%
11832 \backslash
11833 newfangle@caption}
11834 \end_layout
11836 \begin_layout Plain Layout
11839 \backslash
11840 lst@EndAspect
11841 \end_layout
11843 \end_inset
11846 \end_layout
11848 \begin_layout Subsection
11849 Cross references
11850 \end_layout
11852 \begin_layout Standard
11853 We define the 
11854 \backslash
11855 chunkref command which makes it easy to generate visual references to different
11856  code chunks, e.g.
11857 \end_layout
11859 \begin_layout Standard
11860 \begin_inset Tabular
11861 <lyxtabular version="3" rows="4" columns="2">
11862 <features>
11863 <column alignment="center" valignment="top" width="0">
11864 <column alignment="center" valignment="top" width="0">
11865 <row>
11866 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
11867 \begin_inset Text
11869 \begin_layout Plain Layout
11870 Macro
11871 \end_layout
11873 \end_inset
11874 </cell>
11875 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
11876 \begin_inset Text
11878 \begin_layout Plain Layout
11879 Appearance
11880 \end_layout
11882 \end_inset
11883 </cell>
11884 </row>
11885 <row>
11886 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
11887 \begin_inset Text
11889 \begin_layout Plain Layout
11891 \backslash
11892 chunkref{preamble}
11893 \end_layout
11895 \end_inset
11896 </cell>
11897 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
11898 \begin_inset Text
11900 \begin_layout Plain Layout
11901 \begin_inset ERT
11902 status open
11904 \begin_layout Plain Layout
11907 \backslash
11908 chunkref{preamble}
11909 \end_layout
11911 \end_inset
11914 \end_layout
11916 \end_inset
11917 </cell>
11918 </row>
11919 <row>
11920 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
11921 \begin_inset Text
11923 \begin_layout Plain Layout
11925 \backslash
11926 chunkref[3]{preamble}
11927 \end_layout
11929 \end_inset
11930 </cell>
11931 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
11932 \begin_inset Text
11934 \begin_layout Plain Layout
11935 \begin_inset ERT
11936 status open
11938 \begin_layout Plain Layout
11941 \backslash
11942 chunkref[3]{preamble}
11943 \end_layout
11945 \end_inset
11948 \end_layout
11950 \end_inset
11951 </cell>
11952 </row>
11953 <row>
11954 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
11955 \begin_inset Text
11957 \begin_layout Plain Layout
11959 \backslash
11960 chunkref{preamble}[arg1, arg2]
11961 \end_layout
11963 \end_inset
11964 </cell>
11965 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
11966 \begin_inset Text
11968 \begin_layout Plain Layout
11969 \begin_inset ERT
11970 status open
11972 \begin_layout Plain Layout
11975 \backslash
11976 chunkref{preamble}[arg1, arg2]
11977 \end_layout
11979 \end_inset
11982 \end_layout
11984 \end_inset
11985 </cell>
11986 </row>
11987 </lyxtabular>
11989 \end_inset
11992 \end_layout
11994 \begin_layout Standard
11995 Chunkref can also be used within a code chunk to include another code chunk.
11996  The third optional parameter to chunkref is a comma sepatarated list of
11997  arguments, which will replace defined parameters in the chunkref.
11998 \begin_inset Note Note
11999 status open
12001 \begin_layout Plain Layout
12002 Darn it, if I have: =<
12003 \backslash
12004 chunkref{new-mode}[{chunks[chunk_name, "language"]},{mode}]> the inner braces
12005  (inside [ ]) cause _ to signify subscript even though we have lst@ReplaceIn
12006 \end_layout
12008 \end_inset
12011 \end_layout
12013 \begin_layout Standard
12014 \begin_inset listings
12015 inline false
12016 status open
12018 \begin_layout Plain Layout
12021 \backslash
12023 \backslash
12024 chunkref@args#1,{%
12025 \end_layout
12027 \begin_layout Plain Layout
12029   
12030 \backslash
12032 \backslash
12033 arg{#1}%
12034 \end_layout
12036 \begin_layout Plain Layout
12038   
12039 \backslash
12040 lst@ReplaceIn
12041 \backslash
12043 \backslash
12044 lst@filenamerpl%
12045 \end_layout
12047 \begin_layout Plain Layout
12049   
12050 \backslash
12051 arg%
12052 \end_layout
12054 \begin_layout Plain Layout
12056   
12057 \backslash
12058 @ifnextchar){
12059 \backslash
12060 relax}{, 
12061 \backslash
12062 chunkref@args}%
12063 \end_layout
12065 \begin_layout Plain Layout
12068 \end_layout
12070 \begin_layout Plain Layout
12073 \backslash
12074 newcommand
12075 \backslash
12076 chunkref[2][0]{%
12077 \end_layout
12079 \begin_layout Plain Layout
12081   
12082 \backslash
12083 @ifnextchar({
12084 \backslash
12085 chunkref@i{#1}{#2}}{
12086 \backslash
12087 chunkref@i{#1}{#2}()}%
12088 \end_layout
12090 \begin_layout Plain Layout
12093 \end_layout
12095 \begin_layout Plain Layout
12098 \backslash
12100 \backslash
12101 chunkref@i#1#2(#3){%
12102 \end_layout
12104 \begin_layout Plain Layout
12106   
12107 \backslash
12109 \backslash
12110 zero{0}%
12111 \end_layout
12113 \begin_layout Plain Layout
12115   
12116 \backslash
12118 \backslash
12119 chunk{#2}%
12120 \end_layout
12122 \begin_layout Plain Layout
12124   
12125 \backslash
12127 \backslash
12128 chunkno{#1}%
12129 \end_layout
12131 \begin_layout Plain Layout
12133   
12134 \backslash
12136 \backslash
12137 chunkargs{#3}%
12138 \end_layout
12140 \begin_layout Plain Layout
12142   
12143 \backslash
12145 \backslash
12146 chunkno
12147 \backslash
12148 zero%
12149 \end_layout
12151 \begin_layout Plain Layout
12153     
12154 \backslash
12156 \backslash
12157 chunkname{#2-1}%
12158 \end_layout
12160 \begin_layout Plain Layout
12162   
12163 \backslash
12164 else%
12165 \end_layout
12167 \begin_layout Plain Layout
12169     
12170 \backslash
12172 \backslash
12173 chunkname{#2-
12174 \backslash
12175 chunkno}%
12176 \end_layout
12178 \begin_layout Plain Layout
12180   
12181 \backslash
12183 \end_layout
12185 \begin_layout Plain Layout
12187   
12188 \backslash
12190 \backslash
12191 lst@arg
12192 \backslash
12193 chunk%
12194 \end_layout
12196 \begin_layout Plain Layout
12198   
12199 \backslash
12200 lst@ReplaceIn
12201 \backslash
12202 chunk
12203 \backslash
12204 lst@filenamerpl%
12205 \end_layout
12207 \begin_layout Plain Layout
12209   
12210 \backslash
12211 LA{%
12212 \backslash
12213 moddef{%
12214 \end_layout
12216 \begin_layout Plain Layout
12218     {
12219 \backslash
12220 chunk}%
12221 \end_layout
12223 \begin_layout Plain Layout
12225     {%
12226 \end_layout
12228 \begin_layout Plain Layout
12230       
12231 \backslash
12232 nwtagstyle{}
12233 \backslash
12235 \end_layout
12237 \begin_layout Plain Layout
12239       
12240 \backslash
12242 \backslash
12243 chunkno
12244 \backslash
12245 zero%
12246 \end_layout
12248 \begin_layout Plain Layout
12250       
12251 \backslash
12252 else%
12253 \end_layout
12255 \begin_layout Plain Layout
12257       [
12258 \backslash
12259 chunkno]%
12260 \end_layout
12262 \begin_layout Plain Layout
12264       
12265 \backslash
12267 \end_layout
12269 \begin_layout Plain Layout
12271       
12272 \backslash
12274 \backslash
12275 chunkargs
12276 \backslash
12277 empty%
12278 \end_layout
12280 \begin_layout Plain Layout
12282       
12283 \backslash
12284 else%
12285 \end_layout
12287 \begin_layout Plain Layout
12289         (
12290 \backslash
12291 chunkref@args #3,)%
12292 \end_layout
12294 \begin_layout Plain Layout
12296       
12297 \backslash
12299 \end_layout
12301 \begin_layout Plain Layout
12303       ~
12304 \backslash
12305 subpageref{
12306 \backslash
12307 chunkname}%
12308 \end_layout
12310 \begin_layout Plain Layout
12312     }%
12313 \end_layout
12315 \begin_layout Plain Layout
12317   }%
12318 \end_layout
12320 \begin_layout Plain Layout
12322   
12323 \backslash
12325 \backslash
12326 endmoddef%
12327 \end_layout
12329 \begin_layout Plain Layout
12332 \end_layout
12334 \end_inset
12337 \end_layout
12339 \begin_layout Subsection
12340 The end
12341 \end_layout
12343 \begin_layout Standard
12344 \begin_inset listings
12345 inline false
12346 status open
12348 \begin_layout Plain Layout
12351 \end_layout
12353 \begin_layout Plain Layout
12356 \backslash
12357 makeatother
12358 \end_layout
12360 \end_inset
12363 \end_layout
12365 \begin_layout Chapter
12366 Extracting newfangle
12367 \end_layout
12369 \begin_layout Section
12370 Extracting from Lyx
12371 \end_layout
12373 \begin_layout Standard
12374 To extract from LyX, you will need to configure LyX as explained in section
12376 \begin_inset CommandInset ref
12377 LatexCommand ref
12378 reference "sub:Configuring-the-build"
12380 \end_inset
12383 \end_layout
12385 \begin_layout Standard
12386 \begin_inset CommandInset label
12387 LatexCommand label
12388 name "lyx-build-script"
12390 \end_inset
12392 And this lyx-build scrap will extract newfangle for me.
12393 \end_layout
12395 \begin_layout Chunk
12396 lyx-build,language=sh
12397 \end_layout
12399 \begin_layout Standard
12400 \begin_inset listings
12401 inline false
12402 status open
12404 \begin_layout Plain Layout
12406 #! /bin/sh
12407 \end_layout
12409 \begin_layout Plain Layout
12411 set -x
12412 \end_layout
12414 \begin_layout Plain Layout
12416 \end_layout
12418 \begin_layout Plain Layout
12421 \backslash
12422 chunkref{lyx-build-helper}>
12423 \end_layout
12425 \begin_layout Plain Layout
12427 cd $PROJECT_DIR || exit 1
12428 \end_layout
12430 \begin_layout Plain Layout
12432 \end_layout
12434 \begin_layout Plain Layout
12436 /usr/local/bin/newfangle -R./newfangle $TEX_SRC > ./newfangle
12437 \end_layout
12439 \begin_layout Plain Layout
12441 /usr/local/bin/newfangle -R./newfangle.module $TEX_SRC > ./newfangle.module
12442 \end_layout
12444 \end_inset
12447 \end_layout
12449 \begin_layout Standard
12450 With a lyx-build-helper
12451 \end_layout
12453 \begin_layout Chunk
12454 lyx-build-helper,language=sh
12455 \end_layout
12457 \begin_layout Standard
12458 \begin_inset listings
12459 inline false
12460 status open
12462 \begin_layout Plain Layout
12464 PROJECT_DIR="$LYX_r"
12465 \end_layout
12467 \begin_layout Plain Layout
12469 LYX_SRC="$PROJECT_DIR/${LYX_i%.tex}.lyx"
12470 \end_layout
12472 \begin_layout Plain Layout
12474 TEX_DIR="$LYX_p"
12475 \end_layout
12477 \begin_layout Plain Layout
12479 TEX_SRC="$TEX_DIR/$LYX_i"
12480 \end_layout
12482 \end_inset
12485 \end_layout
12487 \begin_layout Section
12488 Extracting from the command line
12489 \end_layout
12491 \begin_layout Standard
12492 First you will need the tex output, then you can extract:
12493 \end_layout
12495 \begin_layout Chunk
12496 lyx-build-manual,language=sh
12497 \end_layout
12499 \begin_layout Standard
12500 \begin_inset listings
12501 inline false
12502 status open
12504 \begin_layout Plain Layout
12506 lyx -e latex newfangle.lyx
12507 \end_layout
12509 \begin_layout Plain Layout
12511 newfangle -R./newfangle newfangle.tex > ./newfangle
12512 \end_layout
12514 \begin_layout Plain Layout
12516 newfangle -R./newfangle.module newfangle.tex > ./newfangle.module
12517 \end_layout
12519 \end_inset
12522 \end_layout
12524 \begin_layout Part
12525 Tests
12526 \end_layout
12528 \begin_layout Chapter
12529 Chunk Parameters
12530 \end_layout
12532 \begin_layout Chunk
12533 tests-sub,params=THING;colour
12534 \end_layout
12536 \begin_layout Standard
12537 \begin_inset listings
12538 inline false
12539 status open
12541 \begin_layout Plain Layout
12543 I see a ${THING} of 
12544 \end_layout
12546 \begin_layout Plain Layout
12548 colour ${colour}, 
12549 \end_layout
12551 \begin_layout Plain Layout
12553 looking closer =<
12554 \backslash
12555 chunkref{tests-sub-sub}(${colour})>
12556 \end_layout
12558 \end_inset
12561 \end_layout
12563 \begin_layout Chunk
12564 tests-sub-sub,params=colour
12565 \end_layout
12567 \begin_layout Standard
12568 \begin_inset listings
12569 inline false
12570 status open
12572 \begin_layout Plain Layout
12574 a funny shade of ${colour}
12575 \end_layout
12577 \end_inset
12580 \end_layout
12582 \begin_layout Chunk
12583 tests
12584 \end_layout
12586 \begin_layout Standard
12587 \begin_inset listings
12588 inline false
12589 status open
12591 \begin_layout Plain Layout
12593 What do you see? "=<
12594 \backslash
12595 chunkref{tests-sub}(joe, red)>"
12596 \end_layout
12598 \begin_layout Plain Layout
12600 Well, fancy!
12601 \end_layout
12603 \end_inset
12606 \end_layout
12608 \begin_layout Standard
12609 Should generate output:
12610 \end_layout
12612 \begin_layout Chunk
12613 tests-result
12614 \end_layout
12616 \begin_layout Standard
12617 \begin_inset listings
12618 inline false
12619 status open
12621 \begin_layout Plain Layout
12623 What do you see? "I see a joe of 
12624 \end_layout
12626 \begin_layout Plain Layout
12628                   colour red, 
12629 \end_layout
12631 \begin_layout Plain Layout
12633                   looking closer a funny shade of red"
12634 \end_layout
12636 \begin_layout Plain Layout
12638 Well, fancy!
12639 \end_layout
12641 \begin_layout Plain Layout
12643 \end_layout
12645 \end_inset
12648 \end_layout
12650 \end_body
12651 \end_document