1 #LyX 1.6.4 created this file. For more info see http://www.lyx.org/
8 %\definecolor{darkgreen}{rgb}{0,0.5,0}
9 \lstset{numbers=left, stepnumber=1, numbersep=5pt, breaklines=false,
10 basicstyle=\footnotesize\ttfamily,
11 %keywordstyle=\color{darkgreen},
12 numberstyle=\tiny,language=C,columns=fullflexible,
15 \use_default_options true
24 \font_typewriter default
25 \font_default_family default
32 \paperfontsize default
35 \pdf_title "Newfangle"
36 \pdf_author "Sam Liddicott"
37 \pdf_subject "Literate Programing"
38 \pdf_keywords "notangle noweb noweave literate programming cweb"
40 \pdf_bookmarksnumbered false
41 \pdf_bookmarksopen false
42 \pdf_bookmarksopenlevel 1
54 \paperorientation portrait
57 \paragraph_separation skip
59 \quotes_language english
62 \paperpagestyle default
63 \tracking_changes false
83 \begin_layout Chapter*
87 \begin_layout Standard
92 is a tool for newfangled literate programming.
93 Newfangled is defined as
95 New and often needlessly novel
104 \begin_layout Standard
105 In this case, newfangled means yet another new and improved method for literate
109 \begin_layout Standard
114 has a long history starting with the great
118 whose literate programming tools seem to make use of as many escaped abbreviati
119 ons for semantic markup as TeX itself.
122 \begin_layout Standard
131 set of tools (notangle, noweave and noroots) and helpfully reduced the
132 amount of magic character sequences to just
133 \begin_inset Flex CharStyle:Code
136 \begin_layout Plain Layout
143 \begin_inset Flex CharStyle:Code
146 \begin_layout Plain Layout
152 , and in doing so brought the wonders of literate programming within my
156 \begin_layout Standard
157 Using LyX for LaTeX editing, I had various troubles with the noweb tools,
158 some of which were my fault, some of which were noweb's fault and some
159 of which were LyX's fault.
162 \begin_layout Standard
167 generally brought literate programming to the masses through removing some
168 of the complexity of the original literate programming, but this would
169 be of no advantage to me if the LyX --- LaTeX combination brought more
170 complications in their place.
173 \begin_layout Standard
178 was thus born --- as an awk replacement for notangle, adding some important
179 features, like better integration with LyX and LaTeX, multiple output format
180 conversions, and fixing notangle bugs like indenting when using -L for
184 \begin_layout Standard
185 Significantly, newfangle is just one program which replaces various programs
187 Specifically noweave is done away with and implemented directly as LaTeX
188 macros, and noroots is implemented as a function of the untangler
195 \begin_layout Standard
196 Newfangle is written in awk for portability reasons, awk being available
198 A python conversion will probably be attempted for the benefit of LyX.
199 (Hasn't anyone implemented awk in python yet?)
202 \begin_layout Section*
206 \begin_layout Enumerate
207 ^^ is always going to be a problem, see texbytopic 1.2.2 (Work out what I
211 \begin_layout Enumerate
212 copy over up to date Makefile guide from noweb-lyx document
215 \begin_layout Enumerate
216 Make chunk-name settings only apply to chunks with that name
219 \begin_layout Enumerate
220 indent of multi-line chunks may be mode dependant (i.e.
221 not in string literals)
224 \begin_layout Enumerate
225 support chunk-param usage =<
230 \begin_layout Enumerate
231 trim spaces from param
234 \begin_layout Enumerate
235 add support for other commands in =<...>, starting with
237 label which takes the line-number within the chunk, and maybe should also
238 take the chunk name/page
241 \begin_layout Enumerate
242 cant have listing inside a ruled box
245 \begin_layout Enumerate
246 when a parameterized chunk is included as well as the #line emission, say
247 what the paremeters were for that invocation.
250 \begin_layout Enumerate
251 with 2 macro expansions on one line ${} ${} the first is too greedy and
255 \begin_layout Chapter*
259 \begin_layout Standard
260 \begin_inset CommandInset label
266 Newfangle is licensed under the GPL 3
267 \begin_inset CommandInset citation
274 This doesn't mean that you can't use or distribute newfangle with sources
275 of an incompatible license, but it means you must make the source of newfangle
280 gpl3-copyright,language=
283 \begin_layout Standard
284 \begin_inset listings
288 \begin_layout Plain Layout
290 #newfangle - fully featured notangle replacement in awk
293 \begin_layout Plain Layout
298 \begin_layout Plain Layout
300 #Copyright (C) Sam Liddicott 2009
303 \begin_layout Plain Layout
308 \begin_layout Plain Layout
310 #This program is free software: you can redistribute it and/or modify
313 \begin_layout Plain Layout
315 #it under the terms of the GNU General Public License as published by
318 \begin_layout Plain Layout
320 #the Free Software Foundation, either version 3 of the License, or
323 \begin_layout Plain Layout
325 #(at your option) any later version.
328 \begin_layout Plain Layout
333 \begin_layout Plain Layout
335 #This program is distributed in the hope that it will be useful,
338 \begin_layout Plain Layout
340 #but WITHOUT ANY WARRANTY; without even the implied warranty of
343 \begin_layout Plain Layout
345 #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
349 \begin_layout Plain Layout
351 #GNU General Public License for more details.
354 \begin_layout Plain Layout
359 \begin_layout Plain Layout
361 #You should have received a copy of the GNU General Public License
364 \begin_layout Plain Layout
366 #along with this program.
367 If not, see <http://www.gnu.org/licenses/>.
375 \begin_layout Standard
376 \begin_inset CommandInset toc
377 LatexCommand tableofcontents
388 \begin_layout Chapter
392 \begin_layout Standard
393 Newfangle is a replacement for noweb, which consists of
394 \begin_inset Flex CharStyle:Code
397 \begin_layout Plain Layout
404 \begin_inset Flex CharStyle:Code
407 \begin_layout Plain Layout
414 \begin_inset Flex CharStyle:Code
417 \begin_layout Plain Layout
426 \begin_layout Standard
428 \begin_inset Flex CharStyle:Code
431 \begin_layout Plain Layout
438 \begin_inset Flex CharStyle:Code
441 \begin_layout Plain Layout
447 it can read multiple named files, or from stdin.
450 \begin_layout Section
454 \begin_layout Standard
455 The -r option causes newfangle to behave like noroots.
458 \begin_layout LyX-Code
459 newfangle -r filename.tex
462 \begin_layout Standard
463 will print out the newfangle roots of a tex file.
467 \begin_layout Standard
469 \begin_inset Flex CharStyle:Code
472 \begin_layout Plain Layout
478 command, the roots are not enclosed in
479 \begin_inset Flex CharStyle:Code
482 \begin_layout Plain Layout
488 , unless at least one of the roots is defined using the
489 \begin_inset Flex CharStyle:Code
492 \begin_layout Plain Layout
499 \begin_inset Flex CharStyle:Code
502 \begin_layout Plain Layout
511 \begin_layout Standard
512 Also, unlike noroots, it prints out all roots --- not just those that are
514 I find that a root not being used, doesn't make it particularly top level.
515 My convention is that top level roots to be extracted begin with
516 \begin_inset Flex CharStyle:Code
519 \begin_layout Plain Layout
525 and have the form of a filename.
528 \begin_layout Section
532 \begin_layout Standard
534 \begin_inset Flex CharStyle:Code
537 \begin_layout Plain Layout
544 \begin_inset Flex CharStyle:Code
547 \begin_layout Plain Layout
553 options are supported.
556 \begin_layout Standard
557 The standard way to extract a file would be:
560 \begin_layout LyX-Code
561 newfangle -R./Makefile.inc newfangle.tex > ./Makefile.inc
564 \begin_layout Standard
566 \begin_inset Flex CharStyle:Code
569 \begin_layout Plain Layout
576 \begin_inset Flex CharStyle:Code
579 \begin_layout Plain Layout
585 option does not break indenting; also the
586 \begin_inset Flex CharStyle:Code
589 \begin_layout Plain Layout
595 option does not interrupt (and break) multi-line C macros --- or indeed
596 any line ending with a backslash.
597 This does mean that sometimes the compiler might calculate the source line
598 wrongly when generating error messages in such cases, but there isn't any
599 other way around if multi-line macros include other chunks.
602 \begin_layout Section
603 Formatting source in LaTeX
606 \begin_layout Standard
607 The noweave replacement is a set of LaTeX macros dependant upon
611 , and which can be included with:
614 \begin_layout LyX-Code
617 usepackage{newfangle.sty}
620 \begin_layout Standard
621 The LaTeX macros are shown in section
622 \begin_inset CommandInset ref
624 reference "sec:Latex-Macros"
628 , and are part of a LyX module file
629 \begin_inset Flex CharStyle:Code
632 \begin_layout Plain Layout
638 , which automatically includes the macros in the document pre-amble when
639 the newfangle LyX module is used.
642 \begin_layout Standard
643 Because the noweave replacement is impemented in LaTeX, there is no processing
644 stage required before running the
645 \begin_inset Flex CharStyle:Code
648 \begin_layout Plain Layout
655 LaTeX may need running two or more times, so that the code chunk references
656 can be fully calculated.
659 \begin_layout Standard
661 \begin_inset Flex CharStyle:Code
664 \begin_layout Plain Layout
670 package is required as it is used for formatting the code chunk captions
673 \begin_layout Standard
675 \begin_inset Flex CharStyle:Code
678 \begin_layout Plain Layout
684 package is also required, as it is used for formatting the code chunks
688 \begin_layout Standard
690 \begin_inset Flex CharStyle:Code
693 \begin_layout Plain Layout
699 package is also required.
702 \begin_layout Chapter
703 Literate Programming with Newfangle
706 \begin_layout Standard
708 Should really follow on from a part-0 explanation of what literate programming
712 \begin_layout Chapter
713 Using Newfangle with LyX
716 \begin_layout Section
720 \begin_layout Subsection
721 Installing the LyX module
724 \begin_layout Standard
726 \begin_inset Flex CharStyle:Code
729 \begin_layout Plain Layout
735 to your LyX layouts directory, which for unix users will be
736 \begin_inset Flex CharStyle:Code
739 \begin_layout Plain Layout
748 \begin_layout Standard
749 You will need to reconfigure LyX by clicking Tools\SpecialChar \menuseparator
750 Reconfigure, and then
754 \begin_layout Subsection
755 \begin_inset CommandInset label
757 name "sub:Configuring-the-build"
761 Configuring the build script
764 \begin_layout Standard
765 Make sure you don't have a conversion defined for Lyx → Program
768 \begin_layout Standard
769 From the menu Tools\SpecialChar \menuseparator
770 Preferences, add a conversion from Latex(Plain) → Program
774 \begin_layout LyX-Code
775 set -x ; newfangle -Rlyx-build $$i |
778 \begin_layout LyX-Code
779 env LYX_b=$$b LYX_i=$$i LYX_o=$$o LYX_p=$$p LYX_r=$$r bash
782 \begin_layout Standard
783 (But don't cut-n-paste it from this document or you'll be pasting a multi-line
784 string which will break your lyx preferences file).
788 \begin_layout Standard
789 I hope that one day, LyX will set these into the environment when calling
793 \begin_layout Standard
794 You may also want to consider adding options to this conversion\SpecialChar \ldots{}
798 \begin_layout LyX-Code
799 parselog=/usr/share/lyx/scripts/listerrors
802 \begin_layout Standard
803 \SpecialChar \ldots{}
804 but if you do you will lose your stderr
808 \begin_layout Plain Layout
809 There is some bash plumbing to get a copy of stderr but this footnote is
818 \begin_layout Standard
819 Now, a shell script chunk called
820 \begin_inset Flex CharStyle:Code
823 \begin_layout Plain Layout
829 will be extracted and run whenever you choose the Document\SpecialChar \menuseparator
834 \begin_layout Standard
835 The lyx-build script for this document is in section
836 \begin_inset CommandInset ref
838 reference "lyx-build-script"
842 and on a unix system will extract
843 \begin_inset Flex CharStyle:Code
846 \begin_layout Plain Layout
853 \begin_inset Flex CharStyle:Code
856 \begin_layout Plain Layout
865 \begin_layout Subsection
866 Preparing your Lyx document
869 \begin_layout Standard
870 It is not necessary to base your literate document on any of the original
871 LyX literate classes; so select a regular class for your document type.
874 \begin_layout Standard
890 \begin_layout Standard
891 In the drop-down style listbox you should notice a new style defined, called
899 \begin_layout Standard
900 When you wish to insert a literate chunk, you enter it's plain name in the
901 Chunk style, instead of the older method that used
902 \begin_inset Flex CharStyle:Code
905 \begin_layout Plain Layout
912 Following the chunk name, you insert a listing with: Insert\SpecialChar \menuseparator
916 \begin_layout Standard
917 Inside the white listing box you can type (or paste using shift+ctrl+V)
919 There is not need to use ctrl+enter at the end of lines as with some older
920 LyX literate techniques --- just press enter as normal.
923 \begin_layout Subsubsection
924 Customising the listing appearance
927 \begin_layout Standard
928 In the final document, the code is formatted using the
933 The chunk style doesn't just define the chunk name, but can also define
934 any other chunk options supported by the lstlistings package
935 \begin_inset Flex CharStyle:Code
938 \begin_layout Plain Layout
947 In fact, what you type in the chunk style is raw latex.
948 If you want to set the chunk language without having to right-click the
950 \begin_inset Flex CharStyle:Code
953 \begin_layout Plain Layout
959 after the chunk name.
962 \begin_layout Standard
963 Of course you can do this by editing the listings box advanced properties
964 by right-clicking on the listings box, but that takes longer, and you can't
965 see at-a-glance what the advanced settings are while editing the document;
966 also advanced settings apply only to that box --- the chunk settings apply
967 through the rest of the document
971 \begin_layout Plain Layout
972 It ought to apply only to subsequent chunks of the same name.
979 \begin_inset Note Note
982 \begin_layout Plain Layout
983 So make sure they only apply to chunks of that name
991 \begin_layout Subsubsection
992 Global customisations
995 \begin_layout Standard
1000 is used to set the code chunks, it's
1001 \begin_inset Flex CharStyle:Code
1004 \begin_layout Plain Layout
1012 command can be used in the pre-amble to set some document wide settings.
1015 \begin_layout Standard
1016 If your source has many words with long sequences of capital letters, then
1018 \begin_inset Flex CharStyle:Code
1021 \begin_layout Plain Layout
1022 columns=fullflexible
1027 may be a good idea, or the capital letters will get crowded.
1028 (I think lstlistings ought to use a slightly smaller font for captial letters
1029 so that they still fit).
1032 \begin_layout Standard
1034 \begin_inset Flex CharStyle:Code
1037 \begin_layout Plain Layout
1045 looks more normal for code, but has no bold (unless luximono is used, but
1046 it doesn't work for me); so I use
1047 \begin_inset Flex CharStyle:Code
1050 \begin_layout Plain Layout
1060 \begin_inset Flex CharStyle:Code
1063 \begin_layout Plain Layout
1072 \begin_inset Flex CharStyle:Code
1075 \begin_layout Plain Layout
1076 columns=fullflexible
1081 is used or the wrong letter spacing is used.
1084 \begin_layout Standard
1085 In my LeTeX pre-amble I usually specialise my code format with:
1089 document-preamble,language=tex
1092 \begin_layout Standard
1093 \begin_inset listings
1097 \begin_layout Plain Layout
1104 \begin_layout Plain Layout
1108 definecolor{darkgreen}{rgb}{0,0.5,0}
1111 \begin_layout Plain Layout
1115 lstset{numbers=left, stepnumber=5, numbersep=5pt, breaklines=false,
1118 \begin_layout Plain Layout
1127 \begin_layout Plain Layout
1134 \begin_layout Plain Layout
1138 tiny,language=C,columns=fullflexible,
1141 \begin_layout Plain Layout
1143 numberfirstline=true
1146 \begin_layout Plain Layout
1156 \begin_layout Chapter
1157 Newfangle with Makefiles
1160 \begin_layout Standard
1161 \begin_inset Note Note
1164 \begin_layout Plain Layout
1165 This chapter needs revising
1171 \begin_inset Note Greyedout
1174 \begin_layout Plain Layout
1175 This chapter needs revising
1180 Here we describe a Makefile.inc that you can include in your own Makefiles,
1181 or glue as a recursive make to other projects.
1184 \begin_layout Standard
1185 The Makefile.inc described here was put together for a Samba4 vfs module,
1186 but can be used in any Make project, including automake projects.
1189 \begin_layout Section
1190 A word about makefiles formats
1193 \begin_layout Standard
1194 Whitespace formatting is very important in a Makefile.
1195 The first character of each command line must be a TAB.
1198 \begin_layout LyX-Code
1199 target: pre-requisite
1200 \begin_inset Newline newline
1204 \begin_inset Newline newline
1210 \begin_layout Standard
1211 But a TAB is pretty hard to enter into most of the Lyx formats and insets
1213 An alternative is to use a semi-colon after the pre-requisite, and a backslash
1214 at the end of each line (except the last).
1215 Then any whitespace (or none) can prefix each action.
1218 \begin_layout LyX-Code
1219 target: pre-requisite ;
1222 \begin_inset Newline newline
1228 \begin_inset Newline newline
1234 \begin_layout Standard
1235 This is the style that we use and it works pretty well for GNU make at least.
1238 \begin_layout Standard
1239 We also adopt a convention that code chunks whose names beginning with ./
1240 should always be automatically extracted from the document.
1241 Code chunks whose names do not begin with ./ are for internal reference.
1242 (This doesn't prevent such chunks from being extracted directly).
1245 \begin_layout Section
1246 Boot-strapping the extraction
1249 \begin_layout Subsection
1253 \begin_layout Standard
1254 \begin_inset CommandInset label
1256 name "sub:Bootstrap-Using-a-Makefile"
1260 It seems convenient to have the makefile extract or update the C source
1261 files as part of it's operation.
1262 It also seems convenient to have the makefile itself extracted from this
1266 \begin_layout Standard
1267 It would also be convenient to have the code to extract the makefile from
1268 this document to also be part of this document, however we have to start
1269 somewhere and this unfortunately requires us to type at least a few words
1270 by hand to start things off.
1273 \begin_layout Standard
1274 Therefore we will have a minimal root fragment, which, when extracted, can
1275 cope with extracting the rest of the source.
1276 perhaps with this shell script, which could be called
1281 \begin_inset Note Note
1284 \begin_layout Plain Layout
1285 FIX THIS CHUNK AND TEST IT
1297 \begin_layout Standard
1298 \begin_inset listings
1302 \begin_layout Plain Layout
1307 \begin_layout Plain Layout
1311 \begin_layout Plain Layout
1313 MAKE_SRC="${1:-${NW_LYX:-../../noweb-lyx/noweb-lyx3.lyx}}"
1316 \begin_layout Plain Layout
1318 MAKE_SRC=`dirname "$MAKE_SRC"`/`basename "$MAKE_SRC" .lyx`
1321 \begin_layout Plain Layout
1323 NOWEB_SRC="${2:-${NOWEB_SRC:-$MAKE_SRC.lyx}}"
1326 \begin_layout Plain Layout
1328 lyx -e latex $MAKE_SRC
1331 \begin_layout Plain Layout
1335 \begin_layout Plain Layout
1337 newfangle -R./Makefile.inc ${MAKE_SRC}.tex
1342 \begin_layout Plain Layout
1344 | sed "/NEWFANGLE_SOURCE=/s/^/#/;T;aNOWEB_SOURCE=$NEWFANGLE_SRC"
1349 \begin_layout Plain Layout
1351 | cpif ./Makefile.inc
1354 \begin_layout Plain Layout
1358 \begin_layout Plain Layout
1360 make -f ./Makefile.inc newfangle_sources
1368 \begin_layout Standard
1369 The general Makefile can be invoked with
1373 and can also be included into any automake file to automatically re-generate
1377 \begin_layout Standard
1382 can be extracted with this command:
1385 \begin_layout LyX-Code
1386 lyx -e latex newfangle.lyx &&
1391 \begin_layout LyX-Code
1392 newfangle newfangle.lyx > ./autoboot
1395 \begin_layout Standard
1396 This looks simple enough, but as mentioned, newfangle has to be had from
1397 somewhere before it can be extracted.
1400 \begin_layout Subsection
1401 \begin_inset Note Note
1404 \begin_layout Plain Layout
1405 MERGE THIS WITH THE SECTIONS OF THIS DOCUMENT
1410 \SpecialChar \ldots{}
1414 \begin_layout Standard
1415 When the lyx-build chunk is executed, the current directory will be a temporary
1417 \begin_inset Flex CharStyle:Code
1420 \begin_layout Plain Layout
1426 will refer to the tex file in this temporary directory.
1427 This is unfortunate as our makefile wants to run from the project directory
1428 where the Lyx file is kept.
1431 \begin_layout Standard
1432 We can extract the project directory from $$r, and derive the probable Lyx
1433 filename from the noweb file that Lyx generated.
1440 \begin_layout Standard
1441 \begin_inset listings
1445 \begin_layout Plain Layout
1447 PROJECT_DIR="$LYX_r"
1450 \begin_layout Plain Layout
1452 LYX_SRC="$PROJECT_DIR/${LYX_i%.tex}.lyx"
1455 \begin_layout Plain Layout
1460 \begin_layout Plain Layout
1462 TEX_SRC="$TEX_DIR/$LYX_i"
1470 \begin_layout Standard
1471 And then we can define a lyx-build fragment similar to the autoboot fragment
1478 \begin_layout Standard
1479 \begin_inset listings
1483 \begin_layout Plain Layout
1488 \begin_layout Plain Layout
1492 chunkref{lyx-build-helper}>
1495 \begin_layout Plain Layout
1497 cd $PROJECT_DIR || exit 1
1500 \begin_layout Plain Layout
1504 \begin_layout Plain Layout
1506 #/usr/bin/newfangle -filter ./notanglefix-filter
1511 \begin_layout Plain Layout
1513 # -R./Makefile.inc "../../noweb-lyx/noweb-lyx3.lyx"
1518 \begin_layout Plain Layout
1520 # | sed '/NOWEB_SOURCE=/s/=.*/=samba4-dfs.lyx/'
1525 \begin_layout Plain Layout
1530 \begin_layout Plain Layout
1535 \begin_layout Plain Layout
1537 #make -f ./Makefile.inc newfangle_sources
1545 \begin_layout Section
1549 \begin_layout Subsection
1550 Including Makefile.inc
1553 \begin_layout Standard
1554 \begin_inset CommandInset label
1556 name "sub:Keeping-extracted-files"
1560 Makefile.inc will cope with extracting all the other source files from this
1561 document and keeping them up to date.
1565 \begin_layout Standard
1566 It may also be included by a Makefile or Makefile.am defined in a Lyx document
1567 to automatically deal with the extraction of source files and documents.
1570 \begin_layout Standard
1571 A makefile has two parts; variables must be defined before the targets that
1579 \begin_layout Standard
1580 \begin_inset listings
1584 \begin_layout Plain Layout
1588 chunkref{Makefile.inc-vars}>
1591 \begin_layout Plain Layout
1595 chunkref{Makefile.inc-targets}>
1603 \begin_layout Standard
1605 \begin_inset Flex CharStyle:Code
1608 \begin_layout Plain Layout
1614 to hold the name of this Lyx file.
1621 \begin_layout Standard
1622 \begin_inset listings
1626 \begin_layout Plain Layout
1631 \begin_layout Plain Layout
1633 LITERATE_SOURCE=$(LYX_SOURCE)
1641 \begin_layout Subsection
1642 Recursive use of Makefile.inc
1645 \begin_layout Standard
1646 The makefile glue described here is used when building Samba4 vfs modules.
1649 \begin_layout Standard
1650 If you are defining a module of an existing program you may find it easier
1651 to use a slight recursive make instead of including the makefile directly.
1652 This way there is less chance of definitions in Makefile.inc interfering
1653 with definitions in the main makefile, or with definitions in other Makefile.inc
1654 from other noweb modules.
1657 \begin_layout Standard
1658 The glue works by adding a .PHONY target to call the recursive make, and
1659 adding this target as an additional pre-requisite to the existing targets.
1662 \begin_layout Standard
1663 In this example, the existing build system already has a build target for
1665 \begin_inset Flex CharStyle:Code
1668 \begin_layout Plain Layout
1674 , so we just add another pre-requisite to that.
1676 \begin_inset Flex CharStyle:Code
1679 \begin_layout Plain Layout
1685 as a pre-requisite, the stamp file's modified time indicating when all
1686 sources were extracted.
1693 \begin_layout Standard
1694 \begin_inset listings
1698 \begin_layout Plain Layout
1700 $(example_srcdir)/example.o: $(example_srcdir)/example.tex.stamp
1708 \begin_layout Standard
1709 The target for this new pre-requisite is generated by a recursive make using
1710 Makefile.inc which will make sure that the source is up to date, before
1711 it is built by the main projects makefile.
1718 \begin_layout Standard
1719 \begin_inset listings
1723 \begin_layout Plain Layout
1725 $(example_srcdir)/example.tex.stamp: $(example_srcdir)/example.tex ;
1730 \begin_layout Plain Layout
1732 cd $(example_srcdir) &&
1737 \begin_layout Plain Layout
1739 $(MAKE) -f Makefile.inc newfangle_sources
1747 \begin_layout Standard
1748 We can do similar glue for the docs, clean and distclean targets.
1749 In this example our build system is using a double colon for these targets,
1750 so we use the same in our glue.
1757 \begin_layout Standard
1758 \begin_inset listings
1762 \begin_layout Plain Layout
1767 \begin_layout Plain Layout
1769 .PHONY: docs_example
1772 \begin_layout Plain Layout
1774 docs_example:: ; cd $(example_srcdir) &&
1779 \begin_layout Plain Layout
1781 $(MAKE) -f Makefile.inc docs
1784 \begin_layout Plain Layout
1788 \begin_layout Plain Layout
1790 clean:: clean_example
1793 \begin_layout Plain Layout
1795 .PHONEY: clean_example
1798 \begin_layout Plain Layout
1800 clean_example: ; cd $(example_srcdir) &&
1805 \begin_layout Plain Layout
1807 $(MAKE) -f Makefile.inc clean
1810 \begin_layout Plain Layout
1814 \begin_layout Plain Layout
1816 distclean:: distclean_example
1819 \begin_layout Plain Layout
1821 .PHONY: distclean_example
1824 \begin_layout Plain Layout
1826 distclean_example: ; cd $(example_srcdir) &&
1831 \begin_layout Plain Layout
1833 $(MAKE) -f Makefile.inc distclean
1841 \begin_layout Standard
1842 We could do similarly for install targets to install the generated docs.
1845 \begin_layout Subsection
1846 \begin_inset CommandInset label
1848 name "sub:Converting-from-Lyx"
1852 Converting from Lyx to LaTeX
1855 \begin_layout Standard
1856 The first stage will always be to convert the Lyx file to a LaTeX file;
1857 this must be so not only because newfangle needs to to run on a TeX file,
1858 but also because the Lyx command
1860 server-goto-file-line
1864 \begin_layout Plain Layout
1867 server-goto-file-line
1869 is used to position the Lyx cursor at the compiler errors.
1876 insists that the line number provided is a line in the TeX file, and always
1877 reverse maps this to derive the line in the Lyx docment.
1878 \begin_inset Note Note
1881 \begin_layout Plain Layout
1882 The tex file should probably be an automake extra dist sources or something,
1883 so that it gets produced and packaged by make dist
1891 \begin_layout Standard
1892 The command [[lyx -e literate noweb-lyx.lyx]] will produce [[noweb-lyx.nw]]
1893 a tex file, so we define the noweb target to be the same as the Lyx file
1894 but with the .nw extension.
1901 \begin_layout Standard
1902 \begin_inset listings
1906 \begin_layout Plain Layout
1908 TEX_SOURCE=$(LYX_SOURCE:.lyx=.tex)
1917 Makefile.inc-targets
1920 \begin_layout Standard
1921 \begin_inset listings
1925 \begin_layout Plain Layout
1927 $(TEX_SOURCE): $(LYX_SOURCE) ;
1932 \begin_layout Plain Layout
1937 \begin_layout Plain Layout
1939 clean_tex: ; rm -f -- $(TEX_SOURCE)
1947 \begin_layout Subsection
1948 Extracting Program Source
1951 \begin_layout Standard
1952 The program source is extracted using newfangle, which is designed to operate
1953 on a LaTeX document.
1961 \begin_layout Standard
1962 \begin_inset listings
1966 \begin_layout Plain Layout
1968 NEWFANGLE_SOURCE=$(TEX_SOURCE)
1976 \begin_layout Standard
1977 The Lyx document can result in any number of source documents, but not all
1978 of these will be changed each time the Lyx document is updated.
1979 We certainly don't want to update the timestamps of these files and cause
1980 the whole source tree to be recompiled just because the Lyx document was
1985 \begin_layout Standard
1986 To solve this problem we use a stamp file which is always updated each time
1987 the sources are extracted from the LaTeX document.
1988 If the stamp file is older than the LaTeX document, then we can make an
1989 attempt to re-extract the sources.
1996 \begin_layout Standard
1997 \begin_inset listings
2001 \begin_layout Plain Layout
2003 NEWFANGLE_SOURCE_STAMP=$(NEWFANGLE_SOURCE).stamp
2012 Makefile.inc-targets
2015 \begin_layout Standard
2016 \begin_inset listings
2020 \begin_layout Plain Layout
2022 $(NEWFANGLE_SOURCE_STAMP): $(NEWFANGLE_SOURCE)
2027 \begin_layout Plain Layout
2029 $(NEWFANGLE_SOURCES) ;
2034 \begin_layout Plain Layout
2036 echo > $(NEWFANGLE_SOURCE_STAMP)
2039 \begin_layout Plain Layout
2041 clean_stamp: ; rm -f $(NEWFANGLE_SOURCE_STAMP)
2044 \begin_layout Plain Layout
2054 \begin_layout Subsection
2055 Extracting C sources
2058 \begin_layout Standard
2060 \begin_inset Flex CharStyle:Code
2063 \begin_layout Plain Layout
2069 to hold the names of all the C source files defined in this document.
2070 We compute this only once, by means of := in assignent.
2071 The sed deletes the any <
2072 \begin_inset space \hspace*{}
2077 \begin_inset space \hspace*{}
2081 > which may surround the roots names (for noroots compatibility).
2085 \begin_layout Standard
2086 As we use chunk names beginning with ./ to denote top level fragments that
2087 should be extracted, we filter out all fragments that do not begin with
2095 \begin_layout Standard
2096 \begin_inset listings
2100 \begin_layout Plain Layout
2109 \begin_layout Plain Layout
2111 NEWFANGLE_SOURCES:=$(shell
2116 \begin_layout Plain Layout
2118 newfangle -r $(NEWFANGLE_SOURCE) |
2123 \begin_layout Plain Layout
2125 sed -e 's/^[<][<]//;s/[>][>]$$//;/^$(NEWFANGLE_PREFIX)/!d'
2130 \begin_layout Plain Layout
2132 -e 's/^$(NEWFANGLE_PREFIX)/
2139 \begin_layout Plain Layout
2150 Makefile.inc-targets
2153 \begin_layout Standard
2154 \begin_inset listings
2158 \begin_layout Plain Layout
2160 .PHONY: echo_newfangle_sources
2163 \begin_layout Plain Layout
2165 echo_newfangle_sources: ; @echo $(NEWFANGLE_SOURCES)
2173 \begin_layout Standard
2174 We define a convenient target called
2175 \begin_inset Flex CharStyle:Code
2178 \begin_layout Plain Layout
2184 to re-extract the source if the LaTeX file has been updated.
2188 Makefile.inc-targets
2191 \begin_layout Standard
2192 \begin_inset listings
2196 \begin_layout Plain Layout
2198 .PHONY: newfangle_sources
2201 \begin_layout Plain Layout
2203 newfangle_sources: $(NEWFANGLE_SOURCE_STAMP)
2211 \begin_layout Standard
2212 And also a convenient target to remove extracted sources.
2216 Makefile.inc-targets
2219 \begin_layout Standard
2220 \begin_inset listings
2224 \begin_layout Plain Layout
2226 .PHONY: clean_newfangle_sources
2229 \begin_layout Plain Layout
2231 clean_newfangle_sources: ;
2236 \begin_layout Plain Layout
2238 rm -f -- $(NEWFANGLE_SOURCE_STAMP) $(NEWFANGLE_SOURCES)
2246 \begin_layout Standard
2248 \begin_inset Flex CharStyle:Code
2251 \begin_layout Plain Layout
2257 macro takes 4 arguments: the filename (1), some extensions to match (2)
2258 and a some shell command to return if the filename matches the exentions
2266 \begin_layout Standard
2267 \begin_inset listings
2271 \begin_layout Plain Layout
2273 if_extension=$(if $(findstring $(suffix $(1)),$(2)),$(3),$(4))
2281 \begin_layout Standard
2282 For some source files like C files, we want to output the line number and
2283 filename of the original LaTeX document from which the source came.
2286 \begin_layout Standard
2287 To make this easier we define the file extensions for which we want to do
2295 \begin_layout Standard
2296 \begin_inset listings
2300 \begin_layout Plain Layout
2310 \begin_layout Standard
2311 We can then use the if_extensions macro to define a macro which expands
2313 \begin_inset Flex CharStyle:Code
2316 \begin_layout Plain Layout
2322 option if newfangle is being invoked in a C source file, so that C compile
2323 errors will refer to the line number in the Lyx document.
2331 \begin_layout Standard
2332 \begin_inset listings
2336 \begin_layout Plain Layout
2341 \begin_layout Plain Layout
2343 nf_line=-L -T$(TABS)
2346 \begin_layout Plain Layout
2353 \begin_layout Plain Layout
2355 $(call if_extension,$(2),$(C_EXTENSIONS),$(nf_line))
2360 \begin_layout Plain Layout
2370 \begin_layout Standard
2371 We can use a similar trick to define an
2375 macro which takes just the filename as an argument and can return a pipeline
2376 stage calling the indent command.
2377 Indent can be turned off with
2378 \begin_inset Flex CharStyle:Code
2381 \begin_layout Plain Layout
2382 make newfangle_sources indent=
2394 \begin_layout Standard
2395 \begin_inset listings
2399 \begin_layout Plain Layout
2401 indent_options=-npro -kr -i8 -ts8 -sob -l80 -ss -ncs
2404 \begin_layout Plain Layout
2406 indent=$(call if_extension,$(1),$(C_EXTENSIONS),
2411 \begin_layout Plain Layout
2413 | indent $(indent_options))
2421 \begin_layout Standard
2422 We now define the pattern for extracting a file.
2423 The files are written using noweb's
2429 \begin_layout Plain Layout
2432 So you still need noweb installed in order to use cpif
2438 \begin_inset Note Note
2441 \begin_layout Plain Layout
2444 Write an awk version
2451 so that the file timestamp will not be touched if the contents haven't
2453 This avoids the need to rebuild the entire project because of a typographical
2454 change in the documentation, or if only a few C source files have changed.
2461 \begin_layout Standard
2462 \begin_inset listings
2466 \begin_layout Plain Layout
2468 newfangle_extract=@mkdir -p $(dir $(1)) &&
2473 \begin_layout Plain Layout
2475 $(call newfangle,$(2),$(1)) > "$(1).tmp" &&
2480 \begin_layout Plain Layout
2482 cat "$(1).tmp" $(indent) | cpif "$(1)"
2487 \begin_layout Plain Layout
2489 && rm -- "$(1).tmp" ||
2494 \begin_layout Plain Layout
2496 (echo error newfangling $(1) from $(2) ; exit 1)
2504 \begin_layout Standard
2505 We define a target which will extract or update all sources.
2506 To do this we first defined a makefile template that can do this for any
2507 source file in the LaTeX document.
2514 \begin_layout Standard
2515 \begin_inset listings
2519 \begin_layout Plain Layout
2521 define NEWFANGLE_template
2524 \begin_layout Plain Layout
2531 \begin_layout Plain Layout
2533 $$(call newfangle_extract,$(1),$(2))
2536 \begin_layout Plain Layout
2538 NEWFANGLE_TARGETS+=$(1)
2541 \begin_layout Plain Layout
2551 \begin_layout Standard
2552 We then enumerate the discovered
2553 \begin_inset Flex CharStyle:Code
2556 \begin_layout Plain Layout
2562 to generate a makefile rule for each one using the makefile template we
2567 Makefile.inc-targets
2570 \begin_layout Standard
2571 \begin_inset listings
2575 \begin_layout Plain Layout
2577 $(foreach source,$(NEWFANGLE_SOURCES),
2582 \begin_layout Plain Layout
2584 $(eval $(call NEWFANGLE_template,$(source),$(NEWFANGLE_SOURCE)))
2589 \begin_layout Plain Layout
2599 \begin_layout Standard
2600 These will all be built with NEWFANGLE_SOURCE_STAMP.
2603 \begin_layout Standard
2604 We also remove the generated sources on a
2612 Makefile.inc-targets
2615 \begin_layout Standard
2616 \begin_inset listings
2620 \begin_layout Plain Layout
2622 _distclean: clean_newfangle_sources
2630 \begin_layout Subsection
2631 Extracting Documentation
2634 \begin_layout Standard
2635 We then identify the intermediate stages of the documentation and their
2636 build and clean targets.
2639 \begin_layout Subsubsection
2643 \begin_layout Standard
2644 We produce a pdf file from the tex file.
2651 \begin_layout Standard
2652 \begin_inset listings
2656 \begin_layout Plain Layout
2658 NEWFANGLE_PDF=$(TEX_SOURCE:.tex=.pdf)
2666 \begin_layout Standard
2667 We run pdflatex twice to be sure that the contents and aux files are up
2669 We certainly are required to run pdflatex twice if these files do not exist!
2673 Makefile.inc-targets
2676 \begin_layout Standard
2677 \begin_inset listings
2681 \begin_layout Plain Layout
2683 $(NEWFANGLE_PDF): $(TEX_SOURCE); pdflatex $< && pdflatex $<
2686 \begin_layout Plain Layout
2688 clean_pdf: ; rm -f -- $(NEWFANGLE_PDF)
2693 \begin_layout Plain Layout
2695 $(TEX_SOURCE:.tex=.toc)
2700 \begin_layout Plain Layout
2702 $(TEX_SOURCE:.tex=.log)
2707 \begin_layout Plain Layout
2709 $(TEX_SOURCE:.tex=.aux)
2717 \begin_layout Subsubsection
2721 \begin_layout Standard
2722 Currently we only build pdf as a final format, but NEWFANGLE_DOCS may later
2723 hold other output formats.
2730 \begin_layout Standard
2731 \begin_inset listings
2735 \begin_layout Plain Layout
2737 NEWFANGLE_DOCS=$(NEWFANGLE_PDF)
2745 \begin_layout Standard
2746 We also define newfangle_docs as a convenient phony target<
2750 Makefile.inc-targets
2753 \begin_layout Standard
2754 \begin_inset listings
2758 \begin_layout Plain Layout
2760 .PHONY: newfangle_docs
2763 \begin_layout Plain Layout
2765 newfangle_docs: $(NEWFANGLE_DOCS)
2768 \begin_layout Plain Layout
2770 docs: newfangle_docs
2778 \begin_layout Standard
2779 And define a convenient clean_noweb_docs which we add to the regular clean
2784 Makefile.inc-targets
2787 \begin_layout Standard
2788 \begin_inset listings
2792 \begin_layout Plain Layout
2794 .PHONEY: clean_newfangle_docs
2797 \begin_layout Plain Layout
2799 clean_newfangle_docs: clean_tex clean_pdf
2802 \begin_layout Plain Layout
2804 clean: clean_newfangle_docs
2807 \begin_layout Plain Layout
2811 \begin_layout Plain Layout
2813 distclean_newfangle_docs: clean_tex clean_newfangle_docs
2816 \begin_layout Plain Layout
2818 distclean: clean distclean_newfangle_docs
2826 \begin_layout Subsection
2830 \begin_layout Standard
2831 If Makefile.inc is included into Makefile, then extracted files can be updated
2835 \begin_layout LyX-Code
2836 make newfangle_sources
2839 \begin_layout Standard
2843 \begin_layout LyX-Code
2844 make -f Makefile.inc newfangle_sources
2851 \begin_layout Chapter
2852 Newfangle awk source code
2855 \begin_layout Standard
2856 We use the copyright notice from chapter
2857 \begin_inset CommandInset ref
2859 reference "cha:License"
2867 ./newfangle,language=awk,morestring=[b]{/},morekeywords=else
2870 \begin_layout Standard
2871 \begin_inset listings
2875 \begin_layout Plain Layout
2880 \begin_layout Plain Layout
2884 chunkref{gpl3-copyright}>
2892 \begin_layout Standard
2893 We also use code from Arnold Robbins public domain getopt (1993 revision)
2895 \begin_inset CommandInset ref
2897 reference "cha:getopt"
2901 , and naturally want to attribute this appropriately.
2904 \begin_layout Standard
2905 \begin_inset listings
2909 \begin_layout Plain Layout
2913 \begin_layout Plain Layout
2915 # NOTE: Arnold Robbins public domain getopt for awk is also used:
2918 \begin_layout Plain Layout
2922 chunkref{getopt.awk-header}>
2925 \begin_layout Plain Layout
2929 \begin_layout Plain Layout
2933 chunkref{getopt.awk-getopt()}>
2936 \begin_layout Plain Layout
2945 \begin_layout Standard
2946 And include the following chunks
2953 \begin_layout Standard
2954 \begin_inset listings
2958 \begin_layout Plain Layout
2962 chunkref{helper-functions}>
2965 \begin_layout Plain Layout
2969 chunkref{mode-tracker}>
2972 \begin_layout Plain Layout
2976 chunkref{chunk-storage-functions}>
2979 \begin_layout Plain Layout
2983 chunkref{output_chunk_names()}>
2986 \begin_layout Plain Layout
2990 chunkref{output_chunks()}>
2993 \begin_layout Plain Layout
2997 chunkref{write_chunk()}>
3000 \begin_layout Plain Layout
3004 chunkref{expand_chunk_args()}>
3007 \begin_layout Plain Layout
3014 \begin_layout Plain Layout
3018 chunkref{recognize-chunk}>
3021 \begin_layout Plain Layout
3033 \begin_layout Section
3037 \begin_layout Standard
3038 The portable way to erase an array in awk is to split the empty string,
3043 awk-delete-array,params=ARRAY
3046 \begin_layout Standard
3047 \begin_inset listings
3051 \begin_layout Plain Layout
3053 split("", ${ARRAY});
3065 \begin_layout Section
3069 \begin_layout Standard
3070 Fatal errors are issued with the error function:
3077 \begin_layout Standard
3078 \begin_inset listings
3082 \begin_layout Plain Layout
3084 function error(message)
3087 \begin_layout Plain Layout
3092 \begin_layout Plain Layout
3094 print message > "/dev/stderr";
3097 \begin_layout Plain Layout
3102 \begin_layout Plain Layout
3112 \begin_layout Standard
3113 This is one of the helper functions.
3120 \begin_layout Standard
3121 \begin_inset listings
3125 \begin_layout Plain Layout
3137 \begin_layout Chapter
3141 \begin_layout Standard
3142 LaTeX arguments to lstlistings macros are a comma seperated list of key-value
3144 Values containing commas are enclosed in { braces }.
3147 \begin_layout Standard
3148 We need a function that can parse such an expression and assign the values
3156 \begin_layout Standard
3157 A sample expressions is:
3160 \begin_layout LyX-Code
3161 name=thomas, params={a, b}, something, something-else
3164 \begin_layout Standard
3165 but we see that this is just a simpler form of this expression:
3168 \begin_layout LyX-Code
3169 name=freddie, foo={bar=baz, quux={quirk, a=fleeg}}, etc
3172 \begin_layout Standard
3173 And that it would be a good idea to use a recursive parser into a multi-dimensio
3178 \begin_layout Plain Layout
3179 as AWK doesn't have nested-hash support
3187 \begin_layout Standard
3188 \begin_inset Tabular
3189 <lyxtabular version="3" rows="6" columns="2">
3191 <column alignment="left" valignment="top" width="0">
3192 <column alignment="left" valignment="top" width="0">
3194 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
3197 \begin_layout Plain Layout
3203 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
3206 \begin_layout Plain Layout
3214 <cell alignment="left" valignment="top" topline="true" leftline="true" usebox="none">
3217 \begin_layout Plain Layout
3223 <cell alignment="left" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
3226 \begin_layout Plain Layout
3234 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
3237 \begin_layout Plain Layout
3243 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
3246 \begin_layout Plain Layout
3254 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
3257 \begin_layout Plain Layout
3263 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
3266 \begin_layout Plain Layout
3274 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
3277 \begin_layout Plain Layout
3283 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
3286 \begin_layout Plain Layout
3294 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
3297 \begin_layout Plain Layout
3303 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
3306 \begin_layout Plain Layout
3320 \begin_layout Standard
3321 On reflection it seems that sometimes such nesting is not desirable, as
3322 the braces are also used to delimit values that contain commas --- we may
3326 \begin_layout LyX-Code
3327 name={williamson, freddie}
3330 \begin_layout Standard
3332 \begin_inset Flex CharStyle:Code
3335 \begin_layout Plain Layout
3342 \begin_inset Flex CharStyle:Code
3345 \begin_layout Plain Layout
3351 --- so I may change this behaviour.
3352 \begin_inset Note Note
3355 \begin_layout Plain Layout
3364 \begin_layout Standard
3366 \begin_inset Flex Chunkref
3369 \begin_layout Plain Layout
3375 will accept two paramters,
3376 \begin_inset Flex CharStyle:Code
3379 \begin_layout Plain Layout
3385 being the text to parse, and
3386 \begin_inset Flex CharStyle:Code
3389 \begin_layout Plain Layout
3395 being an array to receive the parsed values as described above.
3396 The optional parameter
3397 \begin_inset Flex CharStyle:Code
3400 \begin_layout Plain Layout
3406 is used during recursion to build up the multi-dimensional array path.
3413 \begin_layout Standard
3414 \begin_inset listings
3418 \begin_layout Plain Layout
3422 chunkref{get_chunk_args()}>
3434 \begin_layout Standard
3435 \begin_inset listings
3439 \begin_layout Plain Layout
3441 function get_chunk_args(text, values,
3444 \begin_layout Plain Layout
3446 # optional parameters
3449 \begin_layout Plain Layout
3451 path, # hierarchical precursors
3454 \begin_layout Plain Layout
3459 \begin_layout Plain Layout
3469 \begin_layout Standard
3470 The strategy is to parse the name, and then look for a value.
3471 If the value begins with a brace
3472 \begin_inset Flex CharStyle:Code
3475 \begin_layout Plain Layout
3481 , then we recurse and consume as much of the text as necessary, returning
3482 the remaining text when we encounter a leading close-brace
3483 \begin_inset Flex CharStyle:Code
3486 \begin_layout Plain Layout
3493 This being the strategy --- and executed in a loop --- we realise that
3494 we must first look for the closing brace (perhaps preceded by white space)
3495 in order to terminate the recursion, and returning remaining text.
3498 \begin_layout Standard
3499 \begin_inset listings
3503 \begin_layout Plain Layout
3508 \begin_layout Plain Layout
3510 while(length(text)) {
3513 \begin_layout Plain Layout
3515 if (match(text, "^ *}(.*)", a)) {
3518 \begin_layout Plain Layout
3523 \begin_layout Plain Layout
3528 \begin_layout Plain Layout
3532 chunkref{parse-chunk-args}>
3535 \begin_layout Plain Layout
3540 \begin_layout Plain Layout
3545 \begin_layout Plain Layout
3555 \begin_layout Standard
3556 \begin_inset Note Note
3559 \begin_layout Plain Layout
3560 Use BNF package here
3565 We can see that the text could be inspected with this regex:
3572 \begin_layout Standard
3573 \begin_inset listings
3577 \begin_layout Plain Layout
3579 if (! match(text, " *([^,=]*[^,= ]) *(([,=]) *(([^,}]*) *,* *(.*))|)$", a))
3583 \begin_layout Plain Layout
3588 \begin_layout Plain Layout
3598 \begin_layout Standard
3600 \begin_inset Flex CharStyle:Code
3603 \begin_layout Plain Layout
3609 will have the following values:
3612 \begin_layout Standard
3613 \begin_inset Tabular
3614 <lyxtabular version="3" rows="7" columns="2">
3616 <column alignment="center" valignment="top" width="0">
3617 <column alignment="left" valignment="top" width="0">
3619 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
3622 \begin_layout Plain Layout
3628 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
3631 \begin_layout Plain Layout
3639 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
3642 \begin_layout Plain Layout
3648 <cell alignment="left" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
3651 \begin_layout Plain Layout
3659 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
3662 \begin_layout Plain Layout
3668 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
3671 \begin_layout Plain Layout
3672 =freddie, foo={bar=baz, quux={quirk, a=fleeg}}, etc
3679 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
3682 \begin_layout Plain Layout
3688 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
3691 \begin_layout Plain Layout
3699 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
3702 \begin_layout Plain Layout
3708 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
3711 \begin_layout Plain Layout
3712 freddie, foo={bar=baz, quux={quirk, a=fleeg}}, etc
3719 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
3722 \begin_layout Plain Layout
3728 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
3731 \begin_layout Plain Layout
3739 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
3742 \begin_layout Plain Layout
3748 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
3751 \begin_layout Plain Layout
3752 , foo={bar=baz, quux={quirk, a=fleeg}}, etc
3765 \begin_layout Standard
3767 \begin_inset Flex CharStyle:Code
3770 \begin_layout Plain Layout
3777 \begin_inset Flex CharStyle:Code
3780 \begin_layout Plain Layout
3786 and signify whether the option named in
3787 \begin_inset Flex CharStyle:Code
3790 \begin_layout Plain Layout
3796 has a value or not (respectively).
3799 \begin_layout Standard
3800 If the option does have a value, then if the expression
3801 \begin_inset Flex CharStyle:Code
3804 \begin_layout Plain Layout
3811 \begin_inset Flex CharStyle:Code
3814 \begin_layout Plain Layout
3820 it will signify that we need to recurse:
3823 \begin_layout Standard
3824 \begin_inset listings
3828 \begin_layout Plain Layout
3833 \begin_layout Plain Layout
3838 \begin_layout Plain Layout
3840 if (substr(a[4],1,1) == "{") {
3843 \begin_layout Plain Layout
3845 text = get_chunk_args(substr(a[4],2), values, path name SUBSEP);
3848 \begin_layout Plain Layout
3853 \begin_layout Plain Layout
3855 values[path name]=a[5];
3858 \begin_layout Plain Layout
3863 \begin_layout Plain Layout
3868 \begin_layout Plain Layout
3873 \begin_layout Plain Layout
3875 values[path name]="";
3878 \begin_layout Plain Layout
3883 \begin_layout Plain Layout
3893 \begin_layout Standard
3894 We can test this function like this:
3901 \begin_layout Standard
3902 \begin_inset listings
3906 \begin_layout Plain Layout
3910 chunkref{get_chunk_args()}>
3913 \begin_layout Plain Layout
3918 \begin_layout Plain Layout
3923 \begin_layout Plain Layout
3927 \begin_layout Plain Layout
3929 print get_chunk_args("name=freddie, foo={bar=baz, quux={quirk, a=fleeg}},
3933 \begin_layout Plain Layout
3938 \begin_layout Plain Layout
3940 print "a[" b "] => " a[b];
3943 \begin_layout Plain Layout
3948 \begin_layout Plain Layout
3958 \begin_layout Standard
3959 which should give this output:
3963 gca-test.awk-results
3966 \begin_layout Standard
3967 \begin_inset listings
3971 \begin_layout Plain Layout
3973 a[foo.quux.quirk] =>
3976 \begin_layout Plain Layout
3978 a[foo.quux.a] => fleeg
3981 \begin_layout Plain Layout
3986 \begin_layout Plain Layout
3991 \begin_layout Plain Layout
4001 \begin_layout Chapter
4002 Expanding chunk arguments
4005 \begin_layout Standard
4006 \begin_inset CommandInset label
4008 name "cha:Chunk Arguments"
4013 \begin_inset Note Note
4016 \begin_layout Plain Layout
4017 Explain this in the documentation section too
4022 As an extension to many literate-programming styles, newfangle permits code
4023 chunks to take parameters and thus operate somewhat like C pre-processor
4024 macros, or like C++ templates.
4027 \begin_layout Standard
4028 Chunk parameters are declared with a chunk argument called
4029 \begin_inset Flex CharStyle:Code
4032 \begin_layout Plain Layout
4038 , which holds a semi-colon separated list of parameters, like this:
4041 \begin_layout LyX-Code
4042 achunk,language=C,params=name;address
4045 \begin_layout Standard
4046 When such a chunk is included the arguments are expressed thus, in square
4047 brackets as optional arguments separated by a comma
4048 \begin_inset Note Note
4051 \begin_layout Plain Layout
4052 We ought to support qouting in {} like ({Jones, John}, Jones@example.com)
4060 \begin_layout LyX-Code
4063 chunkref{achunk}(John Jones, jones@example.com)
4066 \begin_layout Standard
4067 Within the body a chunk, parameters are expressed as:
4068 \begin_inset Flex CharStyle:Code
4071 \begin_layout Plain Layout
4078 \begin_inset Flex CharStyle:Code
4081 \begin_layout Plain Layout
4088 There is a strong case that a LaTeX style notation should be used, like
4093 param{name}> as it would appear in the lstlisting.
4094 Such notation would make me go blind, but I do intend to adopt it.
4097 \begin_layout Standard
4098 We therefore need a function
4099 \begin_inset Flex CharStyle:Code
4102 \begin_layout Plain Layout
4108 which will take a block of text, a list of permitted parameters and the
4109 arguments which must substitute for the parameters.
4110 We also need to be able to parse a parameter list into an array of parameters.
4113 \begin_layout Section
4114 Parsing argument lists
4117 \begin_layout Standard
4118 An argument list may be as simple as in
4119 \begin_inset Flex CharStyle:Code
4122 \begin_layout Plain Layout
4125 chunkref{pull}(thing, otherthing)
4133 \begin_layout LyX-Code
4136 chunkref{pull}(things[x, y], get_other_things(a, "all"))
4139 \begin_layout Standard
4140 --- which for all it's commas and quotes and parenthesis represents only
4144 \begin_layout Standard
4145 How do we stop the comma in
4146 \begin_inset Flex CharStyle:Code
4149 \begin_layout Plain Layout
4155 from splitting it into two arguments
4156 \begin_inset Flex CharStyle:Code
4159 \begin_layout Plain Layout
4166 \begin_inset Flex CharStyle:Code
4169 \begin_layout Plain Layout
4175 --- neither of which make sense on their own?
4178 \begin_layout Standard
4179 One way it could be done is by refusing to split text between maching delimiters
4181 \begin_inset Flex CharStyle:Code
4184 \begin_layout Plain Layout
4191 \begin_inset Flex CharStyle:Code
4194 \begin_layout Plain Layout
4201 \begin_inset Flex CharStyle:Code
4204 \begin_layout Plain Layout
4211 \begin_inset Flex CharStyle:Code
4214 \begin_layout Plain Layout
4221 \begin_inset Flex CharStyle:Code
4224 \begin_layout Plain Layout
4231 \begin_inset Flex CharStyle:Code
4234 \begin_layout Plain Layout
4240 and most likely also
4241 \begin_inset Flex CharStyle:Code
4244 \begin_layout Plain Layout
4251 \begin_inset Flex CharStyle:Code
4254 \begin_layout Plain Layout
4261 \begin_inset Flex CharStyle:Code
4264 \begin_layout Plain Layout
4271 \begin_inset Flex CharStyle:Code
4274 \begin_layout Plain Layout
4281 Of course this also makes it impossible to pass such mis-matched code fragments
4282 as parameters, but I don't think users could cope with people passing such
4283 code unbalanced fragments as chunk parameters
4287 \begin_layout Plain Layout
4288 I know that I couldn't cope with users doing such things, and although the
4289 GPL3 license prevents me from actually forbidding anyone from trying, if
4290 they wan't it to work they'll have to write the code themselves and not
4291 expect any support from me.
4299 \begin_layout Standard
4300 Unfortunately, the full set of matching delimiters may vary from language
4302 In certain C++ template contexts,
4303 \begin_inset Flex CharStyle:Code
4306 \begin_layout Plain Layout
4313 \begin_inset Flex CharStyle:Code
4316 \begin_layout Plain Layout
4322 would count as delimiters, and yet in other contexts they would not.
4325 \begin_layout Standard
4326 This puts me in the unfortunate position of having to parse-somewhat all
4327 programming languages without knowing what they are! Eventually this will
4328 be managed in the chunk modes in chapter
4329 \begin_inset CommandInset ref
4331 reference "cha:modes"
4338 \begin_layout Standard
4339 Another way, inspired by LaTeX, is if the first character of the parameter
4340 is an opening-delimiter, to read up to the matching closing-delimiter wthout
4341 considering intervening commas; thus the above example could be expressed:
4344 \begin_layout LyX-Code
4347 chunkref{pull}({things[x, y]}, [get_other_things(a, "all")])
4350 \begin_layout Standard
4352 \begin_inset Flex CharStyle:Code
4355 \begin_layout Plain Layout
4362 \begin_inset Flex CharStyle:Code
4365 \begin_layout Plain Layout
4371 to wrap the first agument, and
4372 \begin_inset Flex CharStyle:Code
4375 \begin_layout Plain Layout
4382 \begin_inset Flex CharStyle:Code
4385 \begin_layout Plain Layout
4391 to wrap the second argument and protect the comma.
4394 \begin_layout Standard
4395 In the meantime, I'll work with the first method, and a fixed list of delimiters.
4398 \begin_layout Standard
4406 \begin_layout Standard
4407 \begin_inset listings
4411 \begin_layout Plain Layout
4413 function parse_chunk_args(text, values,
4416 \begin_layout Plain Layout
4418 # optional parameters
4421 \begin_layout Plain Layout
4423 path, # hierarchical precursors
4426 \begin_layout Plain Layout
4428 stack, # delimiters to be matched
4431 \begin_layout Plain Layout
4436 \begin_layout Plain Layout
4441 \begin_layout Plain Layout
4446 \begin_layout Plain Layout
4451 \begin_layout Plain Layout
4453 split(chunklet_parts[2], call_chunk_args, " *, *");
4456 \begin_layout Plain Layout
4466 \begin_layout Standard
4467 The strategy is to parse the name, and then look for a value.
4468 If the value begins with a brace
4469 \begin_inset Flex CharStyle:Code
4472 \begin_layout Plain Layout
4478 , then we recurse and consume as much of the text as necessary, returning
4479 the remaining text when we encounter a leading close-brace
4480 \begin_inset Flex CharStyle:Code
4483 \begin_layout Plain Layout
4490 This being the strategy --- and executed in a loop --- we realise that
4491 we must first look for the closing brace (perhaps preceded by white space)
4492 in order to terminate the recursion, and returning remaining text.
4495 \begin_layout Standard
4496 \begin_inset listings
4500 \begin_layout Plain Layout
4505 \begin_layout Plain Layout
4509 "", "delimiters" ]="
4516 \begin_layout Plain Layout
4520 "", "terminators"]="
4525 \begin_layout Plain Layout
4527 modes["{", "delimiters" ]="
4544 \begin_layout Plain Layout
4546 modes["{", "terminators"]="}";
4549 \begin_layout Plain Layout
4551 modes["[", "delimiters" ]="
4572 \begin_layout Plain Layout
4574 modes["[", "terminators"]="]";
4577 \begin_layout Plain Layout
4579 modes["(", "delimiters" ]="
4596 \begin_layout Plain Layout
4598 modes["(", "terminators"]=")";
4601 \begin_layout Plain Layout
4603 modes["'", "delimiters" ]="
4610 \begin_layout Plain Layout
4612 modes["'", "terminators"]="'";
4615 \begin_layout Plain Layout
4617 modes["/*", "terminators"]="*/";
4620 \begin_layout Plain Layout
4622 modes["//", "terminators"]="
4627 \begin_layout Plain Layout
4629 modes["", "delimiters" ]="
4646 \begin_layout Plain Layout
4651 \begin_layout Plain Layout
4655 \begin_layout Plain Layout
4657 delimiters=modes[mode, "delimiters"];
4660 \begin_layout Plain Layout
4664 \begin_layout Plain Layout
4666 while(length(text)) {
4669 \begin_layout Plain Layout
4671 if match(text, "(" delimiters ")", a) {
4674 \begin_layout Plain Layout
4676 if (a[1] == modes[mode, "terminator"]) return result a[1];
4679 \begin_layout Plain Layout
4684 \begin_layout Plain Layout
4686 #check if new_mode is defined
4689 \begin_layout Plain Layout
4691 if (! (new_mode, "terminators") in modes) {
4694 \begin_layout Plain Layout
4696 error("Delimiter %s set unknown mode in text: %s", new_mode, text);
4699 \begin_layout Plain Layout
4704 \begin_layout Plain Layout
4706 text = substr(text, RSTART));
4709 \begin_layout Plain Layout
4711 result = result substr(text, 1, RSTART -1) RECURSE(text,,new_mode);
4714 \begin_layout Plain Layout
4719 \begin_layout Plain Layout
4721 result = result text;
4724 \begin_layout Plain Layout
4729 \begin_layout Plain Layout
4734 \begin_layout Plain Layout
4739 \begin_layout Plain Layout
4749 \begin_layout Standard
4750 We can test this function like this:
4757 \begin_layout Standard
4758 \begin_inset listings
4762 \begin_layout Plain Layout
4766 chunkref{get_chunk_args()}>
4769 \begin_layout Plain Layout
4774 \begin_layout Plain Layout
4779 \begin_layout Plain Layout
4783 \begin_layout Plain Layout
4785 print parse_chunk_args("things[x, y], get_other_things(a,
4792 \begin_layout Plain Layout
4797 \begin_layout Plain Layout
4799 print "a[" b "] => " a[b];
4802 \begin_layout Plain Layout
4807 \begin_layout Plain Layout
4817 \begin_layout Standard
4818 which should give this output:
4822 pca-test.awk-results
4825 \begin_layout Standard
4826 \begin_inset listings
4830 \begin_layout Plain Layout
4832 a[foo.quux.quirk] =>
4835 \begin_layout Plain Layout
4837 a[foo.quux.a] => fleeg
4840 \begin_layout Plain Layout
4845 \begin_layout Plain Layout
4850 \begin_layout Plain Layout
4860 \begin_layout Section
4861 Expanding parameters
4864 \begin_layout Standard
4865 \begin_inset CommandInset label
4867 name "Here-we-split"
4871 Here we split the text on
4872 \begin_inset Flex CharStyle:Code
4875 \begin_layout Plain Layout
4881 which means that all parts except the first will begin with a parameter
4883 The split function will consume the literal
4884 \begin_inset Flex CharStyle:Code
4887 \begin_layout Plain Layout
4900 \begin_layout Standard
4901 \begin_inset listings
4905 \begin_layout Plain Layout
4907 function expand_chunk_args(text, params, args,
4910 \begin_layout Plain Layout
4912 p, text_array, next_text, v, t, l)
4915 \begin_layout Plain Layout
4920 \begin_layout Plain Layout
4922 if (split(text, text_array, "
4929 \begin_layout Plain Layout
4933 chunkref{substitute-chunk-args}>
4936 \begin_layout Plain Layout
4941 \begin_layout Plain Layout
4946 \begin_layout Plain Layout
4956 \begin_layout Standard
4957 First, we produce an associative array of substitution values indexed by
4962 substitute-chunk-args
4965 \begin_layout Standard
4966 \begin_inset listings
4970 \begin_layout Plain Layout
4975 \begin_layout Plain Layout
4977 v[params[p]]=args[p];
4980 \begin_layout Plain Layout
4990 \begin_layout Standard
4991 We accumulate substituted text in the variable
4992 \begin_inset Flex CharStyle:Code
4995 \begin_layout Plain Layout
5002 As the first part of the split function is the part before the delimiter
5004 \begin_inset Flex CharStyle:Code
5007 \begin_layout Plain Layout
5013 in our case --- this part will never contain a parameter reference, so
5014 we assign this directly to the result kept in
5015 \begin_inset Flex CharStyle:Code
5018 \begin_layout Plain Layout
5025 \begin_inset listings
5029 \begin_layout Plain Layout
5039 \begin_layout Standard
5040 We then iterate over the remaining values in the array
5044 \begin_layout Plain Layout
5045 I don't know why I think that it will enumerate the array in order, but
5052 \begin_inset Note Note
5055 \begin_layout Plain Layout
5056 So fix it or porve it
5061 , and substitute each reference for it's argument.
5064 \begin_layout Standard
5065 \begin_inset listings
5069 \begin_layout Plain Layout
5071 for(t in text_array) if (t>1) {
5074 \begin_layout Plain Layout
5078 chunkref{substitute-chunk-arg}>
5081 \begin_layout Plain Layout
5091 \begin_layout Standard
5093 \begin_inset Flex CharStyle:Code
5096 \begin_layout Plain Layout
5102 a valid parameter reference will consist of valid parameter name terminated
5104 \begin_inset Flex CharStyle:Code
5107 \begin_layout Plain Layout
5114 A valid character name begins with the underscore or a letter, and may
5115 contain letters, digits or underscores.
5118 \begin_layout Standard
5119 A valid looking reference that is not actually the name of a parameter will
5120 be and not substituted.
5121 This is good because there is nothing to substitute anyway, and it avoids
5122 clashes when writing code for languages where ${\SpecialChar \ldots{}
5123 } is a valid construct
5124 --- such constructs will not be interfered with unless the parameter name
5129 substitute-chunk-arg
5132 \begin_layout Standard
5133 \begin_inset listings
5137 \begin_layout Plain Layout
5139 if (match(text_array[t], "^([a-zA-Z_][a-zA-Z0-9_]*)}", l) &&
5142 \begin_layout Plain Layout
5147 \begin_layout Plain Layout
5152 \begin_layout Plain Layout
5154 text = text v[l[1]] substr(text_array[t], length(l[1])+2);
5157 \begin_layout Plain Layout
5162 \begin_layout Plain Layout
5164 text = text "${" text_array[t];
5167 \begin_layout Plain Layout
5177 \begin_layout Chapter
5181 \begin_layout Standard
5182 Newfangle recognizes noweb chunks, but as we also want better LaTeX integration
5183 we will recognize any of these:
5186 \begin_layout Itemize
5187 notangle chunks matching the pattern
5188 \begin_inset Flex CharStyle:Code
5191 \begin_layout Plain Layout
5193 \begin_inset space \hspace*{}
5198 \begin_inset space \hspace*{}
5210 \begin_layout Itemize
5211 a chunks beginning with
5212 \begin_inset Flex CharStyle:Code
5215 \begin_layout Plain Layout
5225 Chunk{\SpecialChar \ldots{}
5226 } on the previous line
5229 \begin_layout Itemize
5230 an older form I have used, beginning with
5231 \begin_inset Flex CharStyle:Code
5234 \begin_layout Plain Layout
5237 begin{Chunk}[options]
5242 --- also more suitable for plain LaTeX users
5246 \begin_layout Plain Layout
5247 Is there such a thing as plain LaTeX?
5255 \begin_layout Section
5259 \begin_layout Standard
5261 \begin_inset Flex CharStyle:Code
5264 \begin_layout Plain Layout
5270 is used to signify that we are processing a code chunk and not document.
5271 In such a state, input lines will be assigned to the current chunk; otherwise
5275 \begin_layout Subsection
5279 \begin_layout Standard
5280 Our current scheme is to recognize the new lstlisting chunks, but these
5281 may be preceded by a
5282 \begin_inset Flex CharStyle:Code
5285 \begin_layout Plain Layout
5293 command which in LyX is a more convenient way to pass the chunk name to
5295 \begin_inset Flex CharStyle:Code
5298 \begin_layout Plain Layout
5306 command, and a more visible way to specify other
5307 \begin_inset Flex CharStyle:Code
5310 \begin_layout Plain Layout
5319 \begin_layout Standard
5320 The arguments to the
5321 \begin_inset Flex CharStyle:Code
5324 \begin_layout Plain Layout
5332 command are a name, and then a comma-seperated list of key-value pairs
5334 \begin_inset Flex CharStyle:Code
5337 \begin_layout Plain Layout
5346 (In fact within the LaTeX
5347 \begin_inset Flex CharStyle:Code
5350 \begin_layout Plain Layout
5359 \begin_inset CommandInset ref
5361 reference "sub:The-chunk-command"
5366 \begin_inset Flex CharStyle:Code
5369 \begin_layout Plain Layout
5375 is prefixed to the argument which is then literally passed to
5376 \begin_inset Flex CharStyle:Code
5379 \begin_layout Plain Layout
5394 \begin_layout Standard
5395 \begin_inset listings
5399 \begin_layout Plain Layout
5408 \begin_layout Plain Layout
5418 Chunk{ *([^ ,}]*),?(.*)}", line)) {
5421 \begin_layout Plain Layout
5423 next_chunk_name = line[1];
5426 \begin_layout Plain Layout
5428 get_chunk_args(line[2], next_chunk_args);
5431 \begin_layout Plain Layout
5436 \begin_layout Plain Layout
5441 \begin_layout Plain Layout
5451 \begin_layout Standard
5452 We also make a basic attempt to parse the name out of the
5453 \begin_inset Flex CharStyle:Code
5456 \begin_layout Plain Layout
5460 \begin_inset space \hspace{}
5469 text, otherwise we fall back to the name found in the previous chunk command.
5470 This attempt is very basic and doesn't support commas or spaces or square
5471 brackets as part of the chunkname.
5473 \begin_inset Flex CharStyle:Code
5476 \begin_layout Plain Layout
5484 which is convenient for some users
5488 \begin_layout Plain Layout
5489 but not yet supported in the LaTeX macros
5495 \begin_inset Note Note
5498 \begin_layout Plain Layout
5507 \begin_layout Standard
5508 \begin_inset listings
5512 \begin_layout Plain Layout
5525 \begin_layout Plain Layout
5527 if (match($0, "}.*[[,] *name= *{? *([^], }]*)", line)) {
5530 \begin_layout Plain Layout
5535 \begin_layout Plain Layout
5540 \begin_layout Plain Layout
5542 new_chunk(next_chunk_name, next_chunk_args);
5545 \begin_layout Plain Layout
5550 \begin_layout Plain Layout
5555 \begin_layout Plain Layout
5560 \begin_layout Plain Layout
5570 \begin_layout Subsection
5574 \begin_layout Standard
5575 We recognize notangle style chunks too:
5582 \begin_layout Standard
5583 \begin_inset listings
5587 \begin_layout Plain Layout
5592 \begin_layout Plain Layout
5594 if (match($0, "^[<]<(.*)[>]>= *$", line)) {
5597 \begin_layout Plain Layout
5602 \begin_layout Plain Layout
5607 \begin_layout Plain Layout
5612 \begin_layout Plain Layout
5617 \begin_layout Plain Layout
5622 \begin_layout Plain Layout
5632 \begin_layout Section
5636 \begin_layout Standard
5637 Likewise, we need to recognize when a chunk ends.
5640 \begin_layout Subsection
5644 \begin_layout Standard
5646 \begin_inset Flex CharStyle:Code
5649 \begin_layout Plain Layout
5656 \begin_inset Flex CharStyle:Code
5659 \begin_layout Plain Layout
5665 is surrounded by square brackets so that when this document is processed,
5666 this chunk doesn't terminate early when the lstlistings package recognizes
5667 it's own end-string!
5668 \begin_inset Note Greyedout
5671 \begin_layout Plain Layout
5672 This doesn't make sense as the regex is anchored with ^, which this line
5673 does not begin with!
5679 \begin_inset Note Note
5682 \begin_layout Plain Layout
5695 \begin_layout Standard
5696 \begin_inset listings
5700 \begin_layout Plain Layout
5713 \begin_layout Plain Layout
5718 \begin_layout Plain Layout
5723 \begin_layout Plain Layout
5728 \begin_layout Plain Layout
5738 \begin_layout Subsection
5746 \begin_layout Standard
5747 \begin_inset listings
5751 \begin_layout Plain Layout
5756 \begin_layout Plain Layout
5761 \begin_layout Plain Layout
5766 \begin_layout Plain Layout
5776 \begin_layout Standard
5777 All other recognizers are only of effect if we are chunking; there's no
5778 point in looking at lines if they aren't part of a chunk, so we just ignore
5779 them as efficiently as we can.
5786 \begin_layout Standard
5787 \begin_inset listings
5791 \begin_layout Plain Layout
5793 ! chunking { next; }
5801 \begin_layout Section
5805 \begin_layout Standard
5806 Chunk contents are any lines read while
5807 \begin_inset Flex CharStyle:Code
5810 \begin_layout Plain Layout
5817 Some chunk contents are special in that they refer to other chunks, and
5818 will be replaced by the contents of these chunks when the file is generated.
5821 \begin_layout Standard
5822 \begin_inset CommandInset label
5824 name "sub:ORS-chunk-text"
5828 We add the output record separator
5829 \begin_inset Flex CharStyle:Code
5832 \begin_layout Plain Layout
5838 to the line now, because we will set
5839 \begin_inset Flex CharStyle:Code
5842 \begin_layout Plain Layout
5848 to the empty string when we generate the output
5852 \begin_layout Plain Layout
5853 So that we can print partial lines using
5854 \begin_inset Flex CharStyle:Code
5857 \begin_layout Plain Layout
5864 \begin_inset Flex CharStyle:Code
5867 \begin_layout Plain Layout
5885 \begin_layout Standard
5886 \begin_inset listings
5890 \begin_layout Plain Layout
5892 length(active_chunk) {
5895 \begin_layout Plain Layout
5899 chunkref{process-chunk-tabs}>
5902 \begin_layout Plain Layout
5906 chunkref{process-chunk}>
5909 \begin_layout Plain Layout
5919 \begin_layout Standard
5920 If a chunk just consisted of plain text, we could handle the chunk like
5925 process-chunk-simple
5928 \begin_layout Standard
5929 \begin_inset listings
5933 \begin_layout Plain Layout
5935 chunk_line(active_chunk, $0 ORS);
5943 \begin_layout Standard
5944 but in fact a chunk can include references to other chunks.
5945 Chunk includes are traditionally written as
5946 \begin_inset Flex CharStyle:Code
5949 \begin_layout Plain Layout
5955 , but we support other variations.
5958 \begin_layout Standard
5959 However, we also process tabs at this point, a tab at input can be replaced
5960 by a number of spaces defined by the
5961 \begin_inset Flex CharStyle:Code
5964 \begin_layout Plain Layout
5970 variable, set by the
5971 \begin_inset Flex CharStyle:Code
5974 \begin_layout Plain Layout
5981 Of course this is poor tab behaviour, we should probably have the option
5982 to use proper counted tab-stops and process this on output.
5989 \begin_layout Standard
5990 \begin_inset listings
5994 \begin_layout Plain Layout
5999 \begin_layout Plain Layout
6006 \begin_layout Plain Layout
6016 \begin_layout Subsection
6017 \begin_inset CommandInset label
6019 name "sub:lstlistings-includes"
6026 \begin_layout Standard
6028 \begin_inset Flex CharStyle:Code
6031 \begin_layout Plain Layout
6034 lstset{escapeinside={=<}{>}}
6039 is set, then we can use
6040 \begin_inset Flex CharStyle:Code
6043 \begin_layout Plain Layout
6047 \begin_inset space \hspace{}
6058 \begin_inset Flex CharStyle:Code
6061 \begin_layout Plain Layout
6070 \begin_layout Enumerate
6071 it is a better mnemonic than
6072 \begin_inset Flex CharStyle:Code
6075 \begin_layout Plain Layout
6081 in that the = sign signifies equivalent or substitutability,
6084 \begin_layout Enumerate
6085 and because =< is not valid in C or in any language I can think of
6088 \begin_layout Enumerate
6089 and also because lstlistings doesn't like
6090 \begin_inset Flex CharStyle:Code
6093 \begin_layout Plain Layout
6099 as an end delimiter for the
6103 escape, so we must make do with a single
6104 \begin_inset Flex CharStyle:Code
6107 \begin_layout Plain Layout
6113 , which is better matched by
6114 \begin_inset Flex CharStyle:Code
6117 \begin_layout Plain Layout
6124 \begin_inset Flex CharStyle:Code
6127 \begin_layout Plain Layout
6136 \begin_layout Standard
6137 As each chunk line may contain more than one chunk include, we will split
6138 out chunk includes in an iterative fashion
6142 \begin_layout Plain Layout
6143 Contrary to our use of
6144 \begin_inset Flex CharStyle:Code
6147 \begin_layout Plain Layout
6153 when substituting parameters in chapter
6154 \begin_inset CommandInset ref
6156 reference "Here-we-split"
6168 \begin_layout Standard
6169 First, as long as the chunk contains a
6170 \begin_inset Flex CharStyle:Code
6173 \begin_layout Plain Layout
6181 command we take as much as we can up to the first
6182 \begin_inset Flex CharStyle:Code
6185 \begin_layout Plain Layout
6200 \begin_layout Standard
6201 \begin_inset listings
6205 \begin_layout Plain Layout
6210 \begin_layout Plain Layout
6215 \begin_layout Plain Layout
6220 \begin_layout Plain Layout
6238 )|)>|<<([a-zA-Z_][-a-zA-Z0-9_]*)>>)",
6241 \begin_layout Plain Layout
6248 \begin_layout Plain Layout
6253 \begin_layout Plain Layout
6255 chunklet = substr(chunk, 1, RSTART - 1);
6263 \begin_layout Standard
6264 We keep track of the indent count, by counting the number of literal characters
6266 We can then preserve this indent on each output line when multi-line chunks
6270 \begin_layout Standard
6271 We then process this first part literal text, and set the chunk which is
6272 still to be processed to be the text after the
6273 \begin_inset Flex CharStyle:Code
6276 \begin_layout Plain Layout
6284 command, which we will process next as we continue around the loop.
6287 \begin_layout Standard
6288 \begin_inset listings
6292 \begin_layout Plain Layout
6294 indent += length(chunklet);
6297 \begin_layout Plain Layout
6299 chunk_line(active_chunk, chunklet);
6302 \begin_layout Plain Layout
6304 chunk = substr(chunk, RSTART + RLENGTH);
6312 \begin_layout Standard
6313 We then consider the type of chunk command we have found, whether it is
6314 the newfangle style command beginning with
6315 \begin_inset Flex CharStyle:Code
6318 \begin_layout Plain Layout
6324 or the older notangle style beginning with
6325 \begin_inset Flex CharStyle:Code
6328 \begin_layout Plain Layout
6338 \begin_layout Standard
6339 Newfangle chunks may have parameters contained within square brackets.
6340 These will be matched in
6341 \begin_inset Flex CharStyle:Code
6344 \begin_layout Plain Layout
6350 and are considered at this stage of processing to be part of the name of
6351 the chunk to be included.
6354 \begin_layout Standard
6355 \begin_inset listings
6359 \begin_layout Plain Layout
6361 if (substr(line[1], 1, 1) == "=") {
6364 \begin_layout Plain Layout
6366 # chunk name up to }
6369 \begin_layout Plain Layout
6371 chunk_include(active_chunk, line[2] line[3], indent);
6374 \begin_layout Plain Layout
6376 } else if (substr(line[1], 1, 1) == "<") {
6379 \begin_layout Plain Layout
6381 chunk_include(active_chunk, line[4], indent);
6384 \begin_layout Plain Layout
6389 \begin_layout Plain Layout
6391 error("Unknown chunk fragment: " line[1]);
6394 \begin_layout Plain Layout
6404 \begin_layout Standard
6405 The loop will continue until there are no more chunkref statements in the
6406 text, at which point we process the final part of the chunk.
6409 \begin_layout Standard
6410 \begin_inset listings
6414 \begin_layout Plain Layout
6419 \begin_layout Plain Layout
6421 chunk_line(active_chunk, chunk);
6429 \begin_layout Standard
6430 \begin_inset CommandInset label
6436 We add the newline character as a chunklet on it's own, to make it easier
6437 to detect new lines and thus manage indentation when processing the output.
6440 \begin_layout Standard
6441 \begin_inset listings
6445 \begin_layout Plain Layout
6447 chunk_line(active_chunk, "
6457 \begin_layout Standard
6458 We will also permit a chunk-part number to follow in square brackets, so
6460 \begin_inset Flex CharStyle:Code
6463 \begin_layout Plain Layout
6466 chunkref{chunk-name[1]}>
6471 will refer to the first part only.
6472 This can make it easy to include a C function prototype in a header file,
6473 if the first part of the chunk is just the function prototype without the
6474 trailing semi-colon.
6475 The header file would include the prototype with the trailing semi-colon,
6479 \begin_layout LyX-Code
6482 chunkref{chunk-name[1]}>;
6485 \begin_layout Standard
6486 This is handled in section
6487 \begin_inset CommandInset ref
6489 reference "sub:Chunk-parts"
6496 \begin_layout Standard
6497 We should perhaps introduce a notion of language specific chunk options;
6498 so that perhaps we could specify:
6501 \begin_layout LyX-Code
6504 chunkref{chunk-name[function-declaration]}>;
6507 \begin_layout Standard
6508 which applies a transform
6509 \begin_inset Flex CharStyle:Code
6512 \begin_layout Plain Layout
6513 function-declaration
6518 to the chunk --- which in this case would extract a function prototype
6520 \begin_inset Note Note
6523 \begin_layout Plain Layout
6532 \begin_layout Chapter
6536 \begin_layout Standard
6537 At the start, first we set the default options.
6544 \begin_layout Standard
6545 \begin_inset listings
6549 \begin_layout Plain Layout
6554 \begin_layout Plain Layout
6559 \begin_layout Plain Layout
6564 \begin_layout Plain Layout
6569 \begin_layout Plain Layout
6574 \begin_layout Plain Layout
6584 \begin_layout Standard
6585 Then we use getopt the standard way, and null out ARGV afterwards in the
6593 \begin_layout Standard
6594 \begin_inset listings
6598 \begin_layout Plain Layout
6600 Optind = 1 # skip ARGV[0]
6603 \begin_layout Plain Layout
6605 while(getopt(ARGC, ARGV, "R:LdT:hr")!=-1) {
6608 \begin_layout Plain Layout
6612 chunkref{handle-options}>
6615 \begin_layout Plain Layout
6620 \begin_layout Plain Layout
6622 for (i=1; i<Optind; i++) { ARGV[i]=""; }
6630 \begin_layout Standard
6631 This is how we handle our options:
6638 \begin_layout Standard
6639 \begin_inset listings
6643 \begin_layout Plain Layout
6645 if (Optopt == "R") root = Optarg;
6648 \begin_layout Plain Layout
6650 else if (Optopt == "r") root="";
6653 \begin_layout Plain Layout
6655 else if (Optopt == "L") linenos = 1;
6658 \begin_layout Plain Layout
6660 else if (Optopt == "d") debug = 1;
6663 \begin_layout Plain Layout
6665 else if (Optopt == "T") tabs = indent_string(Optarg+0);
6668 \begin_layout Plain Layout
6670 else if (Optopt == "h") help();
6673 \begin_layout Plain Layout
6675 else if (Optopt == "?") help();
6683 \begin_layout Standard
6684 We do all of this at the beginning of the program
6691 \begin_layout Standard
6692 \begin_inset listings
6696 \begin_layout Plain Layout
6701 \begin_layout Plain Layout
6705 chunkref{constants}>
6708 \begin_layout Plain Layout
6712 chunkref{default-options}>
6715 \begin_layout Plain Layout
6719 \begin_layout Plain Layout
6723 chunkref{read-options}>
6726 \begin_layout Plain Layout
6736 \begin_layout Standard
6737 And have a simple help function
6744 \begin_layout Standard
6745 \begin_inset listings
6749 \begin_layout Plain Layout
6754 \begin_layout Plain Layout
6759 \begin_layout Plain Layout
6761 print " newfangle [-L] -R<rootname> [source.tex ...]"
6764 \begin_layout Plain Layout
6766 print " newfangle -r [source.tex ...]"
6769 \begin_layout Plain Layout
6771 print " If the filename, source.tex is not specified then stdin is used"
6774 \begin_layout Plain Layout
6779 \begin_layout Plain Layout
6781 print "-L causes the C statement: #line <lineno>
6788 \begin_layout Plain Layout
6790 print "-R causes the named root to be written to stdout"
6793 \begin_layout Plain Layout
6795 print "-r lists all roots in the file (even those used elsewhere)"
6798 \begin_layout Plain Layout
6803 \begin_layout Plain Layout
6813 \begin_layout Chapter
6814 Chunk Language Modes
6817 \begin_layout Standard
6818 \begin_inset CommandInset label
6825 \begin_inset Note Greyedout
6828 \begin_layout Plain Layout
6829 This feature is in-development and does not work yet
6835 \begin_inset Note Note
6838 \begin_layout Plain Layout
6847 \begin_layout Standard
6848 lstlistings and newfangle both recognize source languages, and perform some
6850 lstlistings can detect strings and comments within a language definition
6851 and perform suitable rendering, such as italics for comments, and visible-space
6855 \begin_layout Standard
6856 Newfangle similarly can recognize strings, and comments, etc, within a language,
6857 so that any chunks included with
6858 \begin_inset Flex CharStyle:Code
6861 \begin_layout Plain Layout
6869 can be suitably quoted.
6872 \begin_layout Standard
6873 For instance, consider this chunk with
6874 \begin_inset Flex CharStyle:Code
6877 \begin_layout Plain Layout
6887 example-perl,language=perl
6890 \begin_layout Standard
6891 \begin_inset listings
6895 \begin_layout Plain Layout
6905 \begin_layout Standard
6906 If it were included in a chunk with
6907 \begin_inset Flex CharStyle:Code
6910 \begin_layout Plain Layout
6920 example-sh,language=sh
6923 \begin_layout Standard
6924 \begin_inset listings
6928 \begin_layout Plain Layout
6932 chunkref{example-perl}>"
6940 \begin_layout Standard
6941 would need to generate output like this if it were to work:
6944 \begin_layout LyX-Code
6952 \begin_layout Standard
6953 See that the double quote " as part of the regex has been quoted with a
6954 slash to protect it from shell interpretation.
6957 \begin_layout Standard
6958 If that were then included in a chunk with
6959 \begin_inset Flex CharStyle:Code
6962 \begin_layout Plain Layout
6972 example-makefile,language=make
6975 \begin_layout Standard
6976 \begin_inset listings
6980 \begin_layout Plain Layout
6985 \begin_layout Plain Layout
6989 chunkref{example-sh}>
6997 \begin_layout Standard
6998 We would need the output to look like this --- note the $$:
7001 \begin_layout LyX-Code
7005 \begin_layout LyX-Code
7013 \begin_layout Standard
7014 In order to make this work, we need to define a mode-tracker for each supported
7015 language, that can detect the various quoting modes, and provide a transformati
7016 on that must be applied to any included text so that included text will
7017 be interpreted correctly after the additional interpolation that it will
7018 be subject to at run-time.
7021 \begin_layout Standard
7022 For example, the transformation for text to be inserted into sh double-quoted
7023 strings would be something like:
7026 \begin_layout LyX-Code
7050 \begin_layout Standard
7052 \begin_inset Flex CharStyle:Code
7055 \begin_layout Plain Layout
7066 \begin_layout Standard
7067 \begin_inset Note Note
7070 \begin_layout Plain Layout
7071 I don't think this example is true
7076 The mode tracker must also track nested mode-changes, as in this
7077 \begin_inset Flex CharStyle:Code
7080 \begin_layout Plain Layout
7089 \begin_layout LyX-Code
7090 echo "hello `id **`"
7093 \begin_layout Standard
7094 Any literal text inserted at the point marked ** would need to be escaped
7095 in all kinds of ways, including
7096 \begin_inset Flex CharStyle:Code
7099 \begin_layout Plain Layout
7106 First it would need escaping for the back-ticks `, and then for the double-quot
7110 \begin_layout Standard
7111 Escaping need not occur if the format and mode of the included chunk matches
7112 that of the including chunk, which would suggest that any back-ticks might
7113 need to be part of the included chunk and not including chunk
7114 \begin_inset Note Note
7117 \begin_layout Plain Layout
7118 or is it the other way around?
7126 \begin_layout Standard
7127 As each chunk is output a new mode tracker for that language is initialized
7128 in it's normal state.
7129 As text is output for that chunk the output mode is tracked.
7130 When a new chunk is included, a transformation appropriate to that mode
7131 is selected and pushed onto a stack of transformations.
7132 Any text to be output is first passed through this stack of transformations.
7135 \begin_layout Standard
7136 It remains to consider if the chunk-include function should return it's
7137 generated text so that the caller can apply any transformations (and formatting
7138 ), or if it should apply the stack of transformations itself.
7141 \begin_layout Standard
7142 Note that the transformed text should have the property of not being able
7143 to change the mode in the current chunk.
7146 \begin_layout Standard
7147 \begin_inset Note Note
7150 \begin_layout Plain Layout
7151 Note chunk parameters should probably also be transformed
7163 \begin_layout Standard
7164 \begin_inset listings
7168 \begin_layout Plain Layout
7170 function new_mode(language, mode) {
7173 \begin_layout Plain Layout
7175 mode["language"] = language;
7178 \begin_layout Plain Layout
7183 \begin_layout Plain Layout
7193 \begin_layout Standard
7194 Because awk functions cannot return an array, we must create the array first
7199 new-mode,params=language;mode
7202 \begin_layout Standard
7203 \begin_inset listings
7207 \begin_layout Plain Layout
7211 chunkref{awk-delete-array}(${mode})>
7214 \begin_layout Plain Layout
7216 new_mode(${language}, ${mode});
7224 \begin_layout Standard
7225 And for tracking modes, we dispatch to a mode-tracker action based on the
7233 \begin_layout Standard
7234 \begin_inset listings
7238 \begin_layout Plain Layout
7240 function track_mode(mode, text) {
7243 \begin_layout Plain Layout
7245 if (mode["language"] == "C") {
7248 \begin_layout Plain Layout
7252 chunkref{track-mode-C}>
7255 \begin_layout Plain Layout
7260 \begin_layout Plain Layout
7265 \begin_layout Plain Layout
7275 \begin_layout Standard
7276 For each mode, we look for a character that has the power to change the
7280 \begin_layout Standard
7285 \labelwidthstring 00.00.0000
7286 \begin_inset Quotes eld
7289 enters double-quote mode
7293 \labelwidthstring 00.00.0000
7294 ' enters single-quote mode
7298 \labelwidthstring 00.00.0000
7301 enters multi-line mode
7305 \labelwidthstring 00.00.0000
7306 # enters #define sub-mode, needs
7308 escaping end of line too
7312 \labelwidthstring 00.00.0000
7313 /* enters comment mode
7316 \begin_layout Standard
7317 In double-quote mode, escape
7320 \begin_inset Quotes eld
7326 \begin_layout Standard
7330 \begin_inset Quotes eld
7336 \begin_layout Standard
7337 \begin_inset Quotes eld
7343 \begin_layout Standard
7344 newline needs to close and re-open string or something
7347 \begin_layout Standard
7348 in single-quote mode escape
7351 \begin_inset Quotes eld
7361 \begin_layout Standard
7362 \begin_inset listings
7366 \begin_layout Plain Layout
7379 \begin_layout Standard
7380 \begin_inset listings
7384 \begin_layout Plain Layout
7388 chunkref{new_mode()}>
7396 \begin_layout Chapter
7397 Generating the output
7400 \begin_layout Standard
7401 We generate output by calling output_chunk, or listing the chunk names.
7408 \begin_layout Standard
7409 \begin_inset listings
7413 \begin_layout Plain Layout
7415 if (length(root)) output_chunk(root);
7418 \begin_layout Plain Layout
7420 else output_chunk_names();
7428 \begin_layout Standard
7429 We also have some other output debugging:
7436 \begin_layout Standard
7437 \begin_inset listings
7441 \begin_layout Plain Layout
7446 \begin_layout Plain Layout
7448 print "------ chunk names "
7451 \begin_layout Plain Layout
7453 output_chunk_names();
7456 \begin_layout Plain Layout
7458 print "====== chunks"
7461 \begin_layout Plain Layout
7466 \begin_layout Plain Layout
7468 print "++++++ debug"
7471 \begin_layout Plain Layout
7476 \begin_layout Plain Layout
7478 print a "=" chunks[a];
7481 \begin_layout Plain Layout
7486 \begin_layout Plain Layout
7496 \begin_layout Standard
7497 We do both of these at the end.
7499 \begin_inset Flex CharStyle:Code
7502 \begin_layout Plain Layout
7508 because each chunklet is not necessarily a complete line, and we already
7510 \begin_inset Flex CharStyle:Code
7513 \begin_layout Plain Layout
7519 to each input line in section
7520 \begin_inset CommandInset ref
7522 reference "sub:ORS-chunk-text"
7533 \begin_layout Standard
7534 \begin_inset listings
7538 \begin_layout Plain Layout
7543 \begin_layout Plain Layout
7547 chunkref{debug-output}>
7550 \begin_layout Plain Layout
7555 \begin_layout Plain Layout
7559 chunkref{generate-output}>
7562 \begin_layout Plain Layout
7572 \begin_layout Standard
7573 We write chunk names like this.
7574 If we seem to be running in notangle compatibility mode, then we enclose
7576 \begin_inset Flex CharStyle:Code
7579 \begin_layout Plain Layout
7585 the same way notangle does:
7589 output_chunk_names()
7592 \begin_layout Standard
7593 \begin_inset listings
7597 \begin_layout Plain Layout
7599 function output_chunk_names( c, prefix, suffix)
7602 \begin_layout Plain Layout
7607 \begin_layout Plain Layout
7609 if (notangle_mode) {
7612 \begin_layout Plain Layout
7617 \begin_layout Plain Layout
7622 \begin_layout Plain Layout
7627 \begin_layout Plain Layout
7629 for (c in chunk_names) {
7632 \begin_layout Plain Layout
7634 print prefix c suffix "
7639 \begin_layout Plain Layout
7644 \begin_layout Plain Layout
7654 \begin_layout Standard
7655 This function would write out all chunks
7662 \begin_layout Standard
7663 \begin_inset listings
7667 \begin_layout Plain Layout
7669 function output_chunks( a)
7672 \begin_layout Plain Layout
7677 \begin_layout Plain Layout
7679 for (a in chunk_names) {
7682 \begin_layout Plain Layout
7684 output_chunk(chunk_names[a]);
7687 \begin_layout Plain Layout
7692 \begin_layout Plain Layout
7697 \begin_layout Plain Layout
7701 \begin_layout Plain Layout
7703 function output_chunk(chunk) {
7706 \begin_layout Plain Layout
7711 \begin_layout Plain Layout
7713 lineno_needed = linenos;
7716 \begin_layout Plain Layout
7720 \begin_layout Plain Layout
7725 \begin_layout Plain Layout
7730 \begin_layout Plain Layout
7739 \begin_layout Section
7740 Assembling the chunks
7743 \begin_layout Standard
7744 \begin_inset Flex CharStyle:Code
7747 \begin_layout Plain Layout
7753 holds a string consisting of the names of all the chunks that resulted
7754 in this chunk being output.
7756 \begin_inset Note Note
7759 \begin_layout Plain Layout
7760 Make sure it includes the line numbers too...
7766 It should probably also contain the source line numbers at which each inclusion
7771 write_chunk(),emph={chunk_path}
7774 \begin_layout Standard
7775 \begin_inset listings
7779 \begin_layout Plain Layout
7781 function write_chunk(chunk_name, indent, tail,
7784 \begin_layout Plain Layout
7789 \begin_layout Plain Layout
7791 chunk_path, chunk_args,
7794 \begin_layout Plain Layout
7799 \begin_layout Plain Layout
7801 part, max_part, part_line, frag, max_frag, text,
7804 \begin_layout Plain Layout
7806 chunklet, only_part, call_chunk_args, mode)
7809 \begin_layout Plain Layout
7819 \begin_layout Subsection
7820 \begin_inset CommandInset label
7822 name "sub:Chunk-parts"
7829 \begin_layout Standard
7830 As mentioned in section
7831 \begin_inset CommandInset ref
7833 reference "sub:lstlistings-includes"
7837 , a chunk name may contain a part specifier in square brackets, limiting
7838 the parts that should be emitted.
7841 \begin_layout Standard
7842 \begin_inset listings
7846 \begin_layout Plain Layout
7848 if (match(chunk_name, "^(.*)
7856 ]$", chunk_name_parts)) {
7859 \begin_layout Plain Layout
7861 chunk_name = chunk_name_parts[1];
7864 \begin_layout Plain Layout
7866 only_part = chunk_name_parts[2];
7869 \begin_layout Plain Layout
7879 \begin_layout Standard
7880 We first create the mode tracker for this chunk.
7883 \begin_layout Standard
7886 chunkref{awk-delete-array}(mode)>
7889 \begin_layout Standard
7890 \begin_inset listings
7894 \begin_layout Plain Layout
7899 \begin_layout Plain Layout
7901 new_mode(chunks[chunk_name, "language"], mode);
7909 \begin_layout Standard
7912 chunkref{new-mode}(chunks[chunk_name, "language"], mode)>
7915 \begin_layout Standard
7917 \begin_inset Flex CharStyle:Code
7920 \begin_layout Plain Layout
7926 the names of the parameters that this chunk accepts, whose values were
7927 (optionally) passed in
7928 \begin_inset Flex CharStyle:Code
7931 \begin_layout Plain Layout
7940 \begin_layout Standard
7941 \begin_inset listings
7945 \begin_layout Plain Layout
7947 split(chunks[chunk_name, "params"], chunk_params, " *; *");
7955 \begin_layout Standard
7956 To assemble a chunk, we write out each part.
7963 \begin_layout Standard
7964 \begin_inset listings
7968 \begin_layout Plain Layout
7970 if (! (chunk_name in chunk_names)) {
7973 \begin_layout Plain Layout
7975 error(sprintf(_"The root module <<%s>> was not defined.
7982 \begin_layout Plain Layout
7984 chunk_name, chunk_path));
7987 \begin_layout Plain Layout
7992 \begin_layout Plain Layout
7996 \begin_layout Plain Layout
7998 max_part = chunks[chunk_name, "part"];
8001 \begin_layout Plain Layout
8003 for(part = 1; part <= max_part; part++) {
8006 \begin_layout Plain Layout
8008 if (! only_part || part == only_part) {
8011 \begin_layout Plain Layout
8015 chunkref{write-part}>
8018 \begin_layout Plain Layout
8023 \begin_layout Plain Layout
8028 \begin_layout Plain Layout
8038 \begin_layout Standard
8039 A part can either be a chunklet of lines, or an include of another chunk.
8042 \begin_layout Standard
8043 Chunks may also have parameters, specified in LaTeX style with braces after
8044 the chunk name --- looking like this in the document:
8045 \begin_inset Flex CharStyle:Code
8048 \begin_layout Plain Layout
8049 chunkname{param1, param2}
8055 Arguments are passed in square brackets:
8056 \begin_inset Flex CharStyle:Code
8059 \begin_layout Plain Layout
8062 chunkref{chunkname}[arg1, arg2]
8070 \begin_layout Standard
8071 Before we process each part, we check that the source position hasn't changed
8072 unexpectedly, so that we can know if we need to output a new file-line
8080 \begin_layout Standard
8081 \begin_inset listings
8085 \begin_layout Plain Layout
8089 chunkref{check-source-jump}>
8092 \begin_layout Plain Layout
8096 \begin_layout Plain Layout
8098 chunklet = chunks[chunk_name, "part", part];
8101 \begin_layout Plain Layout
8103 if (chunks[chunk_name, "part", part, "type"] == part_type_chunk) {
8106 \begin_layout Plain Layout
8110 chunkref{write-included-chunk}>
8113 \begin_layout Plain Layout
8115 } else if (chunklet SUBSEP "line" in chunks) {
8118 \begin_layout Plain Layout
8122 chunkref{write-chunklets}>
8125 \begin_layout Plain Layout
8130 \begin_layout Plain Layout
8132 # empty last chunklet
8135 \begin_layout Plain Layout
8145 \begin_layout Standard
8146 To write an included chunk, we must detect any optional chunk arguments
8148 Then we recurse calling
8149 \begin_inset Flex Chunkref
8152 \begin_layout Plain Layout
8162 write-included-chunk
8165 \begin_layout Standard
8166 \begin_inset listings
8170 \begin_layout Plain Layout
8172 if (match(chunklet, "^([^
8184 )$", chunklet_parts)) {
8187 \begin_layout Plain Layout
8189 chunklet = chunklet_parts[1];
8192 \begin_layout Plain Layout
8194 # parse_chunk_args(chunklet_parts[2], chunk_args);
8197 \begin_layout Plain Layout
8199 # TO BE parse_chunk_args SOON
8202 \begin_layout Plain Layout
8204 split(chunklet_parts[2], call_chunk_args, " *, *");
8207 \begin_layout Plain Layout
8209 for (c in call_chunk_args) {
8212 \begin_layout Plain Layout
8214 call_chunk_args[c] = expand_chunk_args(call_chunk_args[c], chunk_params,
8218 \begin_layout Plain Layout
8223 \begin_layout Plain Layout
8228 \begin_layout Plain Layout
8230 split("", call_chunk_args);
8233 \begin_layout Plain Layout
8238 \begin_layout Plain Layout
8240 write_chunk(chunklet,
8243 \begin_layout Plain Layout
8245 chunks[chunk_name, "part", part, "indent"] indent,
8248 \begin_layout Plain Layout
8250 chunks[chunk_name, "part", part, "tail"],
8253 \begin_layout Plain Layout
8260 \begin_layout Plain Layout
8270 \begin_layout Standard
8271 Before we output a chunklet of lines, we first emit the file and line number
8272 if we have one, and if it is safe to do so.
8276 \begin_layout Standard
8277 Chunklets are generally broken up by includes, so the start of a chunklet
8278 is a good place to do this.
8279 Then we output each line of the chunklet.
8282 \begin_layout Standard
8283 When it is not safe, such as in the middle of a multi-line macro definition,
8285 \begin_inset Flex CharStyle:Code
8288 \begin_layout Plain Layout
8294 is set to true, and in such a case we note that we want to emit the line
8295 statement when it is next safe.
8302 \begin_layout Standard
8303 \begin_inset listings
8307 \begin_layout Plain Layout
8309 max_frag = chunks[chunklet, "line"];
8312 \begin_layout Plain Layout
8314 for(frag = 1; frag <= max_frag; frag++) {
8317 \begin_layout Plain Layout
8321 chunkref{write-file-line}>
8329 \begin_layout Standard
8330 We then extract the chunklet text and expand any arguments.
8333 \begin_layout Standard
8334 \begin_inset listings
8338 \begin_layout Plain Layout
8342 \begin_layout Plain Layout
8344 text = chunks[chunklet, frag];
8347 \begin_layout Plain Layout
8352 \begin_layout Plain Layout
8357 \begin_layout Plain Layout
8359 text = expand_chunk_args(text, chunk_params, chunk_args);
8367 \begin_layout Standard
8368 If the text is a single newline (which we keep separate - see
8369 \begin_inset CommandInset ref
8371 reference "lone-newline"
8375 ) then we increment the line number.
8376 In the case where this is the last line of a chunk and it is not a top-level
8377 chunk we replace the newline with an empty string --- because the chunk
8378 that included this chunk will have the newline at the end of the line that
8379 included this chunk.
8382 \begin_layout Standard
8384 \begin_inset Flex CharStyle:Code
8387 \begin_layout Plain Layout
8393 that we have started a new line, so that indentation can be managed with
8394 the following piece of text.
8397 \begin_layout Standard
8398 \begin_inset listings
8402 \begin_layout Plain Layout
8406 \begin_layout Plain Layout
8413 \begin_layout Plain Layout
8418 \begin_layout Plain Layout
8420 if (part == max_part && frag == max_frag && length(chunk_path)) {
8423 \begin_layout Plain Layout
8428 \begin_layout Plain Layout
8433 \begin_layout Plain Layout
8438 \begin_layout Plain Layout
8443 \begin_layout Plain Layout
8453 \begin_layout Standard
8454 If this text does not represent a newline, but we see that we are the first
8455 piece of text on a newline, then we prefix our text with the current indent.
8457 \begin_inset Flex CharStyle:Code
8460 \begin_layout Plain Layout
8466 is a global output-state variable, but the
8467 \begin_inset Flex CharStyle:Code
8470 \begin_layout Plain Layout
8480 \begin_layout Standard
8481 \begin_inset listings
8485 \begin_layout Plain Layout
8487 } else if (length(text) || length(tail)) {
8490 \begin_layout Plain Layout
8492 if (newline) text = indent text;
8495 \begin_layout Plain Layout
8500 \begin_layout Plain Layout
8505 \begin_layout Plain Layout
8514 \begin_layout Standard
8515 Tail will soon no longer be relevant once mode-detection is in place.
8518 \begin_layout Standard
8519 \begin_inset listings
8523 \begin_layout Plain Layout
8528 \begin_layout Plain Layout
8530 # track_mode(mode, text);
8533 \begin_layout Plain Layout
8543 \begin_layout Standard
8544 If a line ends in a backslash --- suggesting continuation --- then we supress
8545 outputting file-line as it would probably break the continued lines.
8549 \begin_layout Standard
8550 \begin_inset listings
8554 \begin_layout Plain Layout
8559 \begin_layout Plain Layout
8561 lineno_suppressed = substr(lastline, length(lastline)) == "
8568 \begin_layout Plain Layout
8573 \begin_layout Plain Layout
8583 \begin_layout Standard
8584 Of course there is no point in actually outputting the source filename and
8585 line number (file-line) if they don't say anything new! We only need to
8586 emit them if they aren't what is expected, or if we we not able to emit
8587 one when they had changed.
8594 \begin_layout Standard
8595 \begin_inset listings
8599 \begin_layout Plain Layout
8601 if (newline && lineno_needed && ! lineno_suppressed) {
8604 \begin_layout Plain Layout
8606 filename = a_filename;
8609 \begin_layout Plain Layout
8614 \begin_layout Plain Layout
8616 print "#line " lineno "
8625 \begin_layout Plain Layout
8630 \begin_layout Plain Layout
8640 \begin_layout Standard
8641 We check if a new file-line is needed by checking if the source line matches
8642 what we (or a compiler) would expect.
8650 \begin_layout Standard
8651 \begin_inset listings
8655 \begin_layout Plain Layout
8657 if (linenos && (chunk_name SUBSEP "part" SUBSEP part SUBSEP "FILENAME" in
8661 \begin_layout Plain Layout
8663 a_filename = chunks[chunk_name, "part", part, "FILENAME"];
8666 \begin_layout Plain Layout
8668 a_lineno = chunks[chunk_name, "part", part, "LINENO"];
8671 \begin_layout Plain Layout
8673 if (a_filename != filename || a_lineno != lineno) {
8676 \begin_layout Plain Layout
8681 \begin_layout Plain Layout
8686 \begin_layout Plain Layout
8696 \begin_layout Chapter
8700 \begin_layout Standard
8701 Awk has pretty limited data structures, so we will use two main hashes.
8702 Uninterrupted sequences of a chunk will be stored in
8703 \begin_inset Flex CharStyle:Code
8706 \begin_layout Plain Layout
8712 and the chunklets used in a chunk will be stored in
8713 \begin_inset Flex CharStyle:Code
8716 \begin_layout Plain Layout
8729 \begin_layout Standard
8730 \begin_inset listings
8734 \begin_layout Plain Layout
8744 \begin_layout Standard
8746 \begin_inset Flex CharStyle:Code
8749 \begin_layout Plain Layout
8755 mentioned are not chunk parameters for parameterized chunks, as mentioned
8757 \begin_inset CommandInset ref
8759 reference "cha:Chunk Arguments"
8763 , but the lstlistings style parameters used in the
8764 \begin_inset Flex CharStyle:Code
8767 \begin_layout Plain Layout
8779 \begin_layout Plain Layout
8781 \begin_inset Flex CharStyle:Code
8784 \begin_layout Plain Layout
8790 parameter is used to hold the parameters for parameterized chunks
8799 chunk-storage-functions
8802 \begin_layout Standard
8803 \begin_inset listings
8807 \begin_layout Plain Layout
8809 function new_chunk(chunk_name, params,
8812 \begin_layout Plain Layout
8817 \begin_layout Plain Layout
8822 \begin_layout Plain Layout
8827 \begin_layout Plain Layout
8829 # HACK WHILE WE CHANGE TO ( ) for PARAM CHUNKS
8832 \begin_layout Plain Layout
8842 )$", "", chunk_name);
8845 \begin_layout Plain Layout
8847 active_chunk = chunk_name;
8850 \begin_layout Plain Layout
8852 if (! (chunk_name in chunk_names)) {
8855 \begin_layout Plain Layout
8857 if (debug) print "New chunk " chunk_name;
8860 \begin_layout Plain Layout
8862 chunk_names[chunk_name];
8865 \begin_layout Plain Layout
8870 \begin_layout Plain Layout
8872 chunks[chunk_name, p] = params[p];
8875 \begin_layout Plain Layout
8880 \begin_layout Plain Layout
8885 \begin_layout Plain Layout
8887 prime_chunk(chunk_name);
8890 \begin_layout Plain Layout
8900 \begin_layout Standard
8901 \begin_inset listings
8905 \begin_layout Plain Layout
8909 \begin_layout Plain Layout
8911 function prime_chunk(chunk_name)
8914 \begin_layout Plain Layout
8919 \begin_layout Plain Layout
8921 chunks[chunk_name, "part", ++chunks[chunk_name, "part"] ] =
8926 \begin_layout Plain Layout
8928 chunk_name SUBSEP "chunklet" SUBSEP "" ++chunks[chunk_name, "chunklet"]
8932 \begin_layout Plain Layout
8934 chunks[chunk_name, "part", chunks[chunk_name, "part"], "FILENAME"] = FILENAME;
8937 \begin_layout Plain Layout
8939 chunks[chunk_name, "part", chunks[chunk_name, "part"], "LINENO"] = FNR
8943 \begin_layout Plain Layout
8948 \begin_layout Plain Layout
8952 \begin_layout Plain Layout
8954 function chunk_line(chunk_name, line){
8957 \begin_layout Plain Layout
8959 chunks[chunk_name, "chunklet", chunks[chunk_name, "chunklet"],
8962 \begin_layout Plain Layout
8964 ++chunks[chunk_name, "chunklet", chunks[chunk_name, "chunklet"],
8968 \begin_layout Plain Layout
8973 \begin_layout Plain Layout
8982 \begin_layout Standard
8983 Chunk include represents a
8987 statement, and stores the requirement to include another chunk.
8988 The parameter indent represents the quanity of literal text characters
8993 statement and therefore by how much additional lines of the included chunk
8997 \begin_layout Standard
8998 \begin_inset listings
9002 \begin_layout Plain Layout
9004 function chunk_include(chunk_name, chunk_ref, indent, tail)
9007 \begin_layout Plain Layout
9012 \begin_layout Plain Layout
9014 chunks[chunk_name, "part", ++chunks[chunk_name, "part"] ] = chunk_ref;
9017 \begin_layout Plain Layout
9019 chunks[chunk_name, "part", chunks[chunk_name, "part"], "type" ] = part_type_ch
9023 \begin_layout Plain Layout
9025 chunks[chunk_name, "part", chunks[chunk_name, "part"], "indent" ] = indent_str
9029 \begin_layout Plain Layout
9031 chunks[chunk_name, "part", chunks[chunk_name, "part"], "tail" ] = tail;
9034 \begin_layout Plain Layout
9036 prime_chunk(chunk_name);
9039 \begin_layout Plain Layout
9044 \begin_layout Plain Layout
9053 \begin_layout Standard
9054 The indent is calculated by indent_string, which may in future convert some
9055 spaces into tab characters.
9056 This function works by generating a printf padded format string, like
9057 \begin_inset Flex CharStyle:Code
9060 \begin_layout Plain Layout
9066 for an indent of 22, and then printing an empty string using that format.
9069 \begin_layout Standard
9070 \begin_inset listings
9074 \begin_layout Plain Layout
9076 function indent_string(indent) {
9079 \begin_layout Plain Layout
9081 return sprintf("%" indent "s", "");
9084 \begin_layout Plain Layout
9094 \begin_layout Chapter
9095 \begin_inset CommandInset label
9104 \begin_layout Standard
9105 I use Arnold Robbins public domain getopt (1993 revision).
9106 This is probably the same one that is covered in chapter 12 of
9107 \begin_inset Quotes eld
9110 Edition 3 of GAWK: Effective AWK Programming: A User's Guide for GNU Awk
9111 \begin_inset Quotes erd
9114 but as that is licensed under the GNU Free Documentation License, Version
9115 1.3, which conflicts with the GPL3, I can't use it from there (or it's accompany
9116 ing explanations), so I do my best to explain how it works here.
9119 \begin_layout Standard
9120 The getopt.awk header is:
9124 getopt.awk-header,language=awk,morestring=[b]{/},morekeywords=else
9127 \begin_layout Standard
9128 \begin_inset listings
9132 \begin_layout Plain Layout
9134 # getopt.awk --- do C library getopt(3) function in awk
9137 \begin_layout Plain Layout
9142 \begin_layout Plain Layout
9144 # Arnold Robbins, arnold@skeeve.com, Public Domain
9147 \begin_layout Plain Layout
9152 \begin_layout Plain Layout
9154 # Initial version: March, 1991
9157 \begin_layout Plain Layout
9159 # Revised: May, 1993
9167 \begin_layout Standard
9168 The provided explanation is:
9175 \begin_layout Standard
9176 \begin_inset listings
9180 \begin_layout Plain Layout
9182 # External variables:
9185 \begin_layout Plain Layout
9187 # Optind -- index in ARGV of first nonoption argument
9190 \begin_layout Plain Layout
9192 # Optarg -- string value of argument to current option
9195 \begin_layout Plain Layout
9197 # Opterr -- if nonzero, print our own diagnostic
9200 \begin_layout Plain Layout
9202 # Optopt -- current option letter
9205 \begin_layout Plain Layout
9209 \begin_layout Plain Layout
9214 \begin_layout Plain Layout
9216 # -1 at end of options
9219 \begin_layout Plain Layout
9221 # ? for unrecognized option
9224 \begin_layout Plain Layout
9226 # <c> a character representing the current option
9229 \begin_layout Plain Layout
9233 \begin_layout Plain Layout
9238 \begin_layout Plain Layout
9240 # _opti -- index in multi-flag option, e.g., -abc
9248 \begin_layout Standard
9249 The function follows.
9250 The final two parameters,
9251 \begin_inset Flex CharStyle:Code
9254 \begin_layout Plain Layout
9261 \begin_inset Flex CharStyle:Code
9264 \begin_layout Plain Layout
9270 are local variables and not parameters --- as indicated by the multiple
9271 spaces preceding them.
9272 Awk doesn't care, the multiple spaces are a convention to help us humans.
9279 \begin_layout Standard
9280 \begin_inset listings
9284 \begin_layout Plain Layout
9286 function getopt(argc, argv, options, thisopt, i)
9289 \begin_layout Plain Layout
9294 \begin_layout Plain Layout
9296 if (length(options) == 0) # no options given
9299 \begin_layout Plain Layout
9304 \begin_layout Plain Layout
9306 if (argv[Optind] == "--") { # all done
9309 \begin_layout Plain Layout
9314 \begin_layout Plain Layout
9319 \begin_layout Plain Layout
9324 \begin_layout Plain Layout
9326 } else if (argv[Optind] !~ /^-[^:
9341 \begin_layout Plain Layout
9346 \begin_layout Plain Layout
9351 \begin_layout Plain Layout
9356 \begin_layout Plain Layout
9361 \begin_layout Plain Layout
9366 \begin_layout Plain Layout
9368 thisopt = substr(argv[Optind], _opti, 1)
9371 \begin_layout Plain Layout
9376 \begin_layout Plain Layout
9378 i = index(options, thisopt)
9381 \begin_layout Plain Layout
9386 \begin_layout Plain Layout
9391 \begin_layout Plain Layout
9393 printf("%c -- invalid option
9398 \begin_layout Plain Layout
9400 thisopt) > "/dev/stderr"
9403 \begin_layout Plain Layout
9405 if (_opti >= length(argv[Optind])) {
9408 \begin_layout Plain Layout
9413 \begin_layout Plain Layout
9418 \begin_layout Plain Layout
9423 \begin_layout Plain Layout
9428 \begin_layout Plain Layout
9433 \begin_layout Plain Layout
9443 \begin_layout Standard
9444 At this point, the option has been found and we need to know if it takes
9448 \begin_layout Standard
9449 \begin_inset listings
9453 \begin_layout Plain Layout
9455 if (substr(options, i + 1, 1) == ":") {
9458 \begin_layout Plain Layout
9460 # get option argument
9463 \begin_layout Plain Layout
9465 if (length(substr(argv[Optind], _opti + 1)) > 0)
9468 \begin_layout Plain Layout
9470 Optarg = substr(argv[Optind], _opti + 1)
9473 \begin_layout Plain Layout
9478 \begin_layout Plain Layout
9480 Optarg = argv[++Optind]
9483 \begin_layout Plain Layout
9488 \begin_layout Plain Layout
9493 \begin_layout Plain Layout
9498 \begin_layout Plain Layout
9500 if (_opti == 0 || _opti >= length(argv[Optind])) {
9503 \begin_layout Plain Layout
9508 \begin_layout Plain Layout
9513 \begin_layout Plain Layout
9518 \begin_layout Plain Layout
9523 \begin_layout Plain Layout
9528 \begin_layout Plain Layout
9535 A test program is built in, too
9542 \begin_layout Standard
9543 \begin_inset listings
9547 \begin_layout Plain Layout
9552 \begin_layout Plain Layout
9554 Opterr = 1 # default is to diagnose
9557 \begin_layout Plain Layout
9559 Optind = 1 # skip ARGV[0]
9562 \begin_layout Plain Layout
9567 \begin_layout Plain Layout
9572 \begin_layout Plain Layout
9574 while ((_go_c = getopt(ARGC, ARGV, "ab:cd")) != -1)
9577 \begin_layout Plain Layout
9579 printf("c = <%c>, optarg = <%s>
9584 \begin_layout Plain Layout
9589 \begin_layout Plain Layout
9591 printf("non-option arguments:
9596 \begin_layout Plain Layout
9598 for (; Optind < ARGC; Optind++)
9601 \begin_layout Plain Layout
9610 \begin_layout Plain Layout
9612 Optind, ARGV[Optind])
9615 \begin_layout Plain Layout
9620 \begin_layout Plain Layout
9630 \begin_layout Standard
9631 The entire getopt.awk is made out of these chunks in order
9638 \begin_layout Standard
9639 \begin_inset listings
9643 \begin_layout Plain Layout
9647 chunkref{getopt.awk-header}>
9650 \begin_layout Plain Layout
9654 \begin_layout Plain Layout
9658 chunkref{getopt.awk-notes}>
9661 \begin_layout Plain Layout
9665 chunkref{getopt.awk-getopt()}>
9668 \begin_layout Plain Layout
9672 chunkref{getopt.awk-begin}>
9680 \begin_layout Standard
9681 Although we only want the header and function:
9688 \begin_layout Standard
9689 \begin_inset listings
9693 \begin_layout Plain Layout
9695 # try: locate getopt.awk for the full original file
9698 \begin_layout Plain Layout
9700 # as part of your standard awk installation
9703 \begin_layout Plain Layout
9707 chunkref{getopt.awk-header}>
9710 \begin_layout Plain Layout
9714 \begin_layout Plain Layout
9718 chunkref{getopt.awk-getopt()}>
9726 \begin_layout Chapter
9727 Newfangle LaTeX source code
9730 \begin_layout Section
9734 \begin_layout Standard
9735 Here we define a Lyx .module file that makes it convenient to use LyX for
9736 writing such literate programs.
9739 \begin_layout Standard
9741 \begin_inset Flex CharStyle:Code
9744 \begin_layout Plain Layout
9750 can be installed in your personal
9751 \begin_inset Flex CharStyle:Code
9754 \begin_layout Plain Layout
9761 You will need to Tools Reconfigure so that LyX notices it.
9762 It adds a new format Chunk, which should precede every listing and contain
9768 ./newfangle.module,language=
9771 \begin_layout Standard
9772 \begin_inset listings
9776 \begin_layout Plain Layout
9780 DeclareLyXModule{Newfangle Literate Listings}
9783 \begin_layout Plain Layout
9788 \begin_layout Plain Layout
9790 # Newfangle literate listings allow one to write
9793 \begin_layout Plain Layout
9795 # literate programs after the fashion of noweb, but without having
9798 \begin_layout Plain Layout
9800 # to use noweave to generate the documentation.
9801 Instead the listings
9804 \begin_layout Plain Layout
9806 # package is extended in conjunction with the noweb package to implement
9809 \begin_layout Plain Layout
9811 # to code formating directly as latex.
9814 \begin_layout Plain Layout
9816 # The newfangle awk script
9819 \begin_layout Plain Layout
9824 \begin_layout Plain Layout
9828 \begin_layout Plain Layout
9833 \begin_layout Plain Layout
9837 \begin_layout Plain Layout
9842 \begin_layout Plain Layout
9846 chunkref{./newfangle.sty}>
9849 \begin_layout Plain Layout
9854 \begin_layout Plain Layout
9858 \begin_layout Plain Layout
9862 chunkref{chunkstyle}>
9865 \begin_layout Plain Layout
9869 \begin_layout Plain Layout
9881 \begin_layout Subsection
9885 \begin_layout Standard
9890 style is to make it easier for LyX users to provide the name to
9891 \begin_inset Flex CharStyle:Code
9894 \begin_layout Plain Layout
9903 Normally this requires right-clicking on the listing, choosing settings,
9904 advanced, and then typing
9905 \begin_inset Flex CharStyle:Code
9908 \begin_layout Plain Layout
9915 This has the further disadvantage that the name (and other options) are
9916 not generally visible during document editing.
9919 \begin_layout Standard
9920 The chunk style is defined as a LaTeX command, so that all text on the same
9921 line is passed to the LaTeX command
9922 \begin_inset Flex CharStyle:Code
9925 \begin_layout Plain Layout
9932 This makes it easy to parse using
9933 \begin_inset Flex CharStyle:Code
9936 \begin_layout Plain Layout
9942 , and easy to pass these options on to the listings package.
9943 The first word in a chunk section should be the chunk name, and will have
9945 \begin_inset Flex CharStyle:Code
9948 \begin_layout Plain Layout
9955 Any other words are accepted arguments to
9956 \begin_inset Flex CharStyle:Code
9959 \begin_layout Plain Layout
9970 \begin_layout Standard
9971 We set PassThru to 1 because the user is actually entering raw latex.
9978 \begin_layout Standard
9979 \begin_inset listings
9983 \begin_layout Plain Layout
9988 \begin_layout Plain Layout
9993 \begin_layout Plain Layout
9998 \begin_layout Plain Layout
10000 Margin First_Dynamic
10003 \begin_layout Plain Layout
10005 LeftMargin Chunk:xxx
10008 \begin_layout Plain Layout
10013 \begin_layout Plain Layout
10018 \begin_layout Plain Layout
10020 LabelString "Chunk:"
10023 \begin_layout Plain Layout
10028 \begin_layout Plain Layout
10033 \begin_layout Plain Layout
10042 \begin_layout Standard
10043 To make the label very visible we choose a larger font coloured red.
10046 \begin_layout Standard
10047 \begin_inset listings
10051 \begin_layout Plain Layout
10056 \begin_layout Plain Layout
10061 \begin_layout Plain Layout
10066 \begin_layout Plain Layout
10071 \begin_layout Plain Layout
10076 \begin_layout Plain Layout
10081 \begin_layout Plain Layout
10086 \begin_layout Plain Layout
10096 \begin_layout Subsection
10100 \begin_layout Standard
10101 We also define the Chunkref style which can be used to express cross references
10105 \begin_layout Chunk
10109 \begin_layout Standard
10110 \begin_inset listings
10114 \begin_layout Plain Layout
10116 InsetLayout Chunkref
10119 \begin_layout Plain Layout
10124 \begin_layout Plain Layout
10129 \begin_layout Plain Layout
10134 \begin_layout Plain Layout
10139 \begin_layout Plain Layout
10144 \begin_layout Plain Layout
10149 \begin_layout Plain Layout
10154 \begin_layout Plain Layout
10159 \begin_layout Plain Layout
10169 \begin_layout Section
10170 \begin_inset CommandInset label
10172 name "sec:Latex-Macros"
10179 \begin_layout Standard
10193 As noweb defines it's own
10194 \begin_inset Flex CharStyle:Code
10197 \begin_layout Plain Layout
10205 environment, we re-define the one that LyX logical markup module expects
10209 \begin_layout Chunk
10210 ./newfangle.sty,language=tex,basicstyle=
10215 \begin_layout Standard
10216 \begin_inset listings
10220 \begin_layout Plain Layout
10224 usepackage{listings}%
10227 \begin_layout Plain Layout
10234 \begin_layout Plain Layout
10241 \begin_layout Plain Layout
10257 \begin_layout Standard
10259 \begin_inset Flex CharStyle:Code
10262 \begin_layout Plain Layout
10269 \begin_inset Flex CharStyle:Code
10272 \begin_layout Plain Layout
10280 which will need renaming to
10281 \begin_inset Flex CharStyle:Code
10284 \begin_layout Plain Layout
10292 when I can do this without clashing with
10293 \begin_inset Flex CharStyle:Code
10296 \begin_layout Plain Layout
10307 \begin_layout Standard
10308 \begin_inset listings
10312 \begin_layout Plain Layout
10316 lstnewenvironment{Chunk}{
10328 \begin_layout Standard
10329 We also define a suitable
10330 \begin_inset Flex CharStyle:Code
10333 \begin_layout Plain Layout
10341 of parameters that suit the literate programming style after the fashion
10349 \begin_layout Standard
10350 \begin_inset listings
10354 \begin_layout Plain Layout
10358 lstset{numbers=left, stepnumber=5, numbersep=5pt,
10361 \begin_layout Plain Layout
10363 breaklines=false,basicstyle=
10368 \begin_layout Plain Layout
10380 \begin_layout Standard
10381 We also define a notangle-like mechanism for
10385 to LaTeX from the listing, and by which we can refer to other listings.
10387 \begin_inset Flex CharStyle:Code
10390 \begin_layout Plain Layout
10391 =<\SpecialChar \ldots{}
10397 sequence to contain LaTeX code, and include another like this chunk:
10398 \begin_inset Flex CharStyle:Code
10401 \begin_layout Plain Layout
10404 chunkref{chunkname}>
10411 \begin_inset Flex CharStyle:Code
10414 \begin_layout Plain Layout
10415 =<\SpecialChar \ldots{}
10421 is already defined to contain LaTeX code for this document --- this is
10426 document after all --- the code fragment below effectively contains the
10428 \begin_inset Flex CharStyle:Code
10431 \begin_layout Plain Layout
10438 To avoid problems with document generation, I had to declare an lstlistings
10440 \begin_inset Flex CharStyle:Code
10443 \begin_layout Plain Layout
10449 for this listing only; which in LyX was done by right-clicking the listings
10451 \begin_inset Flex CharStyle:Code
10454 \begin_layout Plain Layout
10460 \SpecialChar \menuseparator
10462 \begin_inset Flex CharStyle:Code
10465 \begin_layout Plain Layout
10474 \begin_layout Standard
10475 \begin_inset Note Note
10478 \begin_layout Plain Layout
10479 =< isn't enjoyed literally here, in a listing when the escape sequence is
10480 already defined as shown...
10481 we need to somehow escape this representation...
10489 \begin_layout Standard
10490 \begin_inset listings
10491 lstparams "escapeinside={}"
10495 \begin_layout Plain Layout
10499 lstset{escapeinside={=<}{>}}%
10507 \begin_layout Standard
10508 Although our macros will contain the @ symbol, they will be included in
10510 \begin_inset Flex CharStyle:Code
10513 \begin_layout Plain Layout
10521 section by LyX; however we keep the commented out
10522 \begin_inset Flex CharStyle:Code
10525 \begin_layout Plain Layout
10534 The listings package likes to centre the titles, but noweb titles are specially
10535 formatted and must be left aligned.
10536 The simplest way to do this turned out to be by removing the definition
10538 \begin_inset Flex CharStyle:Code
10541 \begin_layout Plain Layout
10550 This may interact badly if other listings want a regular title or caption.
10551 We remember the old maketitle in case we need it.
10554 \begin_layout Standard
10555 \begin_inset listings
10559 \begin_layout Plain Layout
10566 \begin_layout Plain Layout
10568 %somehow re-defining maketitle gives us a left-aligned title
10571 \begin_layout Plain Layout
10573 %which is extactly what our specially formatted title needs!
10576 \begin_layout Plain Layout
10584 newfangle@lst@maketitle
10589 \begin_layout Plain Layout
10605 \begin_layout Subsection
10606 \begin_inset CommandInset label
10608 name "sub:The-chunk-command"
10615 \begin_layout Standard
10616 Our chunk command accepts one argument, and calls
10617 \begin_inset Flex CharStyle:Code
10620 \begin_layout Plain Layout
10630 \begin_inset Flex CharStyle:Code
10633 \begin_layout Plain Layout
10641 will note the name, this is erased when the next
10642 \begin_inset Flex CharStyle:Code
10645 \begin_layout Plain Layout
10653 starts, so we make a note of this in
10654 \begin_inset Flex CharStyle:Code
10657 \begin_layout Plain Layout
10665 and restore in in lstlistings Init hook.
10668 \begin_layout Standard
10669 \begin_inset listings
10673 \begin_layout Plain Layout
10682 \begin_layout Plain Layout
10688 newfanglecaption},name=#1}%
10691 \begin_layout Plain Layout
10704 \begin_layout Plain Layout
10709 \begin_layout Plain Layout
10725 \begin_layout Subsubsection
10729 \begin_layout Standard
10730 Newfangle permits parameterized chunks, and requires the paramters to be
10731 specified as listings options.
10732 The newfangle script uses this, and although we don't do anything with
10733 these in the LaTeX code right now, we need to stop the listings package
10737 \begin_layout Standard
10738 \begin_inset listings
10742 \begin_layout Plain Layout
10752 newfangle@chunk@params{#1}}%
10760 \begin_layout Subsection
10761 The noweb styled caption
10764 \begin_layout Standard
10765 We define a public macro
10766 \begin_inset Flex CharStyle:Code
10769 \begin_layout Plain Layout
10777 which can be set as a regular title.
10779 \begin_inset Flex CharStyle:Code
10782 \begin_layout Plain Layout
10791 \begin_inset Flex CharStyle:Code
10794 \begin_layout Plain Layout
10802 at the appriate time when the caption is emitted.
10805 \begin_layout Standard
10806 \begin_inset listings
10810 \begin_layout Plain Layout
10820 newfangle@caption}%
10828 \begin_layout Standard
10829 \begin_inset Float figure
10835 \begin_layout Plain Layout
10836 \begin_inset Box Boxed
10845 height_special "totalheight"
10848 \begin_layout Plain Layout
10850 \begin_inset space \qquad{}
10858 \begin_inset Formula $\equiv+$
10862 \begin_inset space \qquad{}
10866 \begin_inset space \qquad{}
10870 \begin_inset space \qquad{}
10874 \begin_inset Formula $\triangleleft$
10878 \begin_inset space \quad{}
10882 \begin_inset Formula $\triangleright$
10888 \begin_layout Plain Layout
10891 In this example, the current chunk is 22c, and therefore the third chunk
10895 \begin_layout Plain Layout
10906 \begin_layout Plain Layout
10909 The first chunk with this name (19b) occurs as the second chunk on page
10913 \begin_layout Plain Layout
10916 The previous chunk (22d) with the same name is the second chunk on page
10920 \begin_layout Plain Layout
10923 The next chunk (24d) is the fourth chunk on page 24.
10926 \begin_layout Plain Layout
10927 \begin_inset Caption
10929 \begin_layout Plain Layout
10945 The general noweb output format compactly identifies the current chunk,
10946 and references to the first chunk, and the previous and next chunks that
10947 have the same name.
10951 \begin_layout Standard
10952 This means that we need to keep a counter for each chunk-name, that we use
10953 to count chunks of the same name.
10957 \begin_layout Subsection
10961 \begin_layout Standard
10962 It would be natural to have a counter for each chunk name, but TeX would
10963 soon run out of counters
10967 \begin_layout Plain Layout
10968 \SpecialChar \ldots{}
10973 run out of counters and so I had to re-write the LaTeX macros to share
10974 a counter as described here
10979 , so we have one counter which we save at the end of a chunk and restore
10980 at the beginning of a chunk.
10983 \begin_layout Standard
10984 \begin_inset listings
10988 \begin_layout Plain Layout
10992 newcounter{newfangle@chunkcounter}%
11000 \begin_layout Standard
11001 We construct the name of this variable to store the counter to be the text
11003 \begin_inset Flex CharStyle:Code
11006 \begin_layout Plain Layout
11012 prefixed onto the chunks own name, and store it in
11013 \begin_inset Flex CharStyle:Code
11016 \begin_layout Plain Layout
11028 \begin_layout Standard
11029 We save the counter like this:
11032 \begin_layout Chunk
11036 \begin_layout Standard
11037 \begin_inset listings
11041 \begin_layout Plain Layout
11057 arabic{newfangle@chunkcounter}}%
11065 \begin_layout Standard
11066 and restore the counter like this:
11069 \begin_layout Chunk
11073 \begin_layout Standard
11074 \begin_inset listings
11078 \begin_layout Plain Layout
11082 setcounter{newfangle@chunkcounter}{
11096 \begin_layout Chunk
11100 \begin_layout Standard
11101 If there does not already exist a variable whose name is stored in
11102 \begin_inset Flex CharStyle:Code
11105 \begin_layout Plain Layout
11113 , then we know we are the first chunk with this name, and then define a
11118 \begin_layout Standard
11119 Although chunks of the same name share a common counter, they must still
11121 We use is the internal name of the listing, suffixed by the counter value.
11122 So the first chunk might be
11123 \begin_inset Flex CharStyle:Code
11126 \begin_layout Plain Layout
11132 and the second chunk be
11133 \begin_inset Flex CharStyle:Code
11136 \begin_layout Plain Layout
11145 \begin_layout Standard
11146 We also calculate the name of the previous chunk if we can (before we increment
11147 the chunk counter).
11148 If this is the first chunk of that name, then
11149 \begin_inset Flex CharStyle:Code
11152 \begin_layout Plain Layout
11161 \begin_inset Flex CharStyle:Code
11164 \begin_layout Plain Layout
11172 which the noweb package will interpret as not existing.
11175 \begin_layout Standard
11176 \begin_inset listings
11180 \begin_layout Plain Layout
11186 newfangle@caption{%
11189 \begin_layout Plain Layout
11195 chunkcount{lst-chunk-
11200 \begin_layout Plain Layout
11209 \begin_layout Plain Layout
11224 \begin_layout Plain Layout
11228 setcounter{newfangle@chunkcounter}{
11237 \begin_layout Plain Layout
11248 \begin_layout Plain Layout
11253 \begin_layout Plain Layout
11257 setcounter{newfangle@chunkcounter}{
11266 \begin_layout Plain Layout
11276 arabic{newfangle@chunkcounter}}%
11279 \begin_layout Plain Layout
11289 \begin_layout Standard
11290 After incrementing the chunk counter, we then define the name of this chunk,
11291 as well as the name of the first chunk.
11294 \begin_layout Standard
11295 \begin_inset listings
11299 \begin_layout Plain Layout
11303 addtocounter{newfangle@chunkcounter}{1}%
11306 \begin_layout Plain Layout
11322 arabic{newfangle@chunkcounter}}%
11325 \begin_layout Plain Layout
11335 arabic{newfangle@chunkcounter}}%
11338 \begin_layout Plain Layout
11354 \begin_layout Standard
11355 We now need to calculate the name of the next chunk.
11356 We do this by temporarily skipping the counter on by one; however there
11357 may not actually be another chunk with this name! We detect this by also
11358 defining a label for each chunk based on the chunkname.
11359 If there is a next chunkname then it will define a label with that name.
11360 As labels are persistent, we can at least tell the second time LaTeX is
11362 If we don't find such a defined label then we define
11363 \begin_inset Flex CharStyle:Code
11366 \begin_layout Plain Layout
11375 \begin_inset Flex CharStyle:Code
11378 \begin_layout Plain Layout
11389 \begin_layout Standard
11390 \begin_inset listings
11394 \begin_layout Plain Layout
11398 addtocounter{newfangle@chunkcounter}{1}%
11401 \begin_layout Plain Layout
11411 arabic{newfangle@chunkcounter}}%
11414 \begin_layout Plain Layout
11418 @ifundefined{r@label-
11434 \begin_layout Standard
11435 The noweb package requires that we define a
11436 \begin_inset Flex CharStyle:Code
11439 \begin_layout Plain Layout
11447 for every chunk, with a unique name, which is then used to print out it's
11451 \begin_layout Standard
11452 We also define a regular label for this chunk, as was mentioned above when
11454 \begin_inset Flex CharStyle:Code
11457 \begin_layout Plain Layout
11466 This requires LaTeX to be run at least twice after new chunk sections are
11467 added --- but noweb requried that anyway.
11470 \begin_layout Standard
11471 \begin_inset listings
11475 \begin_layout Plain Layout
11484 \begin_layout Plain Layout
11486 % define this label for every chunk instance, so we
11489 \begin_layout Plain Layout
11491 % can tell when we are the last chunk of this name
11494 \begin_layout Plain Layout
11508 \begin_layout Standard
11509 We also try and add the chunk to the list of listings, but I'm afraid we
11510 don't do very well.
11511 We want each chunk name listing once, with all of it's references.
11514 \begin_layout Standard
11515 \begin_inset listings
11519 \begin_layout Plain Layout
11523 addcontentsline{lol}{lstlisting}{
11539 \begin_layout Standard
11540 We then call the noweb output macros in the same way that noweave generates
11541 them, except that we don't need to call
11542 \begin_inset Flex CharStyle:Code
11545 \begin_layout Plain Layout
11548 nwstartdeflinemarkup
11554 \begin_inset Flex CharStyle:Code
11557 \begin_layout Plain Layout
11565 -- and if we do it messes up the output somewhat.
11568 \begin_layout Standard
11569 \begin_inset listings
11573 \begin_layout Plain Layout
11580 \begin_layout Plain Layout
11585 \begin_layout Plain Layout
11592 \begin_layout Plain Layout
11601 \begin_layout Plain Layout
11606 \begin_layout Plain Layout
11611 \begin_layout Plain Layout
11616 \begin_layout Plain Layout
11623 \begin_layout Plain Layout
11630 \begin_layout Plain Layout
11635 \begin_layout Plain Layout
11644 \begin_layout Plain Layout
11648 @ifundefined{newfangle@chunk@params}{}{%
11651 \begin_layout Plain Layout
11655 newfangle@chunk@params)%
11658 \begin_layout Plain Layout
11663 \begin_layout Plain Layout
11674 \begin_layout Plain Layout
11683 \begin_layout Plain Layout
11688 \begin_layout Plain Layout
11693 \begin_layout Plain Layout
11698 \begin_layout Plain Layout
11717 \begin_layout Plain Layout
11721 nwstartdeflinemarkup%
11724 \begin_layout Plain Layout
11735 \begin_layout Plain Layout
11739 nwenddeflinemarkup%
11742 \begin_layout Plain Layout
11752 \begin_layout Standard
11753 Originally this was developed as a
11754 \begin_inset Flex CharStyle:Code
11757 \begin_layout Plain Layout
11763 aspect, in the Init hook, but it was found easier to affect the title without
11765 \begin_inset Flex CharStyle:Code
11768 \begin_layout Plain Layout
11771 lst@AddToHookExe{PreSet}
11776 is still required to set the listings name to the name passed to the
11777 \begin_inset Flex CharStyle:Code
11780 \begin_layout Plain Layout
11791 \begin_layout Standard
11792 \begin_inset listings
11796 \begin_layout Plain Layout
11800 lst@BeginAspect{newfangle}
11803 \begin_layout Plain Layout
11807 lst@Key{newfangle}{true}[t]{
11809 lstKV@SetIf{#1}{true}}
11812 \begin_layout Plain Layout
11816 lst@AddToHookExe{PreSet}{
11827 \begin_layout Plain Layout
11831 lst@AddToHook{Init}{}%
11836 \begin_layout Plain Layout
11848 \begin_layout Subsection
11852 \begin_layout Standard
11855 chunkref command which makes it easy to generate visual references to different
11859 \begin_layout Standard
11860 \begin_inset Tabular
11861 <lyxtabular version="3" rows="4" columns="2">
11863 <column alignment="center" valignment="top" width="0">
11864 <column alignment="center" valignment="top" width="0">
11866 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
11869 \begin_layout Plain Layout
11875 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
11878 \begin_layout Plain Layout
11886 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
11889 \begin_layout Plain Layout
11897 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
11900 \begin_layout Plain Layout
11904 \begin_layout Plain Layout
11920 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
11923 \begin_layout Plain Layout
11926 chunkref[3]{preamble}
11931 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
11934 \begin_layout Plain Layout
11938 \begin_layout Plain Layout
11942 chunkref[3]{preamble}
11954 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
11957 \begin_layout Plain Layout
11960 chunkref{preamble}[arg1, arg2]
11965 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
11968 \begin_layout Plain Layout
11972 \begin_layout Plain Layout
11976 chunkref{preamble}[arg1, arg2]
11994 \begin_layout Standard
11995 Chunkref can also be used within a code chunk to include another code chunk.
11996 The third optional parameter to chunkref is a comma sepatarated list of
11997 arguments, which will replace defined parameters in the chunkref.
11998 \begin_inset Note Note
12001 \begin_layout Plain Layout
12002 Darn it, if I have: =<
12004 chunkref{new-mode}[{chunks[chunk_name, "language"]},{mode}]> the inner braces
12005 (inside [ ]) cause _ to signify subscript even though we have lst@ReplaceIn
12013 \begin_layout Standard
12014 \begin_inset listings
12018 \begin_layout Plain Layout
12027 \begin_layout Plain Layout
12036 \begin_layout Plain Layout
12047 \begin_layout Plain Layout
12054 \begin_layout Plain Layout
12065 \begin_layout Plain Layout
12070 \begin_layout Plain Layout
12079 \begin_layout Plain Layout
12085 chunkref@i{#1}{#2}}{
12087 chunkref@i{#1}{#2}()}%
12090 \begin_layout Plain Layout
12095 \begin_layout Plain Layout
12101 chunkref@i#1#2(#3){%
12104 \begin_layout Plain Layout
12113 \begin_layout Plain Layout
12122 \begin_layout Plain Layout
12131 \begin_layout Plain Layout
12140 \begin_layout Plain Layout
12151 \begin_layout Plain Layout
12160 \begin_layout Plain Layout
12167 \begin_layout Plain Layout
12178 \begin_layout Plain Layout
12185 \begin_layout Plain Layout
12196 \begin_layout Plain Layout
12207 \begin_layout Plain Layout
12216 \begin_layout Plain Layout
12223 \begin_layout Plain Layout
12228 \begin_layout Plain Layout
12237 \begin_layout Plain Layout
12248 \begin_layout Plain Layout
12255 \begin_layout Plain Layout
12262 \begin_layout Plain Layout
12269 \begin_layout Plain Layout
12280 \begin_layout Plain Layout
12287 \begin_layout Plain Layout
12291 chunkref@args #3,)%
12294 \begin_layout Plain Layout
12301 \begin_layout Plain Layout
12310 \begin_layout Plain Layout
12315 \begin_layout Plain Layout
12320 \begin_layout Plain Layout
12329 \begin_layout Plain Layout
12339 \begin_layout Subsection
12343 \begin_layout Standard
12344 \begin_inset listings
12348 \begin_layout Plain Layout
12353 \begin_layout Plain Layout
12365 \begin_layout Chapter
12366 Extracting newfangle
12369 \begin_layout Section
12370 Extracting from Lyx
12373 \begin_layout Standard
12374 To extract from LyX, you will need to configure LyX as explained in section
12376 \begin_inset CommandInset ref
12378 reference "sub:Configuring-the-build"
12385 \begin_layout Standard
12386 \begin_inset CommandInset label
12388 name "lyx-build-script"
12392 And this lyx-build scrap will extract newfangle for me.
12395 \begin_layout Chunk
12396 lyx-build,language=sh
12399 \begin_layout Standard
12400 \begin_inset listings
12404 \begin_layout Plain Layout
12409 \begin_layout Plain Layout
12414 \begin_layout Plain Layout
12418 \begin_layout Plain Layout
12422 chunkref{lyx-build-helper}>
12425 \begin_layout Plain Layout
12427 cd $PROJECT_DIR || exit 1
12430 \begin_layout Plain Layout
12434 \begin_layout Plain Layout
12436 /usr/local/bin/newfangle -R./newfangle $TEX_SRC > ./newfangle
12439 \begin_layout Plain Layout
12441 /usr/local/bin/newfangle -R./newfangle.module $TEX_SRC > ./newfangle.module
12449 \begin_layout Standard
12450 With a lyx-build-helper
12453 \begin_layout Chunk
12454 lyx-build-helper,language=sh
12457 \begin_layout Standard
12458 \begin_inset listings
12462 \begin_layout Plain Layout
12464 PROJECT_DIR="$LYX_r"
12467 \begin_layout Plain Layout
12469 LYX_SRC="$PROJECT_DIR/${LYX_i%.tex}.lyx"
12472 \begin_layout Plain Layout
12477 \begin_layout Plain Layout
12479 TEX_SRC="$TEX_DIR/$LYX_i"
12487 \begin_layout Section
12488 Extracting from the command line
12491 \begin_layout Standard
12492 First you will need the tex output, then you can extract:
12495 \begin_layout Chunk
12496 lyx-build-manual,language=sh
12499 \begin_layout Standard
12500 \begin_inset listings
12504 \begin_layout Plain Layout
12506 lyx -e latex newfangle.lyx
12509 \begin_layout Plain Layout
12511 newfangle -R./newfangle newfangle.tex > ./newfangle
12514 \begin_layout Plain Layout
12516 newfangle -R./newfangle.module newfangle.tex > ./newfangle.module
12528 \begin_layout Chapter
12532 \begin_layout Chunk
12533 tests-sub,params=THING;colour
12536 \begin_layout Standard
12537 \begin_inset listings
12541 \begin_layout Plain Layout
12543 I see a ${THING} of
12546 \begin_layout Plain Layout
12551 \begin_layout Plain Layout
12555 chunkref{tests-sub-sub}(${colour})>
12563 \begin_layout Chunk
12564 tests-sub-sub,params=colour
12567 \begin_layout Standard
12568 \begin_inset listings
12572 \begin_layout Plain Layout
12574 a funny shade of ${colour}
12582 \begin_layout Chunk
12586 \begin_layout Standard
12587 \begin_inset listings
12591 \begin_layout Plain Layout
12593 What do you see? "=<
12595 chunkref{tests-sub}(joe, red)>"
12598 \begin_layout Plain Layout
12608 \begin_layout Standard
12609 Should generate output:
12612 \begin_layout Chunk
12616 \begin_layout Standard
12617 \begin_inset listings
12621 \begin_layout Plain Layout
12623 What do you see? "I see a joe of
12626 \begin_layout Plain Layout
12631 \begin_layout Plain Layout
12633 looking closer a funny shade of red"
12636 \begin_layout Plain Layout
12641 \begin_layout Plain Layout