Add compile-log-lyx which can go to the error line within an inset
[newfangle.git] / newfangle.lyx
blobe35d967380fc8976f4a4fc7100517b7d2e2c3efe
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 % newfangle - fully featured notangle replacement in awk
9 % Copyright (C) 2009 Sam Liddicott <sam@liddicott.com>
11 % This program is free software: you can redistribute it and/or modify
12 % it under the terms of the GNU General Public License as published by
13 % the Free Software Foundation, either version 3 of the License, or
14 % (at your option) any later version.
16 % This program is distributed in the hope that it will be useful,
17 % but WITHOUT ANY WARRANTY; without even the implied warranty of
18 % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19 % GNU General Public License for more details.
21 % You should have received a copy of the GNU General Public License
22 % along with this program.  If not, see <http://www.gnu.org/licenses/>.
24 \lstset{
25 numbers=left, stepnumber=1, numbersep=5pt,
26 breaklines=false,
27 basicstyle=\footnotesize\ttfamily,
28 numberstyle=\tiny,
29 language=C,
30 columns=fullflexible,
31 numberfirstline=true}
32 \end_preamble
33 \use_default_options true
34 \begin_modules
35 logicalmkup
36 newfangle
37 \end_modules
38 \language english
39 \inputencoding auto
40 \font_roman default
41 \font_sans default
42 \font_typewriter default
43 \font_default_family default
44 \font_sc false
45 \font_osf false
46 \font_sf_scale 100
47 \font_tt_scale 100
49 \graphics default
50 \paperfontsize default
51 \spacing single
52 \use_hyperref true
53 \pdf_title "Newfangle"
54 \pdf_author "Sam Liddicott"
55 \pdf_subject "Literate Programing"
56 \pdf_keywords "notangle noweb noweave literate programming cweb"
57 \pdf_bookmarks true
58 \pdf_bookmarksnumbered false
59 \pdf_bookmarksopen false
60 \pdf_bookmarksopenlevel 1
61 \pdf_breaklinks false
62 \pdf_pdfborder false
63 \pdf_colorlinks true
64 \pdf_backref false
65 \pdf_pdfusetitle true
66 \papersize default
67 \use_geometry false
68 \use_amsmath 1
69 \use_esint 1
70 \cite_engine basic
71 \use_bibtopic false
72 \paperorientation portrait
73 \secnumdepth 3
74 \tocdepth 3
75 \paragraph_separation skip
76 \defskip medskip
77 \quotes_language english
78 \papercolumns 1
79 \papersides 1
80 \paperpagestyle default
81 \tracking_changes false
82 \output_changes false
83 \author "" 
84 \author "" 
85 \end_header
87 \begin_body
89 \begin_layout Title
90 newfangle
91 \end_layout
93 \begin_layout Author
94 Sam Liddicott
95 \end_layout
97 \begin_layout Date
98 August 2009
99 \end_layout
101 \begin_layout Chapter*
102 Introduction
103 \end_layout
105 \begin_layout Standard
107 \noun on
108 Newfangle
109 \noun default
110  is a tool for newfangled literate programming.
111  Newfangled is defined as 
112 \emph on
113 New and often needlessly novel
114 \emph default
115  by 
116 \noun on
117 TheFreeDictionary.com
118 \noun default
120 \end_layout
122 \begin_layout Standard
123 In this case, newfangled means yet another new and improved method for literate
124  programming.
125 \end_layout
127 \begin_layout Standard
129 \noun on
130 Literate Programming
131 \noun default
132  has a long history starting with the great 
133 \noun on
134 Donald Knuth
135 \noun default
136  himself, whose literate programming tools seem to make use of as many escape
137  sequences for semantic markup as TeX itself.
138 \end_layout
140 \begin_layout Standard
142 \noun on
143 Norman Ramsey
144 \noun default
145  wrote the 
146 \noun on
147 noweb
148 \noun default
149  set of tools (notangle, noweave and noroots) and helpfully reduced the
150  amount of magic character sequences to pretty much just 
151 \begin_inset Flex CharStyle:Code
152 status collapsed
154 \begin_layout Plain Layout
156 \end_layout
158 \end_inset
160  and 
161 \begin_inset Flex CharStyle:Code
162 status collapsed
164 \begin_layout Plain Layout
166 \end_layout
168 \end_inset
170 , and in doing so brought the wonders of literate programming within my
171  reach.
172 \end_layout
174 \begin_layout Standard
175 While using the LyX editor for LaTeX editing I had various troubles with
176  the noweb tools, some of which were my fault, some of which were noweb's
177  fault and some of which were LyX's fault.
178 \end_layout
180 \begin_layout Standard
182 \noun on
183 Noweb
184 \noun default
185  generally brought literate programming to the masses through removing some
186  of the complexity of the original literate programming, but this would
187  be of no advantage to me if the LyX / LaTeX combination brought more complicati
188 ons in their place.
189 \end_layout
191 \begin_layout Standard
193 \noun on
194 Newfangle
195 \noun default
196  was thus born --- as an awk replacement for notangle, adding some important
197  features, like better integration with LyX and LaTeX, multiple output format
198  conversions, and fixing notangle bugs like indentation when using -L for
199  line numbers.
200 \end_layout
202 \begin_layout Standard
203 Significantly, newfangle is just one program which replaces various programs
204  in Noweb.
205  Noweave is done away with and implemented directly as LaTeX macros, and
206  noroots is implemented as a function of the untangler 
207 \noun on
208 newfangle
209 \noun default
211 \end_layout
213 \begin_layout Standard
214 Newfangle is written in awk for portability reasons, awk being available
215  for most platforms.
216  A python conversion will probably be attempted for the benefit of LyX.
217  (Hasn't anyone implemented awk in python yet?)
218 \end_layout
220 \begin_layout Standard
221 As an extension to many literate-programming styles, Newfangle permits code
222  chunks to take parameters and thus operate somewhat like C pre-processor
223  macros, or like C++ templates.
224 \end_layout
226 \begin_layout Section*
227 Todo
228 \end_layout
230 \begin_layout Enumerate
231 ^^ is always going to be a problem, see texbytopic 1.2.2 (Work out what I
232  meant by this).
233 \end_layout
235 \begin_layout Enumerate
236 copy over up to date Makefile guide from noweb-lyx document
237 \end_layout
239 \begin_layout Enumerate
240 Make chunk-name settings only apply to chunks with that name
241 \end_layout
243 \begin_layout Enumerate
244 indent of multi-line chunks may be mode dependant (i.e.
245  not in string literals)
246 \end_layout
248 \begin_layout Enumerate
249 add support for other commands in =<...>, starting with 
250 \backslash
251 label which takes the line-number within the chunk, and maybe should also
252  take the chunk name/page
253 \end_layout
255 \begin_layout Enumerate
256 cant have listing inside a ruled box
257 \end_layout
259 \begin_layout Enumerate
260 when a parameterized chunk is included as well as the #line emission, say
261  what the paremeters were for that invocation.
262 \end_layout
264 \begin_layout Enumerate
266 \backslash
267 chunkref[3]{preamble} to include a certain chunk needs to work in newfangle.awk
268  instead of failing to be recognized at all
269 \end_layout
271 \begin_layout Enumerate
272 make in-listins labels track the chunk ref too, and make 
273 \backslash
274 chunref{[2],thing}> resolve to 41c (or d, or whatever chunk the 2nd chunk
275  of thing is
276 \end_layout
278 \begin_layout Enumerate
280 \backslash
281 chunkref in text needs a trailing space maybe, it keeps butting up to the
282  next word
283 \end_layout
285 \begin_layout Enumerate
286 because the white-space indent is output by the parent chunk, the #line
287  is that of the parent chunk.
288  White space indents must be passed to the child chunk
289 \end_layout
291 \begin_layout Chapter*
292 License
293 \end_layout
295 \begin_layout Standard
296 \begin_inset CommandInset label
297 LatexCommand label
298 name "cha:License"
300 \end_inset
302 Newfangle is licensed under the GPL 3
303 \begin_inset CommandInset citation
304 LatexCommand cite
305 key "gpl-licenses"
307 \end_inset
309  (or later).
310  This doesn't mean that you can't use or distribute newfangle with sources
311  of an incompatible license, but it means you must make the source of newfangle
312  available too.
313 \end_layout
315 \begin_layout Standard
316 As newfangle is currently written in 
317 \noun on
319 \noun default
320 , an interpreted language, this should not be too hard.
321 \end_layout
323 \begin_layout Chunk
324 gpl3-copyright,language=
325 \end_layout
327 \begin_layout Standard
328 \begin_inset listings
329 inline false
330 status open
332 \begin_layout Plain Layout
334 newfangle - fully featured notangle replacement in awk
335 \end_layout
337 \begin_layout Plain Layout
339 \end_layout
341 \begin_layout Plain Layout
343 Copyright (C) 2009 Sam Liddicott <sam@liddicott.com>
344 \end_layout
346 \begin_layout Plain Layout
348 \end_layout
350 \begin_layout Plain Layout
352 This program is free software: you can redistribute it and/or modify
353 \end_layout
355 \begin_layout Plain Layout
357 it under the terms of the GNU General Public License as published by
358 \end_layout
360 \begin_layout Plain Layout
362 the Free Software Foundation, either version 3 of the License, or
363 \end_layout
365 \begin_layout Plain Layout
367 (at your option) any later version.
368 \end_layout
370 \begin_layout Plain Layout
372 \end_layout
374 \begin_layout Plain Layout
376 This program is distributed in the hope that it will be useful,
377 \end_layout
379 \begin_layout Plain Layout
381 but WITHOUT ANY WARRANTY; without even the implied warranty of
382 \end_layout
384 \begin_layout Plain Layout
386 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
387   See the
388 \end_layout
390 \begin_layout Plain Layout
392 GNU General Public License for more details.
393 \end_layout
395 \begin_layout Plain Layout
397 \end_layout
399 \begin_layout Plain Layout
401 You should have received a copy of the GNU General Public License
402 \end_layout
404 \begin_layout Plain Layout
406 along with this program.
407   If not, see <http://www.gnu.org/licenses/>.
408 \end_layout
410 \begin_layout Plain Layout
412 \end_layout
414 \end_inset
417 \end_layout
419 \begin_layout Standard
420 \begin_inset CommandInset toc
421 LatexCommand tableofcontents
423 \end_inset
426 \end_layout
428 \begin_layout Part
429 Using Newfangle
430 \end_layout
432 \begin_layout Chapter
433 Running Newfangle
434 \end_layout
436 \begin_layout Standard
437 Newfangle is a replacement for noweb, which consists of 
438 \begin_inset Flex CharStyle:Code
439 status collapsed
441 \begin_layout Plain Layout
442 notangle
443 \end_layout
445 \end_inset
448 \begin_inset Flex CharStyle:Code
449 status collapsed
451 \begin_layout Plain Layout
452 noroots
453 \end_layout
455 \end_inset
457  and 
458 \begin_inset Flex CharStyle:Code
459 status collapsed
461 \begin_layout Plain Layout
462 noweave
463 \end_layout
465 \end_inset
468 \end_layout
470 \begin_layout Standard
471 Like 
472 \begin_inset Flex CharStyle:Code
473 status collapsed
475 \begin_layout Plain Layout
476 notangle
477 \end_layout
479 \end_inset
481  and 
482 \begin_inset Flex CharStyle:Code
483 status collapsed
485 \begin_layout Plain Layout
486 noroots
487 \end_layout
489 \end_inset
491  it can read multiple named files, or from stdin.
492 \end_layout
494 \begin_layout Section
495 Listing roots
496 \end_layout
498 \begin_layout Standard
499 The -r option causes newfangle to behave like noroots.
500 \end_layout
502 \begin_layout LyX-Code
503 newfangle -r filename.tex
504 \end_layout
506 \begin_layout Standard
507 will print out the newfangle roots of a tex file.
509 \end_layout
511 \begin_layout Standard
512 Unlike the 
513 \begin_inset Flex CharStyle:Code
514 status collapsed
516 \begin_layout Plain Layout
517 noroots
518 \end_layout
520 \end_inset
522  command, the roots are not enclosed in 
523 \begin_inset Flex CharStyle:Code
524 status collapsed
526 \begin_layout Plain Layout
527 <<name>>
528 \end_layout
530 \end_inset
532 , unless at least one of the roots is defined using the 
533 \begin_inset Flex CharStyle:Code
534 status collapsed
536 \begin_layout Plain Layout
537 notangle
538 \end_layout
540 \end_inset
542  style 
543 \begin_inset Flex CharStyle:Code
544 status collapsed
546 \begin_layout Plain Layout
547 <<name>>=
548 \end_layout
550 \end_inset
553 \end_layout
555 \begin_layout Standard
556 Also, unlike noroots, it prints out all roots --- not just those that are
557  not used elsewhere.
558  I find that a root not being used, doesn't make it particularly top level,
559  and so-called top level roots could also be included in another root as
560  well.
562 \end_layout
564 \begin_layout Standard
565 My convention is that top level roots to be extracted begin with 
566 \begin_inset Flex CharStyle:Code
567 status collapsed
569 \begin_layout Plain Layout
571 \end_layout
573 \end_inset
575  and have the form of a filename.
576 \end_layout
578 \begin_layout Standard
579 Makefile.inc, discussed in 
580 \begin_inset CommandInset ref
581 LatexCommand ref
582 reference "cha:makefile.inc"
584 \end_inset
586 , can automatically extract all such sources.
587 \end_layout
589 \begin_layout Section
590 Extracting roots
591 \end_layout
593 \begin_layout Standard
594 notangle's 
595 \begin_inset Flex CharStyle:Code
596 status collapsed
598 \begin_layout Plain Layout
600 \end_layout
602 \end_inset
604  and 
605 \begin_inset Flex CharStyle:Code
606 status collapsed
608 \begin_layout Plain Layout
610 \end_layout
612 \end_inset
614  options are supported.
615 \end_layout
617 \begin_layout Standard
618 The standard way to extract a file would be:
619 \end_layout
621 \begin_layout LyX-Code
622 newfangle -R./Makefile.inc newfangle.tex > ./Makefile.inc
623 \end_layout
625 \begin_layout Standard
626 Unlike the 
627 \begin_inset Flex CharStyle:Code
628 status collapsed
630 \begin_layout Plain Layout
631 noroots
632 \end_layout
634 \end_inset
636  command, the 
637 \begin_inset Flex CharStyle:Code
638 status collapsed
640 \begin_layout Plain Layout
642 \end_layout
644 \end_inset
646  option does not break indenting.
647 \end_layout
649 \begin_layout Standard
650 Also, thanks to mode tracking (described in 
651 \begin_inset CommandInset ref
652 LatexCommand ref
653 reference "cha:modes"
655 \end_inset
657 ) the 
658 \begin_inset Flex CharStyle:Code
659 status collapsed
661 \begin_layout Plain Layout
663 \end_layout
665 \end_inset
667  option does not interrupt (and break) multi-line C macros either.
668 \end_layout
670 \begin_layout Standard
671 This does mean that sometimes the compiler might calculate the source line
672  wrongly when generating error messages in such cases, but there isn't any
673  other way around if multi-line macros include other chunks.
674 \end_layout
676 \begin_layout Section
677 Formatting source in LaTeX
678 \end_layout
680 \begin_layout Standard
681 The noweave replacement is a set of LaTeX macros dependant upon 
682 \emph on
683 noweb.sty
684 \emph default
685 , and which can be included with:
686 \end_layout
688 \begin_layout LyX-Code
690 \backslash
691 usepackage{newfangle.sty}
692 \end_layout
694 \begin_layout Standard
695 The LaTeX macros are shown in section 
696 \begin_inset CommandInset ref
697 LatexCommand ref
698 reference "sec:Latex-Macros"
700 \end_inset
702 , and are part of a LyX module file 
703 \begin_inset Flex CharStyle:Code
704 status collapsed
706 \begin_layout Plain Layout
707 newfangle.module
708 \end_layout
710 \end_inset
712 , which automatically includes the macros in the document pre-amble when
713  the newfangle LyX module is used.
714 \end_layout
716 \begin_layout Standard
717 Because the noweave replacement is impemented in LaTeX, there is no processing
718  stage required before running the 
719 \begin_inset Flex CharStyle:Code
720 status collapsed
722 \begin_layout Plain Layout
723 latex
724 \end_layout
726 \end_inset
728  command.
729  LaTeX may need running two or more times, so that the code chunk references
730  can be fully calculated.
731 \end_layout
733 \begin_layout Standard
734 The 
735 \begin_inset Flex CharStyle:Code
736 status collapsed
738 \begin_layout Plain Layout
739 noweb.sty
740 \end_layout
742 \end_inset
744  package is required as it is used for formatting the code chunk captions
745 \end_layout
747 \begin_layout Standard
748 The 
749 \begin_inset Flex CharStyle:Code
750 status collapsed
752 \begin_layout Plain Layout
753 listings.sty
754 \end_layout
756 \end_inset
758  package is also required, as it is used for formatting the code chunks
759  themselves.
760 \end_layout
762 \begin_layout Standard
763 The 
764 \begin_inset Flex CharStyle:Code
765 status collapsed
767 \begin_layout Plain Layout
768 xargs.sty
769 \end_layout
771 \end_inset
773  package is also required.
774 \end_layout
776 \begin_layout Chapter
777 Literate Programming with Newfangle
778 \end_layout
780 \begin_layout Standard
781 Todo.
782  Should really follow on from a part-0 explanation of what literate programming
783  is.
784 \end_layout
786 \begin_layout Chapter
787 Using Newfangle with LyX
788 \end_layout
790 \begin_layout Section
791 Setting up Lyx
792 \end_layout
794 \begin_layout Subsection
795 Installing the LyX module
796 \end_layout
798 \begin_layout Standard
799 Copy 
800 \begin_inset Flex CharStyle:Code
801 status collapsed
803 \begin_layout Plain Layout
804 newfangle.module
805 \end_layout
807 \end_inset
809  to your LyX layouts directory, which for unix users will be 
810 \begin_inset Flex CharStyle:Code
811 status collapsed
813 \begin_layout Plain Layout
814 ~/.lyx/layouts
815 \end_layout
817 \end_inset
820 \end_layout
822 \begin_layout Standard
823 You will need to reconfigure LyX by clicking Tools\SpecialChar \menuseparator
824 Reconfigure, and then
825  re-start LyX.
826 \end_layout
828 \begin_layout Subsection
829 \begin_inset CommandInset label
830 LatexCommand label
831 name "sub:Configuring-the-build"
833 \end_inset
835 Configuring the build script
836 \end_layout
838 \begin_layout Standard
839 Make sure you don't have a conversion defined for Lyx → Program
840 \end_layout
842 \begin_layout Standard
843 From the menu Tools\SpecialChar \menuseparator
844 Preferences, add a conversion from Latex(Plain) → Program
845  as:
846 \end_layout
848 \begin_layout LyX-Code
849 set -x ; newfangle -Rlyx-build $$i | 
850 \end_layout
852 \begin_layout LyX-Code
853   env LYX_b=$$b LYX_i=$$i LYX_o=$$o LYX_p=$$p LYX_r=$$r bash
854 \end_layout
856 \begin_layout Standard
857 (But don't cut-n-paste it from this document or you'll be pasting a multi-line
858  string which will break your lyx preferences file).
860 \end_layout
862 \begin_layout Standard
863 I hope that one day, LyX will set these into the environment when calling
864  the build script.
865 \end_layout
867 \begin_layout Standard
868 You may also want to consider adding options to this conversion\SpecialChar \ldots{}
870 \end_layout
872 \begin_layout LyX-Code
873 parselog=/usr/share/lyx/scripts/listerrors
874 \end_layout
876 \begin_layout Standard
877 \SpecialChar \ldots{}
878 but if you do you will lose your stderr
879 \begin_inset Foot
880 status collapsed
882 \begin_layout Plain Layout
883 There is some bash plumbing to get a copy of stderr but this footnote is
884  too small
885 \end_layout
887 \end_inset
890 \end_layout
892 \begin_layout Standard
893 Now, a shell script chunk called 
894 \begin_inset Flex CharStyle:Code
895 status collapsed
897 \begin_layout Plain Layout
898 lyx-build
899 \end_layout
901 \end_inset
903  will be extracted and run whenever you choose the Document\SpecialChar \menuseparator
904 Build Program
905  menu item.
906 \end_layout
908 \begin_layout Standard
909 The lyx-build script for this document is in section 
910 \begin_inset CommandInset ref
911 LatexCommand ref
912 reference "lyx-build-script"
914 \end_inset
916  and on a unix system will extract 
917 \begin_inset Flex CharStyle:Code
918 status collapsed
920 \begin_layout Plain Layout
921 newfangle.module
922 \end_layout
924 \end_inset
926  and the 
927 \begin_inset Flex CharStyle:Code
928 status collapsed
930 \begin_layout Plain Layout
931 newfangle
932 \end_layout
934 \end_inset
936  awk script, and run some basic tests.
938 \begin_inset Note Note
939 status collapsed
941 \begin_layout Plain Layout
942 cross-ref to test chapter when it is a chapter all on its own
943 \end_layout
945 \end_inset
948 \end_layout
950 \begin_layout Subsection
951 Preparing your Lyx document
952 \end_layout
954 \begin_layout Standard
955 It is not necessary to base your literate document on any of the original
956  LyX literate classes; so select a regular class for your document type.
957 \end_layout
959 \begin_layout Standard
960 Add the new module 
961 \emph on
962 Newfangle Literate
963 \emph default
965 \emph on
966 Listings
967 \emph default
968  and possibly also 
969 \emph on
970 Logical Markup
971 \emph default
973 \end_layout
975 \begin_layout Standard
976 In the drop-down style listbox you should notice a new style defined, called
978 \emph on
979 Chunk
980 \emph default
982 \end_layout
984 \begin_layout Standard
985 When you wish to insert a literate chunk, you enter it's plain name in the
986  Chunk style, instead of the older method that used 
987 \begin_inset Flex CharStyle:Code
988 status collapsed
990 \begin_layout Plain Layout
991 <<name>>=
992 \end_layout
994 \end_inset
996  type tags.
997  Following the chunk name, you insert a listing with: Insert\SpecialChar \menuseparator
998 Program Listing.
999 \end_layout
1001 \begin_layout Standard
1002 Inside the white listing box you can type (or paste using shift+ctrl+V)
1003  your listing.
1004  There is not need to use ctrl+enter at the end of lines as with some older
1005  LyX literate techniques --- just press enter as normal.
1006 \end_layout
1008 \begin_layout Subsubsection
1009 Customising the listing appearance
1010 \end_layout
1012 \begin_layout Standard
1013 In the final document, the code is formatted using the 
1014 \noun on
1015 lstlistings
1016 \noun default
1017  package.
1018  The chunk style doesn't just define the chunk name, but can also define
1019  any other chunk options supported by the lstlistings package 
1020 \begin_inset Flex CharStyle:Code
1021 status collapsed
1023 \begin_layout Plain Layout
1025 \backslash
1026 lstset
1027 \end_layout
1029 \end_inset
1031  command.
1032  In fact, what you type in the chunk style is raw latex.
1033  If you want to set the chunk language without having to right-click the
1034  listing, just add 
1035 \begin_inset Flex CharStyle:Code
1036 status collapsed
1038 \begin_layout Plain Layout
1039 ,lanuage=C
1040 \end_layout
1042 \end_inset
1044  after the chunk name.
1045  (Currently the language will affect all subsequent listings, so you may
1046  need to specify 
1047 \begin_inset Flex CharStyle:Code
1048 status collapsed
1050 \begin_layout Plain Layout
1051 ,language=
1052 \end_layout
1054 \end_inset
1056  quite a lot)
1057 \begin_inset Note Note
1058 status open
1060 \begin_layout Plain Layout
1061 so fix the bug
1062 \end_layout
1064 \end_inset
1067 \end_layout
1069 \begin_layout Standard
1070 Of course you can do this by editing the listings box advanced properties
1071  by right-clicking on the listings box, but that takes longer, and you can't
1072  see at-a-glance what the advanced settings are while editing the document;
1073  also advanced settings apply only to that box --- the chunk settings apply
1074  through the rest of the document
1075 \begin_inset Foot
1076 status collapsed
1078 \begin_layout Plain Layout
1079 It ought to apply only to subsequent chunks of the same name.
1080  I'll fix that later
1081 \end_layout
1083 \end_inset
1086 \begin_inset Note Note
1087 status collapsed
1089 \begin_layout Plain Layout
1090 So make sure they only apply to chunks of that name
1091 \end_layout
1093 \end_inset
1096 \end_layout
1098 \begin_layout Subsubsection
1099 Global customisations
1100 \end_layout
1102 \begin_layout Standard
1103 As 
1104 \emph on
1105 lstlistings
1106 \emph default
1107  is used to set the code chunks, it's 
1108 \begin_inset Flex CharStyle:Code
1109 status collapsed
1111 \begin_layout Plain Layout
1113 \backslash
1114 lstset
1115 \end_layout
1117 \end_inset
1119  command can be used in the pre-amble to set some document wide settings.
1120 \end_layout
1122 \begin_layout Standard
1123 If your source has many words with long sequences of capital letters, then
1125 \begin_inset Flex CharStyle:Code
1126 status collapsed
1128 \begin_layout Plain Layout
1129 columns=fullflexible
1130 \end_layout
1132 \end_inset
1134  may be a good idea, or the capital letters will get crowded.
1135  (I think lstlistings ought to use a slightly smaller font for captial letters
1136  so that they still fit).
1137 \end_layout
1139 \begin_layout Standard
1140 The font family 
1141 \begin_inset Flex CharStyle:Code
1142 status collapsed
1144 \begin_layout Plain Layout
1146 \backslash
1147 ttfamily
1148 \end_layout
1150 \end_inset
1152  looks more normal for code, but has no bold (an alternate typewriter font
1153  is used).
1155 \end_layout
1157 \begin_layout Standard
1158 With 
1159 \begin_inset Flex CharStyle:Code
1160 status collapsed
1162 \begin_layout Plain Layout
1164 \backslash
1165 ttfamily
1166 \end_layout
1168 \end_inset
1170 , I must also specify 
1171 \begin_inset Flex CharStyle:Code
1172 status collapsed
1174 \begin_layout Plain Layout
1175 columns=fullflexible
1176 \end_layout
1178 \end_inset
1180  or the wrong letter spacing is used.
1181 \end_layout
1183 \begin_layout Standard
1184 In my LeTeX pre-amble I usually specialise my code format with:
1185 \end_layout
1187 \begin_layout Chunk
1188 document-preamble,language=tex
1189 \end_layout
1191 \begin_layout Standard
1192 \begin_inset listings
1193 inline false
1194 status open
1196 \begin_layout Plain Layout
1199 \backslash
1200 lstset{
1201 \end_layout
1203 \begin_layout Plain Layout
1205 numbers=left, stepnumber=1, numbersep=5pt,
1206 \end_layout
1208 \begin_layout Plain Layout
1210 breaklines=false,
1211 \end_layout
1213 \begin_layout Plain Layout
1215 basicstyle=
1216 \backslash
1217 footnotesize
1218 \backslash
1219 ttfamily,
1220 \end_layout
1222 \begin_layout Plain Layout
1224 numberstyle=
1225 \backslash
1226 tiny,
1227 \end_layout
1229 \begin_layout Plain Layout
1231 language=C,
1232 \end_layout
1234 \begin_layout Plain Layout
1236 columns=fullflexible,
1237 \end_layout
1239 \begin_layout Plain Layout
1241 numberfirstline=true
1242 \end_layout
1244 \begin_layout Plain Layout
1247 \end_layout
1249 \end_inset
1252 \end_layout
1254 \begin_layout Standard
1255 Obtaining a 
1256 \begin_inset Flex CharStyle:Code
1257 status collapsed
1259 \begin_layout Plain Layout
1261 \series bold
1262 bold
1263 \series default
1264  tt font
1265 \end_layout
1267 \end_inset
1269  can be impossibly difficult and amazingly easy.
1270  I spent many hours at it, following complicated instructions from those
1271  who had spend many hours over it, and was finally delivered the simple
1272  solution
1273 \begin_inset Foot
1274 status collapsed
1276 \begin_layout Plain Layout
1277 on a plate
1278 \end_layout
1280 \end_inset
1282  on the lyx mailing list.
1283 \end_layout
1285 \begin_layout Section
1286 txfonts
1287 \end_layout
1289 \begin_layout Standard
1290 The simple way was to add this to my preamble:
1291 \end_layout
1293 \begin_layout LyX-Code
1295 \backslash
1296 usepackage{txfonts}
1297 \end_layout
1299 \begin_layout LyX-Code
1301 \backslash
1302 renewcommand{
1303 \backslash
1304 ttdefault}{txtt}
1305 \end_layout
1307 \begin_layout Section
1308 ams pmb
1309 \end_layout
1311 \begin_layout Standard
1312 The next simplest way was to use ams poor-mans-bold, and add this to the
1313  pre-amble:
1314 \end_layout
1316 \begin_layout LyX-Code
1318 \backslash
1319 usepackage{amsbsy}
1320 \end_layout
1322 \begin_layout LyX-Code
1324 \backslash
1325 renewcommand{
1326 \backslash
1327 ttdefault}{txtt}
1328 \end_layout
1330 \begin_layout LyX-Code
1331 %somehow make 
1332 \backslash
1333 pmb be the command for bold, forgot how, sorry
1334 \end_layout
1336 \begin_layout Standard
1337 It works, but looks wretched on the dvi viewer.
1338 \end_layout
1340 \begin_layout Section
1341 Luximono
1342 \end_layout
1344 \begin_layout Standard
1345 The 
1346 \noun on
1347 lstlistings
1348 \noun default
1349  documention suggests using Luximono.
1350 \end_layout
1352 \begin_layout Standard
1353 Luximono was installed according to the instructions in Ubuntu Forums: http://ub
1354 untuforums.org/showthread.php?t=1159181 with tips from http://miknight.blogspot.com/
1355 2005/
1356 \begin_inset space \hspace{}
1357 \length 0in
1358 \end_inset
1360 11/how-to-install-luxi-mono-font-in.html stating that:
1361 \end_layout
1363 \begin_layout LyX-Code
1364 sudo updmap --enable MixedMap ul9.map
1365 \end_layout
1367 \begin_layout Standard
1368 is required.
1369 \end_layout
1371 \begin_layout Standard
1372 It looks fine in PDF and PS view but still looks rotten in dvi view.
1373 \end_layout
1375 \begin_layout Chapter
1376 Newfangle with Makefiles
1377 \end_layout
1379 \begin_layout Standard
1380 \begin_inset CommandInset label
1381 LatexCommand label
1382 name "cha:makefile.inc"
1384 \end_inset
1387 \begin_inset Note Note
1388 status open
1390 \begin_layout Plain Layout
1391 This chapter needs revising
1392 \end_layout
1394 \end_inset
1397 \begin_inset Note Greyedout
1398 status open
1400 \begin_layout Plain Layout
1401 This chapter needs revising
1402 \end_layout
1404 \end_inset
1406 Here we describe a Makefile.inc that you can include in your own Makefiles,
1407  or glue as a recursive make to other projects.
1408 \end_layout
1410 \begin_layout Standard
1411 The Makefile.inc described here was put together for a Samba4 vfs module,
1412  but can be used in any Make project, including automake projects.
1413 \end_layout
1415 \begin_layout Section
1416 A word about makefiles formats
1417 \end_layout
1419 \begin_layout Standard
1420 Whitespace formatting is very important in a Makefile.
1421  The first character of each command line must be a TAB.
1422 \end_layout
1424 \begin_layout LyX-Code
1425 target: pre-requisite
1426 \begin_inset Newline newline
1427 \end_inset
1429    →    action
1430 \begin_inset Newline newline
1431 \end_inset
1433    →    action
1434 \end_layout
1436 \begin_layout Standard
1437 But a TAB is pretty hard to enter into most of the Lyx formats and insets
1438  I've been using.
1439  An alternative is to use a semi-colon after the pre-requisite, and a backslash
1440  at the end of each line (except the last).
1441  Then any whitespace (or none) can prefix each action.
1442 \end_layout
1444 \begin_layout LyX-Code
1445 target: pre-requisite ; 
1446 \backslash
1448 \begin_inset Newline newline
1449 \end_inset
1451 ␣␣action 
1452 \backslash
1454 \begin_inset Newline newline
1455 \end_inset
1457 ␣␣action
1458 \end_layout
1460 \begin_layout Standard
1461 This is the style that we use and it works pretty well for GNU make at least.
1462 \end_layout
1464 \begin_layout Standard
1465 We also adopt a convention that code chunks whose names beginning with ./
1466  should always be automatically extracted from the document.
1467  Code chunks whose names do not begin with ./ are for internal reference.
1468  (This doesn't prevent such chunks from being extracted directly).
1469 \end_layout
1471 \begin_layout Section
1472 Boot-strapping the extraction
1473 \end_layout
1475 \begin_layout Subsection
1476 Using a Makefile
1477 \end_layout
1479 \begin_layout Standard
1480 \begin_inset CommandInset label
1481 LatexCommand label
1482 name "sub:Bootstrap-Using-a-Makefile"
1484 \end_inset
1486 It seems convenient to have the makefile extract or update the C source
1487  files as part of it's operation.
1488  It also seems convenient to have the makefile itself extracted from this
1489  document.
1490 \end_layout
1492 \begin_layout Standard
1493 It would also be convenient to have the code to extract the makefile from
1494  this document to also be part of this document, however we have to start
1495  somewhere and this unfortunately requires us to type at least a few words
1496  by hand to start things off.
1497 \end_layout
1499 \begin_layout Standard
1500 Therefore we will have a minimal root fragment, which, when extracted, can
1501  cope with extracting the rest of the source.
1502  perhaps with this shell script, which could be called 
1503 \emph on
1504 autoboot
1505 \emph default
1507 \begin_inset Note Note
1508 status open
1510 \begin_layout Plain Layout
1511 FIX THIS CHUNK AND TEST IT
1512 \end_layout
1514 \end_inset
1517 \end_layout
1519 \begin_layout Chunk
1521 \end_layout
1523 \begin_layout Standard
1524 \begin_inset listings
1525 inline false
1526 status open
1528 \begin_layout Plain Layout
1530 #! /bin/sh
1531 \end_layout
1533 \begin_layout Plain Layout
1535 \end_layout
1537 \begin_layout Plain Layout
1539 MAKE_SRC="${1:-${NW_LYX:-../../noweb-lyx/noweb-lyx3.lyx}}"
1540 \end_layout
1542 \begin_layout Plain Layout
1544 MAKE_SRC=`dirname "$MAKE_SRC"`/`basename "$MAKE_SRC" .lyx`
1545 \end_layout
1547 \begin_layout Plain Layout
1549 NOWEB_SRC="${2:-${NOWEB_SRC:-$MAKE_SRC.lyx}}"
1550 \end_layout
1552 \begin_layout Plain Layout
1554 lyx -e latex $MAKE_SRC
1555 \end_layout
1557 \begin_layout Plain Layout
1559 \end_layout
1561 \begin_layout Plain Layout
1563 newfangle -R./Makefile.inc ${MAKE_SRC}.tex 
1564 \backslash
1566 \end_layout
1568 \begin_layout Plain Layout
1570   | sed "/NEWFANGLE_SOURCE=/s/^/#/;T;aNOWEB_SOURCE=$NEWFANGLE_SRC" 
1571 \backslash
1573 \end_layout
1575 \begin_layout Plain Layout
1577   | cpif ./Makefile.inc
1578 \end_layout
1580 \begin_layout Plain Layout
1582 \end_layout
1584 \begin_layout Plain Layout
1586 make -f ./Makefile.inc newfangle_sources
1587 \end_layout
1589 \end_inset
1592 \end_layout
1594 \begin_layout Standard
1595 The general Makefile can be invoked with 
1596 \emph on
1597 ./autoboot
1598 \emph default
1599  and can also be included into any automake file to automatically re-generate
1600  the source files.
1601 \end_layout
1603 \begin_layout Standard
1604 The 
1605 \emph on
1606 autoboot
1607 \emph default
1608  can be extracted with this command:
1609 \end_layout
1611 \begin_layout LyX-Code
1612 lyx -e latex newfangle.lyx && 
1613 \backslash
1615 \end_layout
1617 \begin_layout LyX-Code
1618 newfangle newfangle.lyx > ./autoboot
1619 \end_layout
1621 \begin_layout Standard
1622 This looks simple enough, but as mentioned, newfangle has to be had from
1623  somewhere before it can be extracted.
1624 \end_layout
1626 \begin_layout Subsection
1627 \begin_inset Note Note
1628 status collapsed
1630 \begin_layout Plain Layout
1631 MERGE THIS WITH THE SECTIONS OF THIS DOCUMENT
1632 \end_layout
1634 \end_inset
1636 \SpecialChar \ldots{}
1638 \end_layout
1640 \begin_layout Standard
1641 When the lyx-build chunk is executed, the current directory will be a temporary
1642  directory, and 
1643 \begin_inset Flex CharStyle:Code
1644 status collapsed
1646 \begin_layout Plain Layout
1647 LYX_SOURCE
1648 \end_layout
1650 \end_inset
1652  will refer to the tex file in this temporary directory.
1653  This is unfortunate as our makefile wants to run from the project directory
1654  where the Lyx file is kept.
1655 \end_layout
1657 \begin_layout Standard
1658 We can extract the project directory from $$r, and derive the probable Lyx
1659  filename from the noweb file that Lyx generated.
1660 \end_layout
1662 \begin_layout Chunk
1663 lyx-build-helper
1664 \end_layout
1666 \begin_layout Standard
1667 \begin_inset listings
1668 inline false
1669 status open
1671 \begin_layout Plain Layout
1673 PROJECT_DIR="$LYX_r"
1674 \end_layout
1676 \begin_layout Plain Layout
1678 LYX_SRC="$PROJECT_DIR/${LYX_i%.tex}.lyx"
1679 \end_layout
1681 \begin_layout Plain Layout
1683 TEX_DIR="$LYX_p"
1684 \end_layout
1686 \begin_layout Plain Layout
1688 TEX_SRC="$TEX_DIR/$LYX_i"
1689 \end_layout
1691 \end_inset
1694 \end_layout
1696 \begin_layout Standard
1697 And then we can define a lyx-build fragment similar to the autoboot fragment
1698 \end_layout
1700 \begin_layout Chunk
1701 lyx-build
1702 \end_layout
1704 \begin_layout Standard
1705 \begin_inset listings
1706 inline false
1707 status open
1709 \begin_layout Plain Layout
1711 #! /bin/sh
1712 \end_layout
1714 \begin_layout Plain Layout
1717 \backslash
1718 chunkref{lyx-build-helper}>
1719 \end_layout
1721 \begin_layout Plain Layout
1723 cd $PROJECT_DIR || exit 1
1724 \end_layout
1726 \begin_layout Plain Layout
1728 \end_layout
1730 \begin_layout Plain Layout
1732 #/usr/bin/newfangle -filter ./notanglefix-filter 
1733 \backslash
1735 \end_layout
1737 \begin_layout Plain Layout
1739 #  -R./Makefile.inc "../../noweb-lyx/noweb-lyx3.lyx" 
1740 \backslash
1742 \end_layout
1744 \begin_layout Plain Layout
1746 #  | sed '/NOWEB_SOURCE=/s/=.*/=samba4-dfs.lyx/' 
1747 \backslash
1749 \end_layout
1751 \begin_layout Plain Layout
1753 #  > ./Makefile.inc
1754 \end_layout
1756 \begin_layout Plain Layout
1759 \end_layout
1761 \begin_layout Plain Layout
1763 #make -f ./Makefile.inc newfangle_sources
1764 \end_layout
1766 \end_inset
1769 \end_layout
1771 \begin_layout Section
1772 Extracting Sources
1773 \end_layout
1775 \begin_layout Subsection
1776 Including Makefile.inc
1777 \end_layout
1779 \begin_layout Standard
1780 \begin_inset CommandInset label
1781 LatexCommand label
1782 name "sub:Keeping-extracted-files"
1784 \end_inset
1786 Makefile.inc will cope with extracting all the other source files from this
1787  document and keeping them up to date.
1789 \end_layout
1791 \begin_layout Standard
1792 It may also be included by a Makefile or Makefile.am defined in a Lyx document
1793  to automatically deal with the extraction of source files and documents.
1794 \end_layout
1796 \begin_layout Standard
1797 A makefile has two parts; variables must be defined before the targets that
1798  use them.
1799 \end_layout
1801 \begin_layout Chunk
1802 ./Makefile.inc
1803 \end_layout
1805 \begin_layout Standard
1806 \begin_inset listings
1807 inline false
1808 status open
1810 \begin_layout Plain Layout
1813 \backslash
1814 chunkref{Makefile.inc-vars}>
1815 \end_layout
1817 \begin_layout Plain Layout
1820 \backslash
1821 chunkref{Makefile.inc-targets}>
1822 \end_layout
1824 \end_inset
1827 \end_layout
1829 \begin_layout Standard
1830 We first define 
1831 \begin_inset Flex CharStyle:Code
1832 status collapsed
1834 \begin_layout Plain Layout
1835 NOWEB_SOURCE
1836 \end_layout
1838 \end_inset
1840  to hold the name of this Lyx file.
1841 \end_layout
1843 \begin_layout Chunk
1844 Makefile.inc-vars
1845 \end_layout
1847 \begin_layout Standard
1848 \begin_inset listings
1849 inline false
1850 status open
1852 \begin_layout Plain Layout
1854 LYX_SOURCE=
1855 \end_layout
1857 \begin_layout Plain Layout
1859 LITERATE_SOURCE=$(LYX_SOURCE)
1860 \end_layout
1862 \end_inset
1865 \end_layout
1867 \begin_layout Subsection
1868 Recursive use of Makefile.inc
1869 \end_layout
1871 \begin_layout Standard
1872 The makefile glue described here is used when building Samba4 vfs modules.
1873 \end_layout
1875 \begin_layout Standard
1876 If you are defining a module of an existing program you may find it easier
1877  to use a slight recursive make instead of including the makefile directly.
1878  This way there is less chance of definitions in Makefile.inc interfering
1879  with definitions in the main makefile, or with definitions in other Makefile.inc
1880  from other noweb modules.
1881 \end_layout
1883 \begin_layout Standard
1884 The glue works by adding a .PHONY target to call the recursive make, and
1885  adding this target as an additional pre-requisite to the existing targets.
1886 \end_layout
1888 \begin_layout Standard
1889 In this example, the existing build system already has a build target for
1891 \begin_inset Flex CharStyle:Code
1892 status collapsed
1894 \begin_layout Plain Layout
1895 example.o
1896 \end_layout
1898 \end_inset
1900 , so we just add another pre-requisite to that.
1901  In this case we use 
1902 \begin_inset Flex CharStyle:Code
1903 status collapsed
1905 \begin_layout Plain Layout
1906 example.tex.stamp
1907 \end_layout
1909 \end_inset
1911  as a pre-requisite, the stamp file's modified time indicating when all
1912  sources were extracted.
1913 \end_layout
1915 \begin_layout Chunk
1916 makefile-glue
1917 \end_layout
1919 \begin_layout Standard
1920 \begin_inset listings
1921 inline false
1922 status open
1924 \begin_layout Plain Layout
1926 $(example_srcdir)/example.o: $(example_srcdir)/example.tex.stamp
1927 \end_layout
1929 \end_inset
1932 \end_layout
1934 \begin_layout Standard
1935 The target for this new pre-requisite is generated by a recursive make using
1936  Makefile.inc which will make sure that the source is up to date, before
1937  it is built by the main projects makefile.
1938 \end_layout
1940 \begin_layout Chunk
1941 makefile-glue
1942 \end_layout
1944 \begin_layout Standard
1945 \begin_inset listings
1946 inline false
1947 status open
1949 \begin_layout Plain Layout
1951 $(example_srcdir)/example.tex.stamp: $(example_srcdir)/example.tex ; 
1952 \backslash
1954 \end_layout
1956 \begin_layout Plain Layout
1958         cd $(example_srcdir) && 
1959 \backslash
1961 \end_layout
1963 \begin_layout Plain Layout
1965         $(MAKE) -f Makefile.inc newfangle_sources
1966 \end_layout
1968 \end_inset
1971 \end_layout
1973 \begin_layout Standard
1974 We can do similar glue for the docs, clean and distclean targets.
1975  In this example our build system is using a double colon for these targets,
1976  so we use the same in our glue.
1977 \end_layout
1979 \begin_layout Chunk
1980 makefile-glue
1981 \end_layout
1983 \begin_layout Standard
1984 \begin_inset listings
1985 inline false
1986 status open
1988 \begin_layout Plain Layout
1990 docs:: docs_example
1991 \end_layout
1993 \begin_layout Plain Layout
1995 .PHONY: docs_example
1996 \end_layout
1998 \begin_layout Plain Layout
2000 docs_example:: ; cd $(example_srcdir) && 
2001 \backslash
2003 \end_layout
2005 \begin_layout Plain Layout
2007         $(MAKE) -f Makefile.inc docs
2008 \end_layout
2010 \begin_layout Plain Layout
2012 \end_layout
2014 \begin_layout Plain Layout
2016 clean:: clean_example
2017 \end_layout
2019 \begin_layout Plain Layout
2021 .PHONEY: clean_example
2022 \end_layout
2024 \begin_layout Plain Layout
2026 clean_example: ; cd $(example_srcdir) && 
2027 \backslash
2029 \end_layout
2031 \begin_layout Plain Layout
2033         $(MAKE) -f Makefile.inc clean
2034 \end_layout
2036 \begin_layout Plain Layout
2038 \end_layout
2040 \begin_layout Plain Layout
2042 distclean:: distclean_example
2043 \end_layout
2045 \begin_layout Plain Layout
2047 .PHONY: distclean_example
2048 \end_layout
2050 \begin_layout Plain Layout
2052 distclean_example: ; cd $(example_srcdir) && 
2053 \backslash
2055 \end_layout
2057 \begin_layout Plain Layout
2059         $(MAKE) -f Makefile.inc distclean
2060 \end_layout
2062 \end_inset
2065 \end_layout
2067 \begin_layout Standard
2068 We could do similarly for install targets to install the generated docs.
2069 \end_layout
2071 \begin_layout Subsection
2072 \begin_inset CommandInset label
2073 LatexCommand label
2074 name "sub:Converting-from-Lyx"
2076 \end_inset
2078 Converting from Lyx to LaTeX
2079 \end_layout
2081 \begin_layout Standard
2082 The first stage will always be to convert the Lyx file to a LaTeX file;
2083  this must be so not only because newfangle needs to to run on a TeX file,
2084  but also because the Lyx command 
2085 \emph on
2086 server-goto-file-line
2087 \begin_inset Foot
2088 status collapsed
2090 \begin_layout Plain Layout
2091 The Lyx command 
2092 \emph on
2093 server-goto-file-line
2094 \emph default
2095  is used to position the Lyx cursor at the compiler errors.
2096 \end_layout
2098 \end_inset
2101 \emph default
2102  insists that the line number provided is a line in the TeX file, and always
2103  reverse maps this to derive the line in the Lyx docment.
2104 \begin_inset Note Note
2105 status collapsed
2107 \begin_layout Plain Layout
2108 The tex file should probably be an automake extra dist sources or something,
2109  so that it gets produced and packaged by make dist
2110 \end_layout
2112 \end_inset
2115 \end_layout
2117 \begin_layout Standard
2118 The command [[lyx -e literate noweb-lyx.lyx]] will produce [[noweb-lyx.nw]]
2119  a tex file, so we define the noweb target to be the same as the Lyx file
2120  but with the .nw extension.
2121 \end_layout
2123 \begin_layout Chunk
2124 Makefile.inc-vars
2125 \end_layout
2127 \begin_layout Standard
2128 \begin_inset listings
2129 inline false
2130 status open
2132 \begin_layout Plain Layout
2134 TEX_SOURCE=$(LYX_SOURCE:.lyx=.tex)
2135 \end_layout
2137 \end_inset
2140 \end_layout
2142 \begin_layout Chunk
2143 Makefile.inc-targets
2144 \end_layout
2146 \begin_layout Standard
2147 \begin_inset listings
2148 inline false
2149 status open
2151 \begin_layout Plain Layout
2153 $(TEX_SOURCE): $(LYX_SOURCE) ;
2154 \backslash
2156 \end_layout
2158 \begin_layout Plain Layout
2160         lyx -e latex $<
2161 \end_layout
2163 \begin_layout Plain Layout
2165 clean_tex: ; rm -f -- $(TEX_SOURCE)
2166 \end_layout
2168 \end_inset
2171 \end_layout
2173 \begin_layout Subsection
2174 Extracting Program Source
2175 \end_layout
2177 \begin_layout Standard
2178 The program source is extracted using newfangle, which is designed to operate
2179  on a LaTeX document.
2181 \end_layout
2183 \begin_layout Chunk
2184 Makefile.inc-vars
2185 \end_layout
2187 \begin_layout Standard
2188 \begin_inset listings
2189 inline false
2190 status open
2192 \begin_layout Plain Layout
2194 NEWFANGLE_SOURCE=$(TEX_SOURCE)
2195 \end_layout
2197 \end_inset
2200 \end_layout
2202 \begin_layout Standard
2203 The Lyx document can result in any number of source documents, but not all
2204  of these will be changed each time the Lyx document is updated.
2205  We certainly don't want to update the timestamps of these files and cause
2206  the whole source tree to be recompiled just because the Lyx document was
2207  edited.
2209 \end_layout
2211 \begin_layout Standard
2212 To solve this problem we use a stamp file which is always updated each time
2213  the sources are extracted from the LaTeX document.
2214  If the stamp file is older than the LaTeX document, then we can make an
2215  attempt to re-extract the sources.
2216 \end_layout
2218 \begin_layout Chunk
2219 Makefile.inc-vars
2220 \end_layout
2222 \begin_layout Standard
2223 \begin_inset listings
2224 inline false
2225 status open
2227 \begin_layout Plain Layout
2229 NEWFANGLE_SOURCE_STAMP=$(NEWFANGLE_SOURCE).stamp
2230 \end_layout
2232 \end_inset
2235 \end_layout
2237 \begin_layout Chunk
2238 Makefile.inc-targets
2239 \end_layout
2241 \begin_layout Standard
2242 \begin_inset listings
2243 inline false
2244 status open
2246 \begin_layout Plain Layout
2248 $(NEWFANGLE_SOURCE_STAMP): $(NEWFANGLE_SOURCE) 
2249 \backslash
2251 \end_layout
2253 \begin_layout Plain Layout
2255                            $(NEWFANGLE_SOURCES) ; 
2256 \backslash
2258 \end_layout
2260 \begin_layout Plain Layout
2262         echo > $(NEWFANGLE_SOURCE_STAMP)
2263 \end_layout
2265 \begin_layout Plain Layout
2267 clean_stamp: ; rm -f $(NEWFANGLE_SOURCE_STAMP)
2268 \end_layout
2270 \begin_layout Plain Layout
2272 clean: clean_stamp
2273 \end_layout
2275 \end_inset
2278 \end_layout
2280 \begin_layout Subsection
2281 Extracting C sources
2282 \end_layout
2284 \begin_layout Standard
2285 We compute 
2286 \begin_inset Flex CharStyle:Code
2287 status collapsed
2289 \begin_layout Plain Layout
2290 NEWFANGLE_SOURCES
2291 \end_layout
2293 \end_inset
2295  to hold the names of all the C source files defined in this document.
2296  We compute this only once, by means of := in assignent.
2297  The sed deletes the any <
2298 \begin_inset space \hspace*{}
2299 \length 0in
2300 \end_inset
2302 < and >
2303 \begin_inset space \hspace*{}
2304 \length 0in
2305 \end_inset
2307 > which may surround the roots names (for noroots compatibility).
2309 \end_layout
2311 \begin_layout Standard
2312 As we use chunk names beginning with ./ to denote top level fragments that
2313  should be extracted, we filter out all fragments that do not begin with
2314  ./
2315 \end_layout
2317 \begin_layout Chunk
2318 Makefile.inc-vars
2319 \end_layout
2321 \begin_layout Standard
2322 \begin_inset listings
2323 inline false
2324 status open
2326 \begin_layout Plain Layout
2328 NEWFANGLE_PREFIX:=
2329 \backslash
2331 \backslash
2333 \end_layout
2335 \begin_layout Plain Layout
2337 NEWFANGLE_SOURCES:=$(shell 
2338 \backslash
2340 \end_layout
2342 \begin_layout Plain Layout
2344   newfangle -r $(NEWFANGLE_SOURCE) |
2345 \backslash
2347 \end_layout
2349 \begin_layout Plain Layout
2351   sed -e 's/^[<][<]//;s/[>][>]$$//;/^$(NEWFANGLE_PREFIX)/!d' 
2352 \backslash
2354 \end_layout
2356 \begin_layout Plain Layout
2358       -e 's/^$(NEWFANGLE_PREFIX)/
2359 \backslash
2361 \backslash
2362 //' )
2363 \end_layout
2365 \begin_layout Plain Layout
2368 \end_layout
2370 \end_inset
2373 \end_layout
2375 \begin_layout Chunk
2376 Makefile.inc-targets
2377 \end_layout
2379 \begin_layout Standard
2380 \begin_inset listings
2381 inline false
2382 status open
2384 \begin_layout Plain Layout
2386 .PHONY: echo_newfangle_sources
2387 \end_layout
2389 \begin_layout Plain Layout
2391 echo_newfangle_sources: ; @echo $(NEWFANGLE_SOURCES)
2392 \end_layout
2394 \end_inset
2397 \end_layout
2399 \begin_layout Standard
2400 We define a convenient target called 
2401 \begin_inset Flex CharStyle:Code
2402 status collapsed
2404 \begin_layout Plain Layout
2405 newfangle_sources
2406 \end_layout
2408 \end_inset
2410  to re-extract the source if the LaTeX file has been updated.
2411 \end_layout
2413 \begin_layout Chunk
2414 Makefile.inc-targets
2415 \end_layout
2417 \begin_layout Standard
2418 \begin_inset listings
2419 inline false
2420 status open
2422 \begin_layout Plain Layout
2424 .PHONY: newfangle_sources
2425 \end_layout
2427 \begin_layout Plain Layout
2429 newfangle_sources: $(NEWFANGLE_SOURCE_STAMP)
2430 \end_layout
2432 \end_inset
2435 \end_layout
2437 \begin_layout Standard
2438 And also a convenient target to remove extracted sources.
2439 \end_layout
2441 \begin_layout Chunk
2442 Makefile.inc-targets
2443 \end_layout
2445 \begin_layout Standard
2446 \begin_inset listings
2447 inline false
2448 status open
2450 \begin_layout Plain Layout
2452 .PHONY: clean_newfangle_sources
2453 \end_layout
2455 \begin_layout Plain Layout
2457 clean_newfangle_sources: ; 
2458 \backslash
2460 \end_layout
2462 \begin_layout Plain Layout
2464         rm -f -- $(NEWFANGLE_SOURCE_STAMP) $(NEWFANGLE_SOURCES)
2465 \end_layout
2467 \end_inset
2470 \end_layout
2472 \begin_layout Standard
2473 This 
2474 \begin_inset Flex CharStyle:Code
2475 status collapsed
2477 \begin_layout Plain Layout
2478 if_extension
2479 \end_layout
2481 \end_inset
2483  macro takes 4 arguments: the filename (1), some extensions to match (2)
2484  and a some shell command to return if the filename matches the exentions
2485  (3), or not (4).
2486 \end_layout
2488 \begin_layout Chunk
2489 Makefile.inc-vars
2490 \end_layout
2492 \begin_layout Standard
2493 \begin_inset listings
2494 inline false
2495 status open
2497 \begin_layout Plain Layout
2499 if_extension=$(if $(findstring $(suffix $(1)),$(2)),$(3),$(4))
2500 \end_layout
2502 \end_inset
2505 \end_layout
2507 \begin_layout Standard
2508 For some source files like C files, we want to output the line number and
2509  filename of the original LaTeX document from which the source came.
2510 \end_layout
2512 \begin_layout Standard
2513 To make this easier we define the file extensions for which we want to do
2514  this.
2515 \end_layout
2517 \begin_layout Chunk
2518 Makefile.inc-vars
2519 \end_layout
2521 \begin_layout Standard
2522 \begin_inset listings
2523 inline false
2524 status open
2526 \begin_layout Plain Layout
2528 C_EXTENSIONS=.c .h
2529 \end_layout
2531 \end_inset
2534 \end_layout
2536 \begin_layout Standard
2537 We can then use the if_extensions macro to define a macro which expands
2538  out to the 
2539 \begin_inset Flex CharStyle:Code
2540 status collapsed
2542 \begin_layout Plain Layout
2544 \end_layout
2546 \end_inset
2548  option if newfangle is being invoked in a C source file, so that C compile
2549  errors will refer to the line number in the Lyx document.
2551 \end_layout
2553 \begin_layout Chunk
2554 Makefile.inc-vars
2555 \end_layout
2557 \begin_layout Standard
2558 \begin_inset listings
2559 inline false
2560 status open
2562 \begin_layout Plain Layout
2564 TABS=8
2565 \end_layout
2567 \begin_layout Plain Layout
2569 nf_line=-L -T$(TABS)
2570 \end_layout
2572 \begin_layout Plain Layout
2574 newfangle=newfangle 
2575 \backslash
2577 \end_layout
2579 \begin_layout Plain Layout
2581   $(call if_extension,$(2),$(C_EXTENSIONS),$(nf_line)) 
2582 \backslash
2584 \end_layout
2586 \begin_layout Plain Layout
2588     -R"$(2)" $(1)
2589 \end_layout
2591 \end_inset
2594 \end_layout
2596 \begin_layout Standard
2597 We can use a similar trick to define an 
2598 \emph on
2599 indent
2600 \emph default
2601  macro which takes just the filename as an argument and can return a pipeline
2602  stage calling the indent command.
2603  Indent can be turned off with 
2604 \begin_inset Flex CharStyle:Code
2605 status collapsed
2607 \begin_layout Plain Layout
2608 make newfangle_sources indent=
2609 \end_layout
2611 \end_inset
2614 \end_layout
2616 \begin_layout Chunk
2617 Makefile.inc-vars
2618 \end_layout
2620 \begin_layout Standard
2621 \begin_inset listings
2622 inline false
2623 status open
2625 \begin_layout Plain Layout
2627 indent_options=-npro -kr -i8 -ts8 -sob -l80 -ss -ncs
2628 \end_layout
2630 \begin_layout Plain Layout
2632 indent=$(call if_extension,$(1),$(C_EXTENSIONS),
2633 \backslash
2635 \end_layout
2637 \begin_layout Plain Layout
2639               | indent $(indent_options))
2640 \end_layout
2642 \end_inset
2645 \end_layout
2647 \begin_layout Standard
2648 We now define the pattern for extracting a file.
2649  The files are written using noweb's 
2650 \emph on
2651 cpif
2652 \begin_inset Foot
2653 status collapsed
2655 \begin_layout Plain Layout
2657 \emph on
2658 So you still need noweb installed in order to use cpif
2659 \end_layout
2661 \end_inset
2664 \begin_inset Note Note
2665 status collapsed
2667 \begin_layout Plain Layout
2669 \emph on
2670 Write an awk version
2671 \end_layout
2673 \end_inset
2676 \emph default
2677  so that the file timestamp will not be touched if the contents haven't
2678  changed.
2679  This avoids the need to rebuild the entire project because of a typographical
2680  change in the documentation, or if only a few C source files have changed.
2681 \end_layout
2683 \begin_layout Chunk
2684 Makefile.inc-vars
2685 \end_layout
2687 \begin_layout Standard
2688 \begin_inset listings
2689 inline false
2690 status open
2692 \begin_layout Plain Layout
2694 newfangle_extract=@mkdir -p $(dir $(1)) && 
2695 \backslash
2697 \end_layout
2699 \begin_layout Plain Layout
2701   $(call newfangle,$(2),$(1)) > "$(1).tmp" && 
2702 \backslash
2704 \end_layout
2706 \begin_layout Plain Layout
2708   cat "$(1).tmp" $(indent) | cpif "$(1)" 
2709 \backslash
2711 \end_layout
2713 \begin_layout Plain Layout
2715   && rm -- "$(1).tmp" || 
2716 \backslash
2718 \end_layout
2720 \begin_layout Plain Layout
2722   (echo error newfangling $(1) from $(2) ; exit 1)
2723 \end_layout
2725 \end_inset
2728 \end_layout
2730 \begin_layout Standard
2731 We define a target which will extract or update all sources.
2732  To do this we first defined a makefile template that can do this for any
2733  source file in the LaTeX document.
2734 \end_layout
2736 \begin_layout Chunk
2737 Makefile.inc-vars
2738 \end_layout
2740 \begin_layout Standard
2741 \begin_inset listings
2742 inline false
2743 status open
2745 \begin_layout Plain Layout
2747 define NEWFANGLE_template
2748 \end_layout
2750 \begin_layout Plain Layout
2752   $(1): $(2); 
2753 \backslash
2755 \end_layout
2757 \begin_layout Plain Layout
2759     $$(call newfangle_extract,$(1),$(2))
2760 \end_layout
2762 \begin_layout Plain Layout
2764   NEWFANGLE_TARGETS+=$(1)
2765 \end_layout
2767 \begin_layout Plain Layout
2769 endef
2770 \end_layout
2772 \end_inset
2775 \end_layout
2777 \begin_layout Standard
2778 We then enumerate the discovered 
2779 \begin_inset Flex CharStyle:Code
2780 status collapsed
2782 \begin_layout Plain Layout
2783 NEWTANGLE_SOURCES
2784 \end_layout
2786 \end_inset
2788  to generate a makefile rule for each one using the makefile template we
2789  defined above.
2790 \end_layout
2792 \begin_layout Chunk
2793 Makefile.inc-targets
2794 \end_layout
2796 \begin_layout Standard
2797 \begin_inset listings
2798 inline false
2799 status open
2801 \begin_layout Plain Layout
2803 $(foreach source,$(NEWFANGLE_SOURCES),
2804 \backslash
2806 \end_layout
2808 \begin_layout Plain Layout
2810   $(eval $(call NEWFANGLE_template,$(source),$(NEWFANGLE_SOURCE))) 
2811 \backslash
2813 \end_layout
2815 \begin_layout Plain Layout
2818 \end_layout
2820 \end_inset
2823 \end_layout
2825 \begin_layout Standard
2826 These will all be built with NEWFANGLE_SOURCE_STAMP.
2827 \end_layout
2829 \begin_layout Standard
2830 We also remove the generated sources on a 
2831 \emph on
2832 make distclean
2833 \emph default
2835 \end_layout
2837 \begin_layout Chunk
2838 Makefile.inc-targets
2839 \end_layout
2841 \begin_layout Standard
2842 \begin_inset listings
2843 inline false
2844 status open
2846 \begin_layout Plain Layout
2848 _distclean: clean_newfangle_sources
2849 \end_layout
2851 \end_inset
2854 \end_layout
2856 \begin_layout Subsection
2857 Extracting Documentation
2858 \end_layout
2860 \begin_layout Standard
2861 We then identify the intermediate stages of the documentation and their
2862  build and clean targets.
2863 \end_layout
2865 \begin_layout Subsubsection
2866 Running pdflatex
2867 \end_layout
2869 \begin_layout Standard
2870 We produce a pdf file from the tex file.
2871 \end_layout
2873 \begin_layout Chunk
2874 Makefile.inc-vars
2875 \end_layout
2877 \begin_layout Standard
2878 \begin_inset listings
2879 inline false
2880 status open
2882 \begin_layout Plain Layout
2884 NEWFANGLE_PDF=$(TEX_SOURCE:.tex=.pdf)
2885 \end_layout
2887 \end_inset
2890 \end_layout
2892 \begin_layout Standard
2893 We run pdflatex twice to be sure that the contents and aux files are up
2894  to date.
2895  We certainly are required to run pdflatex twice if these files do not exist!
2896 \end_layout
2898 \begin_layout Chunk
2899 Makefile.inc-targets
2900 \end_layout
2902 \begin_layout Standard
2903 \begin_inset listings
2904 inline false
2905 status open
2907 \begin_layout Plain Layout
2909 $(NEWFANGLE_PDF): $(TEX_SOURCE); pdflatex $< && pdflatex $<
2910 \end_layout
2912 \begin_layout Plain Layout
2914 clean_pdf: ; rm -f -- $(NEWFANGLE_PDF) 
2915 \backslash
2917 \end_layout
2919 \begin_layout Plain Layout
2921                       $(TEX_SOURCE:.tex=.toc) 
2922 \backslash
2924 \end_layout
2926 \begin_layout Plain Layout
2928                       $(TEX_SOURCE:.tex=.log) 
2929 \backslash
2931 \end_layout
2933 \begin_layout Plain Layout
2935                       $(TEX_SOURCE:.tex=.aux)
2936 \end_layout
2938 \end_inset
2941 \end_layout
2943 \begin_layout Subsubsection
2944 The docs as a whole
2945 \end_layout
2947 \begin_layout Standard
2948 Currently we only build pdf as a final format, but NEWFANGLE_DOCS may later
2949  hold other output formats.
2950 \end_layout
2952 \begin_layout Chunk
2953 Makefile.inc-vars
2954 \end_layout
2956 \begin_layout Standard
2957 \begin_inset listings
2958 inline false
2959 status open
2961 \begin_layout Plain Layout
2963 NEWFANGLE_DOCS=$(NEWFANGLE_PDF)
2964 \end_layout
2966 \end_inset
2969 \end_layout
2971 \begin_layout Standard
2972 We also define newfangle_docs as a convenient phony target<
2973 \end_layout
2975 \begin_layout Chunk
2976 Makefile.inc-targets
2977 \end_layout
2979 \begin_layout Standard
2980 \begin_inset listings
2981 inline false
2982 status open
2984 \begin_layout Plain Layout
2986 .PHONY: newfangle_docs
2987 \end_layout
2989 \begin_layout Plain Layout
2991 newfangle_docs: $(NEWFANGLE_DOCS)
2992 \end_layout
2994 \begin_layout Plain Layout
2996 docs: newfangle_docs
2997 \end_layout
2999 \end_inset
3002 \end_layout
3004 \begin_layout Standard
3005 And define a convenient clean_noweb_docs which we add to the regular clean
3006  target
3007 \end_layout
3009 \begin_layout Chunk
3010 Makefile.inc-targets
3011 \end_layout
3013 \begin_layout Standard
3014 \begin_inset listings
3015 inline false
3016 status open
3018 \begin_layout Plain Layout
3020 .PHONEY: clean_newfangle_docs
3021 \end_layout
3023 \begin_layout Plain Layout
3025 clean_newfangle_docs: clean_tex clean_pdf
3026 \end_layout
3028 \begin_layout Plain Layout
3030 clean: clean_newfangle_docs
3031 \end_layout
3033 \begin_layout Plain Layout
3035 \end_layout
3037 \begin_layout Plain Layout
3039 distclean_newfangle_docs: clean_tex clean_newfangle_docs
3040 \end_layout
3042 \begin_layout Plain Layout
3044 distclean: clean distclean_newfangle_docs
3045 \end_layout
3047 \end_inset
3050 \end_layout
3052 \begin_layout Subsection
3053 Other helpers
3054 \end_layout
3056 \begin_layout Standard
3057 If Makefile.inc is included into Makefile, then extracted files can be updated
3058  with this command:
3059 \end_layout
3061 \begin_layout LyX-Code
3062 make newfangle_sources
3063 \end_layout
3065 \begin_layout Standard
3066 otherwise, with:
3067 \end_layout
3069 \begin_layout LyX-Code
3070 make -f Makefile.inc newfangle_sources
3071 \end_layout
3073 \begin_layout Part
3074 Source Code
3075 \end_layout
3077 \begin_layout Chapter
3078 Newfangle awk source code
3079 \end_layout
3081 \begin_layout Standard
3082 We use the copyright notice from chapter 
3083 \begin_inset CommandInset ref
3084 LatexCommand ref
3085 reference "cha:License"
3087 \end_inset
3090 \end_layout
3092 \begin_layout Chunk
3093 ./newfangle,language=awk,morestring=[b]{/},morekeywords=else
3094 \end_layout
3096 \begin_layout Standard
3097 \begin_inset listings
3098 inline false
3099 status open
3101 \begin_layout Plain Layout
3103 #! /usr/bin/awk -f
3104 \end_layout
3106 \begin_layout Plain Layout
3108 # =<
3109 \backslash
3110 chunkref{gpl3-copyright}>
3111 \end_layout
3113 \begin_layout Plain Layout
3115 \end_layout
3117 \end_inset
3120 \end_layout
3122 \begin_layout Standard
3123 We also use code from Arnold Robbins public domain getopt (1993 revision)
3124  defined in chapter 
3125 \begin_inset CommandInset ref
3126 LatexCommand ref
3127 reference "cha:getopt"
3129 \end_inset
3131 , and naturally want to attribute this appropriately.
3132 \end_layout
3134 \begin_layout Standard
3135 \begin_inset listings
3136 inline false
3137 status open
3139 \begin_layout Plain Layout
3141 \end_layout
3143 \begin_layout Plain Layout
3145 # NOTE: Arnold Robbins public domain getopt for awk is also used:
3146 \end_layout
3148 \begin_layout Plain Layout
3151 \backslash
3152 chunkref{getopt.awk-header}>
3153 \end_layout
3155 \begin_layout Plain Layout
3157 \end_layout
3159 \begin_layout Plain Layout
3162 \backslash
3163 chunkref{getopt.awk-getopt()}>
3164 \end_layout
3166 \begin_layout Plain Layout
3168 \end_layout
3170 \end_inset
3173 \end_layout
3175 \begin_layout Standard
3176 And include the following chunks
3177 \end_layout
3179 \begin_layout Chunk
3180 ./newfangle
3181 \end_layout
3183 \begin_layout Standard
3184 \begin_inset listings
3185 inline false
3186 status open
3188 \begin_layout Plain Layout
3191 \backslash
3192 chunkref{helper-functions}>
3193 \end_layout
3195 \begin_layout Plain Layout
3198 \backslash
3199 chunkref{mode-tracker}>
3200 \end_layout
3202 \begin_layout Plain Layout
3205 \backslash
3206 chunkref{parse_chunk_args}>
3207 \end_layout
3209 \begin_layout Plain Layout
3212 \backslash
3213 chunkref{chunk-storage-functions}>
3214 \end_layout
3216 \begin_layout Plain Layout
3219 \backslash
3220 chunkref{output_chunk_names()}>
3221 \end_layout
3223 \begin_layout Plain Layout
3226 \backslash
3227 chunkref{output_chunks()}>
3228 \end_layout
3230 \begin_layout Plain Layout
3233 \backslash
3234 chunkref{write_chunk()}>
3235 \end_layout
3237 \begin_layout Plain Layout
3240 \backslash
3241 chunkref{expand_chunk_args()}>
3242 \end_layout
3244 \begin_layout Plain Layout
3247 \backslash
3248 chunkref{begin}>
3249 \end_layout
3251 \begin_layout Plain Layout
3254 \backslash
3255 chunkref{recognize-chunk}>
3256 \end_layout
3258 \begin_layout Plain Layout
3261 \backslash
3262 chunkref{end}>
3263 \end_layout
3265 \end_inset
3268 \end_layout
3270 \begin_layout Section
3271 AWK tricks
3272 \end_layout
3274 \begin_layout Standard
3275 The portable way to erase an array in awk is to split the empty string,
3276  like this:
3277 \end_layout
3279 \begin_layout Chunk
3280 awk-delete-array,params=ARRAY
3281 \end_layout
3283 \begin_layout Standard
3284 \begin_inset listings
3285 inline false
3286 status open
3288 \begin_layout Plain Layout
3290 split("", ${ARRAY});
3291 \end_layout
3293 \end_inset
3296 \end_layout
3298 \begin_layout Chunk
3299 dump-array,params=ARRAY
3300 \end_layout
3302 \begin_layout Standard
3303 \begin_inset listings
3304 inline false
3305 status open
3307 \begin_layout Plain Layout
3309 print "
3310 \backslash
3311 nDump: ${ARRAY}
3312 \backslash
3313 n--------
3314 \backslash
3315 n" > "/dev/stderr";
3316 \end_layout
3318 \begin_layout Plain Layout
3320 for (_x in ${ARRAY}) {
3321 \end_layout
3323 \begin_layout Plain Layout
3325   print _x "=" ${ARRAY}[_x] "
3326 \backslash
3327 n" > "/dev/stderr";
3328 \end_layout
3330 \begin_layout Plain Layout
3333 \end_layout
3335 \begin_layout Plain Layout
3337 print "========
3338 \backslash
3339 n" > "/dev/stderr";
3340 \end_layout
3342 \end_inset
3345 \end_layout
3347 \begin_layout Chunk
3348 ,params=
3349 \end_layout
3351 \begin_layout Section
3352 Catching errors
3353 \end_layout
3355 \begin_layout Standard
3356 Fatal errors are issued with the error function:
3357 \end_layout
3359 \begin_layout Chunk
3360 error(),append=helper-functions
3361 \end_layout
3363 \begin_layout Standard
3364 \begin_inset listings
3365 inline false
3366 status open
3368 \begin_layout Plain Layout
3370 function error(message)
3371 \end_layout
3373 \begin_layout Plain Layout
3376 \end_layout
3378 \begin_layout Plain Layout
3380   print "ERROR: " FILENAME ":" FNR " " message > "/dev/stderr";
3381 \end_layout
3383 \begin_layout Plain Layout
3385   exit 1;
3386 \end_layout
3388 \begin_layout Plain Layout
3391 \end_layout
3393 \end_inset
3396 \end_layout
3398 \begin_layout Standard
3399 \begin_inset listings
3400 inline false
3401 status open
3403 \begin_layout Plain Layout
3405 function warning(message)
3406 \end_layout
3408 \begin_layout Plain Layout
3411 \end_layout
3413 \begin_layout Plain Layout
3415   print "WARNING: " FILENAME ":" FNR " " message > "/dev/stderr";
3416 \end_layout
3418 \begin_layout Plain Layout
3420   warnings++;
3421 \end_layout
3423 \begin_layout Plain Layout
3426 \end_layout
3428 \end_inset
3431 \end_layout
3433 \begin_layout Chapter
3434 lstlistings
3435 \end_layout
3437 \begin_layout Standard
3438 LaTeX arguments to lstlistings macros are a comma seperated list of key-value
3439  pairs.
3440  Values containing commas are enclosed in 
3441 \begin_inset Flex CharStyle:Code
3442 status collapsed
3444 \begin_layout Plain Layout
3446 \end_layout
3448 \end_inset
3450  braces 
3451 \begin_inset Flex CharStyle:Code
3452 status collapsed
3454 \begin_layout Plain Layout
3456 \end_layout
3458 \end_inset
3460 , which is to be expected for LaTeX.
3461 \end_layout
3463 \begin_layout Standard
3464 A sample expressions is:
3465 \end_layout
3467 \begin_layout LyX-Code
3468 name=thomas, params={a, b}, something, something-else
3469 \end_layout
3471 \begin_layout Standard
3472 but we see that this is just a simpler form of this expression:
3473 \end_layout
3475 \begin_layout LyX-Code
3476 name=freddie, foo={bar=baz, quux={quirk, a=fleeg}}, etc
3477 \end_layout
3479 \begin_layout Standard
3480 We may consider that we need a function that can parse such LaTeX expressions
3481  and assign the values to an 
3482 \noun on
3484 \noun default
3485  associated array, perhaps using a recursive parser into a multi-dimensional
3486  hash
3487 \begin_inset Foot
3488 status collapsed
3490 \begin_layout Plain Layout
3491 as AWK doesn't have nested-hash support
3492 \end_layout
3494 \end_inset
3496 , resulting in:
3497 \end_layout
3499 \begin_layout Standard
3500 \begin_inset Tabular
3501 <lyxtabular version="3" rows="6" columns="2">
3502 <features>
3503 <column alignment="left" valignment="top" width="0">
3504 <column alignment="left" valignment="top" width="0">
3505 <row>
3506 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
3507 \begin_inset Text
3509 \begin_layout Plain Layout
3511 \end_layout
3513 \end_inset
3514 </cell>
3515 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
3516 \begin_inset Text
3518 \begin_layout Plain Layout
3519 value
3520 \end_layout
3522 \end_inset
3523 </cell>
3524 </row>
3525 <row>
3526 <cell alignment="left" valignment="top" topline="true" leftline="true" usebox="none">
3527 \begin_inset Text
3529 \begin_layout Plain Layout
3530 a[name]
3531 \end_layout
3533 \end_inset
3534 </cell>
3535 <cell alignment="left" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
3536 \begin_inset Text
3538 \begin_layout Plain Layout
3539 freddie
3540 \end_layout
3542 \end_inset
3543 </cell>
3544 </row>
3545 <row>
3546 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
3547 \begin_inset Text
3549 \begin_layout Plain Layout
3550 a[foo, bar]
3551 \end_layout
3553 \end_inset
3554 </cell>
3555 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
3556 \begin_inset Text
3558 \begin_layout Plain Layout
3560 \end_layout
3562 \end_inset
3563 </cell>
3564 </row>
3565 <row>
3566 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
3567 \begin_inset Text
3569 \begin_layout Plain Layout
3570 a[foo, quux, quirk]
3571 \end_layout
3573 \end_inset
3574 </cell>
3575 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
3576 \begin_inset Text
3578 \begin_layout Plain Layout
3580 \end_layout
3582 \end_inset
3583 </cell>
3584 </row>
3585 <row>
3586 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
3587 \begin_inset Text
3589 \begin_layout Plain Layout
3590 a[foo, quux, a]
3591 \end_layout
3593 \end_inset
3594 </cell>
3595 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
3596 \begin_inset Text
3598 \begin_layout Plain Layout
3599 fleeg
3600 \end_layout
3602 \end_inset
3603 </cell>
3604 </row>
3605 <row>
3606 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
3607 \begin_inset Text
3609 \begin_layout Plain Layout
3610 a[etc]
3611 \end_layout
3613 \end_inset
3614 </cell>
3615 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
3616 \begin_inset Text
3618 \begin_layout Plain Layout
3620 \end_layout
3622 \end_inset
3623 </cell>
3624 </row>
3625 </lyxtabular>
3627 \end_inset
3630 \end_layout
3632 \begin_layout Standard
3633 Oon reflection it seems that sometimes such nesting is not desirable, as
3634  the braces are also used to delimit values that contain commas --- we may
3635  consider that
3636 \end_layout
3638 \begin_layout LyX-Code
3639 name={williamson, freddie}
3640 \end_layout
3642 \begin_layout Standard
3643 should assign 
3644 \begin_inset Flex CharStyle:Code
3645 status collapsed
3647 \begin_layout Plain Layout
3648 williamson, freddie
3649 \end_layout
3651 \end_inset
3653  to 
3654 \begin_inset Flex CharStyle:Code
3655 status collapsed
3657 \begin_layout Plain Layout
3658 name
3659 \end_layout
3661 \end_inset
3664 \end_layout
3666 \begin_layout Standard
3667 In fact we are not so interested in the detail so as to be bothered by this,
3668  which turns out to be a good thing for two reasons.
3669  Firstly LaTeX has a malleable parser with no strict syntax, and secondly
3670  whether or not 
3671 \begin_inset Flex CharStyle:Code
3672 status collapsed
3674 \begin_layout Plain Layout
3675 williamson
3676 \end_layout
3678 \end_inset
3680  and 
3681 \begin_inset Flex CharStyle:Code
3682 status collapsed
3684 \begin_layout Plain Layout
3685 freddie
3686 \end_layout
3688 \end_inset
3690  should count as two items will be context dependant anyway.
3691 \end_layout
3693 \begin_layout Standard
3694 We need to parse this latex for only one reason; which is that we are extending
3695  lstlistings to add some additional arguments which will be used to express
3696  chunk parameters and other chunk options.
3697 \end_layout
3699 \begin_layout Section
3700 Additional lstlstings parameters
3701 \end_layout
3703 \begin_layout Standard
3704 Further on we define a 
3705 \begin_inset Flex CharStyle:Code
3706 status collapsed
3708 \begin_layout Plain Layout
3710 \backslash
3711 Chunk
3712 \end_layout
3714 \end_inset
3716  LaTeX macro whose arguments will consist of a the chunk name, optionally
3717  followed by a comma and then a comma separated list of arguments.
3718  In fact we will just need to prefix 
3719 \begin_inset Flex CharStyle:Code
3720 status collapsed
3722 \begin_layout Plain Layout
3723 name=
3724 \end_layout
3726 \end_inset
3728  to the arguments to in order to create valid lstlistings arguments.
3730 \end_layout
3732 \begin_layout Standard
3733 There will be other arguments supported too; 
3734 \end_layout
3736 \begin_layout Description
3737 params As an extension to many literate-programming styles, newfangle permits
3738  code chunks to take parameters and thus operate somewhat like C pre-processor
3739  macros, or like C++ templates.
3740  Chunk parameters are declared with a chunk argument called 
3741 \begin_inset Flex CharStyle:Code
3742 status collapsed
3744 \begin_layout Plain Layout
3745 params
3746 \end_layout
3748 \end_inset
3750 , which holds a semi-colon separated list of parameters, like this:
3751 \end_layout
3753 \begin_layout LyX-Code
3754 achunk,language=C,params=name;address
3755 \end_layout
3757 \begin_layout Description
3758 addto a named chunk that this chunk is to be included into.
3759  This saves the effort of having to declare another listing of the named
3760  chunk merely to include this one.
3761 \end_layout
3763 \begin_layout Standard
3764 Function 
3765 \begin_inset Flex Chunkref
3766 status collapsed
3768 \begin_layout Plain Layout
3769 get_chunk_args()
3770 \end_layout
3772 \end_inset
3774  will accept two paramters, 
3775 \begin_inset Flex CharStyle:Code
3776 status collapsed
3778 \begin_layout Plain Layout
3779 text
3780 \end_layout
3782 \end_inset
3784  being the text to parse, and 
3785 \begin_inset Flex CharStyle:Code
3786 status collapsed
3788 \begin_layout Plain Layout
3789 values
3790 \end_layout
3792 \end_inset
3794  being an array to receive the parsed values as described above.
3795  The optional parameter 
3796 \begin_inset Flex CharStyle:Code
3797 status collapsed
3799 \begin_layout Plain Layout
3800 path
3801 \end_layout
3803 \end_inset
3805  is used during recursion to build up the multi-dimensional array path.
3806 \end_layout
3808 \begin_layout Chunk
3809 ./newfangle
3810 \end_layout
3812 \begin_layout Standard
3813 \begin_inset listings
3814 inline false
3815 status open
3817 \begin_layout Plain Layout
3820 \backslash
3821 chunkref{get_chunk_args()}>
3822 \end_layout
3824 \end_inset
3827 \end_layout
3829 \begin_layout Chunk
3830 get_chunk_args()
3831 \end_layout
3833 \begin_layout Standard
3834 \begin_inset listings
3835 inline false
3836 status open
3838 \begin_layout Plain Layout
3840 function get_chunk_args(text, values,
3841 \end_layout
3843 \begin_layout Plain Layout
3845   # optional parameters
3846 \end_layout
3848 \begin_layout Plain Layout
3850   path, # hierarchical precursors
3851 \end_layout
3853 \begin_layout Plain Layout
3855   # local vars
3856 \end_layout
3858 \begin_layout Plain Layout
3860   a, name)
3861 \end_layout
3863 \end_inset
3866 \end_layout
3868 \begin_layout Standard
3869 The strategy is to parse the name, and then look for a value.
3870  If the value begins with a brace 
3871 \begin_inset Flex CharStyle:Code
3872 status collapsed
3874 \begin_layout Plain Layout
3876 \end_layout
3878 \end_inset
3880 , then we recurse and consume as much of the text as necessary, returning
3881  the remaining text when we encounter a leading close-brace 
3882 \begin_inset Flex CharStyle:Code
3883 status collapsed
3885 \begin_layout Plain Layout
3887 \end_layout
3889 \end_inset
3892  This being the strategy --- and executed in a loop --- we realise that
3893  we must first look for the closing brace (perhaps preceded by white space)
3894  in order to terminate the recursion, and returning remaining text.
3895 \end_layout
3897 \begin_layout Standard
3898 \begin_inset listings
3899 inline false
3900 status open
3902 \begin_layout Plain Layout
3905 \end_layout
3907 \begin_layout Plain Layout
3909   split("", next_chunk_args);
3910 \end_layout
3912 \begin_layout Plain Layout
3914   while(length(text)) {
3915 \end_layout
3917 \begin_layout Plain Layout
3919     if (match(text, "^ *}(.*)", a)) {
3920 \end_layout
3922 \begin_layout Plain Layout
3924       return a[1];
3925 \end_layout
3927 \begin_layout Plain Layout
3929     }
3930 \end_layout
3932 \begin_layout Plain Layout
3934     =<
3935 \backslash
3936 chunkref{parse-chunk-args}>
3937 \end_layout
3939 \begin_layout Plain Layout
3941   }
3942 \end_layout
3944 \begin_layout Plain Layout
3946   return text;
3947 \end_layout
3949 \begin_layout Plain Layout
3952 \end_layout
3954 \end_inset
3957 \end_layout
3959 \begin_layout Standard
3960 \begin_inset Note Note
3961 status collapsed
3963 \begin_layout Plain Layout
3964 Use BNF package here
3965 \end_layout
3967 \end_inset
3969 We can see that the text could be inspected with this regex:
3970 \end_layout
3972 \begin_layout Chunk
3973 parse-chunk-args
3974 \end_layout
3976 \begin_layout Standard
3977 \begin_inset listings
3978 inline false
3979 status open
3981 \begin_layout Plain Layout
3983 if (! match(text, " *([^,=]*[^,= ]) *(([,=]) *(([^,}]*) *,* *(.*))|)$", a))
3985 \end_layout
3987 \begin_layout Plain Layout
3989   return text;
3990 \end_layout
3992 \begin_layout Plain Layout
3995 \end_layout
3997 \end_inset
4000 \end_layout
4002 \begin_layout Standard
4003 and that 
4004 \begin_inset Flex CharStyle:Code
4005 status collapsed
4007 \begin_layout Plain Layout
4009 \end_layout
4011 \end_inset
4013  will have the following values:
4014 \end_layout
4016 \begin_layout Standard
4017 \begin_inset Tabular
4018 <lyxtabular version="3" rows="7" columns="2">
4019 <features>
4020 <column alignment="center" valignment="top" width="0">
4021 <column alignment="left" valignment="top" width="0">
4022 <row>
4023 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
4024 \begin_inset Text
4026 \begin_layout Plain Layout
4027 a[n]
4028 \end_layout
4030 \end_inset
4031 </cell>
4032 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
4033 \begin_inset Text
4035 \begin_layout Plain Layout
4036 assigned text
4037 \end_layout
4039 \end_inset
4040 </cell>
4041 </row>
4042 <row>
4043 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
4044 \begin_inset Text
4046 \begin_layout Plain Layout
4048 \end_layout
4050 \end_inset
4051 </cell>
4052 <cell alignment="left" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
4053 \begin_inset Text
4055 \begin_layout Plain Layout
4056 freddie
4057 \end_layout
4059 \end_inset
4060 </cell>
4061 </row>
4062 <row>
4063 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
4064 \begin_inset Text
4066 \begin_layout Plain Layout
4068 \end_layout
4070 \end_inset
4071 </cell>
4072 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
4073 \begin_inset Text
4075 \begin_layout Plain Layout
4076 =freddie, foo={bar=baz, quux={quirk, a=fleeg}}, etc
4077 \end_layout
4079 \end_inset
4080 </cell>
4081 </row>
4082 <row>
4083 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
4084 \begin_inset Text
4086 \begin_layout Plain Layout
4088 \end_layout
4090 \end_inset
4091 </cell>
4092 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
4093 \begin_inset Text
4095 \begin_layout Plain Layout
4097 \end_layout
4099 \end_inset
4100 </cell>
4101 </row>
4102 <row>
4103 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
4104 \begin_inset Text
4106 \begin_layout Plain Layout
4108 \end_layout
4110 \end_inset
4111 </cell>
4112 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
4113 \begin_inset Text
4115 \begin_layout Plain Layout
4116 freddie, foo={bar=baz, quux={quirk, a=fleeg}}, etc
4117 \end_layout
4119 \end_inset
4120 </cell>
4121 </row>
4122 <row>
4123 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
4124 \begin_inset Text
4126 \begin_layout Plain Layout
4128 \end_layout
4130 \end_inset
4131 </cell>
4132 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
4133 \begin_inset Text
4135 \begin_layout Plain Layout
4136 freddie
4137 \end_layout
4139 \end_inset
4140 </cell>
4141 </row>
4142 <row>
4143 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
4144 \begin_inset Text
4146 \begin_layout Plain Layout
4148 \end_layout
4150 \end_inset
4151 </cell>
4152 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
4153 \begin_inset Text
4155 \begin_layout Plain Layout
4156 , foo={bar=baz, quux={quirk, a=fleeg}}, etc
4157 \end_layout
4159 \end_inset
4160 </cell>
4161 </row>
4162 </lyxtabular>
4164 \end_inset
4167 \end_layout
4169 \begin_layout Standard
4170 a[3] will be either 
4171 \begin_inset Flex CharStyle:Code
4172 status collapsed
4174 \begin_layout Plain Layout
4176 \end_layout
4178 \end_inset
4180  or 
4181 \begin_inset Flex CharStyle:Code
4182 status collapsed
4184 \begin_layout Plain Layout
4186 \end_layout
4188 \end_inset
4190  and signify whether the option named in 
4191 \begin_inset Flex CharStyle:Code
4192 status collapsed
4194 \begin_layout Plain Layout
4195 a[1]
4196 \end_layout
4198 \end_inset
4200  has a value or not (respectively).
4201 \end_layout
4203 \begin_layout Standard
4204 If the option does have a value, then if the expression 
4205 \begin_inset Flex CharStyle:Code
4206 status collapsed
4208 \begin_layout Plain Layout
4209 substr(a[4],1,1)
4210 \end_layout
4212 \end_inset
4214  returns a brace 
4215 \begin_inset Flex CharStyle:Code
4216 status collapsed
4218 \begin_layout Plain Layout
4220 \end_layout
4222 \end_inset
4224  it will signify that we need to recurse:
4225 \end_layout
4227 \begin_layout Standard
4228 \begin_inset listings
4229 inline false
4230 status open
4232 \begin_layout Plain Layout
4234 name=a[1];
4235 \end_layout
4237 \begin_layout Plain Layout
4239 if (a[3] == "=") {
4240 \end_layout
4242 \begin_layout Plain Layout
4244   if (substr(a[4],1,1) == "{") {
4245 \end_layout
4247 \begin_layout Plain Layout
4249     text = get_chunk_args(substr(a[4],2), values, path name SUBSEP);
4250 \end_layout
4252 \begin_layout Plain Layout
4254   } else {
4255 \end_layout
4257 \begin_layout Plain Layout
4259     values[path name]=a[5];
4260 \end_layout
4262 \begin_layout Plain Layout
4264     text = a[6];
4265 \end_layout
4267 \begin_layout Plain Layout
4269   }
4270 \end_layout
4272 \begin_layout Plain Layout
4274 } else {
4275 \end_layout
4277 \begin_layout Plain Layout
4279   values[path name]="";
4280 \end_layout
4282 \begin_layout Plain Layout
4284   text = a[2];
4285 \end_layout
4287 \begin_layout Plain Layout
4290 \end_layout
4292 \end_inset
4295 \end_layout
4297 \begin_layout Standard
4298 We can test this function like this:
4299 \end_layout
4301 \begin_layout Chunk
4302 gca-test.awk
4303 \end_layout
4305 \begin_layout Standard
4306 \begin_inset listings
4307 inline false
4308 status open
4310 \begin_layout Plain Layout
4313 \backslash
4314 chunkref{get_chunk_args()}>
4315 \end_layout
4317 \begin_layout Plain Layout
4319 BEGIN {
4320 \end_layout
4322 \begin_layout Plain Layout
4324   SUBSEP=".";
4325 \end_layout
4327 \begin_layout Plain Layout
4329 \end_layout
4331 \begin_layout Plain Layout
4333   print get_chunk_args("name=freddie, foo={bar=baz, quux={quirk, a=fleeg}},
4334  etc", a);
4335 \end_layout
4337 \begin_layout Plain Layout
4339   for (b in a) {
4340 \end_layout
4342 \begin_layout Plain Layout
4344     print "a[" b "] => " a[b];
4345 \end_layout
4347 \begin_layout Plain Layout
4349   }
4350 \end_layout
4352 \begin_layout Plain Layout
4355 \end_layout
4357 \end_inset
4360 \end_layout
4362 \begin_layout Standard
4363 which should give this output:
4364 \end_layout
4366 \begin_layout Chunk
4367 gca-test.awk-results
4368 \end_layout
4370 \begin_layout Standard
4371 \begin_inset listings
4372 inline false
4373 status open
4375 \begin_layout Plain Layout
4377 a[foo.quux.quirk] => 
4378 \end_layout
4380 \begin_layout Plain Layout
4382 a[foo.quux.a] => fleeg
4383 \end_layout
4385 \begin_layout Plain Layout
4387 a[foo.bar] => baz
4388 \end_layout
4390 \begin_layout Plain Layout
4392 a[etc] => 
4393 \end_layout
4395 \begin_layout Plain Layout
4397 a[name] => freddie
4398 \end_layout
4400 \end_inset
4403 \end_layout
4405 \begin_layout Section
4406 Parsing chunk arguments
4407 \end_layout
4409 \begin_layout Standard
4410 \begin_inset CommandInset label
4411 LatexCommand label
4412 name "cha:Chunk Arguments"
4414 \end_inset
4417 \end_layout
4419 \begin_layout Standard
4420 Arguments to paramterized chunks are expressed in round brackets as a comma
4421  separated list of optional arguments.
4422  For example, a chunk that is defined with:
4423 \end_layout
4425 \begin_layout LyX-Code
4427 \backslash
4428 Chunk{achunk, params=name ; address}
4429 \end_layout
4431 \begin_layout Standard
4432 could be invoked as:
4433 \end_layout
4435 \begin_layout LyX-Code
4437 \backslash
4438 chunkref{achunk}(John Jones, jones@example.com)
4439 \end_layout
4441 \begin_layout Standard
4442 An argument list may be as simple as in 
4443 \begin_inset Flex CharStyle:Code
4444 status collapsed
4446 \begin_layout Plain Layout
4448 \backslash
4449 chunkref{pull}(thing, otherthing)
4450 \end_layout
4452 \end_inset
4454  or as complex as:
4455 \end_layout
4457 \begin_layout LyX-Code
4459 \backslash
4460 chunkref{pull}(things[x, y], get_other_things(a, "(all)")) 
4461 \end_layout
4463 \begin_layout Standard
4464 --- which for all it's commas and quotes and parenthesis represents only
4465  two parameters: 
4466 \begin_inset Flex CharStyle:Code
4467 status collapsed
4469 \begin_layout Plain Layout
4470 things[x, y]
4471 \end_layout
4473 \end_inset
4475  and 
4476 \begin_inset Flex CharStyle:Code
4477 status collapsed
4479 \begin_layout Plain Layout
4480 get_other_things(a, "(all)")
4481 \end_layout
4483 \end_inset
4486 \end_layout
4488 \begin_layout Standard
4489 If we simply split parameter list on commas, then the comma in 
4490 \begin_inset Flex CharStyle:Code
4491 status collapsed
4493 \begin_layout Plain Layout
4494 things[x,y]
4495 \end_layout
4497 \end_inset
4499  would split into two seperate arguments: 
4500 \begin_inset Flex CharStyle:Code
4501 status collapsed
4503 \begin_layout Plain Layout
4504 things[x
4505 \end_layout
4507 \end_inset
4509  and 
4510 \begin_inset Flex CharStyle:Code
4511 status collapsed
4513 \begin_layout Plain Layout
4515 \end_layout
4517 \end_inset
4519 --- neither of which make sense on their own.
4520 \end_layout
4522 \begin_layout Standard
4523 One way to prevent this would be by refusing to split text between matching
4524  delimiters, such as 
4525 \begin_inset Flex CharStyle:Code
4526 status collapsed
4528 \begin_layout Plain Layout
4530 \end_layout
4532 \end_inset
4535 \begin_inset Flex CharStyle:Code
4536 status collapsed
4538 \begin_layout Plain Layout
4540 \end_layout
4542 \end_inset
4545 \begin_inset Flex CharStyle:Code
4546 status collapsed
4548 \begin_layout Plain Layout
4550 \end_layout
4552 \end_inset
4555 \begin_inset Flex CharStyle:Code
4556 status collapsed
4558 \begin_layout Plain Layout
4560 \end_layout
4562 \end_inset
4565 \begin_inset Flex CharStyle:Code
4566 status collapsed
4568 \begin_layout Plain Layout
4570 \end_layout
4572 \end_inset
4575 \begin_inset Flex CharStyle:Code
4576 status collapsed
4578 \begin_layout Plain Layout
4580 \end_layout
4582 \end_inset
4584  and most likely also 
4585 \begin_inset Flex CharStyle:Code
4586 status collapsed
4588 \begin_layout Plain Layout
4590 \end_layout
4592 \end_inset
4595 \begin_inset Flex CharStyle:Code
4596 status collapsed
4598 \begin_layout Plain Layout
4600 \end_layout
4602 \end_inset
4604  and 
4605 \begin_inset Flex CharStyle:Code
4606 status collapsed
4608 \begin_layout Plain Layout
4610 \end_layout
4612 \end_inset
4615 \begin_inset Flex CharStyle:Code
4616 status collapsed
4618 \begin_layout Plain Layout
4620 \end_layout
4622 \end_inset
4625  Of course this also makes it impossible to pass such mis-matched code fragments
4626  as parameters, but I think that it would be hard for readers to cope with
4627  authors who would pass such code unbalanced fragments as chunk parameters
4628 \begin_inset Foot
4629 status collapsed
4631 \begin_layout Plain Layout
4632 I know that I couldn't cope with users doing such things, and although the
4633  GPL3 license prevents me from actually forbidding anyone from trying, if
4634  they want it to work they'll have to write the code themselves and not
4635  expect any support from me.
4636 \end_layout
4638 \end_inset
4641 \end_layout
4643 \begin_layout Standard
4644 Unfortunately, the full set of matching delimiters may vary from language
4645  to language.
4646  In certain C++ template contexts, 
4647 \begin_inset Flex CharStyle:Code
4648 status collapsed
4650 \begin_layout Plain Layout
4652 \end_layout
4654 \end_inset
4656  and 
4657 \begin_inset Flex CharStyle:Code
4658 status collapsed
4660 \begin_layout Plain Layout
4662 \end_layout
4664 \end_inset
4666  would count as delimiters, and yet in other contexts they would not.
4667 \end_layout
4669 \begin_layout Standard
4670 This puts me in the unfortunate position of having to parse-somewhat all
4671  programming languages without knowing what they are!
4672 \end_layout
4674 \begin_layout Standard
4675 However, if this universal mode-tracking is possible, then parsing the arguments
4676  would be trivial.
4677  Such a mode tracker is described in chapter 
4678 \begin_inset CommandInset ref
4679 LatexCommand ref
4680 reference "cha:modes"
4682 \end_inset
4684  and used here with simplicity.
4685 \end_layout
4687 \begin_layout Chunk
4688 parse_chunk_args
4689 \end_layout
4691 \begin_layout Standard
4692 \begin_inset listings
4693 inline false
4694 status open
4696 \begin_layout Plain Layout
4698 function parse_chunk_args(language, text, values, mode,
4699 \end_layout
4701 \begin_layout Plain Layout
4703   # local vars
4704 \end_layout
4706 \begin_layout Plain Layout
4708   c, context, rest)
4709 \end_layout
4711 \begin_layout Plain Layout
4714 \end_layout
4716 \begin_layout Plain Layout
4718   =<
4719 \backslash
4720 chunkref{new-mode-tracker}(context, language, mode)>
4721 \end_layout
4723 \begin_layout Plain Layout
4725   rest = mode_tracker(context, text, values);
4726 \end_layout
4728 \begin_layout Plain Layout
4730   # extract values
4731 \end_layout
4733 \begin_layout Plain Layout
4735   for(c=1; c <= context[0, "values"]; c++) {
4736 \end_layout
4738 \begin_layout Plain Layout
4740     values[c] = context[0, "values", c];
4741 \end_layout
4743 \begin_layout Plain Layout
4745   }
4746 \end_layout
4748 \begin_layout Plain Layout
4750   return rest;
4751 \end_layout
4753 \begin_layout Plain Layout
4756 \end_layout
4758 \end_inset
4761 \end_layout
4763 \begin_layout Section
4764 Expanding parameters in the text
4765 \end_layout
4767 \begin_layout Standard
4768 Within the body of the chunk, the parameters are referred to with: 
4769 \begin_inset Flex CharStyle:Code
4770 status collapsed
4772 \begin_layout Plain Layout
4773 ${name}
4774 \end_layout
4776 \end_inset
4778  and 
4779 \begin_inset Flex CharStyle:Code
4780 status collapsed
4782 \begin_layout Plain Layout
4783 ${address}
4784 \end_layout
4786 \end_inset
4789  There is a strong case that a LaTeX style notation should be used, like
4791 \backslash
4792 param{name} which would be expressed in the listing as =<
4793 \backslash
4794 param{name}> and be rendered as 
4795 \begin_inset listings
4796 inline true
4797 status open
4799 \begin_layout Plain Layout
4802 \backslash
4803 param{name}>
4804 \end_layout
4806 \end_inset
4809  Such notation would make me go blind, but I do intend to adopt it
4810 \begin_inset Foot
4811 status collapsed
4813 \begin_layout Plain Layout
4814 Probably when LyX's listings inset can recognize and render it, so that
4815  I no longer have to type =<\SpecialChar \ldots{}
4817 \end_layout
4819 \end_inset
4822 \end_layout
4824 \begin_layout Standard
4825 We therefore need a function 
4826 \begin_inset Flex CharStyle:Code
4827 status collapsed
4829 \begin_layout Plain Layout
4830 expand_chunk_args
4831 \end_layout
4833 \end_inset
4835  which will take a block of text, a list of permitted parameters, and the
4836  arguments which must substitute for the parameters.
4838 \end_layout
4840 \begin_layout Standard
4841 \begin_inset CommandInset label
4842 LatexCommand label
4843 name "Here-we-split"
4845 \end_inset
4847 Here we split the text on 
4848 \begin_inset Flex CharStyle:Code
4849 status collapsed
4851 \begin_layout Plain Layout
4853 \end_layout
4855 \end_inset
4857  which means that all parts except the first will begin with a parameter
4858  name which will be terminated by 
4859 \begin_inset Flex CharStyle:Code
4860 status collapsed
4862 \begin_layout Plain Layout
4864 \end_layout
4866 \end_inset
4869  The split function will consume the literal 
4870 \begin_inset Flex CharStyle:Code
4871 status collapsed
4873 \begin_layout Plain Layout
4875 \end_layout
4877 \end_inset
4879  in each case.
4880 \end_layout
4882 \begin_layout Chunk
4883 expand_chunk_args()
4884 \end_layout
4886 \begin_layout Standard
4887 \begin_inset listings
4888 inline false
4889 status open
4891 \begin_layout Plain Layout
4893 function expand_chunk_args(text, params, args,  
4894 \end_layout
4896 \begin_layout Plain Layout
4898   p, text_array, next_text, v, t, l)
4899 \end_layout
4901 \begin_layout Plain Layout
4904 \end_layout
4906 \begin_layout Plain Layout
4908   if (split(text, text_array, "
4909 \backslash
4911 \backslash
4912 ${")) {
4913 \end_layout
4915 \begin_layout Plain Layout
4917     =<
4918 \backslash
4919 chunkref{substitute-chunk-args}>
4920 \end_layout
4922 \begin_layout Plain Layout
4924   }
4925 \end_layout
4927 \begin_layout Plain Layout
4929 \end_layout
4931 \begin_layout Plain Layout
4933   return text;
4934 \end_layout
4936 \begin_layout Plain Layout
4939 \end_layout
4941 \end_inset
4944 \end_layout
4946 \begin_layout Standard
4947 First, we produce an associative array of substitution values indexed by
4948  parameter names.
4949  This will serve as a cache, allowing us to look up the replacement values
4950  as we extract each name.
4951 \end_layout
4953 \begin_layout Chunk
4954 substitute-chunk-args
4955 \end_layout
4957 \begin_layout Standard
4958 \begin_inset listings
4959 inline false
4960 status open
4962 \begin_layout Plain Layout
4964 for(p in params) {
4965 \end_layout
4967 \begin_layout Plain Layout
4969   v[params[p]]=args[p];
4970 \end_layout
4972 \begin_layout Plain Layout
4975 \end_layout
4977 \end_inset
4980 \end_layout
4982 \begin_layout Standard
4983 We accumulate substituted text in the variable 
4984 \begin_inset Flex CharStyle:Code
4985 status collapsed
4987 \begin_layout Plain Layout
4988 text
4989 \end_layout
4991 \end_inset
4994  As the first part of the split function is the part before the delimiter
4995  --- which is 
4996 \begin_inset Flex CharStyle:Code
4997 status collapsed
4999 \begin_layout Plain Layout
5001 \end_layout
5003 \end_inset
5005  in our case --- this part will never contain a parameter reference, so
5006  we assign this directly to the result kept in 
5007 \begin_inset Flex CharStyle:Code
5008 status collapsed
5010 \begin_layout Plain Layout
5011 $text
5012 \end_layout
5014 \end_inset
5017 \begin_inset listings
5018 inline false
5019 status open
5021 \begin_layout Plain Layout
5023 text=text_array[1];
5024 \end_layout
5026 \end_inset
5029 \end_layout
5031 \begin_layout Standard
5032 We then iterate over the remaining values in the array
5033 \begin_inset Foot
5034 status collapsed
5036 \begin_layout Plain Layout
5037 I don't know why I think that it will enumerate the array in order, but
5038  it seems to work
5039 \end_layout
5041 \end_inset
5044 \begin_inset Note Note
5045 status collapsed
5047 \begin_layout Plain Layout
5048 So fix it or porve it
5049 \end_layout
5051 \end_inset
5053 , and substitute each reference for it's argument.
5054 \end_layout
5056 \begin_layout Standard
5057 \begin_inset listings
5058 inline false
5059 status open
5061 \begin_layout Plain Layout
5063 for(t=2; t in text_array; t++) {
5064 \end_layout
5066 \begin_layout Plain Layout
5068   =<
5069 \backslash
5070 chunkref{substitute-chunk-arg}>
5071 \end_layout
5073 \begin_layout Plain Layout
5076 \end_layout
5078 \end_inset
5081 \end_layout
5083 \begin_layout Standard
5084 After the split on 
5085 \begin_inset Flex CharStyle:Code
5086 status collapsed
5088 \begin_layout Plain Layout
5090 \end_layout
5092 \end_inset
5094  a valid parameter reference will consist of valid parameter name terminated
5095  by a close-brace 
5096 \begin_inset Flex CharStyle:Code
5097 status collapsed
5099 \begin_layout Plain Layout
5101 \end_layout
5103 \end_inset
5106  A valid character name begins with the underscore or a letter, and may
5107  contain letters, digits or underscores.
5108 \end_layout
5110 \begin_layout Standard
5111 A valid looking reference that is not actually the name of a parameter will
5112  be and not substituted.
5113  This is good because there is nothing to substitute anyway, and it avoids
5114  clashes when writing code for languages where ${\SpecialChar \ldots{}
5115 } is a valid construct
5116  --- such constructs will not be interfered with unless the parameter name
5117  also matches.
5118 \end_layout
5120 \begin_layout Chunk
5121 substitute-chunk-arg
5122 \end_layout
5124 \begin_layout Standard
5125 \begin_inset listings
5126 inline false
5127 status open
5129 \begin_layout Plain Layout
5131 if (match(text_array[t], "^([a-zA-Z_][a-zA-Z0-9_]*)}", l) &&
5132 \end_layout
5134 \begin_layout Plain Layout
5136     l[1] in v) 
5137 \end_layout
5139 \begin_layout Plain Layout
5142 \end_layout
5144 \begin_layout Plain Layout
5146   text = text v[l[1]] substr(text_array[t], length(l[1])+2);
5147 \end_layout
5149 \begin_layout Plain Layout
5151 } else {
5152 \end_layout
5154 \begin_layout Plain Layout
5156   text = text "${" text_array[t];
5157 \end_layout
5159 \begin_layout Plain Layout
5162 \end_layout
5164 \end_inset
5167 \end_layout
5169 \begin_layout Chapter
5170 Language Modes & Quoting
5171 \end_layout
5173 \begin_layout Standard
5174 \begin_inset CommandInset label
5175 LatexCommand label
5176 name "cha:modes"
5178 \end_inset
5181 \end_layout
5183 \begin_layout Section
5184 Modes
5185 \end_layout
5187 \begin_layout Standard
5188 lstlistings and newfangle both recognize source languages, and perform some
5189  basic parsing.
5190  lstlistings can detect strings and comments within a language definition
5191  and perform suitable rendering, such as italics for comments, and visible-space
5192 s within strings.
5193 \end_layout
5195 \begin_layout Standard
5196 Newfangle similarly can recognize strings, and comments, etc, within a language,
5197  so that any chunks included with 
5198 \begin_inset Flex CharStyle:Code
5199 status collapsed
5201 \begin_layout Plain Layout
5203 \backslash
5204 chunkref
5205 \end_layout
5207 \end_inset
5209  can be suitably escape or quoted.
5210 \end_layout
5212 \begin_layout Subsection
5213 Modes to keep code together
5214 \end_layout
5216 \begin_layout Standard
5217 As an example, in the C language there are a few parse modes, affecting
5218  the interpretation of characters.
5219 \end_layout
5221 \begin_layout Standard
5222 One parse mode is the strings mode.
5223  The string mode is commenced by an un-escaped quotation mark 
5224 \begin_inset Flex CharStyle:Code
5225 status collapsed
5227 \begin_layout Plain Layout
5229 \end_layout
5231 \end_inset
5233  and terminated by the same.
5234  Within the string mode, only one additional mode can be commenced, it is
5235  the backslash mode 
5236 \begin_inset Flex CharStyle:Code
5237 status collapsed
5239 \begin_layout Plain Layout
5241 \backslash
5243 \end_layout
5245 \end_inset
5247 , which is always terminated by the folloing character.
5248 \end_layout
5250 \begin_layout Standard
5251 Other modes are 
5252 \begin_inset Flex CharStyle:Code
5253 status collapsed
5255 \begin_layout Plain Layout
5257 \end_layout
5259 \end_inset
5261  which is terminated by a 
5262 \begin_inset Flex CharStyle:Code
5263 status collapsed
5265 \begin_layout Plain Layout
5267 \end_layout
5269 \end_inset
5271  (unless it occurs in a string).
5272 \end_layout
5274 \begin_layout Standard
5275 Consider this line of C code:
5276 \end_layout
5278 \begin_layout Standard
5279 \begin_inset Formula $\mathtt{things\underbrace{[\mathtt{x,\ y}]}_{1.\ [\ mode},\ get\_other\_things\underbrace{(\mathtt{a,\overbrace{"\mathtt{(all)}"}})}_{2.\ (\ mode}^{3.\ "\ mode}}$
5280 \end_inset
5283 \end_layout
5285 \begin_layout Standard
5286 Mode nesting prevents the close parenthesis in quote mode (part 3) from
5287  terminating the parenthesis mode (part 2).
5288 \end_layout
5290 \begin_layout Standard
5291 Each language has a set of modes, the default mode being the null mode.
5292  Each mode can lead to other modes.
5293 \end_layout
5295 \begin_layout Subsection
5296 Modes to included chunks
5297 \end_layout
5299 \begin_layout Standard
5300 For instance, consider this chunk with 
5301 \begin_inset Flex CharStyle:Code
5302 status collapsed
5304 \begin_layout Plain Layout
5305 language=perl
5306 \end_layout
5308 \end_inset
5311 \end_layout
5313 \begin_layout Chunk
5314 example-perl,language=perl
5315 \end_layout
5317 \begin_layout Standard
5318 \begin_inset listings
5319 inline false
5320 status open
5322 \begin_layout Plain Layout
5324 print "hello world $0
5325 \backslash
5327 \end_layout
5329 \end_inset
5332 \end_layout
5334 \begin_layout Standard
5335 If it were included in a chunk with 
5336 \begin_inset Flex CharStyle:Code
5337 status collapsed
5339 \begin_layout Plain Layout
5340 language=sh
5341 \end_layout
5343 \end_inset
5345 , like this:
5346 \end_layout
5348 \begin_layout Chunk
5349 example-sh,language=sh
5350 \end_layout
5352 \begin_layout Standard
5353 \begin_inset listings
5354 inline false
5355 status open
5357 \begin_layout Plain Layout
5359 perl -e "=<
5360 \backslash
5361 chunkref{example-perl}>"
5362 \end_layout
5364 \end_inset
5367 \end_layout
5369 \begin_layout Standard
5370 newfangle would need to generate output like this if it were to work: 
5371 \end_layout
5373 \begin_layout LyX-Code
5374 perl -e "print 
5375 \backslash
5376 "hello world $0
5377 \backslash
5379 \backslash
5381 \backslash
5382 ";" 
5383 \end_layout
5385 \begin_layout Standard
5386 See that the double quote 
5387 \begin_inset Flex CharStyle:Code
5388 status collapsed
5390 \begin_layout Plain Layout
5392 \end_layout
5394 \end_inset
5396 , and 
5397 \begin_inset Flex CharStyle:Code
5398 status collapsed
5400 \begin_layout Plain Layout
5402 \end_layout
5404 \end_inset
5406  in the regex have been quoted with a back-slash to protect them from shell
5407  interpretation.
5408 \end_layout
5410 \begin_layout Standard
5411 If that were then included in a chunk with 
5412 \begin_inset Flex CharStyle:Code
5413 status collapsed
5415 \begin_layout Plain Layout
5416 language=make
5417 \end_layout
5419 \end_inset
5421 , like this:
5422 \end_layout
5424 \begin_layout Chunk
5425 example-makefile,language=make
5426 \end_layout
5428 \begin_layout Standard
5429 \begin_inset listings
5430 inline false
5431 status open
5433 \begin_layout Plain Layout
5435 target: pre-req
5436 \end_layout
5438 \begin_layout Plain Layout
5440                 =<
5441 \backslash
5442 chunkref{example-sh}>
5443 \end_layout
5445 \end_inset
5448 \end_layout
5450 \begin_layout Standard
5451 We would need the output to look like this --- note the $$:
5452 \end_layout
5454 \begin_layout LyX-Code
5455 target: pre-req
5456 \end_layout
5458 \begin_layout LyX-Code
5459         perl -pe "s/
5460 \backslash
5462 \backslash
5463 $$/'/;"
5464 \end_layout
5466 \begin_layout Standard
5467 In order to make this work, we need to define a mode-tracker supporting
5468  each language, that can detect the various quoting modes, and provide a
5469  transformation that must be applied to any included text so that included
5470  text will be interpreted correctly after any interpolation that it may
5471  be subject to at run-time.
5472 \end_layout
5474 \begin_layout Standard
5475 For example, the sed transformation for text to be inserted into sh double-quote
5476 d strings would be something like:
5477 \end_layout
5479 \begin_layout LyX-Code
5481 \backslash
5483 \backslash
5485 \backslash
5487 \backslash
5489 \backslash
5491 \backslash
5492 /g;s/$/
5493 \backslash
5495 \backslash
5496 $/g;s/"/
5497 \backslash
5499 \backslash
5500 "/g;
5501 \end_layout
5503 \begin_layout Standard
5504 which protects 
5505 \begin_inset Flex CharStyle:Code
5506 status collapsed
5508 \begin_layout Plain Layout
5510 \backslash
5511  $ "
5512 \end_layout
5514 \end_inset
5517 \end_layout
5519 \begin_layout Standard
5520 \begin_inset Note Note
5521 status collapsed
5523 \begin_layout Plain Layout
5524 I don't think this example is true
5525 \end_layout
5527 \end_inset
5529 The mode tracker must also track nested mode-changes, as in this 
5530 \begin_inset Flex CharStyle:Code
5531 status collapsed
5533 \begin_layout Plain Layout
5535 \end_layout
5537 \end_inset
5539  example.
5540 \end_layout
5542 \begin_layout LyX-Code
5543 echo "hello `id \SpecialChar \ldots{}
5545 \end_layout
5547 \begin_layout LyX-Code
5548 \begin_inset ERT
5549 status open
5551 \begin_layout Plain Layout
5554 \backslash
5555 noindent
5556 \backslash
5557 hphantom{echo "hello `id}
5558 \end_layout
5560 \end_inset
5563 \end_layout
5565 \begin_layout Standard
5566 Any characters inserted at the point marked ↑ would need to be escaped,
5567  including 
5568 \begin_inset Flex CharStyle:Code
5569 status collapsed
5571 \begin_layout Plain Layout
5572 ` | *
5573 \end_layout
5575 \end_inset
5577  among others.
5578  First it would need escaping for the back-ticks `, and then for the double-quot
5579 es ".
5580 \end_layout
5582 \begin_layout Standard
5583 Escaping need not occur if the format and mode of the included chunk matches
5584  that of the including chunk.
5585 \end_layout
5587 \begin_layout Standard
5588 As each chunk is output a new mode tracker for that language is initialized
5589  in it's normal state.
5590  As text is output for that chunk the output mode is tracked.
5591  When a new chunk is included, a transformation appropriate to that mode
5592  is selected and pushed onto a stack of transformations.
5593  Any text to be output is first passed through this stack of transformations.
5594 \end_layout
5596 \begin_layout Standard
5597 It remains to consider if the chunk-include function should return it's
5598  generated text so that the caller can apply any transformations (and formatting
5599 ), or if it should apply the stack of transformations itself.
5600 \end_layout
5602 \begin_layout Standard
5603 Note that the transformed text should have the property of not being able
5604  to change the mode in the current chunk.
5605 \end_layout
5607 \begin_layout Standard
5608 \begin_inset Note Note
5609 status open
5611 \begin_layout Plain Layout
5612 Note chunk parameters should probably also be transformed
5613 \end_layout
5615 \end_inset
5618 \end_layout
5620 \begin_layout Section
5621 Language Mode Definitions
5622 \end_layout
5624 \begin_layout Standard
5625 All modes are stored in a single multi-dimensional hash.
5626  The first index is the language, and the second index is the mode-identifier.
5627  The third indexes are terminators, and optionally, submodes, and delimiters.
5628 \end_layout
5630 \begin_layout Standard
5631 A useful set of mode definitions for a nameless general C-type language
5632  is shown here.
5633  (Don't be confused by the double backslash escaping needed in awk.
5634  One set of escaping is for the string, and the second set of escaping is
5635  for the regex).
5637 \begin_inset Note Note
5638 status open
5640 \begin_layout Plain Layout
5641 TODO: Add =<
5642 \backslash
5643 mode{}> command which will allow us to signify that a string is regex and
5644  thus newfangle will quote it for us.
5645 \end_layout
5647 \end_inset
5650 \end_layout
5652 \begin_layout Standard
5653 Submodes are entered by the characters 
5654 \begin_inset Flex CharStyle:Code
5655 status collapsed
5657 \begin_layout Plain Layout
5659 \backslash
5661 \end_layout
5663 \end_inset
5666 \begin_inset Flex CharStyle:Code
5667 status collapsed
5669 \begin_layout Plain Layout
5671 \end_layout
5673 \end_inset
5676 \begin_inset Flex CharStyle:Code
5677 status collapsed
5679 \begin_layout Plain Layout
5681 \end_layout
5683 \end_inset
5686 \begin_inset Flex CharStyle:Code
5687 status collapsed
5689 \begin_layout Plain Layout
5691 \end_layout
5693 \end_inset
5696 \begin_inset Flex CharStyle:Code
5697 status collapsed
5699 \begin_layout Plain Layout
5701 \end_layout
5703 \end_inset
5706 \begin_inset Flex CharStyle:Code
5707 status collapsed
5709 \begin_layout Plain Layout
5711 \end_layout
5713 \end_inset
5716 \begin_inset Flex CharStyle:Code
5717 status collapsed
5719 \begin_layout Plain Layout
5721 \end_layout
5723 \end_inset
5726 \end_layout
5728 \begin_layout Chunk
5729 common-mode-definitions,params=language
5730 \end_layout
5732 \begin_layout Standard
5733 \begin_inset listings
5734 inline false
5735 status open
5737 \begin_layout Plain Layout
5739 modes[${language}, "",  "submodes" ]="
5740 \backslash
5742 \backslash
5744 \backslash
5746 \backslash
5748 \backslash
5749 "|'|{|
5750 \backslash
5752 \backslash
5754 \backslash
5756 \backslash
5758 \end_layout
5760 \end_inset
5763 \end_layout
5765 \begin_layout Standard
5766 In the default mode, a comma surrounded by un-important white space is a
5767  delimiter of language items.
5768 \end_layout
5770 \begin_layout Standard
5771 \begin_inset listings
5772 inline false
5773 status open
5775 \begin_layout Plain Layout
5777 modes[${language}, "",  "delimiters"]=" *, *";
5778 \end_layout
5780 \end_inset
5783 \end_layout
5785 \begin_layout Standard
5786 and should pass this test:
5787 \end_layout
5789 \begin_layout Standard
5790 \begin_inset Note Note
5791 status open
5793 \begin_layout Plain Layout
5794 Why do the tests run in 
5795 \begin_inset Quotes eld
5796 \end_inset
5799 \begin_inset Quotes erd
5800 \end_inset
5802  mode and not 
5803 \begin_inset Quotes eld
5804 \end_inset
5807 \begin_inset Quotes erd
5808 \end_inset
5810  mode
5811 \end_layout
5813 \end_inset
5816 \end_layout
5818 \begin_layout Chunk
5819 test:mode-definitions
5820 \end_layout
5822 \begin_layout Standard
5823 \begin_inset listings
5824 inline false
5825 status open
5827 \begin_layout Plain Layout
5829 parse_chunk_args("c-like", "1,2,3", a, "");
5830 \end_layout
5832 \begin_layout Plain Layout
5834 if (a[1] != "1") e++;
5835 \end_layout
5837 \begin_layout Plain Layout
5839 if (a[2] != "2") e++;
5840 \end_layout
5842 \begin_layout Plain Layout
5844 if (a[3] != "3") e++;
5845 \end_layout
5847 \begin_layout Plain Layout
5849 if (length(a) != 3) e++;
5850 \end_layout
5852 \begin_layout Plain Layout
5855 \backslash
5856 chunkref{pca-test.awk:summary}>
5857 \end_layout
5859 \begin_layout Plain Layout
5861 \end_layout
5863 \begin_layout Plain Layout
5865 parse_chunk_args("c-like", "joe, red", a, "");
5866 \end_layout
5868 \begin_layout Plain Layout
5870 if (a[1] != "joe") e++;
5871 \end_layout
5873 \begin_layout Plain Layout
5875 if (a[2] != "red") e++;
5876 \end_layout
5878 \begin_layout Plain Layout
5880 if (length(a) != 2) e++;
5881 \end_layout
5883 \begin_layout Plain Layout
5886 \backslash
5887 chunkref{pca-test.awk:summary}>
5888 \end_layout
5890 \begin_layout Plain Layout
5892 \end_layout
5894 \begin_layout Plain Layout
5896 parse_chunk_args("c-like", "${colour}", a, "");
5897 \end_layout
5899 \begin_layout Plain Layout
5901 if (a[1] != "${colour}") e++;
5902 \end_layout
5904 \begin_layout Plain Layout
5906 if (length(a) != 1) e++;
5907 \end_layout
5909 \begin_layout Plain Layout
5912 \backslash
5913 chunkref{pca-test.awk:summary}>
5914 \end_layout
5916 \end_inset
5919 \end_layout
5921 \begin_layout Standard
5922 Nested modes are identified by a backslash, a double or single quote, various
5923  bracket styles or a /* comment.
5924 \end_layout
5926 \begin_layout Standard
5927 For each of these sub-modes modes we must also identify at a mode terminator,
5928  and any sub-modes or delimiters that may be entered
5929 \begin_inset Foot
5930 status collapsed
5932 \begin_layout Plain Layout
5933 Because we are using the sub-mode characters as the mode identifier it means
5934  we can't currently have a mode character dependant on it's context; i.e.
5936 \begin_inset Flex CharStyle:Code
5937 status collapsed
5939 \begin_layout Plain Layout
5941 \end_layout
5943 \end_inset
5945  can't behave differently when it is inside 
5946 \begin_inset Flex CharStyle:Code
5947 status collapsed
5949 \begin_layout Plain Layout
5951 \end_layout
5953 \end_inset
5956 \end_layout
5958 \end_inset
5961 \end_layout
5963 \begin_layout Subsection
5964 Backslash
5965 \end_layout
5967 \begin_layout Standard
5968 The backslash mode has no submodes or delimiters, and is terminated by any
5969  character.
5970  Note that we are not so much interested in evaluating or interpolating
5971  content as we are in delineating content.
5972  It is no matter that a double backslash (
5973 \begin_inset Flex CharStyle:Code
5974 status collapsed
5976 \begin_layout Plain Layout
5978 \backslash
5980 \backslash
5982 \end_layout
5984 \end_inset
5986 ) may represent a single backslash while a backslash-newline may represent
5987  white space, but it does matter that the newline in a backslash newline
5988  should not be able to terminate a C pre-processor statement; and so the
5989  newline will be consumed by the backslash however it is to be interpreted.
5990 \end_layout
5992 \begin_layout Chunk
5993 common-mode-definitions
5994 \end_layout
5996 \begin_layout Standard
5997 \begin_inset listings
5998 inline false
5999 status open
6001 \begin_layout Plain Layout
6003 modes[${language}, "
6004 \backslash
6006 \backslash
6007 ", "terminators"]=".";
6008 \end_layout
6010 \end_inset
6013 \end_layout
6015 \begin_layout Subsection
6016 Strings
6017 \end_layout
6019 \begin_layout Standard
6020 Common languages support two kinds of strings quoting, double quotes and
6021  single quotes.
6022 \end_layout
6024 \begin_layout Chunk
6025 mode:common-string,params=language;quote
6026 \end_layout
6028 \begin_layout Standard
6029 In a string we have one special mode, which is the backslash.
6030  This may escape an embedded quote and prevent us thinking that it should
6031  terminate the string.
6033 \end_layout
6035 \begin_layout Standard
6036 \begin_inset listings
6037 inline false
6038 status open
6040 \begin_layout Plain Layout
6042 modes[${language}, ${quote}, "submodes" ]="
6043 \backslash
6045 \backslash
6047 \backslash
6049 \backslash
6051 \end_layout
6053 \end_inset
6056 \end_layout
6058 \begin_layout Standard
6059 Otherwise, the string will be terminated by the same character that commenced
6060  it.
6061 \end_layout
6063 \begin_layout Standard
6064 \begin_inset listings
6065 inline false
6066 status open
6068 \begin_layout Plain Layout
6070 modes[${language}, ${quote}, "terminators"]=${quote};
6071 \end_layout
6073 \end_inset
6076 \end_layout
6078 \begin_layout Standard
6079 In C type languages, certain escape sequences exist in strings.
6080  We need to define mechanism to enclode any chunks included in this mode
6081  using those escape sequences.
6082  These are expressed in two parts, s meaning search, and r meaning replace.
6083 \end_layout
6085 \begin_layout Standard
6086 The first substitution is to replace a backslash with a double backslash.
6087  We do this first as other substitutions may introduce a backslash which
6088  we would not then want to escape again here.
6089 \end_layout
6091 \begin_layout Standard
6092 Note: Backslashes need double-escaping in the search pattern but not in
6093  the replacement string, hence we are replacing a literal 
6094 \backslash
6095  with a literal 
6096 \backslash
6098 \backslash
6100 \end_layout
6102 \begin_layout Standard
6103 \begin_inset listings
6104 inline false
6105 status open
6107 \begin_layout Plain Layout
6109 escapes[${language}, ${quote}, ++escapes[${language}, ${quote}], "s"]="
6110 \backslash
6112 \backslash
6114 \backslash
6116 \backslash
6118 \end_layout
6120 \begin_layout Plain Layout
6122 escapes[${language}, ${quote},   escapes[${language}, ${quote}], "r"]="
6123 \backslash
6125 \backslash
6127 \backslash
6129 \backslash
6131 \end_layout
6133 \end_inset
6136 \end_layout
6138 \begin_layout Standard
6139 If the quote character occurs in the text, it should be preceded by a backslash,
6140  otherwise it would terminate the string unexpectedly.
6141 \end_layout
6143 \begin_layout Standard
6144 \begin_inset listings
6145 inline false
6146 status open
6148 \begin_layout Plain Layout
6150 escapes[${language}, ${quote}, ++escapes[${language}, ${quote}], "s"]=${quote};
6151 \end_layout
6153 \begin_layout Plain Layout
6155 escapes[${language}, ${quote},   escapes[${language}, ${quote}], "r"]="
6156 \backslash
6158 \backslash
6159 " ${quote};
6160 \end_layout
6162 \end_inset
6165 \end_layout
6167 \begin_layout Standard
6168 Any newlines in the string, must be replaced by 
6169 \begin_inset Flex CharStyle:Code
6170 status collapsed
6172 \begin_layout Plain Layout
6174 \backslash
6176 \end_layout
6178 \end_inset
6181 \end_layout
6183 \begin_layout Standard
6184 \begin_inset listings
6185 inline false
6186 status open
6188 \begin_layout Plain Layout
6190 escapes[${language}, ${quote}, ++escapes[${language}, ${quote}], "s"]="
6191 \backslash
6193 \end_layout
6195 \begin_layout Plain Layout
6197 escapes[${language}, ${quote},   escapes[${language}, ${quote}], "r"]="
6198 \backslash
6200 \backslash
6202 \end_layout
6204 \end_inset
6207 \end_layout
6209 \begin_layout Standard
6210 For the common modes, we define this string handling for double and single
6211  quotes.
6212 \end_layout
6214 \begin_layout Chunk
6215 common-mode-definitions,params=language
6216 \end_layout
6218 \begin_layout Standard
6219 \begin_inset listings
6220 inline false
6221 status open
6223 \begin_layout Plain Layout
6226 \backslash
6227 chunkref{mode:common-string}(${language}, "
6228 \backslash
6229 textbackslash{}"")>
6230 \end_layout
6232 \begin_layout Plain Layout
6235 \backslash
6236 chunkref{mode:common-string}(${language}, "'")>
6237 \end_layout
6239 \end_inset
6242 \end_layout
6244 \begin_layout Standard
6245 Working strings should pass this test:
6246 \end_layout
6248 \begin_layout Chunk
6249 test:mode-definitions
6250 \end_layout
6252 \begin_layout Standard
6253 \begin_inset listings
6254 inline false
6255 status open
6257 \begin_layout Plain Layout
6259 parse_chunk_args("c-like", "say 
6260 \backslash
6261 "I said, 
6262 \backslash
6264 \backslash
6266 \backslash
6267 "Hello, how are you
6268 \backslash
6270 \backslash
6272 \backslash
6274 \backslash
6275 ", for me", a, "");
6276 \end_layout
6278 \begin_layout Plain Layout
6280 if (a[1] != "say 
6281 \backslash
6282 "I said, 
6283 \backslash
6285 \backslash
6287 \backslash
6288 "Hello, how are you
6289 \backslash
6291 \backslash
6293 \backslash
6295 \backslash
6296 "") e++;
6297 \end_layout
6299 \begin_layout Plain Layout
6301 if (a[2] != "for me") e++;
6302 \end_layout
6304 \begin_layout Plain Layout
6306 if (length(a) != 2) e++;
6307 \end_layout
6309 \begin_layout Plain Layout
6312 \backslash
6313 chunkref{pca-test.awk:summary}>
6314 \end_layout
6316 \end_inset
6319 \end_layout
6321 \begin_layout Subsection
6322 Parentheses, Braces and Brackets
6323 \end_layout
6325 \begin_layout Standard
6326 Where quotes are closed by the same character, parentheses, brackets and
6327  braces are closed by an alternate character.
6328 \end_layout
6330 \begin_layout Chunk
6331 mode:common-brackets,params=language;open;close
6332 \end_layout
6334 \begin_layout Standard
6335 \begin_inset listings
6336 inline false
6337 status open
6339 \begin_layout Plain Layout
6341 modes[${language}, ${open},  "submodes" ]="
6342 \backslash
6344 \backslash
6346 \backslash
6348 \backslash
6350 \backslash
6351 "|{|
6352 \backslash
6354 \backslash
6356 \backslash
6358 \backslash
6359 [|'|/
6360 \backslash
6362 \backslash
6364 \end_layout
6366 \begin_layout Plain Layout
6368 modes[${language}, ${open},  "delimiters"]=" *, *";
6369 \end_layout
6371 \begin_layout Plain Layout
6373 modes[${language}, ${open},  "terminators"]=${close};
6374 \end_layout
6376 \end_inset
6379 \end_layout
6381 \begin_layout Standard
6382 Note that the open is NOT a regex but the close token IS.
6384 \begin_inset Note Note
6385 status open
6387 \begin_layout Plain Layout
6388 When we can quote regex we won't have to put the slashes in here
6389 \end_layout
6391 \end_inset
6394 \end_layout
6396 \begin_layout Chunk
6397 common-mode-definitions,params=language
6398 \end_layout
6400 \begin_layout Standard
6401 \begin_inset listings
6402 inline false
6403 status open
6405 \begin_layout Plain Layout
6408 \backslash
6409 chunkref{mode:common-brackets}(${language}, "{", "}")>
6410 \end_layout
6412 \begin_layout Plain Layout
6415 \backslash
6416 chunkref{mode:common-brackets}(${language}, "[", "
6417 \backslash
6418 textbackslash{}
6419 \backslash
6420 textbackslash{}]")>
6421 \end_layout
6423 \begin_layout Plain Layout
6426 \backslash
6427 chunkref{mode:common-brackets}(${language}, "(", "
6428 \backslash
6429 textbackslash{}
6430 \backslash
6431 textbackslash{})")>
6432 \end_layout
6434 \end_inset
6437 \end_layout
6439 \begin_layout Subsection
6440 Customizing Standard Modes
6441 \end_layout
6443 \begin_layout Chunk
6444 mode:add-submode,params=language;mode;submode
6445 \end_layout
6447 \begin_layout Standard
6448 \begin_inset listings
6449 inline false
6450 status open
6452 \begin_layout Plain Layout
6454 modes[${language}, ${mode}, "submodes"] = modes[${language}, ${mode}, "submodes"
6455 ] "|" ${submode};
6456 \end_layout
6458 \end_inset
6461 \end_layout
6463 \begin_layout Chunk
6464 mode:add-escapes,params=language;mode;search;replace
6465 \end_layout
6467 \begin_layout Standard
6468 \begin_inset listings
6469 inline false
6470 status open
6472 \begin_layout Plain Layout
6474 escapes[${language}, ${mode}, ++escapes[${language}, ${mode}], "s"]=${search};
6475 \end_layout
6477 \begin_layout Plain Layout
6479 escapes[${language}, ${mode},   escapes[${language}, ${mode}], "r"]=${replace};
6480 \end_layout
6482 \end_inset
6485 \end_layout
6487 \begin_layout Subsection
6488 Comments
6489 \end_layout
6491 \begin_layout Standard
6492 We can define 
6493 \begin_inset Flex CharStyle:Code
6494 status collapsed
6496 \begin_layout Plain Layout
6497 /* comment */
6498 \end_layout
6500 \end_inset
6502  style comments and 
6503 \begin_inset Flex CharStyle:Code
6504 status collapsed
6506 \begin_layout Plain Layout
6507 //comment
6508 \end_layout
6510 \end_inset
6512  style comments to be added to any language:
6513 \end_layout
6515 \begin_layout Chunk
6516 mode:multi-line-comments,params=language
6517 \end_layout
6519 \begin_layout Standard
6520 \begin_inset listings
6521 inline false
6522 status open
6524 \begin_layout Plain Layout
6527 \backslash
6528 chunkref{mode:add-submode}(${language}, "", "/
6529 \backslash
6530 textbackslash{}
6531 \backslash
6532 textbackslash{}*")>
6533 \end_layout
6535 \begin_layout Plain Layout
6537 modes[${language}, "/*", "terminators"]="
6538 \backslash
6540 \backslash
6541 */";
6542 \end_layout
6544 \end_inset
6547 \end_layout
6549 \begin_layout Chunk
6550 mode:single-line-slash-comments,params=language
6551 \end_layout
6553 \begin_layout Standard
6554 \begin_inset listings
6555 inline false
6556 status open
6558 \begin_layout Plain Layout
6561 \backslash
6562 chunkref{mode:add-submode}(${language}, "", "//")>
6563 \end_layout
6565 \begin_layout Plain Layout
6567 modes[${language}, "//", "terminators"]="
6568 \backslash
6570 \end_layout
6572 \begin_layout Plain Layout
6575 \backslash
6576 chunkref{mode:add-escapes}(${language}, "//", "
6577 \backslash
6578 textbackslash{}n", "
6579 \backslash
6580 textbackslash{}n//")>
6581 \end_layout
6583 \end_inset
6586 \end_layout
6588 \begin_layout Standard
6589 We can also define 
6590 \begin_inset Flex CharStyle:Code
6591 status collapsed
6593 \begin_layout Plain Layout
6594 # comment
6595 \end_layout
6597 \end_inset
6599  style comments (as used in awk and shell scripts) in a similar manner.
6600 \end_layout
6602 \begin_layout Chunk
6603 mode:add-hash-comments,params=language
6604 \begin_inset Note Note
6605 status open
6607 \begin_layout Plain Layout
6608 I'm having to use 
6609 \backslash
6610 # for hash and 
6611 \backslash
6612 textbackslash{} for 
6613 \backslash
6614  and have hacky work-arounds in the parser for now
6615 \end_layout
6617 \end_inset
6620 \end_layout
6622 \begin_layout Standard
6623 \begin_inset listings
6624 inline false
6625 status open
6627 \begin_layout Plain Layout
6630 \backslash
6631 chunkref{mode:add-submode}(${language}, "", "
6632 \backslash
6633 #")>
6634 \end_layout
6636 \begin_layout Plain Layout
6638 modes[${language}, "#", "terminators"]="
6639 \backslash
6641 \end_layout
6643 \begin_layout Plain Layout
6646 \backslash
6647 chunkref{mode:add-escapes}(${language}, "
6648 \backslash
6649 #", "
6650 \backslash
6651 textbackslash{}n", "
6652 \backslash
6653 textbackslash{}n
6654 \backslash
6655 #")>
6656 \end_layout
6658 \end_inset
6661 \end_layout
6663 \begin_layout Standard
6664 In C, the 
6665 \begin_inset Flex CharStyle:Code
6666 status collapsed
6668 \begin_layout Plain Layout
6670 \end_layout
6672 \end_inset
6674  denotes pre-processor directives which can be multi-line 
6675 \end_layout
6677 \begin_layout Chunk
6678 mode:add-hash-defines,params=language
6679 \end_layout
6681 \begin_layout Standard
6682 \begin_inset listings
6683 inline false
6684 status open
6686 \begin_layout Plain Layout
6689 \backslash
6690 chunkref{mode:add-submode}(${language}, "", "
6691 \backslash
6692 #")>
6693 \end_layout
6695 \begin_layout Plain Layout
6697 modes[${language}, "#", "submodes" ]="
6698 \backslash
6700 \backslash
6702 \backslash
6704 \backslash
6706 \end_layout
6708 \begin_layout Plain Layout
6710 modes[${language}, "#", "terminators"]="
6711 \backslash
6713 \end_layout
6715 \begin_layout Plain Layout
6718 \backslash
6719 chunkref{mode:add-escapes}(${language}, "
6720 \backslash
6721 #", "
6722 \backslash
6723 textbackslash{}n", "
6724 \backslash
6725 textbackslash{}
6726 \backslash
6727 textbackslash{}
6728 \backslash
6729 textbackslash{}
6730 \backslash
6731 textbackslash{}
6732 \backslash
6733 textbackslash{}n")>
6734 \end_layout
6736 \end_inset
6739 \end_layout
6741 \begin_layout Chunk
6742 mode:quote-dollar-escape,params=language;quote
6743 \end_layout
6745 \begin_layout Standard
6746 \begin_inset listings
6747 inline false
6748 status open
6750 \begin_layout Plain Layout
6752 escapes[${language}, ${quote}, ++escapes[${language}, ${quote}], "s"]="
6753 \backslash
6755 \backslash
6757 \end_layout
6759 \begin_layout Plain Layout
6761 escapes[${language}, ${quote},   escapes[${language}, ${quote}], "r"]="
6762 \backslash
6764 \backslash
6766 \end_layout
6768 \end_inset
6771 \end_layout
6773 \begin_layout Standard
6774 We can add these definitions to various languages
6775 \end_layout
6777 \begin_layout Chunk
6778 mode-definitions
6779 \end_layout
6781 \begin_layout Standard
6782 \begin_inset listings
6783 inline false
6784 status open
6786 \begin_layout Plain Layout
6789 \backslash
6790 chunkref{common-mode-definitions}("c-like")>
6791 \end_layout
6793 \begin_layout Plain Layout
6795 \end_layout
6797 \begin_layout Plain Layout
6800 \backslash
6801 chunkref{common-mode-definitions}("c")>
6802 \end_layout
6804 \begin_layout Plain Layout
6807 \backslash
6808 chunkref{mode:multi-line-comments}("c")>
6809 \end_layout
6811 \begin_layout Plain Layout
6814 \backslash
6815 chunkref{mode:single-line-slash-comments}("c")>
6816 \end_layout
6818 \begin_layout Plain Layout
6821 \backslash
6822 chunkref{mode:add-hash-defines}("c")>
6823 \end_layout
6825 \begin_layout Plain Layout
6827 \end_layout
6829 \begin_layout Plain Layout
6832 \backslash
6833 chunkref{common-mode-definitions}("awk")>
6834 \end_layout
6836 \begin_layout Plain Layout
6839 \backslash
6840 chunkref{mode:add-hash-comments}("awk")>
6841 \end_layout
6843 \begin_layout Plain Layout
6846 \backslash
6847 chunkref{mode:add-naked-regex}("awk")>
6848 \end_layout
6850 \end_inset
6853 \end_layout
6855 \begin_layout Standard
6856 The awk definitions should allow a comment block like this:
6857 \end_layout
6859 \begin_layout Chunk
6860 test:comment-quote,language=awk
6861 \end_layout
6863 \begin_layout Standard
6864 \begin_inset listings
6865 inline false
6866 status open
6868 \begin_layout Plain Layout
6870 # Comment: =<
6871 \backslash
6872 chunkref{test:comment-text}>
6873 \end_layout
6875 \end_inset
6878 \end_layout
6880 \begin_layout Chunk
6881 test:comment-text,language=
6882 \end_layout
6884 \begin_layout Standard
6885 \begin_inset listings
6886 inline false
6887 status open
6889 \begin_layout Plain Layout
6891 Now is the time for
6892 \end_layout
6894 \begin_layout Plain Layout
6896 the quick brown fox to bring lemonade
6897 \end_layout
6899 \begin_layout Plain Layout
6901 to the party
6902 \end_layout
6904 \end_inset
6907 \end_layout
6909 \begin_layout Standard
6910 to come out like this:
6911 \end_layout
6913 \begin_layout Chunk
6914 test:comment-quote:result
6915 \end_layout
6917 \begin_layout Standard
6918 \begin_inset listings
6919 inline false
6920 status open
6922 \begin_layout Plain Layout
6924 # Comment: Now is the time for
6925 \end_layout
6927 \begin_layout Plain Layout
6929 #the quick brown fox to bring lemonade
6930 \end_layout
6932 \begin_layout Plain Layout
6934 #to the party
6935 \end_layout
6937 \end_inset
6940 \end_layout
6942 \begin_layout Standard
6943 The C definition for such a block should have it come out like this:
6944 \end_layout
6946 \begin_layout Chunk
6947 test:comment-quote:C-result
6948 \end_layout
6950 \begin_layout Standard
6951 \begin_inset listings
6952 inline false
6953 status open
6955 \begin_layout Plain Layout
6957 # Comment: Now is the time for
6958 \backslash
6960 \end_layout
6962 \begin_layout Plain Layout
6964 the quick brown fox to bring lemonade
6965 \backslash
6967 \end_layout
6969 \begin_layout Plain Layout
6971 to the party
6972 \end_layout
6974 \end_inset
6977 \end_layout
6979 \begin_layout Subsection
6980 Regex
6981 \end_layout
6983 \begin_layout Standard
6984 This pattern is in-complete, but meant to detect naked regular expressions
6985  in awk and perl; e.g.
6987 \begin_inset Flex CharStyle:Code
6988 status collapsed
6990 \begin_layout Plain Layout
6991 /.*$/
6992 \end_layout
6994 \end_inset
6996 , however required capabilities are not present.
6997 \end_layout
6999 \begin_layout Standard
7000 Current it only detects regexes anchored with 
7001 \begin_inset Flex CharStyle:Code
7002 status collapsed
7004 \begin_layout Plain Layout
7006 \end_layout
7008 \end_inset
7010  as used in newfangle.
7011 \end_layout
7013 \begin_layout Standard
7014 For full regex support, modes need to be named not after their starting
7015  character, but some other more fully qualified name.
7016 \end_layout
7018 \begin_layout Chunk
7019 mode:add-naked-regex,params=language
7020 \end_layout
7022 \begin_layout Standard
7023 \begin_inset listings
7024 inline false
7025 status open
7027 \begin_layout Plain Layout
7030 \backslash
7031 chunkref{mode:add-submode}(${language}, "", "/
7032 \backslash
7033 textbackslash{}
7034 \backslash
7035 textbackslash{}
7036 \backslash
7037 ^")>
7038 \end_layout
7040 \begin_layout Plain Layout
7042 modes[${language}, "/^", "terminators"]="/";
7043 \end_layout
7045 \end_inset
7048 \end_layout
7050 \begin_layout Subsection
7051 Perl
7052 \end_layout
7054 \begin_layout Chunk
7055 mode-definitions
7056 \end_layout
7058 \begin_layout Standard
7059 \begin_inset listings
7060 inline false
7061 status open
7063 \begin_layout Plain Layout
7066 \backslash
7067 chunkref{common-mode-definitions}("perl")>
7068 \end_layout
7070 \begin_layout Plain Layout
7073 \backslash
7074 chunkref{mode:multi-line-comments}("perl")>
7075 \end_layout
7077 \begin_layout Plain Layout
7080 \backslash
7081 chunkref{mode:add-hash-comments}("perl")>
7082 \end_layout
7084 \end_inset
7087 \end_layout
7089 \begin_layout Standard
7090 Still need to add add s/, submod /, terminate both with //
7091 \end_layout
7093 \begin_layout Subsection
7095 \end_layout
7097 \begin_layout Chunk
7098 mode-definitions
7099 \end_layout
7101 \begin_layout Standard
7102 \begin_inset listings
7103 inline false
7104 status open
7106 \begin_layout Plain Layout
7109 \backslash
7110 chunkref{common-mode-definitions}("sh")>
7111 \end_layout
7113 \begin_layout Plain Layout
7116 \backslash
7117 chunkref{mode:common-string}("sh", "
7118 \backslash
7119 textbackslash{}"")>
7120 \end_layout
7122 \begin_layout Plain Layout
7125 \backslash
7126 chunkref{mode:common-string}("sh", "'")>
7127 \end_layout
7129 \begin_layout Plain Layout
7132 \backslash
7133 chunkref{mode:add-hash-comments}("sh")>
7134 \end_layout
7136 \begin_layout Plain Layout
7139 \backslash
7140 chunkref{mode:quote-dollar-escape}("sh", "
7141 \backslash
7142 "")>
7143 \end_layout
7145 \end_inset
7148 \end_layout
7150 \begin_layout Section
7151 Some tests
7152 \end_layout
7154 \begin_layout Standard
7155 Also, the parser must return any spare text at the end that has not been
7156  processed due to a mode terminator being found.
7157 \end_layout
7159 \begin_layout Chunk
7160 test:mode-definitions
7161 \end_layout
7163 \begin_layout Standard
7164 \begin_inset listings
7165 inline false
7166 status open
7168 \begin_layout Plain Layout
7170 rest = parse_chunk_args("c-like", "1, 2, 3) spare", a, "(");
7171 \end_layout
7173 \begin_layout Plain Layout
7175 if (a[1] != 1) e++;
7176 \end_layout
7178 \begin_layout Plain Layout
7180 if (a[2] != 2) e++;
7181 \end_layout
7183 \begin_layout Plain Layout
7185 if (a[3] != 3) e++;
7186 \end_layout
7188 \begin_layout Plain Layout
7190 if (length(a) != 3) e++;
7191 \end_layout
7193 \begin_layout Plain Layout
7195 if (rest != " spare") e++;
7196 \end_layout
7198 \begin_layout Plain Layout
7201 \backslash
7202 chunkref{pca-test.awk:summary}>
7203 \end_layout
7205 \end_inset
7208 \end_layout
7210 \begin_layout Standard
7211 We must also be able to parse the example given earlier.
7212 \end_layout
7214 \begin_layout Chunk
7215 test:mode-definitions
7216 \end_layout
7218 \begin_layout Standard
7219 \begin_inset listings
7220 inline false
7221 status open
7223 \begin_layout Plain Layout
7225 parse_chunk_args("c-like", "things[x, y], get_other_things(a, 
7226 \backslash
7227 "(all)
7228 \backslash
7229 "), 99", a, "(");
7230 \end_layout
7232 \begin_layout Plain Layout
7234 if (a[1] != "things[x, y]") e++;
7235 \end_layout
7237 \begin_layout Plain Layout
7239 if (a[2] != "get_other_things(a, 
7240 \backslash
7241 "(all)
7242 \backslash
7243 ")") e++;
7244 \end_layout
7246 \begin_layout Plain Layout
7248 if (a[3] != "99") e++;
7249 \end_layout
7251 \begin_layout Plain Layout
7253 if (length(a) != 3) e++;
7254 \end_layout
7256 \begin_layout Plain Layout
7259 \backslash
7260 chunkref{pca-test.awk:summary}>
7261 \end_layout
7263 \end_inset
7266 \end_layout
7268 \begin_layout Section
7269 A non-recursive mode tracker
7270 \end_layout
7272 \begin_layout Subsection
7273 Constructor
7274 \end_layout
7276 \begin_layout Standard
7277 The mode tracker holds its state in a stack based on a hash.
7278  This function, when passed an empty hash will intialize it.
7279 \end_layout
7281 \begin_layout Chunk
7282 new_mode_tracker()
7283 \end_layout
7285 \begin_layout Standard
7286 \begin_inset listings
7287 inline false
7288 status open
7290 \begin_layout Plain Layout
7292 function new_mode_tracker(context, language, mode) {
7293 \end_layout
7295 \begin_layout Plain Layout
7297   context[""] = 0;
7298 \end_layout
7300 \begin_layout Plain Layout
7302   context[0, "language"] = language;
7303 \end_layout
7305 \begin_layout Plain Layout
7307   context[0, "mode"] = mode;
7308 \end_layout
7310 \begin_layout Plain Layout
7313 \end_layout
7315 \end_inset
7318 \end_layout
7320 \begin_layout Standard
7321 Because awk functions cannot return an array, we must create the array first
7322  and pass it in, so we have a newfangle macro to do this:
7323 \end_layout
7325 \begin_layout Chunk
7326 new-mode-tracker,language=awk,params=context;language;mode
7327 \end_layout
7329 \begin_layout Standard
7330 \begin_inset listings
7331 inline false
7332 status open
7334 \begin_layout Plain Layout
7337 \backslash
7338 chunkref{awk-delete-array}(${context})>
7339 \end_layout
7341 \begin_layout Plain Layout
7343 new_mode_tracker(${context}, ${language}, ${mode});
7344 \end_layout
7346 \end_inset
7349 \end_layout
7351 \begin_layout Subsection
7352 Management
7353 \end_layout
7355 \begin_layout Standard
7356 And for tracking modes, we dispatch to a mode-tracker action based on the
7357  current language
7358 \end_layout
7360 \begin_layout Chunk
7361 mode_tracker,language=awk
7362 \end_layout
7364 \begin_layout Standard
7365 \begin_inset listings
7366 inline false
7367 status open
7369 \begin_layout Plain Layout
7371 function push_mode_tracker(context, language, mode,
7372 \end_layout
7374 \begin_layout Plain Layout
7376   # local vars
7377 \end_layout
7379 \begin_layout Plain Layout
7381   top)
7382 \end_layout
7384 \begin_layout Plain Layout
7387 \end_layout
7389 \begin_layout Plain Layout
7391   if (! ("" in context)) {
7392 \end_layout
7394 \begin_layout Plain Layout
7396     =<
7397 \backslash
7398 chunkref{new-mode-tracker}(context, language, mode)>
7399 \end_layout
7401 \begin_layout Plain Layout
7403   } else {
7404 \end_layout
7406 \begin_layout Plain Layout
7408     top = context[""];
7409 \end_layout
7411 \begin_layout Plain Layout
7413     if (context[top, "language"] == language && mode=="") mode = context[top,
7414  "mode"];
7415 \end_layout
7417 \begin_layout Plain Layout
7419     top++;
7420 \end_layout
7422 \begin_layout Plain Layout
7424     context[top, "language"] = language;
7425 \end_layout
7427 \begin_layout Plain Layout
7429     context[top, "mode"] = mode;
7430 \end_layout
7432 \begin_layout Plain Layout
7434     context[""] = top;
7435 \end_layout
7437 \begin_layout Plain Layout
7439   }
7440 \end_layout
7442 \begin_layout Plain Layout
7445 \end_layout
7447 \end_inset
7450 \end_layout
7452 \begin_layout Standard
7453 \begin_inset listings
7454 inline false
7455 status open
7457 \begin_layout Plain Layout
7459 function dump_mode_tracker(context,  
7460 \end_layout
7462 \begin_layout Plain Layout
7464   c, d)
7465 \end_layout
7467 \begin_layout Plain Layout
7470 \end_layout
7472 \begin_layout Plain Layout
7474   for(c=0; c <= context[""]; c++) {
7475 \end_layout
7477 \begin_layout Plain Layout
7479     printf(" %2d   %s:%s
7480 \backslash
7481 n", c, context[c, "language"], context[c, "mode"]) > "/dev/stderr";
7482 \end_layout
7484 \begin_layout Plain Layout
7486     for(d=1; ( (c, "values", d) in context); d++) {
7487 \end_layout
7489 \begin_layout Plain Layout
7491       printf("   %2d %s
7492 \backslash
7493 n", d, context[c, "values", d]) > "/dev/stderr";
7494 \end_layout
7496 \begin_layout Plain Layout
7498     }
7499 \end_layout
7501 \begin_layout Plain Layout
7503   }
7504 \end_layout
7506 \begin_layout Plain Layout
7509 \end_layout
7511 \end_inset
7514 \end_layout
7516 \begin_layout Standard
7517 \begin_inset listings
7518 inline false
7519 status open
7521 \begin_layout Plain Layout
7523 function finalize_mode_tracker(context)
7524 \end_layout
7526 \begin_layout Plain Layout
7529 \end_layout
7531 \begin_layout Plain Layout
7533   if ( ("" in context) && context[""] != 0) return 0;
7534 \end_layout
7536 \begin_layout Plain Layout
7538   return 1;
7539 \end_layout
7541 \begin_layout Plain Layout
7544 \end_layout
7546 \end_inset
7549 \end_layout
7551 \begin_layout Standard
7552 This implies that any chunk must be syntactically whole; for instance, this
7553  is fine:
7554 \end_layout
7556 \begin_layout Chunk
7557 test:whole-chunk
7558 \end_layout
7560 \begin_layout Standard
7561 \begin_inset listings
7562 inline false
7563 status open
7565 \begin_layout Plain Layout
7567 if (1) {
7568 \end_layout
7570 \begin_layout Plain Layout
7572   =<
7573 \backslash
7574 chunkref{test:say-hello}>
7575 \end_layout
7577 \begin_layout Plain Layout
7580 \end_layout
7582 \end_inset
7585 \end_layout
7587 \begin_layout Chunk
7588 test:say-hello
7589 \end_layout
7591 \begin_layout Standard
7592 \begin_inset listings
7593 inline false
7594 status open
7596 \begin_layout Plain Layout
7598 print "hello";
7599 \end_layout
7601 \end_inset
7604 \end_layout
7606 \begin_layout Standard
7607 But this is not fine; the chunk 
7608 \begin_inset Flex Chunkref
7609 status collapsed
7611 \begin_layout Plain Layout
7612 test:hidden-else
7613 \end_layout
7615 \end_inset
7617  is not properly cromulent.
7618 \end_layout
7620 \begin_layout Chunk
7621 test:partial-chunk
7622 \end_layout
7624 \begin_layout Standard
7625 \begin_inset listings
7626 inline false
7627 status open
7629 \begin_layout Plain Layout
7631 if (1) {
7632 \end_layout
7634 \begin_layout Plain Layout
7636   =<
7637 \backslash
7638 chunkref{test:hidden-else}>
7639 \end_layout
7641 \begin_layout Plain Layout
7644 \end_layout
7646 \end_inset
7649 \end_layout
7651 \begin_layout Chunk
7652 test:hidden-else
7653 \end_layout
7655 \begin_layout Standard
7656 \begin_inset listings
7657 inline false
7658 status open
7660 \begin_layout Plain Layout
7662   print "I'm fine";
7663 \end_layout
7665 \begin_layout Plain Layout
7667 } else {
7668 \end_layout
7670 \begin_layout Plain Layout
7672   print "I'm not";
7673 \end_layout
7675 \end_inset
7678 \end_layout
7680 \begin_layout Standard
7681 These tests will check for correct behaviour:
7682 \end_layout
7684 \begin_layout Chunk
7685 test:cromulence
7686 \end_layout
7688 \begin_layout Standard
7689 \begin_inset listings
7690 inline false
7691 status open
7693 \begin_layout Plain Layout
7695 echo Cromulence test
7696 \end_layout
7698 \begin_layout Plain Layout
7700 passtest $NEWFANGLE -Rtest:whole-chunk $TEX_SRC &>/dev/null || ( echo "Whole
7701  chunk failed" && exit 1 )
7702 \end_layout
7704 \begin_layout Plain Layout
7706 failtest $NEWFANGLE -Rtest:partial-chunk $TEX_SRC &>/dev/null || ( echo
7707  "Partial chunk failed" && exit 1 )
7708 \end_layout
7710 \end_inset
7713 \end_layout
7715 \begin_layout Subsection
7716 Tracker
7717 \end_layout
7719 \begin_layout Standard
7720 We must avoid recursion as a language construct because we intend to employ
7721  mode-tracking to track language mode of emitted code, and the code is emitted
7722  from a function which is itself recursive, so instead we implement psuedo-recur
7723 sion using our own stack based on a hash.
7724 \end_layout
7726 \begin_layout Chunk
7727 mode_tracker()
7728 \end_layout
7730 \begin_layout Standard
7731 \begin_inset listings
7732 inline false
7733 status open
7735 \begin_layout Plain Layout
7737 function mode_tracker(context, text, values, 
7738 \end_layout
7740 \begin_layout Plain Layout
7742   # optional parameters
7743 \end_layout
7745 \begin_layout Plain Layout
7747   # local vars
7748 \end_layout
7750 \begin_layout Plain Layout
7752   mode, submodes, language,
7753 \end_layout
7755 \begin_layout Plain Layout
7757   cindex, c, a, part, item, name, result, new_values, new_mode, 
7758 \end_layout
7760 \begin_layout Plain Layout
7762   delimiters, terminators)
7763 \end_layout
7765 \begin_layout Plain Layout
7768 \end_layout
7770 \end_inset
7773 \end_layout
7775 \begin_layout Standard
7776 We could be re-commencing with a valid context, so we need to setup the
7777  state according to the last context.
7778 \end_layout
7780 \begin_layout Standard
7781 \begin_inset listings
7782 inline false
7783 status open
7785 \begin_layout Plain Layout
7787   cindex = context[""] + 0;
7788 \end_layout
7790 \begin_layout Plain Layout
7792   mode = context[cindex, "mode"];
7793 \end_layout
7795 \begin_layout Plain Layout
7797   language = context[cindex, "language" ];
7798 \end_layout
7800 \end_inset
7803 \end_layout
7805 \begin_layout Standard
7806 First we construct a single large regex combining the possible sub-modes
7807  for the current mode along with the terminators for the current mode.
7808 \end_layout
7810 \begin_layout Chunk
7811 parse_chunk_args-reset-modes
7812 \end_layout
7814 \begin_layout Standard
7815 \begin_inset listings
7816 inline false
7817 status open
7819 \begin_layout Plain Layout
7821   submodes=modes[language, mode, "submodes"];
7822 \end_layout
7824 \begin_layout Plain Layout
7826 \end_layout
7828 \begin_layout Plain Layout
7830   if ((language, mode, "delimiters") in modes) {
7831 \end_layout
7833 \begin_layout Plain Layout
7835     delimiters = modes[language, mode, "delimiters"];
7836 \end_layout
7838 \begin_layout Plain Layout
7840     if (length(submodes)>0) submodes = submodes "|";
7841 \end_layout
7843 \begin_layout Plain Layout
7845     submodes=submodes delimiters;
7846 \end_layout
7848 \begin_layout Plain Layout
7850   } else delimiters="";
7851 \end_layout
7853 \begin_layout Plain Layout
7855   if ((language, mode, "terminators") in modes) {
7856 \end_layout
7858 \begin_layout Plain Layout
7860     terminators = modes[language, mode, "terminators"];
7861 \end_layout
7863 \begin_layout Plain Layout
7865     if (length(submodes)>0) submodes = submodes "|";
7866 \end_layout
7868 \begin_layout Plain Layout
7870     submodes=submodes terminators;
7871 \end_layout
7873 \begin_layout Plain Layout
7875   } else terminators="";
7876 \end_layout
7878 \end_inset
7881 \end_layout
7883 \begin_layout Standard
7884 If we don't find anything to match on --- probably because the language
7885  is not supported --- then we return the entire text without matching anything.
7886 \end_layout
7888 \begin_layout Standard
7889 \begin_inset listings
7890 inline false
7891 status open
7893 \begin_layout Plain Layout
7895   if (! length(submodes)) return text; 
7896 \end_layout
7898 \end_inset
7901 \end_layout
7903 \begin_layout Chunk
7904 mode_tracker()
7905 \end_layout
7907 \begin_layout Standard
7908 \begin_inset listings
7909 inline false
7910 status open
7912 \begin_layout Plain Layout
7915 \backslash
7916 chunkref{parse_chunk_args-reset-modes}>
7917 \end_layout
7919 \end_inset
7922 \end_layout
7924 \begin_layout Standard
7925 We then iterate the text (until there is none left) looking for sub-modes
7926  or terminators in the regex.
7927 \end_layout
7929 \begin_layout Standard
7930 \begin_inset listings
7931 inline false
7932 status open
7934 \begin_layout Plain Layout
7936   while((cindex >= 0) && length(text)) {
7937 \end_layout
7939 \begin_layout Plain Layout
7941     if (match(text, "(" submodes ")", a)) {
7942 \end_layout
7944 \end_inset
7947 \end_layout
7949 \begin_layout Standard
7950 A bug that creeps in regularly during development is bad regexes of zero
7951  length which result in an infinite loop (as no text is consumed), so I
7952  catch that right away with this test.
7953 \end_layout
7955 \begin_layout Standard
7956 \begin_inset listings
7957 inline false
7958 status open
7960 \begin_layout Plain Layout
7962       if (RLENGTH<1) {
7963 \end_layout
7965 \begin_layout Plain Layout
7967         error(sprintf("Internal error, matched zero length submode, should
7968  be impossible - likely regex computation error
7969 \backslash
7970 n" 
7971 \backslash
7973 \end_layout
7975 \begin_layout Plain Layout
7977                 "Language=%s
7978 \backslash
7979 nmode=%s
7980 \backslash
7981 nmatch=%s
7982 \backslash
7983 n", language, mode, submodes));
7984 \end_layout
7986 \begin_layout Plain Layout
7988       }
7989 \end_layout
7991 \end_inset
7994 \end_layout
7996 \begin_layout Standard
7997 \begin_inset Flex CharStyle:Code
7998 status collapsed
8000 \begin_layout Plain Layout
8001 part
8002 \end_layout
8004 \end_inset
8006  is defined as the text up to the sub-mode or terminator, and this is appended
8007  to 
8008 \begin_inset Flex CharStyle:Code
8009 status collapsed
8011 \begin_layout Plain Layout
8012 item
8013 \end_layout
8015 \end_inset
8017  --- which is the current text being gathered.
8018  If a mode has a delimiter, then item is reset each time a delimiter is
8019  found.
8020 \end_layout
8022 \begin_layout Standard
8023 \begin_inset Formula $\mathtt{\overbrace{"\overbrace{hello}^{item},\ \overbrace{there}^{item}"}^{item},\ \overbrace{he\ said.}^{item}}$
8024 \end_inset
8027 \end_layout
8029 \begin_layout Standard
8030 \begin_inset listings
8031 inline false
8032 status open
8034 \begin_layout Plain Layout
8036       part = substr(text, 1, RSTART -1);
8037 \end_layout
8039 \begin_layout Plain Layout
8041       item = item part;
8042 \end_layout
8044 \end_inset
8047 \end_layout
8049 \begin_layout Standard
8050 We must now determine what was matched.
8051  If it was a terminator, then we must restore the previous mode.
8052 \end_layout
8054 \begin_layout Standard
8055 \begin_inset listings
8056 inline false
8057 status open
8059 \begin_layout Plain Layout
8061       if (match(a[1], "^" terminators "$")) {
8062 \end_layout
8064 \begin_layout Plain Layout
8066 #printf("%2d EXIT  MODE [%s] by [%s] [%s]
8067 \backslash
8068 n", cindex, mode, a[1], text) > "/dev/stderr"
8069 \end_layout
8071 \begin_layout Plain Layout
8073         context[cindex, "values", ++context[cindex, "values"]] = item;
8074 \end_layout
8076 \begin_layout Plain Layout
8078         delete context[cindex];
8079 \end_layout
8081 \begin_layout Plain Layout
8083         context[""] = --cindex;
8084 \end_layout
8086 \begin_layout Plain Layout
8088         if (cindex>=0) {
8089 \end_layout
8091 \begin_layout Plain Layout
8093           mode = context[cindex, "mode"];
8094 \end_layout
8096 \begin_layout Plain Layout
8098           language = context[cindex, "language"];
8099 \end_layout
8101 \begin_layout Plain Layout
8103           =<
8104 \backslash
8105 chunkref{parse_chunk_args-reset-modes}>
8106 \end_layout
8108 \begin_layout Plain Layout
8110         }
8111 \end_layout
8113 \begin_layout Plain Layout
8115         item = item a[1];
8116 \end_layout
8118 \begin_layout Plain Layout
8120         text = substr(text, 1 + length(part) + length(a[1]));
8121 \end_layout
8123 \begin_layout Plain Layout
8125       }
8126 \end_layout
8128 \end_inset
8131 \end_layout
8133 \begin_layout Standard
8134 If a delimiter was matched, then we must store the current item in the parsed
8135  values array, and reset the item.
8136 \end_layout
8138 \begin_layout Standard
8139 \begin_inset listings
8140 inline false
8141 status open
8143 \begin_layout Plain Layout
8145       else if (match(a[1], "^" delimiters "$")) {
8146 \end_layout
8148 \begin_layout Plain Layout
8150         if (cindex==0) {
8151 \end_layout
8153 \begin_layout Plain Layout
8155           context[cindex, "values", ++context[cindex, "values"]] = item;
8156 \end_layout
8158 \begin_layout Plain Layout
8160           item = "";
8161 \end_layout
8163 \begin_layout Plain Layout
8165         } else {
8166 \end_layout
8168 \begin_layout Plain Layout
8170           item = item a[1];
8171 \end_layout
8173 \begin_layout Plain Layout
8175         }
8176 \end_layout
8178 \begin_layout Plain Layout
8180         text = substr(text, 1 + length(part) + length(a[1]));
8181 \end_layout
8183 \begin_layout Plain Layout
8185       }
8186 \end_layout
8188 \end_inset
8191 \end_layout
8193 \begin_layout Standard
8194 otherwise, if a new submode is detected (all submodes have terminators),
8195  we must create a nested parse context until we find the terminator for
8196  this mode.
8197 \end_layout
8199 \begin_layout Standard
8200 \begin_inset listings
8201 inline false
8202 status open
8204 \begin_layout Plain Layout
8206  else if ((language, a[1], "terminators") in modes) {
8207 \end_layout
8209 \begin_layout Plain Layout
8211         #check if new_mode is defined
8212 \end_layout
8214 \begin_layout Plain Layout
8216         item = item a[1];
8217 \end_layout
8219 \begin_layout Plain Layout
8221 #printf("%2d ENTER MODE [%s] in [%s]
8222 \backslash
8223 n", cindex, a[1], text) > "/dev/stderr"
8224 \end_layout
8226 \begin_layout Plain Layout
8228         text = substr(text, 1 + length(part) + length(a[1]));
8229 \end_layout
8231 \begin_layout Plain Layout
8233         context[""] = ++cindex;
8234 \end_layout
8236 \begin_layout Plain Layout
8238         context[cindex, "mode"] = a[1];
8239 \end_layout
8241 \begin_layout Plain Layout
8243         context[cindex, "language"] = language;
8244 \end_layout
8246 \begin_layout Plain Layout
8248         mode = a[1];
8249 \end_layout
8251 \begin_layout Plain Layout
8253         =<
8254 \backslash
8255 chunkref{parse_chunk_args-reset-modes}>
8256 \end_layout
8258 \begin_layout Plain Layout
8260       } else {
8261 \end_layout
8263 \begin_layout Plain Layout
8265         error(sprintf("Submode '%s' set unknown mode in text: %s
8266 \backslash
8267 nLanguage %s Mode %s
8268 \backslash
8269 n", a[1], text, language, mode));
8270 \end_layout
8272 \begin_layout Plain Layout
8274         text = substr(text, 1 + length(part) + length(a[1]));
8275 \end_layout
8277 \begin_layout Plain Layout
8279       }
8280 \end_layout
8282 \begin_layout Plain Layout
8284     }
8285 \end_layout
8287 \end_inset
8290 \end_layout
8292 \begin_layout Standard
8293 In the final case, we parsed to the end of the string.
8294  If the string was entire, then we should have no nested mode context, but
8295  if the string was just a fragment we may have a mode context which must
8296  be preserved for the next fragment.
8297  Todo: Consideration ought to be given if sub-mode strings are split over
8298  two fragments.
8299 \begin_inset Note Note
8300 status collapsed
8302 \begin_layout Plain Layout
8303 Consideration ought to be given if sub-mode strings are split over two fragments.
8304 \end_layout
8306 \end_inset
8309 \end_layout
8311 \begin_layout Standard
8312 \begin_inset listings
8313 inline false
8314 status open
8316 \begin_layout Plain Layout
8318 else {
8319 \end_layout
8321 \begin_layout Plain Layout
8323       context[cindex, "values", ++context[cindex, "values"]] = item text;
8324 \end_layout
8326 \begin_layout Plain Layout
8328       text = "";
8329 \end_layout
8331 \begin_layout Plain Layout
8333       item = "";
8334 \end_layout
8336 \begin_layout Plain Layout
8338     }
8339 \end_layout
8341 \begin_layout Plain Layout
8343   }
8344 \end_layout
8346 \begin_layout Plain Layout
8348 \end_layout
8350 \begin_layout Plain Layout
8352   context["item"] = item;
8353 \end_layout
8355 \begin_layout Plain Layout
8357 \end_layout
8359 \begin_layout Plain Layout
8361   if (length(item)) context[cindex, "values", ++context[cindex, "values"]]
8362  = item;
8363 \end_layout
8365 \begin_layout Plain Layout
8367   return text;
8368 \end_layout
8370 \begin_layout Plain Layout
8373 \end_layout
8375 \end_inset
8378 \end_layout
8380 \begin_layout Subsubsection
8381 One happy chunk
8382 \end_layout
8384 \begin_layout Standard
8385 All the mode tracker chunks are referred to here:
8386 \end_layout
8388 \begin_layout Chunk
8389 mode-tracker
8390 \end_layout
8392 \begin_layout Standard
8393 \begin_inset listings
8394 inline false
8395 status open
8397 \begin_layout Plain Layout
8400 \backslash
8401 chunkref{new_mode_tracker()}>
8402 \end_layout
8404 \begin_layout Plain Layout
8407 \backslash
8408 chunkref{mode_tracker()}>
8409 \end_layout
8411 \end_inset
8414 \end_layout
8416 \begin_layout Subsubsection
8417 Tests
8418 \end_layout
8420 \begin_layout Standard
8421 We can test this function like this:
8422 \end_layout
8424 \begin_layout Chunk
8425 pca-test.awk,language=awk
8426 \end_layout
8428 \begin_layout Standard
8429 \begin_inset listings
8430 inline false
8431 status open
8433 \begin_layout Plain Layout
8436 \backslash
8437 chunkref{error()}>
8438 \end_layout
8440 \begin_layout Plain Layout
8443 \backslash
8444 chunkref{mode-tracker}>
8445 \end_layout
8447 \begin_layout Plain Layout
8450 \backslash
8451 chunkref{parse_chunk_args()}>
8452 \end_layout
8454 \begin_layout Plain Layout
8456 BEGIN {
8457 \end_layout
8459 \begin_layout Plain Layout
8461   SUBSEP=".";
8462 \end_layout
8464 \begin_layout Plain Layout
8466   =<
8467 \backslash
8468 chunkref{mode-definitions}>
8469 \end_layout
8471 \begin_layout Plain Layout
8473 \end_layout
8475 \begin_layout Plain Layout
8477   =<
8478 \backslash
8479 chunkref{test:mode-definitions}>
8480 \end_layout
8482 \begin_layout Plain Layout
8485 \end_layout
8487 \end_inset
8490 \end_layout
8492 \begin_layout Chunk
8493 pca-test.awk:summary,language=awk
8494 \end_layout
8496 \begin_layout Standard
8497 \begin_inset listings
8498 inline false
8499 status open
8501 \begin_layout Plain Layout
8503 if (e) {
8504 \end_layout
8506 \begin_layout Plain Layout
8508   printf "Failed " e
8509 \end_layout
8511 \begin_layout Plain Layout
8513   for (b in a) {
8514 \end_layout
8516 \begin_layout Plain Layout
8518     print "a[" b "] => " a[b];
8519 \end_layout
8521 \begin_layout Plain Layout
8523   }
8524 \end_layout
8526 \begin_layout Plain Layout
8528 } else {
8529 \end_layout
8531 \begin_layout Plain Layout
8533   print "Passed"
8534 \end_layout
8536 \begin_layout Plain Layout
8539 \end_layout
8541 \begin_layout Plain Layout
8543 split("", a);
8544 \end_layout
8546 \begin_layout Plain Layout
8548 e=0;
8549 \end_layout
8551 \end_inset
8554 \end_layout
8556 \begin_layout Standard
8557 which should give this output:
8558 \end_layout
8560 \begin_layout Chunk
8561 pca-test.awk-results,language=
8562 \end_layout
8564 \begin_layout Standard
8565 \begin_inset listings
8566 inline false
8567 status open
8569 \begin_layout Plain Layout
8571 a[foo.quux.quirk] => 
8572 \end_layout
8574 \begin_layout Plain Layout
8576 a[foo.quux.a] => fleeg
8577 \end_layout
8579 \begin_layout Plain Layout
8581 a[foo.bar] => baz
8582 \end_layout
8584 \begin_layout Plain Layout
8586 a[etc] => 
8587 \end_layout
8589 \begin_layout Plain Layout
8591 a[name] => freddie
8592 \end_layout
8594 \end_inset
8597 \end_layout
8599 \begin_layout Section
8600 Escaping and Quoting
8601 \end_layout
8603 \begin_layout Standard
8604 Each nested mode can optionally define a set of transforms to be applied
8605  to any text that is included from another language.
8606 \end_layout
8608 \begin_layout Standard
8609 This code can perform transforms
8610 \end_layout
8612 \begin_layout Chunk
8613 mode_tracker,language=awk
8614 \end_layout
8616 \begin_layout Standard
8617 \begin_inset listings
8618 inline false
8619 status open
8621 \begin_layout Plain Layout
8623 function transform_escape(s, r, text,
8624 \end_layout
8626 \begin_layout Plain Layout
8628     # optional
8629 \end_layout
8631 \begin_layout Plain Layout
8633     max, 
8634 \end_layout
8636 \begin_layout Plain Layout
8638         # local vars
8639 \end_layout
8641 \begin_layout Plain Layout
8643         c)
8644 \end_layout
8646 \begin_layout Plain Layout
8649 \end_layout
8651 \begin_layout Plain Layout
8653   for(c=1; c <= max && (c in s); c++) {
8654 \end_layout
8656 \begin_layout Plain Layout
8658     gsub(s[c], r[c], text);
8659 \end_layout
8661 \begin_layout Plain Layout
8663   }
8664 \end_layout
8666 \begin_layout Plain Layout
8668   return text;
8669 \end_layout
8671 \begin_layout Plain Layout
8674 \end_layout
8676 \end_inset
8679 \end_layout
8681 \begin_layout Standard
8682 This function must append from index 
8683 \begin_inset Flex CharStyle:Code
8684 status collapsed
8686 \begin_layout Plain Layout
8688 \end_layout
8690 \end_inset
8692  onwards, and escape transforms from the supplied context, and return c
8693  + number of new transforms.
8694 \end_layout
8696 \begin_layout Standard
8697 \begin_inset listings
8698 inline false
8699 status open
8701 \begin_layout Plain Layout
8703 function mode_escaper(context, s, r, src,
8704 \end_layout
8706 \begin_layout Plain Layout
8708   c, cp, cpl)
8709 \end_layout
8711 \begin_layout Plain Layout
8714 \end_layout
8716 \begin_layout Plain Layout
8718         for(c = context[""]; c >= 0; c--) {
8719 \end_layout
8721 \begin_layout Plain Layout
8723                 if ( (context[c, "language"], context[c, "mode"]) in escapes) {
8724 \end_layout
8726 \begin_layout Plain Layout
8728                         cpl = escapes[context[c, "language"], context[c, "mode"]];
8729 \end_layout
8731 \begin_layout Plain Layout
8733                         for (cp = 1; cp <= cpl; cp ++) {
8734 \end_layout
8736 \begin_layout Plain Layout
8738                                 ++src;
8739 \end_layout
8741 \begin_layout Plain Layout
8743                                 s[src] = escapes[context[c, "language"], context[c, "mode"], cp, "s"];
8744 \end_layout
8746 \begin_layout Plain Layout
8748                                 r[src] = escapes[context[c, "language"], context[c, "mode"], cp, "r"];
8749 \end_layout
8751 \begin_layout Plain Layout
8753                         }
8754 \end_layout
8756 \begin_layout Plain Layout
8758                 }
8759 \end_layout
8761 \begin_layout Plain Layout
8763         }
8764 \end_layout
8766 \begin_layout Plain Layout
8768         return src;
8769 \end_layout
8771 \begin_layout Plain Layout
8774 \end_layout
8776 \begin_layout Plain Layout
8778 function dump_escaper(c, s, r, cc) {
8779 \end_layout
8781 \begin_layout Plain Layout
8783   for(cc=1; cc<=c; cc++) {
8784 \end_layout
8786 \begin_layout Plain Layout
8788     printf("%2d s[%s] r[%s]
8789 \backslash
8790 n", cc, s[cc], r[cc]) > "/dev/stderr"
8791 \end_layout
8793 \begin_layout Plain Layout
8795   }
8796 \end_layout
8798 \begin_layout Plain Layout
8801 \end_layout
8803 \end_inset
8806 \end_layout
8808 \begin_layout Chunk
8809 test:escapes,language=sh
8810 \end_layout
8812 \begin_layout Standard
8813 \begin_inset listings
8814 inline false
8815 status open
8817 \begin_layout Plain Layout
8819 echo escapes test
8820 \end_layout
8822 \begin_layout Plain Layout
8824 passtest $NEWFANGLE -Rtest:comment-quote $TEX_SRC &>/dev/null || ( echo
8825  "Comment-quote failed" && exit 1 )
8826 \end_layout
8828 \end_inset
8831 \end_layout
8833 \begin_layout Chapter
8834 Recognizing Chunks
8835 \end_layout
8837 \begin_layout Standard
8838 Newfangle recognizes noweb chunks, but as we also want better LaTeX integration
8839  we will recognize any of these:
8840 \end_layout
8842 \begin_layout Itemize
8843 notangle chunks matching the pattern 
8844 \begin_inset Flex CharStyle:Code
8845 status collapsed
8847 \begin_layout Plain Layout
8849 \begin_inset space \hspace*{}
8850 \length 0in
8851 \end_inset
8853 <.*?>
8854 \begin_inset space \hspace*{}
8855 \length 0in
8856 \end_inset
8859 \end_layout
8861 \end_inset
8864 \end_layout
8866 \begin_layout Itemize
8867 a chunks beginning with 
8868 \begin_inset Flex CharStyle:Code
8869 status collapsed
8871 \begin_layout Plain Layout
8873 \backslash
8874 begin{lstlistings}
8875 \end_layout
8877 \end_inset
8879 , possibly with 
8880 \backslash
8881 Chunk{\SpecialChar \ldots{}
8882 } on the previous line
8883 \end_layout
8885 \begin_layout Itemize
8886 an older form I have used, beginning with 
8887 \begin_inset Flex CharStyle:Code
8888 status collapsed
8890 \begin_layout Plain Layout
8892 \backslash
8893 begin{Chunk}[options]
8894 \end_layout
8896 \end_inset
8898  --- also more suitable for plain LaTeX users
8899 \begin_inset Foot
8900 status collapsed
8902 \begin_layout Plain Layout
8903 Is there such a thing as plain LaTeX?
8904 \end_layout
8906 \end_inset
8909 \end_layout
8911 \begin_layout Section
8912 Chunk start
8913 \end_layout
8915 \begin_layout Standard
8916 The variable 
8917 \begin_inset Flex CharStyle:Code
8918 status collapsed
8920 \begin_layout Plain Layout
8921 chunking
8922 \end_layout
8924 \end_inset
8926  is used to signify that we are processing a code chunk and not document.
8927  In such a state, input lines will be assigned to the current chunk; otherwise
8928  they are ignored.
8929 \end_layout
8931 \begin_layout Subsection
8932 lstlistings
8933 \end_layout
8935 \begin_layout Standard
8936 Our current scheme is to recognize the new lstlisting chunks, but these
8937  may be preceded by a 
8938 \begin_inset Flex CharStyle:Code
8939 status collapsed
8941 \begin_layout Plain Layout
8943 \backslash
8944 Chunk
8945 \end_layout
8947 \end_inset
8949  command which in LyX is a more convenient way to pass the chunk name to
8950  the 
8951 \begin_inset Flex CharStyle:Code
8952 status collapsed
8954 \begin_layout Plain Layout
8956 \backslash
8957 begin{lstlistings}
8958 \end_layout
8960 \end_inset
8962  command, and a more visible way to specify other 
8963 \begin_inset Flex CharStyle:Code
8964 status collapsed
8966 \begin_layout Plain Layout
8967 lstset
8968 \end_layout
8970 \end_inset
8972  settings.
8973 \end_layout
8975 \begin_layout Standard
8976 The arguments to the 
8977 \begin_inset Flex CharStyle:Code
8978 status collapsed
8980 \begin_layout Plain Layout
8982 \backslash
8983 Chunk
8984 \end_layout
8986 \end_inset
8988  command are a name, and then a comma-seperated list of key-value pairs
8989  after the manner of 
8990 \begin_inset Flex CharStyle:Code
8991 status collapsed
8993 \begin_layout Plain Layout
8995 \backslash
8996 lstset
8997 \end_layout
8999 \end_inset
9002  (In fact within the LaTeX 
9003 \begin_inset Flex CharStyle:Code
9004 status collapsed
9006 \begin_layout Plain Layout
9008 \backslash
9009 Chunk
9010 \end_layout
9012 \end_inset
9014  macro (section 
9015 \begin_inset CommandInset ref
9016 LatexCommand ref
9017 reference "sub:The-chunk-command"
9019 \end_inset
9021 ) the text 
9022 \begin_inset Flex CharStyle:Code
9023 status collapsed
9025 \begin_layout Plain Layout
9026 name=
9027 \end_layout
9029 \end_inset
9031  is prefixed to the argument which is then literally passed to 
9032 \begin_inset Flex CharStyle:Code
9033 status collapsed
9035 \begin_layout Plain Layout
9037 \backslash
9038 lstset
9039 \end_layout
9041 \end_inset
9044 \end_layout
9046 \begin_layout Chunk
9047 recognize-chunk,language=awk
9048 \end_layout
9050 \begin_layout Standard
9051 \begin_inset listings
9052 inline false
9053 status open
9055 \begin_layout Plain Layout
9058 \backslash
9060 \backslash
9061 Chunk{/ {
9062 \end_layout
9064 \begin_layout Plain Layout
9066   if (match($0, "^
9067 \backslash
9069 \backslash
9071 \backslash
9073 \backslash
9074 Chunk{ *([^ ,}]*),?(.*)}", line)) {
9075 \end_layout
9077 \begin_layout Plain Layout
9079     next_chunk_name = line[1];
9080 \end_layout
9082 \begin_layout Plain Layout
9084     get_chunk_args(line[2], next_chunk_args);
9085 \end_layout
9087 \begin_layout Plain Layout
9089   }
9090 \end_layout
9092 \begin_layout Plain Layout
9094   next;
9095 \end_layout
9097 \begin_layout Plain Layout
9100 \end_layout
9102 \end_inset
9105 \end_layout
9107 \begin_layout Standard
9108 We also make a basic attempt to parse the name out of the 
9109 \begin_inset Flex CharStyle:Code
9110 status collapsed
9112 \begin_layout Plain Layout
9114 \backslash
9115 lstlistings[name=
9116 \begin_inset space \hspace{}
9117 \length 0in
9118 \end_inset
9120 chunk-name]
9121 \end_layout
9123 \end_inset
9125  text, otherwise we fall back to the name found in the previous chunk command.
9126  This attempt is very basic and doesn't support commas or spaces or square
9127  brackets as part of the chunkname.
9128  We also recognize 
9129 \begin_inset Flex CharStyle:Code
9130 status collapsed
9132 \begin_layout Plain Layout
9134 \backslash
9135 begin{Chunk}
9136 \end_layout
9138 \end_inset
9140  which is convenient for some users
9141 \begin_inset Foot
9142 status open
9144 \begin_layout Plain Layout
9145 but not yet supported in the LaTeX macros
9146 \end_layout
9148 \end_inset
9151 \begin_inset Note Note
9152 status collapsed
9154 \begin_layout Plain Layout
9155 Add noweave support
9156 \end_layout
9158 \end_inset
9161 \end_layout
9163 \begin_layout Standard
9164 \begin_inset listings
9165 inline false
9166 status open
9168 \begin_layout Plain Layout
9171 \backslash
9173 \backslash
9174 begin{lstlisting}|^
9175 \backslash
9177 \backslash
9178 begin{Chunk}/ {
9179 \end_layout
9181 \begin_layout Plain Layout
9183   if (match($0, "}.*[[,] *name= *{? *([^], }]*)", line)) {
9184 \end_layout
9186 \begin_layout Plain Layout
9188     new_chunk(line[1]);
9189 \end_layout
9191 \begin_layout Plain Layout
9193   } else {
9194 \end_layout
9196 \begin_layout Plain Layout
9198     new_chunk(next_chunk_name, next_chunk_args);
9199 \end_layout
9201 \begin_layout Plain Layout
9203   }
9204 \end_layout
9206 \begin_layout Plain Layout
9208   chunking=1;
9209 \end_layout
9211 \begin_layout Plain Layout
9213   next;
9214 \end_layout
9216 \begin_layout Plain Layout
9219 \end_layout
9221 \end_inset
9224 \end_layout
9226 \begin_layout Subsection
9227 Noweb
9228 \end_layout
9230 \begin_layout Standard
9231 We recognize notangle style chunks too:
9232 \end_layout
9234 \begin_layout Chunk
9235 recognize-chunk,language=awk
9236 \end_layout
9238 \begin_layout Standard
9239 \begin_inset listings
9240 inline false
9241 status open
9243 \begin_layout Plain Layout
9245 /^[<]<.*[>]>=/ {
9246 \end_layout
9248 \begin_layout Plain Layout
9250   if (match($0, "^[<]<(.*)[>]>= *$", line)) {
9251 \end_layout
9253 \begin_layout Plain Layout
9255     chunking=1;
9256 \end_layout
9258 \begin_layout Plain Layout
9260     notangle_mode=1;
9261 \end_layout
9263 \begin_layout Plain Layout
9265     new_chunk(line[1]);
9266 \end_layout
9268 \begin_layout Plain Layout
9270     next;
9271 \end_layout
9273 \begin_layout Plain Layout
9275   }
9276 \end_layout
9278 \begin_layout Plain Layout
9281 \end_layout
9283 \end_inset
9286 \end_layout
9288 \begin_layout Section
9289 Chunk end
9290 \end_layout
9292 \begin_layout Standard
9293 Likewise, we need to recognize when a chunk ends.
9294 \end_layout
9296 \begin_layout Subsection
9297 lstlistings
9298 \end_layout
9300 \begin_layout Standard
9301 The 
9302 \begin_inset Flex CharStyle:Code
9303 status collapsed
9305 \begin_layout Plain Layout
9307 \end_layout
9309 \end_inset
9311  in 
9312 \begin_inset Flex CharStyle:Code
9313 status collapsed
9315 \begin_layout Plain Layout
9316 [e]end{lislisting}
9317 \end_layout
9319 \end_inset
9321  is surrounded by square brackets so that when this document is processed,
9322  this chunk doesn't terminate early when the lstlistings package recognizes
9323  it's own end-string! 
9324 \begin_inset Note Greyedout
9325 status collapsed
9327 \begin_layout Plain Layout
9328 This doesn't make sense as the regex is anchored with ^, which this line
9329  does not begin with!
9330 \end_layout
9332 \end_inset
9335 \begin_inset Note Note
9336 status open
9338 \begin_layout Plain Layout
9339 No, it doesn't.
9340 \end_layout
9342 \end_inset
9345 \end_layout
9347 \begin_layout Chunk
9348 recognize-chunk
9349 \end_layout
9351 \begin_layout Standard
9352 \begin_inset listings
9353 inline false
9354 status open
9356 \begin_layout Plain Layout
9359 \backslash
9361 \backslash
9362 [e]nd{lstlisting}|^
9363 \backslash
9365 \backslash
9366 [e]nd{Chunk}/ {
9367 \end_layout
9369 \begin_layout Plain Layout
9371   chunking=0;
9372 \end_layout
9374 \begin_layout Plain Layout
9376   active_chunk="";
9377 \end_layout
9379 \begin_layout Plain Layout
9381   next;
9382 \end_layout
9384 \begin_layout Plain Layout
9387 \end_layout
9389 \end_inset
9392 \end_layout
9394 \begin_layout Subsection
9395 noweb
9396 \end_layout
9398 \begin_layout Chunk
9399 recognize-chunk
9400 \end_layout
9402 \begin_layout Standard
9403 \begin_inset listings
9404 inline false
9405 status open
9407 \begin_layout Plain Layout
9409 /^@ *$/ {
9410 \end_layout
9412 \begin_layout Plain Layout
9414   chunking=0;
9415 \end_layout
9417 \begin_layout Plain Layout
9419   active_chunk="";
9420 \end_layout
9422 \begin_layout Plain Layout
9425 \end_layout
9427 \end_inset
9430 \end_layout
9432 \begin_layout Standard
9433 All other recognizers are only of effect if we are chunking; there's no
9434  point in looking at lines if they aren't part of a chunk, so we just ignore
9435  them as efficiently as we can.
9436 \end_layout
9438 \begin_layout Chunk
9439 recognize-chunk
9440 \end_layout
9442 \begin_layout Standard
9443 \begin_inset listings
9444 inline false
9445 status open
9447 \begin_layout Plain Layout
9449 ! chunking { next; }
9450 \end_layout
9452 \end_inset
9455 \end_layout
9457 \begin_layout Section
9458 Chunk contents
9459 \end_layout
9461 \begin_layout Standard
9462 Chunk contents are any lines read while 
9463 \begin_inset Flex CharStyle:Code
9464 status collapsed
9466 \begin_layout Plain Layout
9467 chunking
9468 \end_layout
9470 \end_inset
9472  is true.
9473  Some chunk contents are special in that they refer to other chunks, and
9474  will be replaced by the contents of these chunks when the file is generated.
9475 \end_layout
9477 \begin_layout Standard
9478 \begin_inset CommandInset label
9479 LatexCommand label
9480 name "sub:ORS-chunk-text"
9482 \end_inset
9484 We add the output record separator 
9485 \begin_inset Flex CharStyle:Code
9486 status collapsed
9488 \begin_layout Plain Layout
9490 \end_layout
9492 \end_inset
9494  to the line now, because we will set 
9495 \begin_inset Flex CharStyle:Code
9496 status collapsed
9498 \begin_layout Plain Layout
9500 \end_layout
9502 \end_inset
9504  to the empty string when we generate the output
9505 \begin_inset Foot
9506 status collapsed
9508 \begin_layout Plain Layout
9509 So that we can print partial lines using 
9510 \begin_inset Flex CharStyle:Code
9511 status collapsed
9513 \begin_layout Plain Layout
9514 print
9515 \end_layout
9517 \end_inset
9519  instead of 
9520 \begin_inset Flex CharStyle:Code
9521 status collapsed
9523 \begin_layout Plain Layout
9524 printf
9525 \end_layout
9527 \end_inset
9530 \end_layout
9532 \end_inset
9535 \end_layout
9537 \begin_layout Chunk
9538 recognize-chunk
9539 \end_layout
9541 \begin_layout Standard
9542 \begin_inset listings
9543 inline false
9544 status open
9546 \begin_layout Plain Layout
9548 length(active_chunk) {
9549 \end_layout
9551 \begin_layout Plain Layout
9553   =<
9554 \backslash
9555 chunkref{process-chunk-tabs}>
9556 \end_layout
9558 \begin_layout Plain Layout
9560   =<
9561 \backslash
9562 chunkref{process-chunk}>
9563 \end_layout
9565 \begin_layout Plain Layout
9568 \end_layout
9570 \end_inset
9573 \end_layout
9575 \begin_layout Standard
9576 If a chunk just consisted of plain text, we could handle the chunk like
9577  this:
9578 \end_layout
9580 \begin_layout Chunk
9581 process-chunk-simple
9582 \end_layout
9584 \begin_layout Standard
9585 \begin_inset listings
9586 inline false
9587 status open
9589 \begin_layout Plain Layout
9591 chunk_line(active_chunk, $0 ORS);
9592 \end_layout
9594 \end_inset
9597 \end_layout
9599 \begin_layout Standard
9600 but in fact a chunk can include references to other chunks.
9601  Chunk includes are traditionally written as 
9602 \begin_inset Flex CharStyle:Code
9603 status collapsed
9605 \begin_layout Plain Layout
9606 <<chunk-name>>
9607 \end_layout
9609 \end_inset
9611 , but we support other variations.
9612 \end_layout
9614 \begin_layout Standard
9615 However, we also process tabs at this point, a tab at input can be replaced
9616  by a number of spaces defined by the 
9617 \begin_inset Flex CharStyle:Code
9618 status collapsed
9620 \begin_layout Plain Layout
9621 tabs
9622 \end_layout
9624 \end_inset
9626  variable, set by the 
9627 \begin_inset Flex CharStyle:Code
9628 status collapsed
9630 \begin_layout Plain Layout
9632 \end_layout
9634 \end_inset
9636  option.
9637  Of course this is poor tab behaviour, we should probably have the option
9638  to use proper counted tab-stops and process this on output.
9639 \end_layout
9641 \begin_layout Chunk
9642 process-chunk-tabs
9643 \end_layout
9645 \begin_layout Standard
9646 \begin_inset listings
9647 inline false
9648 status open
9650 \begin_layout Plain Layout
9652 if (length(tabs)) {
9653 \end_layout
9655 \begin_layout Plain Layout
9657   gsub("
9658 \backslash
9659 t", tabs);
9660 \end_layout
9662 \begin_layout Plain Layout
9665 \end_layout
9667 \end_inset
9670 \end_layout
9672 \begin_layout Subsection
9673 \begin_inset CommandInset label
9674 LatexCommand label
9675 name "sub:lstlistings-includes"
9677 \end_inset
9679 lstlistings
9680 \end_layout
9682 \begin_layout Standard
9683 If 
9684 \begin_inset Flex CharStyle:Code
9685 status collapsed
9687 \begin_layout Plain Layout
9689 \backslash
9690 lstset{escapeinside={=<}{>}}
9691 \end_layout
9693 \end_inset
9695  is set, then we can use 
9696 \begin_inset Flex CharStyle:Code
9697 status collapsed
9699 \begin_layout Plain Layout
9701 \backslash
9702 chunkref{
9703 \begin_inset space \hspace{}
9704 \length 0in
9705 \end_inset
9707 chunk-name}>
9708 \end_layout
9710 \end_inset
9712  in listings.
9713  The sequence 
9714 \begin_inset Flex CharStyle:Code
9715 status collapsed
9717 \begin_layout Plain Layout
9719 \end_layout
9721 \end_inset
9723  was chosen because:
9724 \end_layout
9726 \begin_layout Enumerate
9727 it is a better mnemonic than 
9728 \begin_inset Flex CharStyle:Code
9729 status collapsed
9731 \begin_layout Plain Layout
9732 <<chunk-name>>
9733 \end_layout
9735 \end_inset
9737  in that the = sign signifies equivalent or substitutability, 
9738 \end_layout
9740 \begin_layout Enumerate
9741 and because =< is not valid in C or in any language I can think of 
9742 \end_layout
9744 \begin_layout Enumerate
9745 and also because lstlistings doesn't like 
9746 \begin_inset Flex CharStyle:Code
9747 status collapsed
9749 \begin_layout Plain Layout
9751 \end_layout
9753 \end_inset
9755  as an end delimiter for the 
9756 \emph on
9757 texcl
9758 \emph default
9759  escape, so we must make do with a single 
9760 \begin_inset Flex CharStyle:Code
9761 status collapsed
9763 \begin_layout Plain Layout
9765 \end_layout
9767 \end_inset
9769 , which is better matched by 
9770 \begin_inset Flex CharStyle:Code
9771 status collapsed
9773 \begin_layout Plain Layout
9775 \end_layout
9777 \end_inset
9779  than 
9780 \begin_inset Flex CharStyle:Code
9781 status collapsed
9783 \begin_layout Plain Layout
9785 \end_layout
9787 \end_inset
9790 \end_layout
9792 \begin_layout Standard
9793 Unfortunately 
9794 \begin_inset Note Note
9795 status open
9797 \begin_layout Plain Layout
9798 fix this then
9799 \end_layout
9801 \end_inset
9803  the 
9804 \begin_inset Flex CharStyle:Code
9805 status collapsed
9807 \begin_layout Plain Layout
9808 =<\SpecialChar \ldots{}
9810 \end_layout
9812 \end_inset
9814  that we use re-enters a LaTeX parsing mode in which some characters are
9815  special, e.g.
9817 \begin_inset Flex CharStyle:Code
9818 status collapsed
9820 \begin_layout Plain Layout
9822 \backslash
9824 \end_layout
9826 \end_inset
9828 , and so these cause trouble if used in arguments to 
9829 \begin_inset Flex CharStyle:Code
9830 status collapsed
9832 \begin_layout Plain Layout
9834 \backslash
9835 chunkref
9836 \end_layout
9838 \end_inset
9841  At some point I must fix the LaTeX command 
9842 \begin_inset Flex CharStyle:Code
9843 status collapsed
9845 \begin_layout Plain Layout
9847 \backslash
9848 chunkref
9849 \end_layout
9851 \end_inset
9853  so that it can accept these literally, but until then, when writing chunkref
9854  argumemts that need these characters, I must use the forms 
9855 \begin_inset Flex CharStyle:Code
9856 status collapsed
9858 \begin_layout Plain Layout
9860 \backslash
9861 textbackslash{}
9862 \end_layout
9864 \end_inset
9866  and 
9867 \begin_inset Flex CharStyle:Code
9868 status collapsed
9870 \begin_layout Plain Layout
9872 \backslash
9874 \end_layout
9876 \end_inset
9878 ; so I also define a hacky chunk 
9879 \begin_inset Flex CharStyle:Code
9880 status collapsed
9882 \begin_layout Plain Layout
9883 delatex
9884 \end_layout
9886 \end_inset
9888  whose purpose it is to remove these from any arguments parsed by newfangle,
9889  and used further on.
9890 \end_layout
9892 \begin_layout Chunk
9893 delatex,params=text
9894 \end_layout
9896 \begin_layout Standard
9897 \begin_inset listings
9898 inline false
9899 status open
9901 \begin_layout Plain Layout
9903 # FILTHY HACK
9904 \end_layout
9906 \begin_layout Plain Layout
9908 gsub("
9909 \backslash
9911 \backslash
9913 \backslash
9915 \backslash
9916 #", "#", ${text});
9917 \end_layout
9919 \begin_layout Plain Layout
9921 gsub("
9922 \backslash
9924 \backslash
9926 \backslash
9928 \backslash
9929 textbackslash{}", "
9930 \backslash
9932 \backslash
9933 ", ${text});
9934 \end_layout
9936 \begin_layout Plain Layout
9938 gsub("
9939 \backslash
9941 \backslash
9943 \backslash
9945 \backslash
9947 \backslash
9949 \backslash
9950 ^", "^", ${text});
9951 \end_layout
9953 \end_inset
9956 \end_layout
9958 \begin_layout Standard
9959 As each chunk line may contain more than one chunk include, we will split
9960  out chunk includes in an iterative fashion
9961 \begin_inset Foot
9962 status collapsed
9964 \begin_layout Plain Layout
9965 Contrary to our use of 
9966 \begin_inset Flex CharStyle:Code
9967 status collapsed
9969 \begin_layout Plain Layout
9970 split
9971 \end_layout
9973 \end_inset
9975  when substituting parameters in chapter 
9976 \begin_inset CommandInset ref
9977 LatexCommand ref
9978 reference "Here-we-split"
9980 \end_inset
9983 \end_layout
9985 \end_inset
9988 \end_layout
9990 \begin_layout Standard
9991 First, as long as the chunk contains a 
9992 \begin_inset Flex CharStyle:Code
9993 status collapsed
9995 \begin_layout Plain Layout
9997 \backslash
9998 chunkref
9999 \end_layout
10001 \end_inset
10003  command we take as much as we can up to the first 
10004 \begin_inset Flex CharStyle:Code
10005 status collapsed
10007 \begin_layout Plain Layout
10009 \backslash
10010 chunkref
10011 \end_layout
10013 \end_inset
10015  command.
10016 \end_layout
10018 \begin_layout Chunk
10019 process-chunk
10020 \end_layout
10022 \begin_layout Standard
10023 \begin_inset listings
10024 inline false
10025 status open
10027 \begin_layout Plain Layout
10029 chunk = $0;
10030 \end_layout
10032 \begin_layout Plain Layout
10034 indent = 0;
10035 \end_layout
10037 \begin_layout Plain Layout
10039 while(match(chunk, 
10040 \end_layout
10042 \begin_layout Plain Layout
10044             "([=]<
10045 \backslash
10047 \backslash
10049 \backslash
10051 \backslash
10052 chunkref{([^}>]*)}(
10053 \backslash
10055 \backslash
10057 \backslash
10059 \backslash
10060 )|)>|<<([a-zA-Z_][-a-zA-Z0-9_]*)>>)", 
10061 \end_layout
10063 \begin_layout Plain Layout
10065             line)
10066 \backslash
10068 \end_layout
10070 \begin_layout Plain Layout
10072 ) {
10073 \end_layout
10075 \begin_layout Plain Layout
10077   chunklet = substr(chunk, 1, RSTART - 1);
10078 \end_layout
10080 \end_inset
10083 \end_layout
10085 \begin_layout Standard
10086 We keep track of the indent count, by counting the number of literal characters
10087  found.
10088  We can then preserve this indent on each output line when multi-line chunks
10089  are expanded.
10090 \end_layout
10092 \begin_layout Standard
10093 We then process this first part literal text, and set the chunk which is
10094  still to be processed to be the text after the 
10095 \begin_inset Flex CharStyle:Code
10096 status collapsed
10098 \begin_layout Plain Layout
10100 \backslash
10101 chunkref
10102 \end_layout
10104 \end_inset
10106  command, which we will process next as we continue around the loop.
10107 \end_layout
10109 \begin_layout Standard
10110 \begin_inset listings
10111 inline false
10112 status open
10114 \begin_layout Plain Layout
10116   indent += length(chunklet);
10117 \end_layout
10119 \begin_layout Plain Layout
10121   chunk_line(active_chunk, chunklet);
10122 \end_layout
10124 \begin_layout Plain Layout
10126   chunk = substr(chunk, RSTART + RLENGTH);
10127 \end_layout
10129 \end_inset
10132 \end_layout
10134 \begin_layout Standard
10135 We then consider the type of chunk command we have found, whether it is
10136  the newfangle style command beginning with 
10137 \begin_inset Flex CharStyle:Code
10138 status collapsed
10140 \begin_layout Plain Layout
10142 \end_layout
10144 \end_inset
10146  or the older notangle style beginning with 
10147 \begin_inset Flex CharStyle:Code
10148 status collapsed
10150 \begin_layout Plain Layout
10152 \end_layout
10154 \end_inset
10158 \end_layout
10160 \begin_layout Standard
10161 Newfangle chunks may have parameters contained within square brackets.
10162  These will be matched in 
10163 \begin_inset Flex CharStyle:Code
10164 status collapsed
10166 \begin_layout Plain Layout
10167 line[3]
10168 \end_layout
10170 \end_inset
10172  and are considered at this stage of processing to be part of the name of
10173  the chunk to be included.
10174 \end_layout
10176 \begin_layout Standard
10177 \begin_inset listings
10178 inline false
10179 status open
10181 \begin_layout Plain Layout
10183   if (substr(line[1], 1, 1) == "=") {
10184 \end_layout
10186 \begin_layout Plain Layout
10188     # chunk name up to }
10189 \end_layout
10191 \begin_layout Plain Layout
10193         =<
10194 \backslash
10195 chunkref{delatex}(line[3])>
10196 \end_layout
10198 \begin_layout Plain Layout
10200     chunk_include(active_chunk, line[2] line[3], indent);
10201 \end_layout
10203 \begin_layout Plain Layout
10205   } else if (substr(line[1], 1, 1) == "<") {
10206 \end_layout
10208 \begin_layout Plain Layout
10210     chunk_include(active_chunk, line[4], indent);
10211 \end_layout
10213 \begin_layout Plain Layout
10215   } else {
10216 \end_layout
10218 \begin_layout Plain Layout
10220     error("Unknown chunk fragment: " line[1]);
10221 \end_layout
10223 \begin_layout Plain Layout
10225   }
10226 \end_layout
10228 \end_inset
10231 \end_layout
10233 \begin_layout Standard
10234 The loop will continue until there are no more chunkref statements in the
10235  text, at which point we process the final part of the chunk.
10236 \end_layout
10238 \begin_layout Standard
10239 \begin_inset listings
10240 inline false
10241 status open
10243 \begin_layout Plain Layout
10246 \end_layout
10248 \begin_layout Plain Layout
10250 chunk_line(active_chunk, chunk);
10251 \end_layout
10253 \end_inset
10256 \end_layout
10258 \begin_layout Standard
10259 \begin_inset CommandInset label
10260 LatexCommand label
10261 name "lone-newline"
10263 \end_inset
10265 We add the newline character as a chunklet on it's own, to make it easier
10266  to detect new lines and thus manage indentation when processing the output.
10267 \end_layout
10269 \begin_layout Standard
10270 \begin_inset listings
10271 inline false
10272 status open
10274 \begin_layout Plain Layout
10276 chunk_line(active_chunk, "
10277 \backslash
10278 n");
10279 \end_layout
10281 \end_inset
10284 \end_layout
10286 \begin_layout Standard
10287 We will also permit a chunk-part number to follow in square brackets, so
10288  that 
10289 \begin_inset Flex CharStyle:Code
10290 status collapsed
10292 \begin_layout Plain Layout
10294 \backslash
10295 chunkref{chunk-name[1]}>
10296 \end_layout
10298 \end_inset
10300  will refer to the first part only.
10301  This can make it easy to include a C function prototype in a header file,
10302  if the first part of the chunk is just the function prototype without the
10303  trailing semi-colon.
10304  The header file would include the prototype with the trailing semi-colon,
10305  like this:
10306 \end_layout
10308 \begin_layout LyX-Code
10310 \backslash
10311 chunkref{chunk-name[1]}>;
10312 \end_layout
10314 \begin_layout Standard
10315 This is handled in section 
10316 \begin_inset CommandInset ref
10317 LatexCommand ref
10318 reference "sub:Chunk-parts"
10320 \end_inset
10323 \end_layout
10325 \begin_layout Standard
10326 We should perhaps introduce a notion of language specific chunk options;
10327  so that perhaps we could specify:
10328 \end_layout
10330 \begin_layout LyX-Code
10332 \backslash
10333 chunkref{chunk-name[function-declaration]}>;
10334 \end_layout
10336 \begin_layout Standard
10337 which applies a transform 
10338 \begin_inset Flex CharStyle:Code
10339 status collapsed
10341 \begin_layout Plain Layout
10342 function-declaration
10343 \end_layout
10345 \end_inset
10347  to the chunk --- which in this case would extract a function prototype
10348  from a function.
10349 \begin_inset Note Note
10350 status open
10352 \begin_layout Plain Layout
10353 So do it
10354 \end_layout
10356 \end_inset
10359 \end_layout
10361 \begin_layout Chapter
10362 Processing Options
10363 \end_layout
10365 \begin_layout Standard
10366 At the start, first we set the default options.
10367 \end_layout
10369 \begin_layout Chunk
10370 default-options
10371 \end_layout
10373 \begin_layout Standard
10374 \begin_inset listings
10375 inline false
10376 status open
10378 \begin_layout Plain Layout
10380 debug=0;
10381 \end_layout
10383 \begin_layout Plain Layout
10385 linenos=0;
10386 \end_layout
10388 \begin_layout Plain Layout
10390 notangle_mode=0;
10391 \end_layout
10393 \begin_layout Plain Layout
10395 root="*";
10396 \end_layout
10398 \begin_layout Plain Layout
10400 tabs = "";
10401 \end_layout
10403 \end_inset
10406 \end_layout
10408 \begin_layout Standard
10409 Then we use getopt the standard way, and null out ARGV afterwards in the
10410  normal AWK fashion.
10411 \end_layout
10413 \begin_layout Chunk
10414 read-options
10415 \end_layout
10417 \begin_layout Standard
10418 \begin_inset listings
10419 inline false
10420 status open
10422 \begin_layout Plain Layout
10424 Optind = 1    # skip ARGV[0]
10425 \end_layout
10427 \begin_layout Plain Layout
10429 while(getopt(ARGC, ARGV, "R:LdT:hr")!=-1) {
10430 \end_layout
10432 \begin_layout Plain Layout
10434   =<
10435 \backslash
10436 chunkref{handle-options}>
10437 \end_layout
10439 \begin_layout Plain Layout
10442 \end_layout
10444 \begin_layout Plain Layout
10446 for (i=1; i<Optind; i++) { ARGV[i]=""; }
10447 \end_layout
10449 \end_inset
10452 \end_layout
10454 \begin_layout Standard
10455 This is how we handle our options:
10456 \end_layout
10458 \begin_layout Chunk
10459 handle-options
10460 \end_layout
10462 \begin_layout Standard
10463 \begin_inset listings
10464 inline false
10465 status open
10467 \begin_layout Plain Layout
10469 if (Optopt == "R") root = Optarg;
10470 \end_layout
10472 \begin_layout Plain Layout
10474 else if (Optopt == "r") root="";
10475 \end_layout
10477 \begin_layout Plain Layout
10479 else if (Optopt == "L") linenos = 1;
10480 \end_layout
10482 \begin_layout Plain Layout
10484 else if (Optopt == "d") debug = 1;
10485 \end_layout
10487 \begin_layout Plain Layout
10489 else if (Optopt == "T") tabs = indent_string(Optarg+0);
10490 \end_layout
10492 \begin_layout Plain Layout
10494 else if (Optopt == "h") help();
10495 \end_layout
10497 \begin_layout Plain Layout
10499 else if (Optopt == "?") help();
10500 \end_layout
10502 \end_inset
10505 \end_layout
10507 \begin_layout Standard
10508 We do all of this at the beginning of the program
10509 \end_layout
10511 \begin_layout Chunk
10512 begin
10513 \end_layout
10515 \begin_layout Standard
10516 \begin_inset listings
10517 inline false
10518 status open
10520 \begin_layout Plain Layout
10522 BEGIN {
10523 \end_layout
10525 \begin_layout Plain Layout
10527   =<
10528 \backslash
10529 chunkref{constants}>
10530 \end_layout
10532 \begin_layout Plain Layout
10534   =<
10535 \backslash
10536 chunkref{mode-definitions}>
10537 \end_layout
10539 \begin_layout Plain Layout
10541   =<
10542 \backslash
10543 chunkref{default-options}>
10544 \end_layout
10546 \begin_layout Plain Layout
10548 \end_layout
10550 \begin_layout Plain Layout
10552   =<
10553 \backslash
10554 chunkref{read-options}>
10555 \end_layout
10557 \begin_layout Plain Layout
10560 \end_layout
10562 \end_inset
10565 \end_layout
10567 \begin_layout Standard
10568 And have a simple help function
10569 \end_layout
10571 \begin_layout Chunk
10572 help()
10573 \end_layout
10575 \begin_layout Standard
10576 \begin_inset listings
10577 inline false
10578 status open
10580 \begin_layout Plain Layout
10582 function help() {
10583 \end_layout
10585 \begin_layout Plain Layout
10587   print "Usage:"
10588 \end_layout
10590 \begin_layout Plain Layout
10592   print "  newfangle [-L] -R<rootname> [source.tex ...]"
10593 \end_layout
10595 \begin_layout Plain Layout
10597   print "  newfangle -r [source.tex ...]"
10598 \end_layout
10600 \begin_layout Plain Layout
10602   print "  If the filename, source.tex is not specified then stdin is used"
10603 \end_layout
10605 \begin_layout Plain Layout
10607   print
10608 \end_layout
10610 \begin_layout Plain Layout
10612   print "-L causes the C statement: #line <lineno> 
10613 \backslash
10614 "filename
10615 \backslash
10616 "" to be issued"
10617 \end_layout
10619 \begin_layout Plain Layout
10621   print "-R causes the named root to be written to stdout"
10622 \end_layout
10624 \begin_layout Plain Layout
10626   print "-r lists all roots in the file (even those used elsewhere)"
10627 \end_layout
10629 \begin_layout Plain Layout
10631   exit 1;
10632 \end_layout
10634 \begin_layout Plain Layout
10637 \end_layout
10639 \end_inset
10642 \end_layout
10644 \begin_layout Chapter
10645 Generating the output
10646 \end_layout
10648 \begin_layout Standard
10649 We generate output by calling output_chunk, or listing the chunk names.
10650 \end_layout
10652 \begin_layout Chunk
10653 generate-output
10654 \end_layout
10656 \begin_layout Standard
10657 \begin_inset listings
10658 inline false
10659 status open
10661 \begin_layout Plain Layout
10663 if (length(root)) output_chunk(root);
10664 \end_layout
10666 \begin_layout Plain Layout
10668 else output_chunk_names();
10669 \end_layout
10671 \end_inset
10674 \end_layout
10676 \begin_layout Standard
10677 We also have some other output debugging:
10678 \end_layout
10680 \begin_layout Chunk
10681 debug-output
10682 \end_layout
10684 \begin_layout Standard
10685 \begin_inset listings
10686 inline false
10687 status open
10689 \begin_layout Plain Layout
10691 if (debug) {
10692 \end_layout
10694 \begin_layout Plain Layout
10696   print "------ chunk names "
10697 \end_layout
10699 \begin_layout Plain Layout
10701   output_chunk_names();
10702 \end_layout
10704 \begin_layout Plain Layout
10706   print "====== chunks"
10707 \end_layout
10709 \begin_layout Plain Layout
10711   output_chunks();
10712 \end_layout
10714 \begin_layout Plain Layout
10716   print "++++++ debug"
10717 \end_layout
10719 \begin_layout Plain Layout
10721   for (a in chunks) {
10722 \end_layout
10724 \begin_layout Plain Layout
10726     print a "=" chunks[a];
10727 \end_layout
10729 \begin_layout Plain Layout
10731   }
10732 \end_layout
10734 \begin_layout Plain Layout
10737 \end_layout
10739 \end_inset
10742 \end_layout
10744 \begin_layout Standard
10745 We do both of these at the end.
10746  We also set 
10747 \begin_inset Flex CharStyle:Code
10748 status collapsed
10750 \begin_layout Plain Layout
10751 ORS=""
10752 \end_layout
10754 \end_inset
10756  because each chunklet is not necessarily a complete line, and we already
10757  added 
10758 \begin_inset Flex CharStyle:Code
10759 status collapsed
10761 \begin_layout Plain Layout
10763 \end_layout
10765 \end_inset
10767  to each input line in section 
10768 \begin_inset CommandInset ref
10769 LatexCommand ref
10770 reference "sub:ORS-chunk-text"
10772 \end_inset
10775 \end_layout
10777 \begin_layout Chunk
10779 \end_layout
10781 \begin_layout Standard
10782 \begin_inset listings
10783 inline false
10784 status open
10786 \begin_layout Plain Layout
10788 END {
10789 \end_layout
10791 \begin_layout Plain Layout
10793   =<
10794 \backslash
10795 chunkref{debug-output}>
10796 \end_layout
10798 \begin_layout Plain Layout
10800   ORS="";
10801 \end_layout
10803 \begin_layout Plain Layout
10805   =<
10806 \backslash
10807 chunkref{generate-output}>
10808 \end_layout
10810 \begin_layout Plain Layout
10813 \end_layout
10815 \end_inset
10818 \end_layout
10820 \begin_layout Standard
10821 We write chunk names like this.
10822  If we seem to be running in notangle compatibility mode, then we enclose
10823  the name like this 
10824 \begin_inset Flex CharStyle:Code
10825 status collapsed
10827 \begin_layout Plain Layout
10828 <<name>>
10829 \end_layout
10831 \end_inset
10833  the same way notangle does:
10834 \end_layout
10836 \begin_layout Chunk
10837 output_chunk_names()
10838 \end_layout
10840 \begin_layout Standard
10841 \begin_inset listings
10842 inline false
10843 status open
10845 \begin_layout Plain Layout
10847 function output_chunk_names(   c, prefix, suffix) 
10848 \end_layout
10850 \begin_layout Plain Layout
10853 \end_layout
10855 \begin_layout Plain Layout
10857   if (notangle_mode) {
10858 \end_layout
10860 \begin_layout Plain Layout
10862     prefix="<<";
10863 \end_layout
10865 \begin_layout Plain Layout
10867     suffix=">>";
10868 \end_layout
10870 \begin_layout Plain Layout
10872   }
10873 \end_layout
10875 \begin_layout Plain Layout
10877   for (c in chunk_names) {
10878 \end_layout
10880 \begin_layout Plain Layout
10882     print prefix c suffix "
10883 \backslash
10885 \end_layout
10887 \begin_layout Plain Layout
10889   }
10890 \end_layout
10892 \begin_layout Plain Layout
10895 \end_layout
10897 \end_inset
10900 \end_layout
10902 \begin_layout Standard
10903 This function would write out all chunks
10904 \end_layout
10906 \begin_layout Chunk
10907 output_chunks()
10908 \end_layout
10910 \begin_layout Standard
10911 \begin_inset listings
10912 inline false
10913 status open
10915 \begin_layout Plain Layout
10917 function output_chunks(  a) 
10918 \end_layout
10920 \begin_layout Plain Layout
10923 \end_layout
10925 \begin_layout Plain Layout
10927   for (a in chunk_names) {
10928 \end_layout
10930 \begin_layout Plain Layout
10932     output_chunk(chunk_names[a]);
10933 \end_layout
10935 \begin_layout Plain Layout
10937   }
10938 \end_layout
10940 \begin_layout Plain Layout
10943 \end_layout
10945 \begin_layout Plain Layout
10947 \end_layout
10949 \begin_layout Plain Layout
10951 function output_chunk(chunk) {
10952 \end_layout
10954 \begin_layout Plain Layout
10956   newline = 1;
10957 \end_layout
10959 \begin_layout Plain Layout
10961   lineno_needed = linenos;
10962 \end_layout
10964 \begin_layout Plain Layout
10966 \end_layout
10968 \begin_layout Plain Layout
10970   write_chunk(chunk);
10971 \end_layout
10973 \begin_layout Plain Layout
10976 \end_layout
10978 \begin_layout Plain Layout
10980 \end_layout
10982 \end_inset
10985 \end_layout
10987 \begin_layout Section
10988 Assembling the chunks
10989 \end_layout
10991 \begin_layout Standard
10992 \begin_inset Flex CharStyle:Code
10993 status collapsed
10995 \begin_layout Plain Layout
10996 chunk_path
10997 \end_layout
10999 \end_inset
11001  holds a string consisting of the names of all the chunks that resulted
11002  in this chunk being output.
11004 \begin_inset Note Note
11005 status collapsed
11007 \begin_layout Plain Layout
11008 Make sure it includes the line numbers too...
11010 \end_layout
11012 \end_inset
11014 It should probably also contain the source line numbers at which each inclusion
11015  also occured.
11016 \end_layout
11018 \begin_layout Chunk
11019 write_chunk()
11020 \end_layout
11022 \begin_layout Standard
11023 We first initialize the mode tracker for this chunk.
11024 \end_layout
11026 \begin_layout Standard
11027 \begin_inset listings
11028 inline false
11029 status open
11031 \begin_layout Plain Layout
11033 function write_chunk(chunk_name) {
11034 \end_layout
11036 \begin_layout Plain Layout
11038   =<
11039 \backslash
11040 chunkref{awk-delete-array}(context)>
11041 \end_layout
11043 \begin_layout Plain Layout
11045   return write_chunk_r(chunk_name, context);
11046 \end_layout
11048 \begin_layout Plain Layout
11051 \end_layout
11053 \end_inset
11056 \end_layout
11058 \begin_layout Chunk
11059 write_chunk(),emph={chunk_path}
11060 \end_layout
11062 \begin_layout Standard
11063 \begin_inset listings
11064 inline false
11065 status open
11067 \begin_layout Plain Layout
11069 function write_chunk_r(chunk_name, context, indent, tail,
11070 \end_layout
11072 \begin_layout Plain Layout
11074   # optional vars
11075 \end_layout
11077 \begin_layout Plain Layout
11079   chunk_path, chunk_args, 
11080 \end_layout
11082 \begin_layout Plain Layout
11084   s, r, src, new_src, 
11085 \end_layout
11087 \begin_layout Plain Layout
11089   # local vars
11090 \end_layout
11092 \begin_layout Plain Layout
11094   chunk_params, part, max_part, part_line, frag, max_frag, text, 
11095 \end_layout
11097 \begin_layout Plain Layout
11099   chunklet, only_part, call_chunk_args, new_context)
11100 \end_layout
11102 \begin_layout Plain Layout
11105 \end_layout
11107 \end_inset
11110 \end_layout
11112 \begin_layout Subsection
11113 \begin_inset CommandInset label
11114 LatexCommand label
11115 name "sub:Chunk-parts"
11117 \end_inset
11119 Chunk parts
11120 \end_layout
11122 \begin_layout Standard
11123 As mentioned in section 
11124 \begin_inset CommandInset ref
11125 LatexCommand ref
11126 reference "sub:lstlistings-includes"
11128 \end_inset
11130 , a chunk name may contain a part specifier in square brackets, limiting
11131  the parts that should be emitted.
11132 \end_layout
11134 \begin_layout Standard
11135 \begin_inset listings
11136 inline false
11137 status open
11139 \begin_layout Plain Layout
11141   if (match(chunk_name, "^(.*)
11142 \backslash
11144 \backslash
11145 [([0-9]*)
11146 \backslash
11148 \backslash
11149 ]$", chunk_name_parts)) {
11150 \end_layout
11152 \begin_layout Plain Layout
11154     chunk_name = chunk_name_parts[1];
11155 \end_layout
11157 \begin_layout Plain Layout
11159     only_part = chunk_name_parts[2];
11160 \end_layout
11162 \begin_layout Plain Layout
11164   }
11165 \end_layout
11167 \end_inset
11170 \end_layout
11172 \begin_layout Standard
11173 We then create a mode tracker 
11174 \end_layout
11176 \begin_layout Standard
11177 \begin_inset listings
11178 inline false
11179 status open
11181 \begin_layout Plain Layout
11183   =<
11184 \backslash
11185 chunkref{new-mode-tracker}(context, chunks[chunk_name, "language"], "")>
11186 \end_layout
11188 \end_inset
11191 \end_layout
11193 \begin_layout Standard
11194 We extract into 
11195 \begin_inset Flex CharStyle:Code
11196 status collapsed
11198 \begin_layout Plain Layout
11199 chunk_params
11200 \end_layout
11202 \end_inset
11204  the names of the parameters that this chunk accepts, whose values were
11205  (optionally) passed in 
11206 \begin_inset Flex CharStyle:Code
11207 status collapsed
11209 \begin_layout Plain Layout
11210 chunk_args
11211 \end_layout
11213 \end_inset
11216 \end_layout
11218 \begin_layout Standard
11219 \begin_inset listings
11220 inline false
11221 status open
11223 \begin_layout Plain Layout
11225   split(chunks[chunk_name, "params"], chunk_params, " *; *");
11226 \end_layout
11228 \end_inset
11231 \end_layout
11233 \begin_layout Standard
11234 To assemble a chunk, we write out each part.
11235 \end_layout
11237 \begin_layout Chunk
11238 write_chunk()
11239 \end_layout
11241 \begin_layout Standard
11242 \begin_inset listings
11243 inline false
11244 status open
11246 \begin_layout Plain Layout
11248   if (! (chunk_name in chunk_names)) {
11249 \end_layout
11251 \begin_layout Plain Layout
11253     error(sprintf(_"The root module <<%s>> was not defined.
11254 \backslash
11255 nUsed by: %s",
11256 \backslash
11258 \end_layout
11260 \begin_layout Plain Layout
11262                   chunk_name, chunk_path));
11263 \end_layout
11265 \begin_layout Plain Layout
11267   }
11268 \end_layout
11270 \begin_layout Plain Layout
11272 \end_layout
11274 \begin_layout Plain Layout
11276   max_part = chunks[chunk_name, "part"];
11277 \end_layout
11279 \begin_layout Plain Layout
11281   for(part = 1; part <= max_part; part++) {
11282 \end_layout
11284 \begin_layout Plain Layout
11286     if (! only_part || part == only_part) {
11287 \end_layout
11289 \begin_layout Plain Layout
11291       =<
11292 \backslash
11293 chunkref{write-part}>
11294 \end_layout
11296 \begin_layout Plain Layout
11298     }
11299 \end_layout
11301 \begin_layout Plain Layout
11303   }
11304 \end_layout
11306 \begin_layout Plain Layout
11308   if (! finalize_mode_tracker(context)) {
11309 \end_layout
11311 \begin_layout Plain Layout
11313     dump_mode_tracker(context);
11314 \end_layout
11316 \begin_layout Plain Layout
11318     error(sprintf(_"Module %s did not close context properly.
11319 \backslash
11320 nUsed by: %s
11321 \backslash
11322 n", chunk_name, chunk_path));
11323 \end_layout
11325 \begin_layout Plain Layout
11327   }
11328 \end_layout
11330 \begin_layout Plain Layout
11333 \end_layout
11335 \end_inset
11338 \end_layout
11340 \begin_layout Standard
11341 A part can either be a chunklet of lines, or an include of another chunk.
11342 \end_layout
11344 \begin_layout Standard
11345 Chunks may also have parameters, specified in LaTeX style with braces after
11346  the chunk name --- looking like this in the document: 
11347 \begin_inset Flex CharStyle:Code
11348 status collapsed
11350 \begin_layout Plain Layout
11351 chunkname{param1, param2}
11352 \end_layout
11354 \end_inset
11357  Arguments are passed in square brackets: 
11358 \begin_inset Flex CharStyle:Code
11359 status collapsed
11361 \begin_layout Plain Layout
11363 \backslash
11364 chunkref{chunkname}[arg1, arg2]
11365 \end_layout
11367 \end_inset
11370 \end_layout
11372 \begin_layout Standard
11373 Before we process each part, we check that the source position hasn't changed
11374  unexpectedly, so that we can know if we need to output a new file-line
11375  directive.
11376 \end_layout
11378 \begin_layout Chunk
11379 write-part
11380 \end_layout
11382 \begin_layout Standard
11383 \begin_inset listings
11384 inline false
11385 status open
11387 \begin_layout Plain Layout
11390 \backslash
11391 chunkref{check-source-jump}>
11392 \end_layout
11394 \begin_layout Plain Layout
11396 \end_layout
11398 \begin_layout Plain Layout
11400 chunklet = chunks[chunk_name, "part", part];
11401 \end_layout
11403 \begin_layout Plain Layout
11405 if (chunks[chunk_name, "part", part, "type"] == part_type_chunk) {
11406 \end_layout
11408 \begin_layout Plain Layout
11410   =<
11411 \backslash
11412 chunkref{write-included-chunk}>
11413 \end_layout
11415 \begin_layout Plain Layout
11417 } else if (chunklet SUBSEP "line" in chunks) {
11418 \end_layout
11420 \begin_layout Plain Layout
11422   =<
11423 \backslash
11424 chunkref{write-chunklets}>
11425 \end_layout
11427 \begin_layout Plain Layout
11429 } else {
11430 \end_layout
11432 \begin_layout Plain Layout
11434   # empty last chunklet
11435 \end_layout
11437 \begin_layout Plain Layout
11440 \end_layout
11442 \end_inset
11445 \end_layout
11447 \begin_layout Standard
11448 To write an included chunk, we must detect any optional chunk arguments
11449  in parenthesis.
11450  Then we recurse calling 
11451 \begin_inset Flex Chunkref
11452 status collapsed
11454 \begin_layout Plain Layout
11455 write_chunk()
11456 \end_layout
11458 \end_inset
11461 \end_layout
11463 \begin_layout Chunk
11464 write-included-chunk
11465 \end_layout
11467 \begin_layout Standard
11468 \begin_inset listings
11469 inline false
11470 status open
11472 \begin_layout Plain Layout
11474 if (match(chunklet, "^([^
11475 \backslash
11477 \backslash
11479 \backslash
11481 \backslash
11482 (]*)
11483 \backslash
11485 \backslash
11486 ((.*)
11487 \backslash
11489 \backslash
11490 )$", chunklet_parts)) {
11491 \end_layout
11493 \begin_layout Plain Layout
11495   chunklet = chunklet_parts[1];
11496 \end_layout
11498 \begin_layout Plain Layout
11500   parse_chunk_args("c-like", chunklet_parts[2], call_chunk_args, "(");
11501 \end_layout
11503 \begin_layout Plain Layout
11505   for (c in call_chunk_args) {
11506 \end_layout
11508 \begin_layout Plain Layout
11510     call_chunk_args[c] = expand_chunk_args(call_chunk_args[c], chunk_params,
11511  chunk_args);
11512 \end_layout
11514 \begin_layout Plain Layout
11516   }
11517 \end_layout
11519 \begin_layout Plain Layout
11521 } else {
11522 \end_layout
11524 \begin_layout Plain Layout
11526   split("", call_chunk_args);
11527 \end_layout
11529 \begin_layout Plain Layout
11532 \end_layout
11534 \begin_layout Plain Layout
11536 # update the transforms arrays
11537 \end_layout
11539 \begin_layout Plain Layout
11541 new_src = mode_escaper(context, s, r, src);
11542 \end_layout
11544 \begin_layout Plain Layout
11547 \backslash
11548 chunkref{awk-delete-array}(new_context)>
11549 \end_layout
11551 \begin_layout Plain Layout
11553 write_chunk_r(chunklet, new_context,
11554 \end_layout
11556 \begin_layout Plain Layout
11558             chunks[chunk_name, "part", part, "indent"] indent,
11559 \end_layout
11561 \begin_layout Plain Layout
11563             chunks[chunk_name, "part", part, "tail"],
11564 \end_layout
11566 \begin_layout Plain Layout
11568             chunk_path "
11569 \backslash
11570 n         " chunk_name,
11571 \end_layout
11573 \begin_layout Plain Layout
11575             call_chunk_args,
11576 \end_layout
11578 \begin_layout Plain Layout
11580                         s, r, new_src);
11581 \end_layout
11583 \end_inset
11586 \end_layout
11588 \begin_layout Standard
11589 Before we output a chunklet of lines, we first emit the file and line number
11590  if we have one, and if it is safe to do so.
11592 \end_layout
11594 \begin_layout Standard
11595 Chunklets are generally broken up by includes, so the start of a chunklet
11596  is a good place to do this.
11597  Then we output each line of the chunklet.
11598 \end_layout
11600 \begin_layout Standard
11601 When it is not safe, such as in the middle of a multi-line macro definition,
11603 \begin_inset Flex CharStyle:Code
11604 status collapsed
11606 \begin_layout Plain Layout
11607 lineno_suppressed
11608 \end_layout
11610 \end_inset
11612  is set to true, and in such a case we note that we want to emit the line
11613  statement when it is next safe.
11614 \end_layout
11616 \begin_layout Chunk
11617 write-chunklets
11618 \end_layout
11620 \begin_layout Standard
11621 \begin_inset listings
11622 inline false
11623 status open
11625 \begin_layout Plain Layout
11627 max_frag = chunks[chunklet, "line"];
11628 \end_layout
11630 \begin_layout Plain Layout
11632 for(frag = 1; frag <= max_frag; frag++) {
11633 \end_layout
11635 \begin_layout Plain Layout
11637   =<
11638 \backslash
11639 chunkref{write-file-line}>
11640 \end_layout
11642 \end_inset
11645 \end_layout
11647 \begin_layout Standard
11648 We then extract the chunklet text and expand any arguments.
11649 \end_layout
11651 \begin_layout Standard
11652 \begin_inset listings
11653 inline false
11654 status open
11656 \begin_layout Plain Layout
11658 \end_layout
11660 \begin_layout Plain Layout
11662   text = chunks[chunklet, frag];
11663 \end_layout
11665 \begin_layout Plain Layout
11668 \end_layout
11670 \begin_layout Plain Layout
11672   /* check params */
11673 \end_layout
11675 \begin_layout Plain Layout
11677   text = expand_chunk_args(text, chunk_params, chunk_args);
11678 \end_layout
11680 \end_inset
11683 \end_layout
11685 \begin_layout Standard
11686 If the text is a single newline (which we keep separate - see 
11687 \begin_inset CommandInset ref
11688 LatexCommand ref
11689 reference "lone-newline"
11691 \end_inset
11693 ) then we increment the line number.
11694  In the case where this is the last line of a chunk and it is not a top-level
11695  chunk we replace the newline with an empty string --- because the chunk
11696  that included this chunk will have the newline at the end of the line that
11697  included this chunk.
11698 \end_layout
11700 \begin_layout Standard
11701 We also note by 
11702 \begin_inset Flex CharStyle:Code
11703 status collapsed
11705 \begin_layout Plain Layout
11706 newline = 1
11707 \end_layout
11709 \end_inset
11711  that we have started a new line, so that indentation can be managed with
11712  the following piece of text.
11713 \end_layout
11715 \begin_layout Standard
11716 \begin_inset listings
11717 inline false
11718 status open
11720 \begin_layout Plain Layout
11722 \end_layout
11724 \begin_layout Plain Layout
11726  if (text == "
11727 \backslash
11728 n") {
11729 \end_layout
11731 \begin_layout Plain Layout
11733     lineno++;
11734 \end_layout
11736 \begin_layout Plain Layout
11738     if (part == max_part && frag == max_frag && length(chunk_path)) {
11739 \end_layout
11741 \begin_layout Plain Layout
11743       text = "";
11744 \end_layout
11746 \begin_layout Plain Layout
11748       break;
11749 \end_layout
11751 \begin_layout Plain Layout
11753     } else {
11754 \end_layout
11756 \begin_layout Plain Layout
11758       newline = 1;
11759 \end_layout
11761 \begin_layout Plain Layout
11763     }
11764 \end_layout
11766 \end_inset
11769 \end_layout
11771 \begin_layout Standard
11772 If this text does not represent a newline, but we see that we are the first
11773  piece of text on a newline, then we prefix our text with the current indent.
11774  NOTE: 
11775 \begin_inset Flex CharStyle:Code
11776 status collapsed
11778 \begin_layout Plain Layout
11779 newline
11780 \end_layout
11782 \end_inset
11784  is a global output-state variable, but the 
11785 \begin_inset Flex CharStyle:Code
11786 status collapsed
11788 \begin_layout Plain Layout
11789 indent
11790 \end_layout
11792 \end_inset
11794  is not.
11796 \end_layout
11798 \begin_layout Standard
11799 \begin_inset listings
11800 inline false
11801 status open
11803 \begin_layout Plain Layout
11805   } else if (length(text) || length(tail)) {
11806 \end_layout
11808 \begin_layout Plain Layout
11810     if (newline) text = indent text;
11811 \end_layout
11813 \begin_layout Plain Layout
11815     newline = 0;
11816 \end_layout
11818 \begin_layout Plain Layout
11820   }
11821 \end_layout
11823 \begin_layout Plain Layout
11825 \end_layout
11827 \end_inset
11830 \end_layout
11832 \begin_layout Standard
11833 Tail will soon no longer be relevant once mode-detection is in place.
11834 \end_layout
11836 \begin_layout Standard
11837 \begin_inset listings
11838 inline false
11839 status open
11841 \begin_layout Plain Layout
11843   text = text tail;
11844 \end_layout
11846 \begin_layout Plain Layout
11848   mode_tracker(context, text);
11849 \end_layout
11851 \begin_layout Plain Layout
11853   print transform_escape(s, r, text, src);
11854 \end_layout
11856 \end_inset
11859 \end_layout
11861 \begin_layout Standard
11862 If a line ends in a backslash --- suggesting continuation --- then we supress
11863  outputting file-line as it would probably break the continued lines.
11865 \end_layout
11867 \begin_layout Standard
11868 \begin_inset listings
11869 inline false
11870 status open
11872 \begin_layout Plain Layout
11874   if (linenos) {
11875 \end_layout
11877 \begin_layout Plain Layout
11879     lineno_suppressed = substr(lastline, length(lastline)) == "
11880 \backslash
11882 \backslash
11884 \end_layout
11886 \begin_layout Plain Layout
11888   }
11889 \end_layout
11891 \begin_layout Plain Layout
11894 \end_layout
11896 \end_inset
11899 \end_layout
11901 \begin_layout Standard
11902 Of course there is no point in actually outputting the source filename and
11903  line number (file-line) if they don't say anything new! We only need to
11904  emit them if they aren't what is expected, or if we we not able to emit
11905  one when they had changed.
11906 \end_layout
11908 \begin_layout Chunk
11909 write-file-line
11910 \end_layout
11912 \begin_layout Standard
11913 \begin_inset listings
11914 inline false
11915 status open
11917 \begin_layout Plain Layout
11919 if (newline && lineno_needed && ! lineno_suppressed) {
11920 \end_layout
11922 \begin_layout Plain Layout
11924   filename = a_filename;
11925 \end_layout
11927 \begin_layout Plain Layout
11929   lineno = a_lineno;
11930 \end_layout
11932 \begin_layout Plain Layout
11934   print "#line " lineno " 
11935 \backslash
11936 "" filename "
11937 \backslash
11939 \backslash
11941 \end_layout
11943 \begin_layout Plain Layout
11945   lineno_needed = 0;
11946 \end_layout
11948 \begin_layout Plain Layout
11951 \end_layout
11953 \end_inset
11956 \end_layout
11958 \begin_layout Standard
11959 We check if a new file-line is needed by checking if the source line matches
11960  what we (or a compiler) would expect.
11962 \end_layout
11964 \begin_layout Chunk
11965 check-source-jump
11966 \end_layout
11968 \begin_layout Standard
11969 \begin_inset listings
11970 inline false
11971 status open
11973 \begin_layout Plain Layout
11975 if (linenos && (chunk_name SUBSEP "part" SUBSEP part SUBSEP "FILENAME" in
11976  chunks)) {
11977 \end_layout
11979 \begin_layout Plain Layout
11981   a_filename = chunks[chunk_name, "part", part, "FILENAME"];
11982 \end_layout
11984 \begin_layout Plain Layout
11986   a_lineno = chunks[chunk_name, "part", part, "LINENO"];
11987 \end_layout
11989 \begin_layout Plain Layout
11991   if (a_filename != filename || a_lineno != lineno) {
11992 \end_layout
11994 \begin_layout Plain Layout
11996     lineno_needed++;
11997 \end_layout
11999 \begin_layout Plain Layout
12001   }
12002 \end_layout
12004 \begin_layout Plain Layout
12007 \end_layout
12009 \end_inset
12012 \end_layout
12014 \begin_layout Chapter
12015 Storing chunks
12016 \end_layout
12018 \begin_layout Standard
12019 Awk has pretty limited data structures, so we will use two main hashes.
12020  Uninterrupted sequences of a chunk will be stored in 
12021 \begin_inset Flex CharStyle:Code
12022 status collapsed
12024 \begin_layout Plain Layout
12025 chunklets
12026 \end_layout
12028 \end_inset
12030  and the chunklets used in a chunk will be stored in 
12031 \begin_inset Flex CharStyle:Code
12032 status collapsed
12034 \begin_layout Plain Layout
12035 chunks
12036 \end_layout
12038 \end_inset
12041 \end_layout
12043 \begin_layout Chunk
12044 constants
12045 \end_layout
12047 \begin_layout Standard
12048 \begin_inset listings
12049 inline false
12050 status open
12052 \begin_layout Plain Layout
12054 part_type_chunk=1;
12055 \end_layout
12057 \begin_layout Plain Layout
12059 SUBSEP=",";
12060 \end_layout
12062 \end_inset
12065 \end_layout
12067 \begin_layout Standard
12068 The 
12069 \begin_inset Flex CharStyle:Code
12070 status collapsed
12072 \begin_layout Plain Layout
12073 params
12074 \end_layout
12076 \end_inset
12078  mentioned are not chunk parameters for parameterized chunks, as mentioned
12079  in 
12080 \begin_inset CommandInset ref
12081 LatexCommand ref
12082 reference "cha:Chunk Arguments"
12084 \end_inset
12086 , but the lstlistings style parameters used in the 
12087 \begin_inset Flex CharStyle:Code
12088 status collapsed
12090 \begin_layout Plain Layout
12092 \backslash
12093 Chunk
12094 \end_layout
12096 \end_inset
12098  command
12099 \begin_inset Foot
12100 status collapsed
12102 \begin_layout Plain Layout
12103 The 
12104 \begin_inset Flex CharStyle:Code
12105 status collapsed
12107 \begin_layout Plain Layout
12108 params
12109 \end_layout
12111 \end_inset
12113  parameter is used to hold the parameters for parameterized chunks
12114 \end_layout
12116 \end_inset
12119 \end_layout
12121 \begin_layout Chunk
12122 chunk-storage-functions
12123 \end_layout
12125 \begin_layout Standard
12126 \begin_inset listings
12127 inline false
12128 status open
12130 \begin_layout Plain Layout
12132 function new_chunk(chunk_name, params,
12133 \end_layout
12135 \begin_layout Plain Layout
12137   # local vars
12138 \end_layout
12140 \begin_layout Plain Layout
12142   p, append )
12143 \end_layout
12145 \begin_layout Plain Layout
12148 \end_layout
12150 \begin_layout Plain Layout
12152   # HACK WHILE WE CHANGE TO ( ) for PARAM CHUNKS
12153 \end_layout
12155 \begin_layout Plain Layout
12157   gsub("
12158 \backslash
12160 \backslash
12162 \backslash
12164 \backslash
12165 )$", "", chunk_name);
12166 \end_layout
12168 \begin_layout Plain Layout
12170   if (! (chunk_name in chunk_names)) {
12171 \end_layout
12173 \begin_layout Plain Layout
12175     if (debug) print "New chunk " chunk_name;
12176 \end_layout
12178 \begin_layout Plain Layout
12180     chunk_names[chunk_name];
12181 \end_layout
12183 \begin_layout Plain Layout
12185     for (p in params) {
12186 \end_layout
12188 \begin_layout Plain Layout
12190       chunks[chunk_name, p] = params[p];
12191 \end_layout
12193 \begin_layout Plain Layout
12195     }
12196 \end_layout
12198 \begin_layout Plain Layout
12200     if ("append" in params) {
12201 \end_layout
12203 \begin_layout Plain Layout
12205       append=params["append"];
12206 \end_layout
12208 \begin_layout Plain Layout
12210       if (! (append in chunk_names)) {
12211 \end_layout
12213 \begin_layout Plain Layout
12215         warning("Chunk " chunk_name " is appended to chunk " append " which
12216  is not defined yet");
12217 \end_layout
12219 \begin_layout Plain Layout
12221         new_chunk(append);
12222 \end_layout
12224 \begin_layout Plain Layout
12226       }
12227 \end_layout
12229 \begin_layout Plain Layout
12231       chunk_include(append, chunk_name);
12232 \end_layout
12234 \begin_layout Plain Layout
12236       chunk_line(append, ORS);
12237 \end_layout
12239 \begin_layout Plain Layout
12241     }
12242 \end_layout
12244 \begin_layout Plain Layout
12246   }
12247 \end_layout
12249 \begin_layout Plain Layout
12251   active_chunk = chunk_name;
12252 \end_layout
12254 \begin_layout Plain Layout
12256   prime_chunk(chunk_name);
12257 \end_layout
12259 \begin_layout Plain Layout
12262 \end_layout
12264 \end_inset
12267 \end_layout
12269 \begin_layout Standard
12270 \begin_inset listings
12271 inline false
12272 status open
12274 \begin_layout Plain Layout
12276 \end_layout
12278 \begin_layout Plain Layout
12280 function prime_chunk(chunk_name)
12281 \end_layout
12283 \begin_layout Plain Layout
12286 \end_layout
12288 \begin_layout Plain Layout
12290   chunks[chunk_name, "part", ++chunks[chunk_name, "part"] ] = 
12291 \backslash
12293 \end_layout
12295 \begin_layout Plain Layout
12297          chunk_name SUBSEP "chunklet" SUBSEP "" ++chunks[chunk_name, "chunklet"]
12299 \end_layout
12301 \begin_layout Plain Layout
12303   chunks[chunk_name, "part", chunks[chunk_name, "part"], "FILENAME"] = FILENAME;
12304 \end_layout
12306 \begin_layout Plain Layout
12308   chunks[chunk_name, "part", chunks[chunk_name, "part"], "LINENO"] = FNR
12309  + 1;
12310 \end_layout
12312 \begin_layout Plain Layout
12315 \end_layout
12317 \begin_layout Plain Layout
12319 \end_layout
12321 \begin_layout Plain Layout
12323 function chunk_line(chunk_name, line){
12324 \end_layout
12326 \begin_layout Plain Layout
12328   chunks[chunk_name, "chunklet", chunks[chunk_name, "chunklet"],
12329 \end_layout
12331 \begin_layout Plain Layout
12333          ++chunks[chunk_name, "chunklet", chunks[chunk_name, "chunklet"],
12334  "line"]  ] = line;
12335 \end_layout
12337 \begin_layout Plain Layout
12340 \end_layout
12342 \begin_layout Plain Layout
12344 \end_layout
12346 \end_inset
12349 \end_layout
12351 \begin_layout Standard
12352 Chunk include represents a 
12353 \emph on
12354 chunkref
12355 \emph default
12356  statement, and stores the requirement to include another chunk.
12357  The parameter indent represents the quanity of literal text characters
12358  that preceded this 
12359 \emph on
12360 chunkref
12361 \emph default
12362  statement and therefore by how much additional lines of the included chunk
12363  should be indented.
12364 \end_layout
12366 \begin_layout Standard
12367 \begin_inset listings
12368 inline false
12369 status open
12371 \begin_layout Plain Layout
12373 function chunk_include(chunk_name, chunk_ref, indent, tail)
12374 \end_layout
12376 \begin_layout Plain Layout
12379 \end_layout
12381 \begin_layout Plain Layout
12383   chunks[chunk_name, "part", ++chunks[chunk_name, "part"] ] = chunk_ref;
12384 \end_layout
12386 \begin_layout Plain Layout
12388   chunks[chunk_name, "part", chunks[chunk_name, "part"], "type" ] = part_type_ch
12389 unk;
12390 \end_layout
12392 \begin_layout Plain Layout
12394   chunks[chunk_name, "part", chunks[chunk_name, "part"], "indent" ] = indent_str
12395 ing(indent);
12396 \end_layout
12398 \begin_layout Plain Layout
12400   chunks[chunk_name, "part", chunks[chunk_name, "part"], "tail" ] = tail;
12401 \end_layout
12403 \begin_layout Plain Layout
12405   prime_chunk(chunk_name);
12406 \end_layout
12408 \begin_layout Plain Layout
12411 \end_layout
12413 \begin_layout Plain Layout
12415 \end_layout
12417 \end_inset
12420 \end_layout
12422 \begin_layout Standard
12423 The indent is calculated by indent_string, which may in future convert some
12424  spaces into tab characters.
12425  This function works by generating a printf padded format string, like 
12426 \begin_inset Flex CharStyle:Code
12427 status collapsed
12429 \begin_layout Plain Layout
12430 %22s
12431 \end_layout
12433 \end_inset
12435  for an indent of 22, and then printing an empty string using that format.
12436 \end_layout
12438 \begin_layout Standard
12439 \begin_inset listings
12440 inline false
12441 status open
12443 \begin_layout Plain Layout
12445 function indent_string(indent) {
12446 \end_layout
12448 \begin_layout Plain Layout
12450   return sprintf("%" indent "s", "");
12451 \end_layout
12453 \begin_layout Plain Layout
12456 \end_layout
12458 \end_inset
12461 \end_layout
12463 \begin_layout Chapter
12464 \begin_inset CommandInset label
12465 LatexCommand label
12466 name "cha:getopt"
12468 \end_inset
12470 getopt
12471 \end_layout
12473 \begin_layout Standard
12474 I use Arnold Robbins public domain getopt (1993 revision).
12475  This is probably the same one that is covered in chapter 12 of 
12476 \begin_inset Quotes eld
12477 \end_inset
12479 Edition 3 of GAWK: Effective AWK Programming: A User's Guide for GNU Awk
12480 \begin_inset Quotes erd
12481 \end_inset
12483  but as that is licensed under the GNU Free Documentation License, Version
12484  1.3, which conflicts with the GPL3, I can't use it from there (or it's accompany
12485 ing explanations), so I do my best to explain how it works here.
12486 \end_layout
12488 \begin_layout Standard
12489 The getopt.awk header is:
12490 \end_layout
12492 \begin_layout Chunk
12493 getopt.awk-header,language=awk,morestring=[b]{/},morekeywords=else
12494 \end_layout
12496 \begin_layout Standard
12497 \begin_inset listings
12498 inline false
12499 status open
12501 \begin_layout Plain Layout
12503 # getopt.awk --- do C library getopt(3) function in awk
12504 \end_layout
12506 \begin_layout Plain Layout
12509 \end_layout
12511 \begin_layout Plain Layout
12513 # Arnold Robbins, arnold@skeeve.com, Public Domain
12514 \end_layout
12516 \begin_layout Plain Layout
12519 \end_layout
12521 \begin_layout Plain Layout
12523 # Initial version: March, 1991
12524 \end_layout
12526 \begin_layout Plain Layout
12528 # Revised: May, 1993
12529 \end_layout
12531 \begin_layout Plain Layout
12533 \end_layout
12535 \end_inset
12538 \end_layout
12540 \begin_layout Standard
12541 The provided explanation is:
12542 \end_layout
12544 \begin_layout Chunk
12545 getopt.awk-notes
12546 \end_layout
12548 \begin_layout Standard
12549 \begin_inset listings
12550 inline false
12551 status open
12553 \begin_layout Plain Layout
12555 # External variables:
12556 \end_layout
12558 \begin_layout Plain Layout
12560 #    Optind -- index in ARGV of first nonoption argument
12561 \end_layout
12563 \begin_layout Plain Layout
12565 #    Optarg -- string value of argument to current option
12566 \end_layout
12568 \begin_layout Plain Layout
12570 #    Opterr -- if nonzero, print our own diagnostic
12571 \end_layout
12573 \begin_layout Plain Layout
12575 #    Optopt -- current option letter
12576 \end_layout
12578 \begin_layout Plain Layout
12580 \end_layout
12582 \begin_layout Plain Layout
12584 # Returns:
12585 \end_layout
12587 \begin_layout Plain Layout
12589 #    -1     at end of options
12590 \end_layout
12592 \begin_layout Plain Layout
12594 #    ?      for unrecognized option
12595 \end_layout
12597 \begin_layout Plain Layout
12599 #    <c>    a character representing the current option
12600 \end_layout
12602 \begin_layout Plain Layout
12604 \end_layout
12606 \begin_layout Plain Layout
12608 # Private Data:
12609 \end_layout
12611 \begin_layout Plain Layout
12613 #    _opti  -- index in multi-flag option, e.g., -abc
12614 \end_layout
12616 \begin_layout Plain Layout
12618 \end_layout
12620 \end_inset
12623 \end_layout
12625 \begin_layout Standard
12626 The function follows.
12627  The final two parameters, 
12628 \begin_inset Flex CharStyle:Code
12629 status collapsed
12631 \begin_layout Plain Layout
12632 thisopt
12633 \end_layout
12635 \end_inset
12637  and 
12638 \begin_inset Flex CharStyle:Code
12639 status collapsed
12641 \begin_layout Plain Layout
12643 \end_layout
12645 \end_inset
12647  are local variables and not parameters --- as indicated by the multiple
12648  spaces preceding them.
12649  Awk doesn't care, the multiple spaces are a convention to help us humans.
12650 \end_layout
12652 \begin_layout Chunk
12653 getopt.awk-getopt()
12654 \end_layout
12656 \begin_layout Standard
12657 \begin_inset listings
12658 inline false
12659 status open
12661 \begin_layout Plain Layout
12663 function getopt(argc, argv, options,    thisopt, i)
12664 \end_layout
12666 \begin_layout Plain Layout
12669 \end_layout
12671 \begin_layout Plain Layout
12673     if (length(options) == 0)    # no options given
12674 \end_layout
12676 \begin_layout Plain Layout
12678         return -1
12679 \end_layout
12681 \begin_layout Plain Layout
12683     if (argv[Optind] == "--") {  # all done
12684 \end_layout
12686 \begin_layout Plain Layout
12688         Optind++
12689 \end_layout
12691 \begin_layout Plain Layout
12693         _opti = 0
12694 \end_layout
12696 \begin_layout Plain Layout
12698         return -1
12699 \end_layout
12701 \begin_layout Plain Layout
12703     } else if (argv[Optind] !~ /^-[^: 
12704 \backslash
12706 \backslash
12708 \backslash
12710 \backslash
12712 \backslash
12714 \backslash
12715 b]/) {
12716 \end_layout
12718 \begin_layout Plain Layout
12720         _opti = 0
12721 \end_layout
12723 \begin_layout Plain Layout
12725         return -1
12726 \end_layout
12728 \begin_layout Plain Layout
12730     }
12731 \end_layout
12733 \begin_layout Plain Layout
12735     if (_opti == 0)
12736 \end_layout
12738 \begin_layout Plain Layout
12740         _opti = 2
12741 \end_layout
12743 \begin_layout Plain Layout
12745     thisopt = substr(argv[Optind], _opti, 1)
12746 \end_layout
12748 \begin_layout Plain Layout
12750     Optopt = thisopt
12751 \end_layout
12753 \begin_layout Plain Layout
12755     i = index(options, thisopt)
12756 \end_layout
12758 \begin_layout Plain Layout
12760     if (i == 0) {
12761 \end_layout
12763 \begin_layout Plain Layout
12765         if (Opterr)
12766 \end_layout
12768 \begin_layout Plain Layout
12770             printf("%c -- invalid option
12771 \backslash
12773 \end_layout
12775 \begin_layout Plain Layout
12777                                   thisopt) > "/dev/stderr"
12778 \end_layout
12780 \begin_layout Plain Layout
12782         if (_opti >= length(argv[Optind])) {
12783 \end_layout
12785 \begin_layout Plain Layout
12787             Optind++
12788 \end_layout
12790 \begin_layout Plain Layout
12792             _opti = 0
12793 \end_layout
12795 \begin_layout Plain Layout
12797         } else
12798 \end_layout
12800 \begin_layout Plain Layout
12802             _opti++
12803 \end_layout
12805 \begin_layout Plain Layout
12807         return "?"
12808 \end_layout
12810 \begin_layout Plain Layout
12812     }
12813 \end_layout
12815 \end_inset
12818 \end_layout
12820 \begin_layout Standard
12821 At this point, the option has been found and we need to know if it takes
12822  any arguments.
12823 \end_layout
12825 \begin_layout Standard
12826 \begin_inset listings
12827 inline false
12828 status open
12830 \begin_layout Plain Layout
12832     if (substr(options, i + 1, 1) == ":") {
12833 \end_layout
12835 \begin_layout Plain Layout
12837         # get option argument
12838 \end_layout
12840 \begin_layout Plain Layout
12842         if (length(substr(argv[Optind], _opti + 1)) > 0)
12843 \end_layout
12845 \begin_layout Plain Layout
12847             Optarg = substr(argv[Optind], _opti + 1)
12848 \end_layout
12850 \begin_layout Plain Layout
12852         else
12853 \end_layout
12855 \begin_layout Plain Layout
12857             Optarg = argv[++Optind]
12858 \end_layout
12860 \begin_layout Plain Layout
12862         _opti = 0
12863 \end_layout
12865 \begin_layout Plain Layout
12867     } else
12868 \end_layout
12870 \begin_layout Plain Layout
12872         Optarg = ""
12873 \end_layout
12875 \begin_layout Plain Layout
12877     if (_opti == 0 || _opti >= length(argv[Optind])) {
12878 \end_layout
12880 \begin_layout Plain Layout
12882         Optind++
12883 \end_layout
12885 \begin_layout Plain Layout
12887         _opti = 0
12888 \end_layout
12890 \begin_layout Plain Layout
12892     } else
12893 \end_layout
12895 \begin_layout Plain Layout
12897         _opti++
12898 \end_layout
12900 \begin_layout Plain Layout
12902     return thisopt
12903 \end_layout
12905 \begin_layout Plain Layout
12908 \end_layout
12910 \end_inset
12912 A test program is built in, too
12913 \end_layout
12915 \begin_layout Chunk
12916 getopt.awk-begin
12917 \end_layout
12919 \begin_layout Standard
12920 \begin_inset listings
12921 inline false
12922 status open
12924 \begin_layout Plain Layout
12926 BEGIN {
12927 \end_layout
12929 \begin_layout Plain Layout
12931     Opterr = 1    # default is to diagnose
12932 \end_layout
12934 \begin_layout Plain Layout
12936     Optind = 1    # skip ARGV[0]
12937 \end_layout
12939 \begin_layout Plain Layout
12941     # test program
12942 \end_layout
12944 \begin_layout Plain Layout
12946     if (_getopt_test) {
12947 \end_layout
12949 \begin_layout Plain Layout
12951         while ((_go_c = getopt(ARGC, ARGV, "ab:cd")) != -1)
12952 \end_layout
12954 \begin_layout Plain Layout
12956             printf("c = <%c>, optarg = <%s>
12957 \backslash
12959 \end_layout
12961 \begin_layout Plain Layout
12963                                        _go_c, Optarg)
12964 \end_layout
12966 \begin_layout Plain Layout
12968         printf("non-option arguments:
12969 \backslash
12971 \end_layout
12973 \begin_layout Plain Layout
12975         for (; Optind < ARGC; Optind++)
12976 \end_layout
12978 \begin_layout Plain Layout
12980             printf("
12981 \backslash
12982 tARGV[%d] = <%s>
12983 \backslash
12985 \end_layout
12987 \begin_layout Plain Layout
12989                                     Optind, ARGV[Optind])
12990 \end_layout
12992 \begin_layout Plain Layout
12994     }
12995 \end_layout
12997 \begin_layout Plain Layout
13000 \end_layout
13002 \end_inset
13005 \end_layout
13007 \begin_layout Standard
13008 The entire getopt.awk is made out of these chunks in order
13009 \end_layout
13011 \begin_layout Chunk
13012 getopt.awk
13013 \end_layout
13015 \begin_layout Standard
13016 \begin_inset listings
13017 inline false
13018 status open
13020 \begin_layout Plain Layout
13023 \backslash
13024 chunkref{getopt.awk-header}>
13025 \end_layout
13027 \begin_layout Plain Layout
13029 \end_layout
13031 \begin_layout Plain Layout
13034 \backslash
13035 chunkref{getopt.awk-notes}>
13036 \end_layout
13038 \begin_layout Plain Layout
13041 \backslash
13042 chunkref{getopt.awk-getopt()}>
13043 \end_layout
13045 \begin_layout Plain Layout
13048 \backslash
13049 chunkref{getopt.awk-begin}>
13050 \end_layout
13052 \end_inset
13055 \end_layout
13057 \begin_layout Standard
13058 Although we only want the header and function:
13059 \end_layout
13061 \begin_layout Chunk
13062 getopt
13063 \end_layout
13065 \begin_layout Standard
13066 \begin_inset listings
13067 inline false
13068 status open
13070 \begin_layout Plain Layout
13072 # try: locate getopt.awk for the full original file
13073 \end_layout
13075 \begin_layout Plain Layout
13077 # as part of your standard awk installation
13078 \end_layout
13080 \begin_layout Plain Layout
13083 \backslash
13084 chunkref{getopt.awk-header}>
13085 \end_layout
13087 \begin_layout Plain Layout
13089 \end_layout
13091 \begin_layout Plain Layout
13094 \backslash
13095 chunkref{getopt.awk-getopt()}>
13096 \end_layout
13098 \end_inset
13101 \end_layout
13103 \begin_layout Chapter
13104 Newfangle LaTeX source code
13105 \end_layout
13107 \begin_layout Section
13108 newfangle module
13109 \end_layout
13111 \begin_layout Standard
13112 Here we define a Lyx .module file that makes it convenient to use LyX for
13113  writing such literate programs.
13114 \end_layout
13116 \begin_layout Standard
13117 This file 
13118 \begin_inset Flex CharStyle:Code
13119 status collapsed
13121 \begin_layout Plain Layout
13122 ./newfangle.module
13123 \end_layout
13125 \end_inset
13127  can be installed in your personal 
13128 \begin_inset Flex CharStyle:Code
13129 status collapsed
13131 \begin_layout Plain Layout
13132 .lyx/layouts folder
13133 \end_layout
13135 \end_inset
13138  You will need to Tools Reconfigure so that LyX notices it.
13139  It adds a new format Chunk, which should precede every listing and contain
13140  the chunk name.
13142 \end_layout
13144 \begin_layout Chunk
13145 ./newfangle.module,language=
13146 \end_layout
13148 \begin_layout Standard
13149 \begin_inset listings
13150 inline false
13151 status open
13153 \begin_layout Plain Layout
13156 \backslash
13157 DeclareLyXModule{Newfangle Literate Listings}
13158 \end_layout
13160 \begin_layout Plain Layout
13162 #DescriptionBegin
13163 \end_layout
13165 \begin_layout Plain Layout
13167 #  Newfangle literate listings allow one to write
13168 \end_layout
13170 \begin_layout Plain Layout
13172 #   literate programs after the fashion of noweb, but without having
13173 \end_layout
13175 \begin_layout Plain Layout
13177 #   to use noweave to generate the documentation.
13178  Instead the listings
13179 \end_layout
13181 \begin_layout Plain Layout
13183 #   package is extended in conjunction with the noweb package to implement
13184 \end_layout
13186 \begin_layout Plain Layout
13188 #   to code formating directly as latex.
13189 \end_layout
13191 \begin_layout Plain Layout
13193 #  The newfangle awk script
13194 \end_layout
13196 \begin_layout Plain Layout
13198 #DescriptionEnd
13199 \end_layout
13201 \begin_layout Plain Layout
13203 \end_layout
13205 \begin_layout Plain Layout
13208 \backslash
13209 chunkref{gpl3-copyright.hashed}>
13210 \end_layout
13212 \begin_layout Plain Layout
13214 \end_layout
13216 \begin_layout Plain Layout
13218 Format 11
13219 \end_layout
13221 \begin_layout Plain Layout
13223 \end_layout
13225 \begin_layout Plain Layout
13227 AddToPreamble
13228 \end_layout
13230 \begin_layout Plain Layout
13233 \backslash
13234 chunkref{./newfangle.sty}>
13235 \end_layout
13237 \begin_layout Plain Layout
13239 EndPreamble
13240 \end_layout
13242 \begin_layout Plain Layout
13244 \end_layout
13246 \begin_layout Plain Layout
13249 \backslash
13250 chunkref{chunkstyle}>
13251 \end_layout
13253 \begin_layout Plain Layout
13255 \end_layout
13257 \begin_layout Plain Layout
13260 \backslash
13261 chunkref{chunkref}>
13262 \end_layout
13264 \end_inset
13267 \end_layout
13269 \begin_layout Standard
13270 Because LyX modules are not yet a language supported by newfangle or lstlistings
13271 , we resort to this fake awk chunk below in order to have each line of the
13272  GPL3 license commence with a #
13273 \end_layout
13275 \begin_layout Chunk
13276 gpl3-copyright.hashed,language=awk
13277 \end_layout
13279 \begin_layout Standard
13280 \begin_inset listings
13281 inline false
13282 status open
13284 \begin_layout Plain Layout
13287 \backslash
13288 chunkref{gpl3-copyright}>
13289 \end_layout
13291 \begin_layout Plain Layout
13293 \end_layout
13295 \end_inset
13298 \end_layout
13300 \begin_layout Subsection
13301 The Chunk style
13302 \end_layout
13304 \begin_layout Standard
13305 The purpose of the 
13306 \noun on
13307 chunk
13308 \noun default
13309  style is to make it easier for LyX users to provide the name to 
13310 \begin_inset Flex CharStyle:Code
13311 status collapsed
13313 \begin_layout Plain Layout
13315 \backslash
13316 lstlistings
13317 \end_layout
13319 \end_inset
13322  Normally this requires right-clicking on the listing, choosing settings,
13323  advanced, and then typing 
13324 \begin_inset Flex CharStyle:Code
13325 status collapsed
13327 \begin_layout Plain Layout
13328 name=chunk-name
13329 \end_layout
13331 \end_inset
13334  This has the further disadvantage that the name (and other options) are
13335  not generally visible during document editing.
13336 \end_layout
13338 \begin_layout Standard
13339 The chunk style is defined as a LaTeX command, so that all text on the same
13340  line is passed to the LaTeX command 
13341 \begin_inset Flex CharStyle:Code
13342 status collapsed
13344 \begin_layout Plain Layout
13345 Chunk
13346 \end_layout
13348 \end_inset
13351  This makes it easy to parse using 
13352 \begin_inset Flex CharStyle:Code
13353 status collapsed
13355 \begin_layout Plain Layout
13356 newfangle
13357 \end_layout
13359 \end_inset
13361 , and easy to pass these options on to the listings package.
13362  The first word in a chunk section should be the chunk name, and will have
13364 \begin_inset Flex CharStyle:Code
13365 status collapsed
13367 \begin_layout Plain Layout
13368 name=
13369 \end_layout
13371 \end_inset
13373  prepended to it.
13374  Any other words are accepted arguments to 
13375 \begin_inset Flex CharStyle:Code
13376 status collapsed
13378 \begin_layout Plain Layout
13380 \backslash
13381 lstset
13382 \end_layout
13384 \end_inset
13387 \end_layout
13389 \begin_layout Standard
13390 We set PassThru to 1 because the user is actually entering raw latex.
13391 \end_layout
13393 \begin_layout Chunk
13394 chunkstyle
13395 \end_layout
13397 \begin_layout Standard
13398 \begin_inset listings
13399 inline false
13400 status open
13402 \begin_layout Plain Layout
13404 Style Chunk
13405 \end_layout
13407 \begin_layout Plain Layout
13409   LatexType             Command
13410 \end_layout
13412 \begin_layout Plain Layout
13414   LatexName             Chunk
13415 \end_layout
13417 \begin_layout Plain Layout
13419   Margin                First_Dynamic
13420 \end_layout
13422 \begin_layout Plain Layout
13424   LeftMargin            Chunk:xxx
13425 \end_layout
13427 \begin_layout Plain Layout
13429   LabelSep              xx
13430 \end_layout
13432 \begin_layout Plain Layout
13434   LabelType             Static
13435 \end_layout
13437 \begin_layout Plain Layout
13439   LabelString           "Chunk:"
13440 \end_layout
13442 \begin_layout Plain Layout
13444   Align                 Left
13445 \end_layout
13447 \begin_layout Plain Layout
13449   PassThru              1
13450 \end_layout
13452 \begin_layout Plain Layout
13454 \end_layout
13456 \end_inset
13459 \end_layout
13461 \begin_layout Standard
13462 To make the label very visible we choose a larger font coloured red.
13463 \end_layout
13465 \begin_layout Standard
13466 \begin_inset listings
13467 inline false
13468 status open
13470 \begin_layout Plain Layout
13472   LabelFont
13473 \end_layout
13475 \begin_layout Plain Layout
13477     Family              Sans
13478 \end_layout
13480 \begin_layout Plain Layout
13482     Size                Large
13483 \end_layout
13485 \begin_layout Plain Layout
13487     Series              Bold
13488 \end_layout
13490 \begin_layout Plain Layout
13492     Shape               Italic
13493 \end_layout
13495 \begin_layout Plain Layout
13497     Color               red
13498 \end_layout
13500 \begin_layout Plain Layout
13502   EndFont
13503 \end_layout
13505 \begin_layout Plain Layout
13508 \end_layout
13510 \end_inset
13513 \end_layout
13515 \begin_layout Subsection
13516 The chunkref style
13517 \end_layout
13519 \begin_layout Standard
13520 We also define the Chunkref style which can be used to express cross references
13521  to chunks.
13522 \end_layout
13524 \begin_layout Chunk
13525 chunkref
13526 \end_layout
13528 \begin_layout Standard
13529 \begin_inset listings
13530 inline false
13531 status open
13533 \begin_layout Plain Layout
13535 InsetLayout Chunkref
13536 \end_layout
13538 \begin_layout Plain Layout
13540   LyxType               charstyle
13541 \end_layout
13543 \begin_layout Plain Layout
13545   LatexType             Command
13546 \end_layout
13548 \begin_layout Plain Layout
13550   LatexName             chunkref
13551 \end_layout
13553 \begin_layout Plain Layout
13555   PassThru              1
13556 \end_layout
13558 \begin_layout Plain Layout
13560   LabelFont             
13561 \end_layout
13563 \begin_layout Plain Layout
13565     Shape               Italic
13566 \end_layout
13568 \begin_layout Plain Layout
13570     Color               red
13571 \end_layout
13573 \begin_layout Plain Layout
13575   EndFont
13576 \end_layout
13578 \begin_layout Plain Layout
13581 \end_layout
13583 \end_inset
13586 \end_layout
13588 \begin_layout Section
13589 \begin_inset CommandInset label
13590 LatexCommand label
13591 name "sec:Latex-Macros"
13593 \end_inset
13595 Latex Macros
13596 \end_layout
13598 \begin_layout Standard
13599 We require the 
13600 \noun on
13601 listings
13602 \noun default
13604 \noun on
13605 noweb
13606 \noun default
13607  and 
13608 \noun on
13609 xargs
13610 \noun default
13611  packages.
13612  As noweb defines it's own 
13613 \begin_inset Flex CharStyle:Code
13614 status collapsed
13616 \begin_layout Plain Layout
13618 \backslash
13619 code
13620 \end_layout
13622 \end_inset
13624  environment, we re-define the one that LyX logical markup module expects
13625  here.
13626 \end_layout
13628 \begin_layout Chunk
13629 ./newfangle.sty,language=tex,basicstyle=
13630 \backslash
13631 ttfamily
13632 \end_layout
13634 \begin_layout Standard
13635 \begin_inset listings
13636 inline false
13637 status open
13639 \begin_layout Plain Layout
13642 \backslash
13643 usepackage{listings}%
13644 \end_layout
13646 \begin_layout Plain Layout
13649 \backslash
13650 usepackage{noweb}%
13651 \end_layout
13653 \begin_layout Plain Layout
13656 \backslash
13657 usepackage{xargs}%
13658 \end_layout
13660 \begin_layout Plain Layout
13663 \backslash
13664 renewcommand{
13665 \backslash
13666 code}[1]{
13667 \backslash
13668 texttt{#1}}%
13669 \end_layout
13671 \end_inset
13674 \end_layout
13676 \begin_layout Standard
13677 We also define a 
13678 \begin_inset Flex CharStyle:Code
13679 status collapsed
13681 \begin_layout Plain Layout
13682 CChunk
13683 \end_layout
13685 \end_inset
13687  macro, for use as: 
13688 \begin_inset Flex CharStyle:Code
13689 status collapsed
13691 \begin_layout Plain Layout
13693 \backslash
13694 begin{CChunk}
13695 \end_layout
13697 \end_inset
13699  which will need renaming to 
13700 \begin_inset Flex CharStyle:Code
13701 status collapsed
13703 \begin_layout Plain Layout
13705 \backslash
13706 begin{Chunk}
13707 \end_layout
13709 \end_inset
13711  when I can do this without clashing with 
13712 \begin_inset Flex CharStyle:Code
13713 status collapsed
13715 \begin_layout Plain Layout
13717 \backslash
13718 Chunk
13719 \end_layout
13721 \end_inset
13724 \end_layout
13726 \begin_layout Standard
13727 \begin_inset listings
13728 inline false
13729 status open
13731 \begin_layout Plain Layout
13734 \backslash
13735 lstnewenvironment{Chunk}{
13736 \backslash
13737 relax}{
13738 \backslash
13739 relax}%
13740 \end_layout
13742 \end_inset
13745 \end_layout
13747 \begin_layout Standard
13748 We also define a suitable 
13749 \begin_inset Flex CharStyle:Code
13750 status collapsed
13752 \begin_layout Plain Layout
13754 \backslash
13755 lstset
13756 \end_layout
13758 \end_inset
13760  of parameters that suit the literate programming style after the fashion
13761  of 
13762 \noun on
13763 noweave
13764 \noun default
13766 \end_layout
13768 \begin_layout Standard
13769 \begin_inset listings
13770 inline false
13771 status open
13773 \begin_layout Plain Layout
13776 \backslash
13777 lstset{numbers=left, stepnumber=5, numbersep=5pt,
13778 \end_layout
13780 \begin_layout Plain Layout
13782         breaklines=false,basicstyle=
13783 \backslash
13784 ttfamily,
13785 \end_layout
13787 \begin_layout Plain Layout
13789         numberstyle=
13790 \backslash
13791 tiny, language=C}%
13792 \end_layout
13794 \end_inset
13797 \end_layout
13799 \begin_layout Standard
13800 We also define a notangle-like mechanism for 
13801 \emph on
13802 escaping
13803 \emph default
13804  to LaTeX from the listing, and by which we can refer to other listings.
13805  We declare the 
13806 \begin_inset Flex CharStyle:Code
13807 status collapsed
13809 \begin_layout Plain Layout
13810 =<\SpecialChar \ldots{}
13812 \end_layout
13814 \end_inset
13816  sequence to contain LaTeX code, and include another like this chunk: 
13817 \begin_inset Flex CharStyle:Code
13818 status collapsed
13820 \begin_layout Plain Layout
13822 \backslash
13823 chunkref{chunkname}>
13824 \end_layout
13826 \end_inset
13829  However, because 
13830 \begin_inset Flex CharStyle:Code
13831 status collapsed
13833 \begin_layout Plain Layout
13834 =<\SpecialChar \ldots{}
13836 \end_layout
13838 \end_inset
13840  is already defined to contain LaTeX code for this document --- this is
13841  a 
13842 \noun on
13843 newfangle
13844 \noun default
13845  document after all --- the code fragment below effectively contains the
13846  LaTeX code: 
13847 \begin_inset Flex CharStyle:Code
13848 status collapsed
13850 \begin_layout Plain Layout
13852 \end_layout
13854 \end_inset
13857  To avoid problems with document generation, I had to declare an lstlistings
13858  property: 
13859 \begin_inset Flex CharStyle:Code
13860 status collapsed
13862 \begin_layout Plain Layout
13863 escapeinside={}
13864 \end_layout
13866 \end_inset
13868  for this listing only; which in LyX was done by right-clicking the listings
13869  inset, choosing 
13870 \begin_inset Flex CharStyle:Code
13871 status collapsed
13873 \begin_layout Plain Layout
13874 settings
13875 \end_layout
13877 \end_inset
13879 \SpecialChar \menuseparator
13881 \begin_inset Flex CharStyle:Code
13882 status collapsed
13884 \begin_layout Plain Layout
13885 advanced
13886 \end_layout
13888 \end_inset
13891 \end_layout
13893 \begin_layout Standard
13894 \begin_inset Note Note
13895 status collapsed
13897 \begin_layout Plain Layout
13898 =< isn't enjoyed literally here, in a listing when the escape sequence is
13899  already defined as shown...
13900  we need to somehow escape this representation...
13901 \end_layout
13903 \end_inset
13906 \end_layout
13908 \begin_layout Standard
13909 \begin_inset listings
13910 lstparams "escapeinside={}"
13911 inline false
13912 status open
13914 \begin_layout Plain Layout
13917 \backslash
13918 lstset{escapeinside={=<}{>}}%
13919 \end_layout
13921 \end_inset
13924 \end_layout
13926 \begin_layout Standard
13927 Although our macros will contain the @ symbol, they will be included in
13928  a 
13929 \begin_inset Flex CharStyle:Code
13930 status collapsed
13932 \begin_layout Plain Layout
13934 \backslash
13935 makeatletter
13936 \end_layout
13938 \end_inset
13940  section by LyX; however we keep the commented out 
13941 \begin_inset Flex CharStyle:Code
13942 status collapsed
13944 \begin_layout Plain Layout
13946 \backslash
13947 makeatletter
13948 \end_layout
13950 \end_inset
13952  as a reminder.
13953  The listings package likes to centre the titles, but noweb titles are specially
13954  formatted and must be left aligned.
13955  The simplest way to do this turned out to be by removing the definition
13956  of 
13957 \begin_inset Flex CharStyle:Code
13958 status collapsed
13960 \begin_layout Plain Layout
13962 \backslash
13963 lst@maketitle
13964 \end_layout
13966 \end_inset
13969  This may interact badly if other listings want a regular title or caption.
13970  We remember the old maketitle in case we need it.
13971 \end_layout
13973 \begin_layout Standard
13974 \begin_inset listings
13975 inline false
13976 status open
13978 \begin_layout Plain Layout
13981 \backslash
13982 makeatletter
13983 \end_layout
13985 \begin_layout Plain Layout
13987 %somehow re-defining maketitle gives us a left-aligned title
13988 \end_layout
13990 \begin_layout Plain Layout
13992 %which is extactly what our specially formatted title needs!
13993 \end_layout
13995 \begin_layout Plain Layout
13998 \backslash
13999 global
14000 \backslash
14002 \backslash
14003 newfangle@lst@maketitle
14004 \backslash
14005 lst@maketitle%
14006 \end_layout
14008 \begin_layout Plain Layout
14011 \backslash
14012 global
14013 \backslash
14015 \backslash
14016 lst@maketitle{}%
14017 \end_layout
14019 \end_inset
14022 \end_layout
14024 \begin_layout Subsection
14025 \begin_inset CommandInset label
14026 LatexCommand label
14027 name "sub:The-chunk-command"
14029 \end_inset
14031 The chunk command
14032 \end_layout
14034 \begin_layout Standard
14035 Our chunk command accepts one argument, and calls 
14036 \begin_inset Flex CharStyle:Code
14037 status collapsed
14039 \begin_layout Plain Layout
14041 \backslash
14042 ltset
14043 \end_layout
14045 \end_inset
14048  Although 
14049 \begin_inset Flex CharStyle:Code
14050 status collapsed
14052 \begin_layout Plain Layout
14054 \backslash
14055 ltset
14056 \end_layout
14058 \end_inset
14060  will note the name, this is erased when the next 
14061 \begin_inset Flex CharStyle:Code
14062 status collapsed
14064 \begin_layout Plain Layout
14066 \backslash
14067 lstlisting
14068 \end_layout
14070 \end_inset
14072  starts, so we make a note of this in 
14073 \begin_inset Flex CharStyle:Code
14074 status collapsed
14076 \begin_layout Plain Layout
14078 \backslash
14079 lst@chunkname
14080 \end_layout
14082 \end_inset
14084  and restore in in lstlistings Init hook.
14085 \end_layout
14087 \begin_layout Standard
14088 \begin_inset listings
14089 inline false
14090 status open
14092 \begin_layout Plain Layout
14095 \backslash
14097 \backslash
14098 Chunk#1{%
14099 \end_layout
14101 \begin_layout Plain Layout
14103   
14104 \backslash
14105 lstset{title={
14106 \backslash
14107 newfanglecaption},name=#1}%
14108 \end_layout
14110 \begin_layout Plain Layout
14112   
14113 \backslash
14114 global
14115 \backslash
14116 edef
14117 \backslash
14118 lst@chunkname{
14119 \backslash
14120 lst@intname}%
14121 \end_layout
14123 \begin_layout Plain Layout
14126 \end_layout
14128 \begin_layout Plain Layout
14131 \backslash
14133 \backslash
14134 lst@chunkname{
14135 \backslash
14136 empty}%
14137 \end_layout
14139 \end_inset
14142 \end_layout
14144 \begin_layout Subsubsection
14145 Chunk parameters
14146 \end_layout
14148 \begin_layout Standard
14149 Newfangle permits parameterized chunks, and requires the paramters to be
14150  specified as listings options.
14151  The newfangle script uses this, and although we don't do anything with
14152  these in the LaTeX code right now, we need to stop the listings package
14153  complaining.
14154 \end_layout
14156 \begin_layout Standard
14157 \begin_inset listings
14158 inline false
14159 status open
14161 \begin_layout Plain Layout
14164 \backslash
14165 lst@Key{params}
14166 \backslash
14167 relax{
14168 \backslash
14170 \backslash
14171 newfangle@chunk@params{#1}}%
14172 \end_layout
14174 \end_inset
14177 \end_layout
14179 \begin_layout Standard
14180 As it is common to define a chunk which then needs appending to another
14181  chunk, and annoying to have to declare a single line chunk to manage the
14182  include, we support an 
14183 \begin_inset Flex CharStyle:Code
14184 status collapsed
14186 \begin_layout Plain Layout
14187 append=
14188 \end_layout
14190 \end_inset
14192  option.
14194 \end_layout
14196 \begin_layout Standard
14197 \begin_inset listings
14198 inline false
14199 status open
14201 \begin_layout Plain Layout
14204 \backslash
14205 lst@Key{append}
14206 \backslash
14207 relax{
14208 \backslash
14210 \backslash
14211 newfangle@chunk@append{#1}}%
14212 \end_layout
14214 \end_inset
14217 \end_layout
14219 \begin_layout Subsection
14220 The noweb styled caption
14221 \end_layout
14223 \begin_layout Standard
14224 We define a public macro 
14225 \begin_inset Flex CharStyle:Code
14226 status collapsed
14228 \begin_layout Plain Layout
14230 \backslash
14231 newfanglecaption
14232 \end_layout
14234 \end_inset
14236  which can be set as a regular title.
14237  By means of 
14238 \begin_inset Flex CharStyle:Code
14239 status collapsed
14241 \begin_layout Plain Layout
14243 \backslash
14244 protect
14245 \end_layout
14247 \end_inset
14249 , It expands to 
14250 \begin_inset Flex CharStyle:Code
14251 status collapsed
14253 \begin_layout Plain Layout
14255 \backslash
14256 newfangle@caption
14257 \end_layout
14259 \end_inset
14261  at the appriate time when the caption is emitted.
14262 \end_layout
14264 \begin_layout Standard
14265 \begin_inset listings
14266 inline false
14267 status open
14269 \begin_layout Plain Layout
14272 \backslash
14274 \backslash
14275 newfanglecaption{
14276 \backslash
14277 protect
14278 \backslash
14279 newfangle@caption}%
14280 \end_layout
14282 \end_inset
14285 \end_layout
14287 \begin_layout Standard
14288 \begin_inset Float figure
14289 placement H
14290 wide false
14291 sideways false
14292 status collapsed
14294 \begin_layout Plain Layout
14295 \begin_inset Box Boxed
14296 position "t"
14297 hor_pos "c"
14298 has_inner_box 1
14299 inner_pos "t"
14300 use_parbox 0
14301 width "100col%"
14302 special "none"
14303 height "1in"
14304 height_special "totalheight"
14305 status open
14307 \begin_layout Plain Layout
14309 \begin_inset space \qquad{}
14310 \end_inset
14313 \shape italic
14314 some-chunk
14315 \shape default
14316  19b⟩
14317 \begin_inset Formula $\equiv+$
14318 \end_inset
14321 \begin_inset space \qquad{}
14322 \end_inset
14325 \begin_inset space \qquad{}
14326 \end_inset
14329 \begin_inset space \qquad{}
14330 \end_inset
14333 \begin_inset Formula $\triangleleft$
14334 \end_inset
14337 \begin_inset space \quad{}
14338 \end_inset
14341 \begin_inset Formula $\triangleright$
14342 \end_inset
14345 \end_layout
14347 \begin_layout Plain Layout
14349 \size footnotesize
14350 In this example, the current chunk is 22c, and therefore the third chunk
14351  on page 22.
14352 \end_layout
14354 \begin_layout Plain Layout
14356 \size footnotesize
14357 It's name is 
14358 \emph on
14359 some-chunk
14360 \emph default
14363 \end_layout
14365 \begin_layout Plain Layout
14367 \size footnotesize
14368 The first chunk with this name (19b) occurs as the second chunk on page
14369  19.
14370 \end_layout
14372 \begin_layout Plain Layout
14374 \size footnotesize
14375 The previous chunk (22d) with the same name is the second chunk on page
14376  22.
14377 \end_layout
14379 \begin_layout Plain Layout
14381 \size footnotesize
14382 The next chunk (24d) is the fourth chunk on page 24.
14383 \end_layout
14385 \begin_layout Plain Layout
14386 \begin_inset Caption
14388 \begin_layout Plain Layout
14389 noweb heading
14390 \end_layout
14392 \end_inset
14395 \end_layout
14397 \end_inset
14400 \end_layout
14402 \end_inset
14404 The general noweb output format compactly identifies the current chunk,
14405  and references to the first chunk, and the previous and next chunks that
14406  have the same name.
14408 \end_layout
14410 \begin_layout Standard
14411 This means that we need to keep a counter for each chunk-name, that we use
14412  to count chunks of the same name.
14414 \end_layout
14416 \begin_layout Subsection
14417 The chunk counter
14418 \end_layout
14420 \begin_layout Standard
14421 It would be natural to have a counter for each chunk name, but TeX would
14422  soon run out of counters
14423 \begin_inset Foot
14424 status collapsed
14426 \begin_layout Plain Layout
14427 \SpecialChar \ldots{}
14428 soon 
14429 \emph on
14431 \emph default
14432  run out of counters and so I had to re-write the LaTeX macros to share
14433  a counter as described here
14434 \end_layout
14436 \end_inset
14438 , so we have one counter which we save at the end of a chunk and restore
14439  at the beginning of a chunk.
14440 \end_layout
14442 \begin_layout Standard
14443 \begin_inset listings
14444 inline false
14445 status open
14447 \begin_layout Plain Layout
14450 \backslash
14451 newcounter{newfangle@chunkcounter}%
14452 \end_layout
14454 \end_inset
14457 \end_layout
14459 \begin_layout Standard
14460 We construct the name of this variable to store the counter to be the text
14462 \begin_inset Flex CharStyle:Code
14463 status collapsed
14465 \begin_layout Plain Layout
14466 lst-chunk-
14467 \end_layout
14469 \end_inset
14471  prefixed onto the chunks own name, and store it in 
14472 \begin_inset Flex CharStyle:Code
14473 status collapsed
14475 \begin_layout Plain Layout
14477 \backslash
14478 chunkcount
14479 \end_layout
14481 \end_inset
14485 \end_layout
14487 \begin_layout Standard
14488 We save the counter like this:
14489 \end_layout
14491 \begin_layout Chunk
14492 save-counter
14493 \end_layout
14495 \begin_layout Standard
14496 \begin_inset listings
14497 inline false
14498 status open
14500 \begin_layout Plain Layout
14503 \backslash
14504 global
14505 \backslash
14506 expandafter
14507 \backslash
14508 edef
14509 \backslash
14510 csname 
14511 \backslash
14512 chunkcount
14513 \backslash
14514 endcsname{
14515 \backslash
14516 arabic{newfangle@chunkcounter}}%
14517 \end_layout
14519 \end_inset
14522 \end_layout
14524 \begin_layout Standard
14525 and restore the counter like this:
14526 \end_layout
14528 \begin_layout Chunk
14529 restore-counter
14530 \end_layout
14532 \begin_layout Standard
14533 \begin_inset listings
14534 inline false
14535 status open
14537 \begin_layout Plain Layout
14540 \backslash
14541 setcounter{newfangle@chunkcounter}{
14542 \backslash
14543 csname 
14544 \backslash
14545 chunkcount
14546 \backslash
14547 endcsname}%
14548 \end_layout
14550 \end_inset
14553 \end_layout
14555 \begin_layout Chunk
14556 ./newfangle.sty
14557 \end_layout
14559 \begin_layout Standard
14560 If there does not already exist a variable whose name is stored in 
14561 \begin_inset Flex CharStyle:Code
14562 status collapsed
14564 \begin_layout Plain Layout
14566 \backslash
14567 chunkcount
14568 \end_layout
14570 \end_inset
14572 , then we know we are the first chunk with this name, and then define a
14573  counter.
14575 \end_layout
14577 \begin_layout Standard
14578 Although chunks of the same name share a common counter, they must still
14579  be distinguished.
14580  We use is the internal name of the listing, suffixed by the counter value.
14581  So the first chunk might be 
14582 \begin_inset Flex CharStyle:Code
14583 status collapsed
14585 \begin_layout Plain Layout
14586 something-1
14587 \end_layout
14589 \end_inset
14591  and the second chunk be 
14592 \begin_inset Flex CharStyle:Code
14593 status collapsed
14595 \begin_layout Plain Layout
14596 something-2
14597 \end_layout
14599 \end_inset
14601 , etc.
14602 \end_layout
14604 \begin_layout Standard
14605 We also calculate the name of the previous chunk if we can (before we increment
14606  the chunk counter).
14607  If this is the first chunk of that name, then 
14608 \begin_inset Flex CharStyle:Code
14609 status collapsed
14611 \begin_layout Plain Layout
14613 \backslash
14614 prevchunkname
14615 \end_layout
14617 \end_inset
14619  is set to 
14620 \begin_inset Flex CharStyle:Code
14621 status collapsed
14623 \begin_layout Plain Layout
14625 \backslash
14626 relax
14627 \end_layout
14629 \end_inset
14631  which the noweb package will interpret as not existing.
14632 \end_layout
14634 \begin_layout Standard
14635 \begin_inset listings
14636 inline false
14637 status open
14639 \begin_layout Plain Layout
14642 \backslash
14644 \backslash
14645 newfangle@caption{%
14646 \end_layout
14648 \begin_layout Plain Layout
14650   
14651 \backslash
14652 edef
14653 \backslash
14654 chunkcount{lst-chunk-
14655 \backslash
14656 lst@intname}%
14657 \end_layout
14659 \begin_layout Plain Layout
14661   
14662 \backslash
14663 @ifundefined{
14664 \backslash
14665 chunkcount}{%
14666 \end_layout
14668 \begin_layout Plain Layout
14670     
14671 \backslash
14672 expandafter
14673 \backslash
14674 gdef
14675 \backslash
14676 csname 
14677 \backslash
14678 chunkcount
14679 \backslash
14680 endcsname{0}%
14681 \end_layout
14683 \begin_layout Plain Layout
14685     
14686 \backslash
14687 setcounter{newfangle@chunkcounter}{
14688 \backslash
14689 csname 
14690 \backslash
14691 chunkcount
14692 \backslash
14693 endcsname}%
14694 \end_layout
14696 \begin_layout Plain Layout
14698     
14699 \backslash
14701 \backslash
14702 prevchunkname
14703 \backslash
14704 relax%
14705 \end_layout
14707 \begin_layout Plain Layout
14709   }{%
14710 \end_layout
14712 \begin_layout Plain Layout
14714     
14715 \backslash
14716 setcounter{newfangle@chunkcounter}{
14717 \backslash
14718 csname 
14719 \backslash
14720 chunkcount
14721 \backslash
14722 endcsname}%
14723 \end_layout
14725 \begin_layout Plain Layout
14727     
14728 \backslash
14729 edef
14730 \backslash
14731 prevchunkname{
14732 \backslash
14733 lst@intname-
14734 \backslash
14735 arabic{newfangle@chunkcounter}}%
14736 \end_layout
14738 \begin_layout Plain Layout
14740   }%
14741 \end_layout
14743 \end_inset
14746 \end_layout
14748 \begin_layout Standard
14749 After incrementing the chunk counter, we then define the name of this chunk,
14750  as well as the name of the first chunk.
14751 \end_layout
14753 \begin_layout Standard
14754 \begin_inset listings
14755 inline false
14756 status open
14758 \begin_layout Plain Layout
14760   
14761 \backslash
14762 addtocounter{newfangle@chunkcounter}{1}%
14763 \end_layout
14765 \begin_layout Plain Layout
14767   
14768 \backslash
14769 global
14770 \backslash
14771 expandafter
14772 \backslash
14773 edef
14774 \backslash
14775 csname 
14776 \backslash
14777 chunkcount
14778 \backslash
14779 endcsname{
14780 \backslash
14781 arabic{newfangle@chunkcounter}}%
14782 \end_layout
14784 \begin_layout Plain Layout
14786   
14787 \backslash
14788 edef
14789 \backslash
14790 chunkname{
14791 \backslash
14792 lst@intname-
14793 \backslash
14794 arabic{newfangle@chunkcounter}}%
14795 \end_layout
14797 \begin_layout Plain Layout
14799   
14800 \backslash
14801 edef
14802 \backslash
14803 firstchunkname{
14804 \backslash
14805 lst@intname-1}%
14806 \end_layout
14808 \end_inset
14811 \end_layout
14813 \begin_layout Standard
14814 We now need to calculate the name of the next chunk.
14815  We do this by temporarily skipping the counter on by one; however there
14816  may not actually be another chunk with this name! We detect this by also
14817  defining a label for each chunk based on the chunkname.
14818  If there is a next chunkname then it will define a label with that name.
14819  As labels are persistent, we can at least tell the second time LaTeX is
14820  run.
14821  If we don't find such a defined label then we define 
14822 \begin_inset Flex CharStyle:Code
14823 status collapsed
14825 \begin_layout Plain Layout
14827 \backslash
14828 nextchunkname
14829 \end_layout
14831 \end_inset
14833  to 
14834 \begin_inset Flex CharStyle:Code
14835 status collapsed
14837 \begin_layout Plain Layout
14839 \backslash
14840 relax
14841 \end_layout
14843 \end_inset
14846 \end_layout
14848 \begin_layout Standard
14849 \begin_inset listings
14850 inline false
14851 status open
14853 \begin_layout Plain Layout
14855   
14856 \backslash
14857 addtocounter{newfangle@chunkcounter}{1}%
14858 \end_layout
14860 \begin_layout Plain Layout
14862   
14863 \backslash
14864 edef
14865 \backslash
14866 nextchunkname{
14867 \backslash
14868 lst@intname-
14869 \backslash
14870 arabic{newfangle@chunkcounter}}%
14871 \end_layout
14873 \begin_layout Plain Layout
14875   
14876 \backslash
14877 @ifundefined{r@label-
14878 \backslash
14879 nextchunkname}{
14880 \backslash
14882 \backslash
14883 nextchunkname
14884 \backslash
14885 relax}{}%
14886 \end_layout
14888 \end_inset
14891 \end_layout
14893 \begin_layout Standard
14894 The noweb package requires that we define a 
14895 \begin_inset Flex CharStyle:Code
14896 status collapsed
14898 \begin_layout Plain Layout
14900 \backslash
14901 sublabel
14902 \end_layout
14904 \end_inset
14906  for every chunk, with a unique name, which is then used to print out it's
14907  navigation hints.
14908 \end_layout
14910 \begin_layout Standard
14911 We also define a regular label for this chunk, as was mentioned above when
14912  we calculated 
14913 \begin_inset Flex CharStyle:Code
14914 status collapsed
14916 \begin_layout Plain Layout
14918 \backslash
14919 nextchunkname
14920 \end_layout
14922 \end_inset
14925  This requires LaTeX to be run at least twice after new chunk sections are
14926  added --- but noweb requried that anyway.
14927 \end_layout
14929 \begin_layout Standard
14930 \begin_inset listings
14931 inline false
14932 status open
14934 \begin_layout Plain Layout
14936   
14937 \backslash
14938 sublabel{
14939 \backslash
14940 chunkname}%
14941 \end_layout
14943 \begin_layout Plain Layout
14945 % define this label for every chunk instance, so we
14946 \end_layout
14948 \begin_layout Plain Layout
14950 % can tell when we are the last chunk of this name
14951 \end_layout
14953 \begin_layout Plain Layout
14955   
14956 \backslash
14957 label{label-
14958 \backslash
14959 chunkname}%
14960 \end_layout
14962 \end_inset
14965 \end_layout
14967 \begin_layout Standard
14968 We also try and add the chunk to the list of listings, but I'm afraid we
14969  don't do very well.
14970  We want each chunk name listing once, with all of it's references.
14971 \end_layout
14973 \begin_layout Standard
14974 \begin_inset listings
14975 inline false
14976 status open
14978 \begin_layout Plain Layout
14980   
14981 \backslash
14982 addcontentsline{lol}{lstlisting}{
14983 \backslash
14984 lst@name~[
14985 \backslash
14986 protect
14987 \backslash
14988 subpageref{
14989 \backslash
14990 chunkname}]}%
14991 \end_layout
14993 \end_inset
14996 \end_layout
14998 \begin_layout Standard
14999 We then call the noweb output macros in the same way that noweave generates
15000  them, except that we don't need to call 
15001 \begin_inset Flex CharStyle:Code
15002 status collapsed
15004 \begin_layout Plain Layout
15006 \backslash
15007 nwstartdeflinemarkup
15008 \end_layout
15010 \end_inset
15012  or 
15013 \begin_inset Flex CharStyle:Code
15014 status collapsed
15016 \begin_layout Plain Layout
15018 \backslash
15019 nwenddeflinemarkup
15020 \end_layout
15022 \end_inset
15024  -- and if we do it messes up the output somewhat.
15025 \end_layout
15027 \begin_layout Standard
15028 \begin_inset listings
15029 inline false
15030 status open
15032 \begin_layout Plain Layout
15034   
15035 \backslash
15036 nwmargintag{%
15037 \end_layout
15039 \begin_layout Plain Layout
15041     {%
15042 \end_layout
15044 \begin_layout Plain Layout
15046       
15047 \backslash
15048 nwtagstyle{}%
15049 \end_layout
15051 \begin_layout Plain Layout
15053       
15054 \backslash
15055 subpageref{
15056 \backslash
15057 chunkname}%
15058 \end_layout
15060 \begin_layout Plain Layout
15062     }%
15063 \end_layout
15065 \begin_layout Plain Layout
15067   }%
15068 \end_layout
15070 \begin_layout Plain Layout
15073 \end_layout
15075 \begin_layout Plain Layout
15077   
15078 \backslash
15079 moddef{%
15080 \end_layout
15082 \begin_layout Plain Layout
15084     {
15085 \backslash
15086 lst@name}%
15087 \end_layout
15089 \begin_layout Plain Layout
15091     {%
15092 \end_layout
15094 \begin_layout Plain Layout
15096       
15097 \backslash
15098 nwtagstyle{}
15099 \backslash
15101 \end_layout
15103 \begin_layout Plain Layout
15105       
15106 \backslash
15107 @ifundefined{newfangle@chunk@params}{}{%
15108 \end_layout
15110 \begin_layout Plain Layout
15112         (
15113 \backslash
15114 newfangle@chunk@params)%
15115 \end_layout
15117 \begin_layout Plain Layout
15119       }%
15120 \end_layout
15122 \begin_layout Plain Layout
15124       [
15125 \backslash
15126 csname 
15127 \backslash
15128 chunkcount
15129 \backslash
15130 endcsname]~%
15131 \end_layout
15133 \begin_layout Plain Layout
15135       
15136 \backslash
15137 subpageref{
15138 \backslash
15139 firstchunkname}%
15140 \end_layout
15142 \begin_layout Plain Layout
15144     }%
15145 \end_layout
15147 \begin_layout Plain Layout
15149     
15150 \backslash
15151 @ifundefined{newfangle@chunk@append}{}{%
15152 \end_layout
15154 \begin_layout Plain Layout
15156     
15157 \backslash
15158 ifx{}
15159 \backslash
15160 newfangle@chunk@append{x}
15161 \backslash
15162 else%
15163 \end_layout
15165 \begin_layout Plain Layout
15167         ,~add~to~
15168 \backslash
15169 newfangle@chunk@append%
15170 \end_layout
15172 \begin_layout Plain Layout
15174     
15175 \backslash
15177 \end_layout
15179 \begin_layout Plain Layout
15181     }%
15182 \end_layout
15184 \begin_layout Plain Layout
15187 \backslash
15188 global
15189 \backslash
15191 \backslash
15192 newfangle@chunk@append{}%
15193 \end_layout
15195 \begin_layout Plain Layout
15198 \backslash
15199 lstset{append=x}%
15200 \end_layout
15202 \begin_layout Plain Layout
15204   }%
15205 \end_layout
15207 \begin_layout Plain Layout
15210 \end_layout
15212 \begin_layout Plain Layout
15214   
15215 \backslash
15217 \backslash
15218 relax
15219 \backslash
15220 prevchunkname
15221 \backslash
15222 endmoddef
15223 \backslash
15224 else
15225 \backslash
15226 plusendmoddef
15227 \backslash
15229 \end_layout
15231 \begin_layout Plain Layout
15233 %  
15234 \backslash
15235 nwstartdeflinemarkup%
15236 \end_layout
15238 \begin_layout Plain Layout
15240   
15241 \backslash
15242 nwprevnextdefs{
15243 \backslash
15244 prevchunkname}{
15245 \backslash
15246 nextchunkname}%
15247 \end_layout
15249 \begin_layout Plain Layout
15251 %  
15252 \backslash
15253 nwenddeflinemarkup%
15254 \end_layout
15256 \begin_layout Plain Layout
15259 \end_layout
15261 \end_inset
15264 \end_layout
15266 \begin_layout Standard
15267 Originally this was developed as a 
15268 \begin_inset Flex CharStyle:Code
15269 status collapsed
15271 \begin_layout Plain Layout
15272 listings
15273 \end_layout
15275 \end_inset
15277  aspect, in the Init hook, but it was found easier to affect the title without
15278  using a hook --- 
15279 \begin_inset Flex CharStyle:Code
15280 status collapsed
15282 \begin_layout Plain Layout
15284 \backslash
15285 lst@AddToHookExe{PreSet}
15286 \end_layout
15288 \end_inset
15290  is still required to set the listings name to the name passed to the 
15291 \begin_inset Flex CharStyle:Code
15292 status collapsed
15294 \begin_layout Plain Layout
15296 \backslash
15297 Chunk
15298 \end_layout
15300 \end_inset
15302  command, though.
15303 \end_layout
15305 \begin_layout Standard
15306 \begin_inset listings
15307 inline false
15308 status open
15310 \begin_layout Plain Layout
15313 \backslash
15314 lst@BeginAspect{newfangle}
15315 \end_layout
15317 \begin_layout Plain Layout
15320 \backslash
15321 lst@Key{newfangle}{true}[t]{
15322 \backslash
15323 lstKV@SetIf{#1}{true}}
15324 \end_layout
15326 \begin_layout Plain Layout
15329 \backslash
15330 lst@AddToHookExe{PreSet}{
15331 \backslash
15332 global
15333 \backslash
15335 \backslash
15336 lst@intname
15337 \backslash
15338 lst@chunkname}
15339 \end_layout
15341 \begin_layout Plain Layout
15344 \backslash
15345 lst@AddToHook{Init}{}%
15346 \backslash
15347 newfangle@caption}
15348 \end_layout
15350 \begin_layout Plain Layout
15353 \backslash
15354 lst@EndAspect
15355 \end_layout
15357 \end_inset
15360 \end_layout
15362 \begin_layout Subsection
15363 Cross references
15364 \end_layout
15366 \begin_layout Standard
15367 We define the 
15368 \backslash
15369 chunkref command which makes it easy to generate visual references to different
15370  code chunks, e.g.
15371 \end_layout
15373 \begin_layout Standard
15374 \begin_inset Tabular
15375 <lyxtabular version="3" rows="4" columns="2">
15376 <features>
15377 <column alignment="center" valignment="top" width="0">
15378 <column alignment="center" valignment="top" width="0">
15379 <row>
15380 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
15381 \begin_inset Text
15383 \begin_layout Plain Layout
15384 Macro
15385 \end_layout
15387 \end_inset
15388 </cell>
15389 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
15390 \begin_inset Text
15392 \begin_layout Plain Layout
15393 Appearance
15394 \end_layout
15396 \end_inset
15397 </cell>
15398 </row>
15399 <row>
15400 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
15401 \begin_inset Text
15403 \begin_layout Plain Layout
15405 \backslash
15406 chunkref{preamble}
15407 \end_layout
15409 \end_inset
15410 </cell>
15411 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
15412 \begin_inset Text
15414 \begin_layout Plain Layout
15415 \begin_inset ERT
15416 status open
15418 \begin_layout Plain Layout
15421 \backslash
15422 chunkref{preamble}
15423 \end_layout
15425 \end_inset
15428 \end_layout
15430 \end_inset
15431 </cell>
15432 </row>
15433 <row>
15434 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
15435 \begin_inset Text
15437 \begin_layout Plain Layout
15439 \backslash
15440 chunkref[3]{preamble}
15441 \end_layout
15443 \end_inset
15444 </cell>
15445 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
15446 \begin_inset Text
15448 \begin_layout Plain Layout
15449 \begin_inset ERT
15450 status open
15452 \begin_layout Plain Layout
15455 \backslash
15456 chunkref[3]{preamble}
15457 \end_layout
15459 \end_inset
15462 \end_layout
15464 \end_inset
15465 </cell>
15466 </row>
15467 <row>
15468 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
15469 \begin_inset Text
15471 \begin_layout Plain Layout
15473 \backslash
15474 chunkref{preamble}[arg1, arg2]
15475 \end_layout
15477 \end_inset
15478 </cell>
15479 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
15480 \begin_inset Text
15482 \begin_layout Plain Layout
15483 \begin_inset ERT
15484 status open
15486 \begin_layout Plain Layout
15489 \backslash
15490 chunkref{preamble}[arg1, arg2]
15491 \end_layout
15493 \end_inset
15496 \end_layout
15498 \end_inset
15499 </cell>
15500 </row>
15501 </lyxtabular>
15503 \end_inset
15506 \end_layout
15508 \begin_layout Standard
15509 Chunkref can also be used within a code chunk to include another code chunk.
15510  The third optional parameter to chunkref is a comma sepatarated list of
15511  arguments, which will replace defined parameters in the chunkref.
15512 \begin_inset Note Note
15513 status open
15515 \begin_layout Plain Layout
15516 Darn it, if I have: =<
15517 \backslash
15518 chunkref{new-mode-tracker}[{chunks[chunk_name, "language"]},{mode}]> the
15519  inner braces (inside [ ]) cause _ to signify subscript even though we have
15520  lst@ReplaceIn
15521 \end_layout
15523 \end_inset
15526 \end_layout
15528 \begin_layout Standard
15529 \begin_inset listings
15530 inline false
15531 status open
15533 \begin_layout Plain Layout
15536 \backslash
15538 \backslash
15539 chunkref@args#1,{%
15540 \end_layout
15542 \begin_layout Plain Layout
15544   
15545 \backslash
15547 \backslash
15548 arg{#1}%
15549 \end_layout
15551 \begin_layout Plain Layout
15553   
15554 \backslash
15555 lst@ReplaceIn
15556 \backslash
15558 \backslash
15559 lst@filenamerpl%
15560 \end_layout
15562 \begin_layout Plain Layout
15564   
15565 \backslash
15566 arg%
15567 \end_layout
15569 \begin_layout Plain Layout
15571   
15572 \backslash
15573 @ifnextchar){
15574 \backslash
15575 relax}{, 
15576 \backslash
15577 chunkref@args}%
15578 \end_layout
15580 \begin_layout Plain Layout
15583 \end_layout
15585 \begin_layout Plain Layout
15588 \backslash
15589 newcommand
15590 \backslash
15591 chunkref[2][0]{%
15592 \end_layout
15594 \begin_layout Plain Layout
15596   
15597 \backslash
15598 @ifnextchar({
15599 \backslash
15600 chunkref@i{#1}{#2}}{
15601 \backslash
15602 chunkref@i{#1}{#2}()}%
15603 \end_layout
15605 \begin_layout Plain Layout
15608 \end_layout
15610 \begin_layout Plain Layout
15613 \backslash
15615 \backslash
15616 chunkref@i#1#2(#3){%
15617 \end_layout
15619 \begin_layout Plain Layout
15621   
15622 \backslash
15624 \backslash
15625 zero{0}%
15626 \end_layout
15628 \begin_layout Plain Layout
15630   
15631 \backslash
15633 \backslash
15634 chunk{#2}%
15635 \end_layout
15637 \begin_layout Plain Layout
15639   
15640 \backslash
15642 \backslash
15643 chunkno{#1}%
15644 \end_layout
15646 \begin_layout Plain Layout
15648   
15649 \backslash
15651 \backslash
15652 chunkargs{#3}%
15653 \end_layout
15655 \begin_layout Plain Layout
15657   
15658 \backslash
15660 \backslash
15661 chunkno
15662 \backslash
15663 zero%
15664 \end_layout
15666 \begin_layout Plain Layout
15668     
15669 \backslash
15671 \backslash
15672 chunkname{#2-1}%
15673 \end_layout
15675 \begin_layout Plain Layout
15677   
15678 \backslash
15679 else%
15680 \end_layout
15682 \begin_layout Plain Layout
15684     
15685 \backslash
15687 \backslash
15688 chunkname{#2-
15689 \backslash
15690 chunkno}%
15691 \end_layout
15693 \begin_layout Plain Layout
15695   
15696 \backslash
15698 \end_layout
15700 \begin_layout Plain Layout
15702   
15703 \backslash
15705 \backslash
15706 lst@arg
15707 \backslash
15708 chunk%
15709 \end_layout
15711 \begin_layout Plain Layout
15713   
15714 \backslash
15715 lst@ReplaceIn
15716 \backslash
15717 chunk
15718 \backslash
15719 lst@filenamerpl%
15720 \end_layout
15722 \begin_layout Plain Layout
15724   
15725 \backslash
15726 LA{%
15727 \backslash
15728 moddef{%
15729 \end_layout
15731 \begin_layout Plain Layout
15733     {
15734 \backslash
15735 chunk}%
15736 \end_layout
15738 \begin_layout Plain Layout
15740     {%
15741 \end_layout
15743 \begin_layout Plain Layout
15745       
15746 \backslash
15747 nwtagstyle{}
15748 \backslash
15750 \end_layout
15752 \begin_layout Plain Layout
15754       
15755 \backslash
15757 \backslash
15758 chunkno
15759 \backslash
15760 zero%
15761 \end_layout
15763 \begin_layout Plain Layout
15765       
15766 \backslash
15767 else%
15768 \end_layout
15770 \begin_layout Plain Layout
15772       [
15773 \backslash
15774 chunkno]%
15775 \end_layout
15777 \begin_layout Plain Layout
15779       
15780 \backslash
15782 \end_layout
15784 \begin_layout Plain Layout
15786       
15787 \backslash
15789 \backslash
15790 chunkargs
15791 \backslash
15792 empty%
15793 \end_layout
15795 \begin_layout Plain Layout
15797       
15798 \backslash
15799 else%
15800 \end_layout
15802 \begin_layout Plain Layout
15804         (
15805 \backslash
15806 chunkref@args #3,)%
15807 \end_layout
15809 \begin_layout Plain Layout
15811       
15812 \backslash
15814 \end_layout
15816 \begin_layout Plain Layout
15818       ~
15819 \backslash
15820 subpageref{
15821 \backslash
15822 chunkname}%
15823 \end_layout
15825 \begin_layout Plain Layout
15827     }%
15828 \end_layout
15830 \begin_layout Plain Layout
15832   }%
15833 \end_layout
15835 \begin_layout Plain Layout
15837   
15838 \backslash
15840 \backslash
15841 endmoddef%
15842 \end_layout
15844 \begin_layout Plain Layout
15847 \end_layout
15849 \end_inset
15852 \end_layout
15854 \begin_layout Subsection
15855 The end
15856 \end_layout
15858 \begin_layout Standard
15859 \begin_inset listings
15860 inline false
15861 status open
15863 \begin_layout Plain Layout
15866 \end_layout
15868 \begin_layout Plain Layout
15871 \backslash
15872 makeatother
15873 \end_layout
15875 \end_inset
15878 \end_layout
15880 \begin_layout Chapter
15881 Extracting newfangle
15882 \end_layout
15884 \begin_layout Section
15885 Extracting from Lyx
15886 \end_layout
15888 \begin_layout Standard
15889 To extract from LyX, you will need to configure LyX as explained in section
15891 \begin_inset CommandInset ref
15892 LatexCommand ref
15893 reference "sub:Configuring-the-build"
15895 \end_inset
15898 \end_layout
15900 \begin_layout Standard
15901 \begin_inset CommandInset label
15902 LatexCommand label
15903 name "lyx-build-script"
15905 \end_inset
15907 And this lyx-build scrap will extract newfangle for me.
15908 \end_layout
15910 \begin_layout Chunk
15911 lyx-build,language=sh
15912 \end_layout
15914 \begin_layout Standard
15915 \begin_inset listings
15916 inline false
15917 status open
15919 \begin_layout Plain Layout
15921 #! /bin/sh
15922 \end_layout
15924 \begin_layout Plain Layout
15926 set -x
15927 \end_layout
15929 \begin_layout Plain Layout
15931 \end_layout
15933 \begin_layout Plain Layout
15936 \backslash
15937 chunkref{lyx-build-helper}>
15938 \end_layout
15940 \begin_layout Plain Layout
15942 cd $PROJECT_DIR || exit 1
15943 \end_layout
15945 \begin_layout Plain Layout
15947 \end_layout
15949 \begin_layout Plain Layout
15951 /usr/local/bin/newfangle -R./newfangle $TEX_SRC > ./newfangle
15952 \end_layout
15954 \begin_layout Plain Layout
15956 /usr/local/bin/newfangle -R./newfangle.module $TEX_SRC > ./newfangle.module
15957 \end_layout
15959 \begin_layout Plain Layout
15961 \end_layout
15963 \begin_layout Plain Layout
15966 \backslash
15967 chunkref{test:helpers}>
15968 \end_layout
15970 \begin_layout Plain Layout
15972 export NEWFANGLE=./newfangle
15973 \end_layout
15975 \begin_layout Plain Layout
15977 export TMP=${TMP:-/tmp}
15978 \end_layout
15980 \begin_layout Plain Layout
15983 \backslash
15984 chunkref{test:run-tests}>
15985 \end_layout
15987 \begin_layout Plain Layout
15989 # Now check that we can extract a newfangle that also passes the tests!
15990 \end_layout
15992 \begin_layout Plain Layout
15994 $NEWFANGLE -R./newfangle $TEX_SRC > ./new-newfangle
15995 \end_layout
15997 \begin_layout Plain Layout
15999 export NEWFANGLE=./new-newfangle
16000 \end_layout
16002 \begin_layout Plain Layout
16005 \backslash
16006 chunkref{test:run-tests}>
16007 \end_layout
16009 \end_inset
16012 \end_layout
16014 \begin_layout Chunk
16015 test:run-tests
16016 \end_layout
16018 \begin_layout Standard
16019 \begin_inset listings
16020 inline false
16021 status open
16023 \begin_layout Plain Layout
16025 # run tests
16026 \end_layout
16028 \begin_layout Plain Layout
16030 $NEWFANGLE -Rpca-test.awk $TEX_SRC | awk -f - || exit 1
16031 \end_layout
16033 \begin_layout Plain Layout
16036 \backslash
16037 chunkref{test:cromulence}>
16038 \end_layout
16040 \begin_layout Plain Layout
16043 \backslash
16044 chunkref{test:escapes}>
16045 \end_layout
16047 \begin_layout Plain Layout
16050 \backslash
16051 chunkref{test:chunk-params}>
16052 \end_layout
16054 \end_inset
16057 \end_layout
16059 \begin_layout Standard
16060 With a lyx-build-helper
16061 \end_layout
16063 \begin_layout Chunk
16064 lyx-build-helper,language=sh
16065 \end_layout
16067 \begin_layout Standard
16068 \begin_inset listings
16069 inline false
16070 status open
16072 \begin_layout Plain Layout
16074 PROJECT_DIR="$LYX_r"
16075 \end_layout
16077 \begin_layout Plain Layout
16079 LYX_SRC="$PROJECT_DIR/${LYX_i%.tex}.lyx"
16080 \end_layout
16082 \begin_layout Plain Layout
16084 TEX_DIR="$LYX_p"
16085 \end_layout
16087 \begin_layout Plain Layout
16089 TEX_SRC="$TEX_DIR/$LYX_i"
16090 \end_layout
16092 \end_inset
16095 \end_layout
16097 \begin_layout Section
16098 Extracting documentation
16099 \end_layout
16101 \begin_layout Chunk
16102 ./gen-www
16103 \end_layout
16105 \begin_layout Standard
16106 \begin_inset listings
16107 inline false
16108 status open
16110 \begin_layout Plain Layout
16112 #python -m elyxer --css lyx.css $LYX_SRC | 
16113 \backslash
16115 \end_layout
16117 \begin_layout Plain Layout
16119 #  iconv -c -f utf-8 -t ISO-8859-1//TRANSLIT | 
16120 \backslash
16122 \end_layout
16124 \begin_layout Plain Layout
16126 #  sed 's/UTF-8"
16127 \backslash
16129 \backslash
16130 )>/ISO-8859-1"
16131 \backslash
16132 1>/' > www/docs/newfangle.html
16133 \end_layout
16135 \begin_layout Plain Layout
16137 \end_layout
16139 \begin_layout Plain Layout
16141 ( mkdir -p www/docs/newfangle && cd www/docs/newfangle && 
16142 \backslash
16144 \end_layout
16146 \begin_layout Plain Layout
16148   lyx -e latex ../../../newfangle.lyx && 
16149 \backslash
16151 \end_layout
16153 \begin_layout Plain Layout
16155   htlatex ../../../newfangle.tex "xhtml,fn-in" && 
16156 \backslash
16158 \end_layout
16160 \begin_layout Plain Layout
16162   sed -i -e 's/<!--l
16163 \backslash
16165  [0-9][0-9]* *-->//g' newfangle.html
16166 \end_layout
16168 \begin_layout Plain Layout
16171 \end_layout
16173 \begin_layout Plain Layout
16175 \end_layout
16177 \begin_layout Plain Layout
16179 ( mkdir -p www/docs/literate && cd www/docs/literate && 
16180 \backslash
16182 \end_layout
16184 \begin_layout Plain Layout
16186   lyx -e latex ../../../literate.lyx && 
16187 \backslash
16189 \end_layout
16191 \begin_layout Plain Layout
16193   htlatex ../../../literate.tex "xhtml,fn-in" && 
16194 \backslash
16196 \end_layout
16198 \begin_layout Plain Layout
16200   sed -i -e 's/<!--l
16201 \backslash
16203  [0-9][0-9]* *-->$//g' literate.html
16204 \end_layout
16206 \begin_layout Plain Layout
16209 \end_layout
16211 \end_inset
16214 \end_layout
16216 \begin_layout Section
16217 Extracting from the command line
16218 \end_layout
16220 \begin_layout Standard
16221 First you will need the tex output, then you can extract:
16222 \end_layout
16224 \begin_layout Chunk
16225 lyx-build-manual,language=sh
16226 \end_layout
16228 \begin_layout Standard
16229 \begin_inset listings
16230 inline false
16231 status open
16233 \begin_layout Plain Layout
16235 lyx -e latex newfangle.lyx
16236 \end_layout
16238 \begin_layout Plain Layout
16240 newfangle -R./newfangle newfangle.tex > ./newfangle
16241 \end_layout
16243 \begin_layout Plain Layout
16245 newfangle -R./newfangle.module newfangle.tex > ./newfangle.module
16246 \end_layout
16248 \end_inset
16251 \end_layout
16253 \begin_layout Section
16254 Testing
16255 \end_layout
16257 \begin_layout Chunk
16258 test:helpers
16259 \end_layout
16261 \begin_layout Standard
16262 \begin_inset listings
16263 inline false
16264 status open
16266 \begin_layout Plain Layout
16268 passtest() {
16269 \end_layout
16271 \begin_layout Plain Layout
16273   if "$@"
16274 \end_layout
16276 \begin_layout Plain Layout
16278   then echo "Passed"
16279 \end_layout
16281 \begin_layout Plain Layout
16283   else echo "Failed"
16284 \end_layout
16286 \begin_layout Plain Layout
16288        return 1
16289 \end_layout
16291 \begin_layout Plain Layout
16293   fi
16294 \end_layout
16296 \begin_layout Plain Layout
16299 \end_layout
16301 \begin_layout Plain Layout
16303 \end_layout
16305 \begin_layout Plain Layout
16307 failtest() {
16308 \end_layout
16310 \begin_layout Plain Layout
16312   if ! "$@"
16313 \end_layout
16315 \begin_layout Plain Layout
16317   then echo "Passed"
16318 \end_layout
16320 \begin_layout Plain Layout
16322   else echo "Failed"
16323 \end_layout
16325 \begin_layout Plain Layout
16327        return 1
16328 \end_layout
16330 \begin_layout Plain Layout
16332   fi
16333 \end_layout
16335 \begin_layout Plain Layout
16338 \end_layout
16340 \end_inset
16343 \end_layout
16345 \begin_layout Part
16346 Tests
16347 \end_layout
16349 \begin_layout Chapter
16350 Chunk Parameters
16351 \end_layout
16353 \begin_layout Chunk
16354 test:chunk-params:sub,language=,params=THING;colour
16355 \end_layout
16357 \begin_layout Standard
16358 \begin_inset listings
16359 inline false
16360 status open
16362 \begin_layout Plain Layout
16364 I see a ${THING},
16365 \end_layout
16367 \begin_layout Plain Layout
16369 a ${THING} of colour ${colour}, 
16370 \end_layout
16372 \begin_layout Plain Layout
16374 and looking closer =<
16375 \backslash
16376 chunkref{test:chunk-params:sub:sub}(${colour})>
16377 \end_layout
16379 \end_inset
16382 \end_layout
16384 \begin_layout Chunk
16385 test:chunk-params:sub:sub,params=colour,language=
16386 \end_layout
16388 \begin_layout Standard
16389 \begin_inset listings
16390 inline false
16391 status open
16393 \begin_layout Plain Layout
16395 a funny shade of ${colour}
16396 \end_layout
16398 \end_inset
16401 \end_layout
16403 \begin_layout Chunk
16404 test:chunk-params:text,language=
16405 \end_layout
16407 \begin_layout Standard
16408 \begin_inset listings
16409 inline false
16410 status open
16412 \begin_layout Plain Layout
16414 What do you see? "=<
16415 \backslash
16416 chunkref{test:chunk-params:sub}(joe, red)>"
16417 \end_layout
16419 \begin_layout Plain Layout
16421 Well, fancy!
16422 \end_layout
16424 \end_inset
16427 \end_layout
16429 \begin_layout Standard
16430 Should generate output:
16431 \end_layout
16433 \begin_layout Chunk
16434 test:chunk-params:result
16435 \end_layout
16437 \begin_layout Standard
16438 \begin_inset listings
16439 inline false
16440 status open
16442 \begin_layout Plain Layout
16444 What do you see? "I see a joe,
16445 \end_layout
16447 \begin_layout Plain Layout
16449                   a joe of colour red, 
16450 \end_layout
16452 \begin_layout Plain Layout
16454                   and looking closer a funny shade of red"
16455 \end_layout
16457 \begin_layout Plain Layout
16459 Well, fancy!
16460 \end_layout
16462 \end_inset
16465 \end_layout
16467 \begin_layout Standard
16468 And this chunk will perform the test:
16469 \end_layout
16471 \begin_layout Chunk
16472 test:chunk-params
16473 \end_layout
16475 \begin_layout Standard
16476 \begin_inset listings
16477 inline false
16478 status open
16480 \begin_layout Plain Layout
16482 $NEWFANGLE -Rtest:chunk-params:result $TEX_SRC > $TMP/answer || exit 1
16483 \end_layout
16485 \begin_layout Plain Layout
16487 $NEWFANGLE -Rtest:chunk-params:text $TEX_SRC > $TMP/result || exit 1
16488 \end_layout
16490 \begin_layout Plain Layout
16492 passtest diff $TMP/answer $TMP/result || (echo test:chunk-params:text failed
16493  ; exit 1)
16494 \end_layout
16496 \end_inset
16499 \end_layout
16501 \begin_layout Chapter
16502 Compile-log-lyx
16503 \begin_inset CommandInset label
16504 LatexCommand label
16505 name "cha:Compile-log-lyx"
16507 \end_inset
16510 \end_layout
16512 \begin_layout Chunk
16513 ./compile-log-lyx,language=sh
16514 \end_layout
16516 \begin_layout Standard
16517 \begin_inset listings
16518 inline false
16519 status open
16521 \begin_layout Plain Layout
16523 #! /bin/sh
16524 \end_layout
16526 \begin_layout Plain Layout
16528 # can't use gtkdialog -i, cos it uses the "source" command which ubuntu
16529  sh doesn't have
16530 \end_layout
16532 \begin_layout Plain Layout
16534 \end_layout
16536 \begin_layout Plain Layout
16538 main() {
16539 \end_layout
16541 \begin_layout Plain Layout
16543   errors="/tmp/compile.log.$$"
16544 \end_layout
16546 \begin_layout Plain Layout
16548 #  if grep '^[^ ]*:
16549 \backslash
16550 ( In 
16551 \backslash
16552 |[0-9][0-9]*: [^ ]*:
16553 \backslash
16554 )' > $errors
16555 \end_layout
16557 \begin_layout Plain Layout
16559 if grep '^[^ ]*(
16560 \backslash
16561 ([0-9][0-9]*
16562 \backslash
16563 )) *: *
16564 \backslash
16565 (error
16566 \backslash
16567 |warning
16568 \backslash
16569 )' > $errors
16570 \end_layout
16572 \begin_layout Plain Layout
16574   then
16575 \end_layout
16577 \begin_layout Plain Layout
16579     sed -i -e 's/^[^ ]*[/
16580 \backslash
16582 \backslash
16584 \backslash
16585 ([^/
16586 \backslash
16588 \backslash
16590 \backslash
16592 \backslash
16593 ([ 0-9][ 0-9]*
16594 \backslash
16595 )) *: */
16596 \backslash
16598 \backslash
16600 \backslash
16601 2|/' $errors
16602 \end_layout
16604 \begin_layout Plain Layout
16606     COMPILE_DIALOG='
16607 \end_layout
16609 \begin_layout Plain Layout
16611  <vbox>
16612 \end_layout
16614 \begin_layout Plain Layout
16616   <text>
16617 \end_layout
16619 \begin_layout Plain Layout
16621     <label>Compiler errors:</label>
16622 \end_layout
16624 \begin_layout Plain Layout
16626   </text>
16627 \end_layout
16629 \begin_layout Plain Layout
16631   <tree exported_column="0">
16632 \end_layout
16634 \begin_layout Plain Layout
16636     <variable>LINE</variable>
16637 \end_layout
16639 \begin_layout Plain Layout
16641     <height>400</height><width>800</width>
16642 \end_layout
16644 \begin_layout Plain Layout
16646     <label>File | Line | Message</label>
16647 \end_layout
16649 \begin_layout Plain Layout
16651     <action>'".
16652  $SELF ; "'lyxgoto $LINE</action>
16653 \end_layout
16655 \begin_layout Plain Layout
16657     <input>'"cat $errors"'</input>
16658 \end_layout
16660 \begin_layout Plain Layout
16662   </tree>
16663 \end_layout
16665 \begin_layout Plain Layout
16667   <hbox>
16668 \end_layout
16670 \begin_layout Plain Layout
16672    <button><label>Build</label>
16673 \end_layout
16675 \begin_layout Plain Layout
16677      <action>lyxclient -c "LYXCMD:build-program" &</action>
16678 \end_layout
16680 \begin_layout Plain Layout
16682    </button>
16683 \end_layout
16685 \begin_layout Plain Layout
16687    <button ok></button>
16688 \end_layout
16690 \begin_layout Plain Layout
16692   </hbox>
16693 \end_layout
16695 \begin_layout Plain Layout
16697  </vbox>
16698 \end_layout
16700 \begin_layout Plain Layout
16703 \end_layout
16705 \begin_layout Plain Layout
16707     export COMPILE_DIALOG
16708 \end_layout
16710 \begin_layout Plain Layout
16712     ( gtkdialog --program=COMPILE_DIALOG ; rm $errors ) &
16713 \end_layout
16715 \begin_layout Plain Layout
16717   else
16718 \end_layout
16720 \begin_layout Plain Layout
16722     rm $errors
16723 \end_layout
16725 \begin_layout Plain Layout
16727   fi
16728 \end_layout
16730 \begin_layout Plain Layout
16733 \end_layout
16735 \begin_layout Plain Layout
16737 \end_layout
16739 \begin_layout Plain Layout
16741 lyxgoto() {
16742 \end_layout
16744 \begin_layout Plain Layout
16746   file="${LINE%:*}"
16747 \end_layout
16749 \begin_layout Plain Layout
16751   line="${LINE##*:}"
16752 \end_layout
16754 \begin_layout Plain Layout
16756   extraline=`cat $file | head -n $line | tac | sed '/^
16757 \backslash
16759 \backslash
16761 \backslash
16763 \backslash
16764 begin{lstlisting}/q' | wc -l`
16765 \end_layout
16767 \begin_layout Plain Layout
16769   extraline=`expr $extraline - 1`
16770 \end_layout
16772 \begin_layout Plain Layout
16774   lyxclient -c "LYXCMD:command-sequence server-goto-file-row $file $line
16775  ; char-forward ; repeat $extraline paragraph-down ; paragraph-up-select"
16776 \end_layout
16778 \begin_layout Plain Layout
16781 \end_layout
16783 \begin_layout Plain Layout
16785 \end_layout
16787 \begin_layout Plain Layout
16789 SELF="$0"
16790 \end_layout
16792 \begin_layout Plain Layout
16794 if test -z "$COMPILE_DIALOG"
16795 \end_layout
16797 \begin_layout Plain Layout
16799 then main "$@" 
16800 \end_layout
16802 \begin_layout Plain Layout
16805 \end_layout
16807 \end_inset
16810 \end_layout
16812 \end_body
16813 \end_document