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 Chapter*
254 \begin_layout Standard
255 \begin_inset CommandInset label
261 Newfangle is licensed under the GPL 3
262 \begin_inset CommandInset citation
269 This doesn't mean that you can't use or distribute newfangle with sources
270 of an incompatible license, but it means you must make the source of newfangle
275 gpl3-copyright,language=
278 \begin_layout Standard
279 \begin_inset listings
283 \begin_layout Plain Layout
285 #newfangle - fully featured notangle replacement in awk
288 \begin_layout Plain Layout
293 \begin_layout Plain Layout
295 #Copyright (C) Sam Liddicott 2009
298 \begin_layout Plain Layout
303 \begin_layout Plain Layout
305 #This program is free software: you can redistribute it and/or modify
308 \begin_layout Plain Layout
310 #it under the terms of the GNU General Public License as published by
313 \begin_layout Plain Layout
315 #the Free Software Foundation, either version 3 of the License, or
318 \begin_layout Plain Layout
320 #(at your option) any later version.
323 \begin_layout Plain Layout
328 \begin_layout Plain Layout
330 #This program is distributed in the hope that it will be useful,
333 \begin_layout Plain Layout
335 #but WITHOUT ANY WARRANTY; without even the implied warranty of
338 \begin_layout Plain Layout
340 #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
344 \begin_layout Plain Layout
346 #GNU General Public License for more details.
349 \begin_layout Plain Layout
354 \begin_layout Plain Layout
356 #You should have received a copy of the GNU General Public License
359 \begin_layout Plain Layout
361 #along with this program.
362 If not, see <http://www.gnu.org/licenses/>.
370 \begin_layout Standard
371 \begin_inset CommandInset toc
372 LatexCommand tableofcontents
383 \begin_layout Chapter
387 \begin_layout Standard
388 Newfangle is a replacement for noweb, which consists of
389 \begin_inset Flex CharStyle:Code
392 \begin_layout Plain Layout
399 \begin_inset Flex CharStyle:Code
402 \begin_layout Plain Layout
409 \begin_inset Flex CharStyle:Code
412 \begin_layout Plain Layout
421 \begin_layout Standard
423 \begin_inset Flex CharStyle:Code
426 \begin_layout Plain Layout
433 \begin_inset Flex CharStyle:Code
436 \begin_layout Plain Layout
442 it can read multiple named files, or from stdin.
445 \begin_layout Section
449 \begin_layout Standard
450 The -r option causes newfangle to behave like noroots.
453 \begin_layout LyX-Code
454 newfangle -r filename.tex
457 \begin_layout Standard
458 will print out the newfangle roots of a tex file.
462 \begin_layout Standard
464 \begin_inset Flex CharStyle:Code
467 \begin_layout Plain Layout
473 command, the roots are not enclosed in
474 \begin_inset Flex CharStyle:Code
477 \begin_layout Plain Layout
483 , unless at least one of the roots is defined using the
484 \begin_inset Flex CharStyle:Code
487 \begin_layout Plain Layout
494 \begin_inset Flex CharStyle:Code
497 \begin_layout Plain Layout
506 \begin_layout Standard
507 Also, unlike noroots, it prints out all roots --- not just those that are
509 I find that a root not being used, doesn't make it particularly top level.
510 My convention is that top level roots to be extracted begin with
511 \begin_inset Flex CharStyle:Code
514 \begin_layout Plain Layout
520 and have the form of a filename.
523 \begin_layout Section
527 \begin_layout Standard
529 \begin_inset Flex CharStyle:Code
532 \begin_layout Plain Layout
539 \begin_inset Flex CharStyle:Code
542 \begin_layout Plain Layout
548 options are supported.
551 \begin_layout Standard
552 The standard way to extract a file would be:
555 \begin_layout LyX-Code
556 newfangle -R./Makefile.inc newfangle.tex > ./Makefile.inc
559 \begin_layout Standard
561 \begin_inset Flex CharStyle:Code
564 \begin_layout Plain Layout
571 \begin_inset Flex CharStyle:Code
574 \begin_layout Plain Layout
580 option does not break indenting; also the
581 \begin_inset Flex CharStyle:Code
584 \begin_layout Plain Layout
590 option does not interrupt (and break) multi-line C macros --- or indeed
591 any line ending with a backslash.
592 This does mean that sometimes the compiler might calculate the source line
593 wrongly when generating error messages in such cases, but there isn't any
594 other way around if multi-line macros include other chunks.
597 \begin_layout Section
598 Formatting source in LaTeX
601 \begin_layout Standard
602 The noweave replacement is a set of LaTeX macros dependant upon
606 , and which can be included with:
609 \begin_layout LyX-Code
612 usepackage{newfangle.sty}
615 \begin_layout Standard
616 The LaTeX macros are shown in section
617 \begin_inset CommandInset ref
619 reference "sec:Latex-Macros"
623 , and are part of a LyX module file
624 \begin_inset Flex CharStyle:Code
627 \begin_layout Plain Layout
633 , which automatically includes the macros in the document pre-amble when
634 the newfangle LyX module is used.
637 \begin_layout Standard
638 Because the noweave replacement is impemented in LaTeX, there is no processing
639 stage required before running the
640 \begin_inset Flex CharStyle:Code
643 \begin_layout Plain Layout
650 LaTeX may need running two or more times, so that the code chunk references
651 can be fully calculated.
654 \begin_layout Standard
656 \begin_inset Flex CharStyle:Code
659 \begin_layout Plain Layout
665 package is required as it is used for formatting the code chunk captions
668 \begin_layout Standard
670 \begin_inset Flex CharStyle:Code
673 \begin_layout Plain Layout
679 package is also required, as it is used for formatting the code chunks
683 \begin_layout Standard
685 \begin_inset Flex CharStyle:Code
688 \begin_layout Plain Layout
694 package is also required.
697 \begin_layout Chapter
698 Literate Programming with Newfangle
701 \begin_layout Standard
703 Should really follow on from a part-0 explanation of what literate programming
707 \begin_layout Chapter
708 Using Newfangle with LyX
711 \begin_layout Section
715 \begin_layout Subsection
716 Installing the LyX module
719 \begin_layout Standard
721 \begin_inset Flex CharStyle:Code
724 \begin_layout Plain Layout
730 to your LyX layouts directory, which for unix users will be
731 \begin_inset Flex CharStyle:Code
734 \begin_layout Plain Layout
743 \begin_layout Standard
744 You will need to reconfigure LyX by clicking Tools\SpecialChar \menuseparator
745 Reconfigure, and then
749 \begin_layout Subsection
750 \begin_inset CommandInset label
752 name "sub:Configuring-the-build"
756 Configuring the build script
759 \begin_layout Standard
760 Make sure you don't have a conversion defined for Lyx → Program
763 \begin_layout Standard
764 From the menu Tools\SpecialChar \menuseparator
765 Preferences, add a conversion from Latex(Plain) → Program
769 \begin_layout LyX-Code
770 set -x ; newfangle -Rlyx-build $$i |
773 \begin_layout LyX-Code
774 env LYX_b=$$b LYX_i=$$i LYX_o=$$o LYX_p=$$p LYX_r=$$r bash
777 \begin_layout Standard
778 (But don't cut-n-paste it from this document or you'll be pasting a multi-line
779 string which will break your lyx preferences file).
783 \begin_layout Standard
784 I hope that one day, LyX will set these into the environment when calling
788 \begin_layout Standard
789 You may also want to consider adding options to this conversion\SpecialChar \ldots{}
793 \begin_layout LyX-Code
794 parselog=/usr/share/lyx/scripts/listerrors
797 \begin_layout Standard
798 \SpecialChar \ldots{}
799 but if you do you will lose your stderr
803 \begin_layout Plain Layout
804 There is some bash plumbing to get a copy of stderr but this footnote is
813 \begin_layout Standard
814 Now, a shell script chunk called
815 \begin_inset Flex CharStyle:Code
818 \begin_layout Plain Layout
824 will be extracted and run whenever you choose the Document\SpecialChar \menuseparator
829 \begin_layout Standard
830 The lyx-build script for this document is in section
831 \begin_inset CommandInset ref
833 reference "lyx-build-script"
837 and on a unix system will extract
838 \begin_inset Flex CharStyle:Code
841 \begin_layout Plain Layout
848 \begin_inset Flex CharStyle:Code
851 \begin_layout Plain Layout
860 \begin_layout Subsection
861 Preparing your Lyx document
864 \begin_layout Standard
865 It is not necessary to base your literate document on any of the original
866 LyX literate classes; so select a regular class for your document type.
869 \begin_layout Standard
885 \begin_layout Standard
886 In the drop-down style listbox you should notice a new style defined, called
894 \begin_layout Standard
895 When you wish to insert a literate chunk, you enter it's plain name in the
896 Chunk style, instead of the older method that used
897 \begin_inset Flex CharStyle:Code
900 \begin_layout Plain Layout
907 Following the chunk name, you insert a listing with: Insert\SpecialChar \menuseparator
911 \begin_layout Standard
912 Inside the white listing box you can type (or paste using shift+ctrl+V)
914 There is not need to use ctrl+enter at the end of lines as with some older
915 LyX literate techniques --- just press enter as normal.
918 \begin_layout Subsubsection
919 Customising the listing appearance
922 \begin_layout Standard
923 In the final document, the code is formatted using the
928 The chunk style doesn't just define the chunk name, but can also define
929 any other chunk options supported by the lstlistings package
930 \begin_inset Flex CharStyle:Code
933 \begin_layout Plain Layout
942 In fact, what you type in the chunk style is raw latex.
943 If you want to set the chunk language without having to right-click the
945 \begin_inset Flex CharStyle:Code
948 \begin_layout Plain Layout
954 after the chunk name.
957 \begin_layout Standard
958 Of course you can do this by editing the listings box advanced properties
959 by right-clicking on the listings box, but that takes longer, and you can't
960 see at-a-glance what the advanced settings are while editing the document;
961 also advanced settings apply only to that box --- the chunk settings apply
962 through the rest of the document
966 \begin_layout Plain Layout
967 It ought to apply only to subsequent chunks of the same name.
974 \begin_inset Note Note
977 \begin_layout Plain Layout
978 So make sure they only apply to chunks of that name
986 \begin_layout Subsubsection
987 Global customisations
990 \begin_layout Standard
995 is used to set the code chunks, it's
996 \begin_inset Flex CharStyle:Code
999 \begin_layout Plain Layout
1007 command can be used in the pre-amble to set some document wide settings.
1010 \begin_layout Standard
1011 If your source has many words with long sequences of capital letters, then
1013 \begin_inset Flex CharStyle:Code
1016 \begin_layout Plain Layout
1017 columns=fullflexible
1022 may be a good idea, or the capital letters will get crowded.
1023 (I think lstlistings ought to use a slightly smaller font for captial letters
1024 so that they still fit).
1027 \begin_layout Standard
1029 \begin_inset Flex CharStyle:Code
1032 \begin_layout Plain Layout
1040 looks more normal for code, but has no bold (unless luximono is used, but
1041 it doesn't work for me); so I use
1042 \begin_inset Flex CharStyle:Code
1045 \begin_layout Plain Layout
1055 \begin_inset Flex CharStyle:Code
1058 \begin_layout Plain Layout
1067 \begin_inset Flex CharStyle:Code
1070 \begin_layout Plain Layout
1071 columns=fullflexible
1076 is used or the wrong letter spacing is used.
1079 \begin_layout Standard
1080 In my LeTeX pre-amble I usually specialise my code format with:
1084 document-preamble,language=tex
1087 \begin_layout Standard
1088 \begin_inset listings
1092 \begin_layout Plain Layout
1099 \begin_layout Plain Layout
1103 definecolor{darkgreen}{rgb}{0,0.5,0}
1106 \begin_layout Plain Layout
1110 lstset{numbers=left, stepnumber=5, numbersep=5pt, breaklines=false,
1113 \begin_layout Plain Layout
1122 \begin_layout Plain Layout
1129 \begin_layout Plain Layout
1133 tiny,language=C,columns=fullflexible,
1136 \begin_layout Plain Layout
1138 numberfirstline=true
1141 \begin_layout Plain Layout
1151 \begin_layout Chapter
1152 Newfangle with Makefiles
1155 \begin_layout Standard
1156 \begin_inset Note Note
1159 \begin_layout Plain Layout
1160 This chapter needs revising
1166 \begin_inset Note Greyedout
1169 \begin_layout Plain Layout
1170 This chapter needs revising
1175 Here we describe a Makefile.inc that you can include in your own Makefiles,
1176 or glue as a recursive make to other projects.
1179 \begin_layout Standard
1180 The Makefile.inc described here was put together for a Samba4 vfs module,
1181 but can be used in any Make project, including automake projects.
1184 \begin_layout Section
1185 A word about makefiles formats
1188 \begin_layout Standard
1189 Whitespace formatting is very important in a Makefile.
1190 The first character of each command line must be a TAB.
1193 \begin_layout LyX-Code
1194 target: pre-requisite
1195 \begin_inset Newline newline
1199 \begin_inset Newline newline
1205 \begin_layout Standard
1206 But a TAB is pretty hard to enter into most of the Lyx formats and insets
1208 An alternative is to use a semi-colon after the pre-requisite, and a backslash
1209 at the end of each line (except the last).
1210 Then any whitespace (or none) can prefix each action.
1213 \begin_layout LyX-Code
1214 target: pre-requisite ;
1217 \begin_inset Newline newline
1223 \begin_inset Newline newline
1229 \begin_layout Standard
1230 This is the style that we use and it works pretty well for GNU make at least.
1233 \begin_layout Standard
1234 We also adopt a convention that code chunks whose names beginning with ./
1235 should always be automatically extracted from the document.
1236 Code chunks whose names do not begin with ./ are for internal reference.
1237 (This doesn't prevent such chunks from being extracted directly).
1240 \begin_layout Section
1241 Boot-strapping the extraction
1244 \begin_layout Subsection
1248 \begin_layout Standard
1249 \begin_inset CommandInset label
1251 name "sub:Bootstrap-Using-a-Makefile"
1255 It seems convenient to have the makefile extract or update the C source
1256 files as part of it's operation.
1257 It also seems convenient to have the makefile itself extracted from this
1261 \begin_layout Standard
1262 It would also be convenient to have the code to extract the makefile from
1263 this document to also be part of this document, however we have to start
1264 somewhere and this unfortunately requires us to type at least a few words
1265 by hand to start things off.
1268 \begin_layout Standard
1269 Therefore we will have a minimal root fragment, which, when extracted, can
1270 cope with extracting the rest of the source.
1271 perhaps with this shell script, which could be called
1276 \begin_inset Note Note
1279 \begin_layout Plain Layout
1280 FIX THIS CHUNK AND TEST IT
1292 \begin_layout Standard
1293 \begin_inset listings
1297 \begin_layout Plain Layout
1302 \begin_layout Plain Layout
1306 \begin_layout Plain Layout
1308 MAKE_SRC="${1:-${NW_LYX:-../../noweb-lyx/noweb-lyx3.lyx}}"
1311 \begin_layout Plain Layout
1313 MAKE_SRC=`dirname "$MAKE_SRC"`/`basename "$MAKE_SRC" .lyx`
1316 \begin_layout Plain Layout
1318 NOWEB_SRC="${2:-${NOWEB_SRC:-$MAKE_SRC.lyx}}"
1321 \begin_layout Plain Layout
1323 lyx -e latex $MAKE_SRC
1326 \begin_layout Plain Layout
1330 \begin_layout Plain Layout
1332 newfangle -R./Makefile.inc ${MAKE_SRC}.tex
1337 \begin_layout Plain Layout
1339 | sed "/NEWFANGLE_SOURCE=/s/^/#/;T;aNOWEB_SOURCE=$NEWFANGLE_SRC"
1344 \begin_layout Plain Layout
1346 | cpif ./Makefile.inc
1349 \begin_layout Plain Layout
1353 \begin_layout Plain Layout
1355 make -f ./Makefile.inc newfangle_sources
1363 \begin_layout Standard
1364 The general Makefile can be invoked with
1368 and can also be included into any automake file to automatically re-generate
1372 \begin_layout Standard
1377 can be extracted with this command:
1380 \begin_layout LyX-Code
1381 lyx -e latex newfangle.lyx &&
1386 \begin_layout LyX-Code
1387 newfangle newfangle.lyx > ./autoboot
1390 \begin_layout Standard
1391 This looks simple enough, but as mentioned, newfangle has to be had from
1392 somewhere before it can be extracted.
1395 \begin_layout Subsection
1396 \begin_inset Note Note
1399 \begin_layout Plain Layout
1400 MERGE THIS WITH THE SECTIONS OF THIS DOCUMENT
1405 \SpecialChar \ldots{}
1409 \begin_layout Standard
1410 When the lyx-build chunk is executed, the current directory will be a temporary
1412 \begin_inset Flex CharStyle:Code
1415 \begin_layout Plain Layout
1421 will refer to the tex file in this temporary directory.
1422 This is unfortunate as our makefile wants to run from the project directory
1423 where the Lyx file is kept.
1426 \begin_layout Standard
1427 We can extract the project directory from $$r, and derive the probable Lyx
1428 filename from the noweb file that Lyx generated.
1435 \begin_layout Standard
1436 \begin_inset listings
1440 \begin_layout Plain Layout
1442 PROJECT_DIR="$LYX_r"
1445 \begin_layout Plain Layout
1447 LYX_SRC="$PROJECT_DIR/${LYX_i%.tex}.lyx"
1450 \begin_layout Plain Layout
1455 \begin_layout Plain Layout
1457 TEX_SRC="$TEX_DIR/$LYX_i"
1465 \begin_layout Standard
1466 And then we can define a lyx-build fragment similar to the autoboot fragment
1473 \begin_layout Standard
1474 \begin_inset listings
1478 \begin_layout Plain Layout
1483 \begin_layout Plain Layout
1487 chunkref{lyx-build-helper}>
1490 \begin_layout Plain Layout
1492 cd $PROJECT_DIR || exit 1
1495 \begin_layout Plain Layout
1499 \begin_layout Plain Layout
1501 #/usr/bin/newfangle -filter ./notanglefix-filter
1506 \begin_layout Plain Layout
1508 # -R./Makefile.inc "../../noweb-lyx/noweb-lyx3.lyx"
1513 \begin_layout Plain Layout
1515 # | sed '/NOWEB_SOURCE=/s/=.*/=samba4-dfs.lyx/'
1520 \begin_layout Plain Layout
1525 \begin_layout Plain Layout
1530 \begin_layout Plain Layout
1532 #make -f ./Makefile.inc newfangle_sources
1540 \begin_layout Section
1544 \begin_layout Subsection
1545 Including Makefile.inc
1548 \begin_layout Standard
1549 \begin_inset CommandInset label
1551 name "sub:Keeping-extracted-files"
1555 Makefile.inc will cope with extracting all the other source files from this
1556 document and keeping them up to date.
1560 \begin_layout Standard
1561 It may also be included by a Makefile or Makefile.am defined in a Lyx document
1562 to automatically deal with the extraction of source files and documents.
1565 \begin_layout Standard
1566 A makefile has two parts; variables must be defined before the targets that
1574 \begin_layout Standard
1575 \begin_inset listings
1579 \begin_layout Plain Layout
1583 chunkref{Makefile.inc-vars}>
1586 \begin_layout Plain Layout
1590 chunkref{Makefile.inc-targets}>
1598 \begin_layout Standard
1600 \begin_inset Flex CharStyle:Code
1603 \begin_layout Plain Layout
1609 to hold the name of this Lyx file.
1616 \begin_layout Standard
1617 \begin_inset listings
1621 \begin_layout Plain Layout
1626 \begin_layout Plain Layout
1628 LITERATE_SOURCE=$(LYX_SOURCE)
1636 \begin_layout Subsection
1637 Recursive use of Makefile.inc
1640 \begin_layout Standard
1641 The makefile glue described here is used when building Samba4 vfs modules.
1644 \begin_layout Standard
1645 If you are defining a module of an existing program you may find it easier
1646 to use a slight recursive make instead of including the makefile directly.
1647 This way there is less chance of definitions in Makefile.inc interfering
1648 with definitions in the main makefile, or with definitions in other Makefile.inc
1649 from other noweb modules.
1652 \begin_layout Standard
1653 The glue works by adding a .PHONY target to call the recursive make, and
1654 adding this target as an additional pre-requisite to the existing targets.
1657 \begin_layout Standard
1658 In this example, the existing build system already has a build target for
1660 \begin_inset Flex CharStyle:Code
1663 \begin_layout Plain Layout
1669 , so we just add another pre-requisite to that.
1671 \begin_inset Flex CharStyle:Code
1674 \begin_layout Plain Layout
1680 as a pre-requisite, the stamp file's modified time indicating when all
1681 sources were extracted.
1688 \begin_layout Standard
1689 \begin_inset listings
1693 \begin_layout Plain Layout
1695 $(example_srcdir)/example.o: $(example_srcdir)/example.tex.stamp
1703 \begin_layout Standard
1704 The target for this new pre-requisite is generated by a recursive make using
1705 Makefile.inc which will make sure that the source is up to date, before
1706 it is built by the main projects makefile.
1713 \begin_layout Standard
1714 \begin_inset listings
1718 \begin_layout Plain Layout
1720 $(example_srcdir)/example.tex.stamp: $(example_srcdir)/example.tex ;
1725 \begin_layout Plain Layout
1727 cd $(example_srcdir) &&
1732 \begin_layout Plain Layout
1734 $(MAKE) -f Makefile.inc newfangle_sources
1742 \begin_layout Standard
1743 We can do similar glue for the docs, clean and distclean targets.
1744 In this example our build system is using a double colon for these targets,
1745 so we use the same in our glue.
1752 \begin_layout Standard
1753 \begin_inset listings
1757 \begin_layout Plain Layout
1762 \begin_layout Plain Layout
1764 .PHONY: docs_example
1767 \begin_layout Plain Layout
1769 docs_example:: ; cd $(example_srcdir) &&
1774 \begin_layout Plain Layout
1776 $(MAKE) -f Makefile.inc docs
1779 \begin_layout Plain Layout
1783 \begin_layout Plain Layout
1785 clean:: clean_example
1788 \begin_layout Plain Layout
1790 .PHONEY: clean_example
1793 \begin_layout Plain Layout
1795 clean_example: ; cd $(example_srcdir) &&
1800 \begin_layout Plain Layout
1802 $(MAKE) -f Makefile.inc clean
1805 \begin_layout Plain Layout
1809 \begin_layout Plain Layout
1811 distclean:: distclean_example
1814 \begin_layout Plain Layout
1816 .PHONY: distclean_example
1819 \begin_layout Plain Layout
1821 distclean_example: ; cd $(example_srcdir) &&
1826 \begin_layout Plain Layout
1828 $(MAKE) -f Makefile.inc distclean
1836 \begin_layout Standard
1837 We could do similarly for install targets to install the generated docs.
1840 \begin_layout Subsection
1841 \begin_inset CommandInset label
1843 name "sub:Converting-from-Lyx"
1847 Converting from Lyx to LaTeX
1850 \begin_layout Standard
1851 The first stage will always be to convert the Lyx file to a LaTeX file;
1852 this must be so not only because newfangle needs to to run on a TeX file,
1853 but also because the Lyx command
1855 server-goto-file-line
1859 \begin_layout Plain Layout
1862 server-goto-file-line
1864 is used to position the Lyx cursor at the compiler errors.
1871 insists that the line number provided is a line in the TeX file, and always
1872 reverse maps this to derive the line in the Lyx docment.
1873 \begin_inset Note Note
1876 \begin_layout Plain Layout
1877 The tex file should probably be an automake extra dist sources or something,
1878 so that it gets produced and packaged by make dist
1886 \begin_layout Standard
1887 The command [[lyx -e literate noweb-lyx.lyx]] will produce [[noweb-lyx.nw]]
1888 a tex file, so we define the noweb target to be the same as the Lyx file
1889 but with the .nw extension.
1896 \begin_layout Standard
1897 \begin_inset listings
1901 \begin_layout Plain Layout
1903 TEX_SOURCE=$(LYX_SOURCE:.lyx=.tex)
1912 Makefile.inc-targets
1915 \begin_layout Standard
1916 \begin_inset listings
1920 \begin_layout Plain Layout
1922 $(TEX_SOURCE): $(LYX_SOURCE) ;
1927 \begin_layout Plain Layout
1932 \begin_layout Plain Layout
1934 clean_tex: ; rm -f -- $(TEX_SOURCE)
1942 \begin_layout Subsection
1943 Extracting Program Source
1946 \begin_layout Standard
1947 The program source is extracted using newfangle, which is designed to operate
1948 on a LaTeX document.
1956 \begin_layout Standard
1957 \begin_inset listings
1961 \begin_layout Plain Layout
1963 NEWFANGLE_SOURCE=$(TEX_SOURCE)
1971 \begin_layout Standard
1972 The Lyx document can result in any number of source documents, but not all
1973 of these will be changed each time the Lyx document is updated.
1974 We certainly don't want to update the timestamps of these files and cause
1975 the whole source tree to be recompiled just because the Lyx document was
1980 \begin_layout Standard
1981 To solve this problem we use a stamp file which is always updated each time
1982 the sources are extracted from the LaTeX document.
1983 If the stamp file is older than the LaTeX document, then we can make an
1984 attempt to re-extract the sources.
1991 \begin_layout Standard
1992 \begin_inset listings
1996 \begin_layout Plain Layout
1998 NEWFANGLE_SOURCE_STAMP=$(NEWFANGLE_SOURCE).stamp
2007 Makefile.inc-targets
2010 \begin_layout Standard
2011 \begin_inset listings
2015 \begin_layout Plain Layout
2017 $(NEWFANGLE_SOURCE_STAMP): $(NEWFANGLE_SOURCE)
2022 \begin_layout Plain Layout
2024 $(NEWFANGLE_SOURCES) ;
2029 \begin_layout Plain Layout
2031 echo > $(NEWFANGLE_SOURCE_STAMP)
2034 \begin_layout Plain Layout
2036 clean_stamp: ; rm -f $(NEWFANGLE_SOURCE_STAMP)
2039 \begin_layout Plain Layout
2049 \begin_layout Subsection
2050 Extracting C sources
2053 \begin_layout Standard
2055 \begin_inset Flex CharStyle:Code
2058 \begin_layout Plain Layout
2064 to hold the names of all the C source files defined in this document.
2065 We compute this only once, by means of := in assignent.
2066 The sed deletes the any <
2067 \begin_inset space \hspace*{}
2072 \begin_inset space \hspace*{}
2076 > which may surround the roots names (for noroots compatibility).
2080 \begin_layout Standard
2081 As we use chunk names beginning with ./ to denote top level fragments that
2082 should be extracted, we filter out all fragments that do not begin with
2090 \begin_layout Standard
2091 \begin_inset listings
2095 \begin_layout Plain Layout
2104 \begin_layout Plain Layout
2106 NEWFANGLE_SOURCES:=$(shell
2111 \begin_layout Plain Layout
2113 newfangle -r $(NEWFANGLE_SOURCE) |
2118 \begin_layout Plain Layout
2120 sed -e 's/^[<][<]//;s/[>][>]$$//;/^$(NEWFANGLE_PREFIX)/!d'
2125 \begin_layout Plain Layout
2127 -e 's/^$(NEWFANGLE_PREFIX)/
2134 \begin_layout Plain Layout
2145 Makefile.inc-targets
2148 \begin_layout Standard
2149 \begin_inset listings
2153 \begin_layout Plain Layout
2155 .PHONY: echo_newfangle_sources
2158 \begin_layout Plain Layout
2160 echo_newfangle_sources: ; @echo $(NEWFANGLE_SOURCES)
2168 \begin_layout Standard
2169 We define a convenient target called
2170 \begin_inset Flex CharStyle:Code
2173 \begin_layout Plain Layout
2179 to re-extract the source if the LaTeX file has been updated.
2183 Makefile.inc-targets
2186 \begin_layout Standard
2187 \begin_inset listings
2191 \begin_layout Plain Layout
2193 .PHONY: newfangle_sources
2196 \begin_layout Plain Layout
2198 newfangle_sources: $(NEWFANGLE_SOURCE_STAMP)
2206 \begin_layout Standard
2207 And also a convenient target to remove extracted sources.
2211 Makefile.inc-targets
2214 \begin_layout Standard
2215 \begin_inset listings
2219 \begin_layout Plain Layout
2221 .PHONY: clean_newfangle_sources
2224 \begin_layout Plain Layout
2226 clean_newfangle_sources: ;
2231 \begin_layout Plain Layout
2233 rm -f -- $(NEWFANGLE_SOURCE_STAMP) $(NEWFANGLE_SOURCES)
2241 \begin_layout Standard
2243 \begin_inset Flex CharStyle:Code
2246 \begin_layout Plain Layout
2252 macro takes 4 arguments: the filename (1), some extensions to match (2)
2253 and a some shell command to return if the filename matches the exentions
2261 \begin_layout Standard
2262 \begin_inset listings
2266 \begin_layout Plain Layout
2268 if_extension=$(if $(findstring $(suffix $(1)),$(2)),$(3),$(4))
2276 \begin_layout Standard
2277 For some source files like C files, we want to output the line number and
2278 filename of the original LaTeX document from which the source came.
2281 \begin_layout Standard
2282 To make this easier we define the file extensions for which we want to do
2290 \begin_layout Standard
2291 \begin_inset listings
2295 \begin_layout Plain Layout
2305 \begin_layout Standard
2306 We can then use the if_extensions macro to define a macro which expands
2308 \begin_inset Flex CharStyle:Code
2311 \begin_layout Plain Layout
2317 option if newfangle is being invoked in a C source file, so that C compile
2318 errors will refer to the line number in the Lyx document.
2326 \begin_layout Standard
2327 \begin_inset listings
2331 \begin_layout Plain Layout
2336 \begin_layout Plain Layout
2338 nf_line=-L -T$(TABS)
2341 \begin_layout Plain Layout
2348 \begin_layout Plain Layout
2350 $(call if_extension,$(2),$(C_EXTENSIONS),$(nf_line))
2355 \begin_layout Plain Layout
2365 \begin_layout Standard
2366 We can use a similar trick to define an
2370 macro which takes just the filename as an argument and can return a pipeline
2371 stage calling the indent command.
2372 Indent can be turned off with
2373 \begin_inset Flex CharStyle:Code
2376 \begin_layout Plain Layout
2377 make newfangle_sources indent=
2389 \begin_layout Standard
2390 \begin_inset listings
2394 \begin_layout Plain Layout
2396 indent_options=-npro -kr -i8 -ts8 -sob -l80 -ss -ncs
2399 \begin_layout Plain Layout
2401 indent=$(call if_extension,$(1),$(C_EXTENSIONS),
2406 \begin_layout Plain Layout
2408 | indent $(indent_options))
2416 \begin_layout Standard
2417 We now define the pattern for extracting a file.
2418 The files are written using noweb's
2424 \begin_layout Plain Layout
2427 So you still need noweb installed in order to use cpif
2433 \begin_inset Note Note
2436 \begin_layout Plain Layout
2439 Write an awk version
2446 so that the file timestamp will not be touched if the contents haven't
2448 This avoids the need to rebuild the entire project because of a typographical
2449 change in the documentation, or if only a few C source files have changed.
2456 \begin_layout Standard
2457 \begin_inset listings
2461 \begin_layout Plain Layout
2463 newfangle_extract=@mkdir -p $(dir $(1)) &&
2468 \begin_layout Plain Layout
2470 $(call newfangle,$(2),$(1)) > "$(1).tmp" &&
2475 \begin_layout Plain Layout
2477 cat "$(1).tmp" $(indent) | cpif "$(1)"
2482 \begin_layout Plain Layout
2484 && rm -- "$(1).tmp" ||
2489 \begin_layout Plain Layout
2491 (echo error newfangling $(1) from $(2) ; exit 1)
2499 \begin_layout Standard
2500 We define a target which will extract or update all sources.
2501 To do this we first defined a makefile template that can do this for any
2502 source file in the LaTeX document.
2509 \begin_layout Standard
2510 \begin_inset listings
2514 \begin_layout Plain Layout
2516 define NEWFANGLE_template
2519 \begin_layout Plain Layout
2526 \begin_layout Plain Layout
2528 $$(call newfangle_extract,$(1),$(2))
2531 \begin_layout Plain Layout
2533 NEWFANGLE_TARGETS+=$(1)
2536 \begin_layout Plain Layout
2546 \begin_layout Standard
2547 We then enumerate the discovered
2548 \begin_inset Flex CharStyle:Code
2551 \begin_layout Plain Layout
2557 to generate a makefile rule for each one using the makefile template we
2562 Makefile.inc-targets
2565 \begin_layout Standard
2566 \begin_inset listings
2570 \begin_layout Plain Layout
2572 $(foreach source,$(NEWFANGLE_SOURCES),
2577 \begin_layout Plain Layout
2579 $(eval $(call NEWFANGLE_template,$(source),$(NEWFANGLE_SOURCE)))
2584 \begin_layout Plain Layout
2594 \begin_layout Standard
2595 These will all be built with NEWFANGLE_SOURCE_STAMP.
2598 \begin_layout Standard
2599 We also remove the generated sources on a
2607 Makefile.inc-targets
2610 \begin_layout Standard
2611 \begin_inset listings
2615 \begin_layout Plain Layout
2617 _distclean: clean_newfangle_sources
2625 \begin_layout Subsection
2626 Extracting Documentation
2629 \begin_layout Standard
2630 We then identify the intermediate stages of the documentation and their
2631 build and clean targets.
2634 \begin_layout Subsubsection
2638 \begin_layout Standard
2639 We produce a pdf file from the tex file.
2646 \begin_layout Standard
2647 \begin_inset listings
2651 \begin_layout Plain Layout
2653 NEWFANGLE_PDF=$(TEX_SOURCE:.tex=.pdf)
2661 \begin_layout Standard
2662 We run pdflatex twice to be sure that the contents and aux files are up
2664 We certainly are required to run pdflatex twice if these files do not exist!
2668 Makefile.inc-targets
2671 \begin_layout Standard
2672 \begin_inset listings
2676 \begin_layout Plain Layout
2678 $(NEWFANGLE_PDF): $(TEX_SOURCE); pdflatex $< && pdflatex $<
2681 \begin_layout Plain Layout
2683 clean_pdf: ; rm -f -- $(NEWFANGLE_PDF)
2688 \begin_layout Plain Layout
2690 $(TEX_SOURCE:.tex=.toc)
2695 \begin_layout Plain Layout
2697 $(TEX_SOURCE:.tex=.log)
2702 \begin_layout Plain Layout
2704 $(TEX_SOURCE:.tex=.aux)
2712 \begin_layout Subsubsection
2716 \begin_layout Standard
2717 Currently we only build pdf as a final format, but NEWFANGLE_DOCS may later
2718 hold other output formats.
2725 \begin_layout Standard
2726 \begin_inset listings
2730 \begin_layout Plain Layout
2732 NEWFANGLE_DOCS=$(NEWFANGLE_PDF)
2740 \begin_layout Standard
2741 We also define newfangle_docs as a convenient phony target<
2745 Makefile.inc-targets
2748 \begin_layout Standard
2749 \begin_inset listings
2753 \begin_layout Plain Layout
2755 .PHONY: newfangle_docs
2758 \begin_layout Plain Layout
2760 newfangle_docs: $(NEWFANGLE_DOCS)
2763 \begin_layout Plain Layout
2765 docs: newfangle_docs
2773 \begin_layout Standard
2774 And define a convenient clean_noweb_docs which we add to the regular clean
2779 Makefile.inc-targets
2782 \begin_layout Standard
2783 \begin_inset listings
2787 \begin_layout Plain Layout
2789 .PHONEY: clean_newfangle_docs
2792 \begin_layout Plain Layout
2794 clean_newfangle_docs: clean_tex clean_pdf
2797 \begin_layout Plain Layout
2799 clean: clean_newfangle_docs
2802 \begin_layout Plain Layout
2806 \begin_layout Plain Layout
2808 distclean_newfangle_docs: clean_tex clean_newfangle_docs
2811 \begin_layout Plain Layout
2813 distclean: clean distclean_newfangle_docs
2821 \begin_layout Subsection
2825 \begin_layout Standard
2826 If Makefile.inc is included into Makefile, then extracted files can be updated
2830 \begin_layout LyX-Code
2831 make newfangle_sources
2834 \begin_layout Standard
2838 \begin_layout LyX-Code
2839 make -f Makefile.inc newfangle_sources
2846 \begin_layout Chapter
2847 Newfangle awk source code
2850 \begin_layout Standard
2851 We use the copyright notice from chapter
2852 \begin_inset CommandInset ref
2854 reference "cha:License"
2862 ./newfangle,language=awk,morestring=[b]{/},morekeywords=else
2865 \begin_layout Standard
2866 \begin_inset listings
2870 \begin_layout Plain Layout
2875 \begin_layout Plain Layout
2879 chunkref{gpl3-copyright}>
2887 \begin_layout Standard
2888 We also use code from Arnold Robbins public domain getopt (1993 revision)
2890 \begin_inset CommandInset ref
2892 reference "cha:getopt"
2896 , and naturally want to attribute this appropriately.
2899 \begin_layout Standard
2900 \begin_inset listings
2904 \begin_layout Plain Layout
2908 \begin_layout Plain Layout
2910 # NOTE: Arnold Robbins public domain getopt for awk is also used:
2913 \begin_layout Plain Layout
2917 chunkref{getopt.awk-header}>
2920 \begin_layout Plain Layout
2924 \begin_layout Plain Layout
2928 chunkref{getopt.awk-getopt()}>
2931 \begin_layout Plain Layout
2940 \begin_layout Standard
2941 And include the following chunks
2948 \begin_layout Standard
2949 \begin_inset listings
2953 \begin_layout Plain Layout
2957 chunkref{helper-functions}>
2960 \begin_layout Plain Layout
2964 chunkref{mode-tracker}>
2967 \begin_layout Plain Layout
2971 chunkref{chunk-storage-functions}>
2974 \begin_layout Plain Layout
2978 chunkref{output_chunk_names()}>
2981 \begin_layout Plain Layout
2985 chunkref{output_chunks()}>
2988 \begin_layout Plain Layout
2992 chunkref{write_chunk()}>
2995 \begin_layout Plain Layout
2999 chunkref{expand_chunk_args()}>
3002 \begin_layout Plain Layout
3009 \begin_layout Plain Layout
3013 chunkref{recognize-chunk}>
3016 \begin_layout Plain Layout
3028 \begin_layout Section
3032 \begin_layout Standard
3033 The portable way to erase an array in awk is to split the empty string,
3038 awk-delete-array,params=ARRAY
3041 \begin_layout Standard
3042 \begin_inset listings
3046 \begin_layout Plain Layout
3048 split("", ${ARRAY});
3060 \begin_layout Section
3064 \begin_layout Standard
3065 Fatal errors are issued with the error function:
3072 \begin_layout Standard
3073 \begin_inset listings
3077 \begin_layout Plain Layout
3079 function error(message)
3082 \begin_layout Plain Layout
3087 \begin_layout Plain Layout
3089 print message > "/dev/stderr";
3092 \begin_layout Plain Layout
3097 \begin_layout Plain Layout
3107 \begin_layout Standard
3108 This is one of the helper functions.
3115 \begin_layout Standard
3116 \begin_inset listings
3120 \begin_layout Plain Layout
3132 \begin_layout Chapter
3136 \begin_layout Standard
3137 LaTeX arguments to lstlistings macros are a comma seperated list of key-value
3139 Values containing commas are enclosed in { braces }.
3142 \begin_layout Standard
3143 We need a function that can parse such an expression and assign the values
3151 \begin_layout Standard
3152 A sample expressions is:
3155 \begin_layout LyX-Code
3156 name=thomas, params={a, b}, something, something-else
3159 \begin_layout Standard
3160 but we see that this is just a simpler form of this expression:
3163 \begin_layout LyX-Code
3164 name=freddie, foo={bar=baz, quux={quirk, a=fleeg}}, etc
3167 \begin_layout Standard
3168 And that it would be a good idea to use a recursive parser into a multi-dimensio
3173 \begin_layout Plain Layout
3174 as AWK doesn't have nested-hash support
3182 \begin_layout Standard
3183 \begin_inset Tabular
3184 <lyxtabular version="3" rows="6" columns="2">
3186 <column alignment="left" valignment="top" width="0">
3187 <column alignment="left" valignment="top" width="0">
3189 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
3192 \begin_layout Plain Layout
3198 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
3201 \begin_layout Plain Layout
3209 <cell alignment="left" valignment="top" topline="true" leftline="true" usebox="none">
3212 \begin_layout Plain Layout
3218 <cell alignment="left" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
3221 \begin_layout Plain Layout
3229 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
3232 \begin_layout Plain Layout
3238 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
3241 \begin_layout Plain Layout
3249 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
3252 \begin_layout Plain Layout
3258 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
3261 \begin_layout Plain Layout
3269 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
3272 \begin_layout Plain Layout
3278 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
3281 \begin_layout Plain Layout
3289 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
3292 \begin_layout Plain Layout
3298 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
3301 \begin_layout Plain Layout
3315 \begin_layout Standard
3316 On reflection it seems that sometimes such nesting is not desirable, as
3317 the braces are also used to delimit values that contain commas --- we may
3321 \begin_layout LyX-Code
3322 name={williamson, freddie}
3325 \begin_layout Standard
3327 \begin_inset Flex CharStyle:Code
3330 \begin_layout Plain Layout
3337 \begin_inset Flex CharStyle:Code
3340 \begin_layout Plain Layout
3346 --- so I may change this behaviour.
3347 \begin_inset Note Note
3350 \begin_layout Plain Layout
3359 \begin_layout Standard
3361 \begin_inset Flex Chunkref
3364 \begin_layout Plain Layout
3370 will accept two paramters,
3371 \begin_inset Flex CharStyle:Code
3374 \begin_layout Plain Layout
3380 being the text to parse, and
3381 \begin_inset Flex CharStyle:Code
3384 \begin_layout Plain Layout
3390 being an array to receive the parsed values as described above.
3391 The optional parameter
3392 \begin_inset Flex CharStyle:Code
3395 \begin_layout Plain Layout
3401 is used during recursion to build up the multi-dimensional array path.
3408 \begin_layout Standard
3409 \begin_inset listings
3413 \begin_layout Plain Layout
3417 chunkref{get_chunk_args()}>
3429 \begin_layout Standard
3430 \begin_inset listings
3434 \begin_layout Plain Layout
3436 function get_chunk_args(text, values,
3439 \begin_layout Plain Layout
3441 # optional parameters
3444 \begin_layout Plain Layout
3446 path, # hierarchical precursors
3449 \begin_layout Plain Layout
3454 \begin_layout Plain Layout
3464 \begin_layout Standard
3465 The strategy is to parse the name, and then look for a value.
3466 If the value begins with a brace
3467 \begin_inset Flex CharStyle:Code
3470 \begin_layout Plain Layout
3476 , then we recurse and consume as much of the text as necessary, returning
3477 the remaining text when we encounter a leading close-brace
3478 \begin_inset Flex CharStyle:Code
3481 \begin_layout Plain Layout
3488 This being the strategy --- and executed in a loop --- we realise that
3489 we must first look for the closing brace (perhaps preceded by white space)
3490 in order to terminate the recursion, and returning remaining text.
3493 \begin_layout Standard
3494 \begin_inset listings
3498 \begin_layout Plain Layout
3503 \begin_layout Plain Layout
3505 while(length(text)) {
3508 \begin_layout Plain Layout
3510 if (match(text, "^ *}(.*)", a)) {
3513 \begin_layout Plain Layout
3518 \begin_layout Plain Layout
3523 \begin_layout Plain Layout
3527 chunkref{parse-chunk-args}>
3530 \begin_layout Plain Layout
3535 \begin_layout Plain Layout
3540 \begin_layout Plain Layout
3550 \begin_layout Standard
3551 \begin_inset Note Note
3554 \begin_layout Plain Layout
3555 Use BNF package here
3560 We can see that the text could be inspected with this regex:
3567 \begin_layout Standard
3568 \begin_inset listings
3572 \begin_layout Plain Layout
3574 if (! match(text, " *([^,=]*[^,= ]) *(([,=]) *(([^,}]*) *,* *(.*))|)$", a))
3578 \begin_layout Plain Layout
3583 \begin_layout Plain Layout
3593 \begin_layout Standard
3595 \begin_inset Flex CharStyle:Code
3598 \begin_layout Plain Layout
3604 will have the following values:
3607 \begin_layout Standard
3608 \begin_inset Tabular
3609 <lyxtabular version="3" rows="7" columns="2">
3611 <column alignment="center" valignment="top" width="0">
3612 <column alignment="left" valignment="top" width="0">
3614 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
3617 \begin_layout Plain Layout
3623 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
3626 \begin_layout Plain Layout
3634 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
3637 \begin_layout Plain Layout
3643 <cell alignment="left" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
3646 \begin_layout Plain Layout
3654 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
3657 \begin_layout Plain Layout
3663 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
3666 \begin_layout Plain Layout
3667 =freddie, foo={bar=baz, quux={quirk, a=fleeg}}, etc
3674 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
3677 \begin_layout Plain Layout
3683 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
3686 \begin_layout Plain Layout
3694 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
3697 \begin_layout Plain Layout
3703 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
3706 \begin_layout Plain Layout
3707 freddie, foo={bar=baz, quux={quirk, a=fleeg}}, etc
3714 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
3717 \begin_layout Plain Layout
3723 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
3726 \begin_layout Plain Layout
3734 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
3737 \begin_layout Plain Layout
3743 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
3746 \begin_layout Plain Layout
3747 , foo={bar=baz, quux={quirk, a=fleeg}}, etc
3760 \begin_layout Standard
3762 \begin_inset Flex CharStyle:Code
3765 \begin_layout Plain Layout
3772 \begin_inset Flex CharStyle:Code
3775 \begin_layout Plain Layout
3781 and signify whether the option named in
3782 \begin_inset Flex CharStyle:Code
3785 \begin_layout Plain Layout
3791 has a value or not (respectively).
3794 \begin_layout Standard
3795 If the option does have a value, then if the expression
3796 \begin_inset Flex CharStyle:Code
3799 \begin_layout Plain Layout
3806 \begin_inset Flex CharStyle:Code
3809 \begin_layout Plain Layout
3815 it will signify that we need to recurse:
3818 \begin_layout Standard
3819 \begin_inset listings
3823 \begin_layout Plain Layout
3828 \begin_layout Plain Layout
3833 \begin_layout Plain Layout
3835 if (substr(a[4],1,1) == "{") {
3838 \begin_layout Plain Layout
3840 text = get_chunk_args(substr(a[4],2), values, path name SUBSEP);
3843 \begin_layout Plain Layout
3848 \begin_layout Plain Layout
3850 values[path name]=a[5];
3853 \begin_layout Plain Layout
3858 \begin_layout Plain Layout
3863 \begin_layout Plain Layout
3868 \begin_layout Plain Layout
3870 values[path name]="";
3873 \begin_layout Plain Layout
3878 \begin_layout Plain Layout
3888 \begin_layout Standard
3889 We can test this function like this:
3896 \begin_layout Standard
3897 \begin_inset listings
3901 \begin_layout Plain Layout
3905 chunkref{get_chunk_args()}>
3908 \begin_layout Plain Layout
3913 \begin_layout Plain Layout
3918 \begin_layout Plain Layout
3922 \begin_layout Plain Layout
3924 print get_chunk_args("name=freddie, foo={bar=baz, quux={quirk, a=fleeg}},
3928 \begin_layout Plain Layout
3933 \begin_layout Plain Layout
3935 print "a[" b "] => " a[b];
3938 \begin_layout Plain Layout
3943 \begin_layout Plain Layout
3953 \begin_layout Standard
3954 which should give this output:
3958 gca-test.awk-results
3961 \begin_layout Standard
3962 \begin_inset listings
3966 \begin_layout Plain Layout
3968 a[foo.quux.quirk] =>
3971 \begin_layout Plain Layout
3973 a[foo.quux.a] => fleeg
3976 \begin_layout Plain Layout
3981 \begin_layout Plain Layout
3986 \begin_layout Plain Layout
3996 \begin_layout Chapter
3997 Expanding chunk arguments
4000 \begin_layout Standard
4001 \begin_inset CommandInset label
4003 name "cha:Chunk Arguments"
4008 \begin_inset Note Note
4011 \begin_layout Plain Layout
4012 Explain this in the documentation section too
4017 As an extension to many literate-programming styles, newfangle permits code
4018 chunks to take parameters and thus operate somewhat like C pre-processor
4019 macros, or like C++ templates.
4022 \begin_layout Standard
4023 Chunk parameters are declared with a chunk argument called
4024 \begin_inset Flex CharStyle:Code
4027 \begin_layout Plain Layout
4033 , which holds a semi-colon separated list of parameters, like this:
4036 \begin_layout LyX-Code
4037 achunk,language=C,params=name;address
4040 \begin_layout Standard
4041 When such a chunk is included the arguments are expressed thus, in square
4042 brackets as optional arguments separated by a comma
4043 \begin_inset Note Note
4046 \begin_layout Plain Layout
4047 We ought to support qouting in {} like ({Jones, John}, Jones@example.com)
4055 \begin_layout LyX-Code
4058 chunkref{achunk}(John Jones, jones@example.com)
4061 \begin_layout Standard
4062 Within the body a chunk, parameters are expressed as:
4063 \begin_inset Flex CharStyle:Code
4066 \begin_layout Plain Layout
4073 \begin_inset Flex CharStyle:Code
4076 \begin_layout Plain Layout
4083 There is a strong case that a LaTeX style notation should be used, like
4088 param{name}> as it would appear in the lstlisting.
4089 Such notation would make me go blind, but I do intend to adopt it.
4092 \begin_layout Standard
4093 We therefore need a function
4094 \begin_inset Flex CharStyle:Code
4097 \begin_layout Plain Layout
4103 which will take a block of text, a list of permitted parameters and the
4104 arguments which must substitute for the parameters.
4105 We also need to be able to parse a parameter list into an array of parameters.
4108 \begin_layout Section
4109 Parsing argument lists
4112 \begin_layout Standard
4113 An argument list may be as simple as in
4114 \begin_inset Flex CharStyle:Code
4117 \begin_layout Plain Layout
4120 chunkref{pull}(thing, otherthing)
4128 \begin_layout LyX-Code
4131 chunkref{pull}(things[x, y], get_other_things(a, "all"))
4134 \begin_layout Standard
4135 --- which for all it's commas and quotes and parenthesis represents only
4139 \begin_layout Standard
4140 How do we stop the comma in
4141 \begin_inset Flex CharStyle:Code
4144 \begin_layout Plain Layout
4150 from splitting it into two arguments
4151 \begin_inset Flex CharStyle:Code
4154 \begin_layout Plain Layout
4161 \begin_inset Flex CharStyle:Code
4164 \begin_layout Plain Layout
4170 --- neither of which make sense on their own?
4173 \begin_layout Standard
4174 One way it could be done is by refusing to split text between maching delimiters
4176 \begin_inset Flex CharStyle:Code
4179 \begin_layout Plain Layout
4186 \begin_inset Flex CharStyle:Code
4189 \begin_layout Plain Layout
4196 \begin_inset Flex CharStyle:Code
4199 \begin_layout Plain Layout
4206 \begin_inset Flex CharStyle:Code
4209 \begin_layout Plain Layout
4216 \begin_inset Flex CharStyle:Code
4219 \begin_layout Plain Layout
4226 \begin_inset Flex CharStyle:Code
4229 \begin_layout Plain Layout
4235 and most likely also
4236 \begin_inset Flex CharStyle:Code
4239 \begin_layout Plain Layout
4246 \begin_inset Flex CharStyle:Code
4249 \begin_layout Plain Layout
4256 \begin_inset Flex CharStyle:Code
4259 \begin_layout Plain Layout
4266 \begin_inset Flex CharStyle:Code
4269 \begin_layout Plain Layout
4276 Of course this also makes it impossible to pass such mis-matched code fragments
4277 as parameters, but I don't think users could cope with people passing such
4278 code unbalanced fragments as chunk parameters
4282 \begin_layout Plain Layout
4283 I know that I couldn't cope with users doing such things, and although the
4284 GPL3 license prevents me from actually forbidding anyone from trying, if
4285 they wan't it to work they'll have to write the code themselves and not
4286 expect any support from me.
4294 \begin_layout Standard
4295 Unfortunately, the full set of matching delimiters may vary from language
4297 In certain C++ template contexts,
4298 \begin_inset Flex CharStyle:Code
4301 \begin_layout Plain Layout
4308 \begin_inset Flex CharStyle:Code
4311 \begin_layout Plain Layout
4317 would count as delimiters, and yet in other contexts they would not.
4320 \begin_layout Standard
4321 This puts me in the unfortunate position of having to parse-somewhat all
4322 programming languages without knowing what they are! Eventually this will
4323 be managed in the chunk modes in chapter
4324 \begin_inset CommandInset ref
4326 reference "cha:modes"
4333 \begin_layout Standard
4334 Another way, inspired by LaTeX, is if the first character of the parameter
4335 is an opening-delimiter, to read up to the matching closing-delimiter wthout
4336 considering intervening commas; thus the above example could be expressed:
4339 \begin_layout LyX-Code
4342 chunkref{pull}({things[x, y]}, [get_other_things(a, "all")])
4345 \begin_layout Standard
4347 \begin_inset Flex CharStyle:Code
4350 \begin_layout Plain Layout
4357 \begin_inset Flex CharStyle:Code
4360 \begin_layout Plain Layout
4366 to wrap the first agument, and
4367 \begin_inset Flex CharStyle:Code
4370 \begin_layout Plain Layout
4377 \begin_inset Flex CharStyle:Code
4380 \begin_layout Plain Layout
4386 to wrap the second argument and protect the comma.
4389 \begin_layout Standard
4390 In the meantime, I'll work with the first method, and a fixed list of delimiters.
4393 \begin_layout Standard
4401 \begin_layout Standard
4402 \begin_inset listings
4406 \begin_layout Plain Layout
4408 function parse_chunk_args(text, values,
4411 \begin_layout Plain Layout
4413 # optional parameters
4416 \begin_layout Plain Layout
4418 path, # hierarchical precursors
4421 \begin_layout Plain Layout
4423 stack, # delimiters to be matched
4426 \begin_layout Plain Layout
4431 \begin_layout Plain Layout
4436 \begin_layout Plain Layout
4441 \begin_layout Plain Layout
4446 \begin_layout Plain Layout
4448 split(chunklet_parts[2], call_chunk_args, " *, *");
4451 \begin_layout Plain Layout
4461 \begin_layout Standard
4462 The strategy is to parse the name, and then look for a value.
4463 If the value begins with a brace
4464 \begin_inset Flex CharStyle:Code
4467 \begin_layout Plain Layout
4473 , then we recurse and consume as much of the text as necessary, returning
4474 the remaining text when we encounter a leading close-brace
4475 \begin_inset Flex CharStyle:Code
4478 \begin_layout Plain Layout
4485 This being the strategy --- and executed in a loop --- we realise that
4486 we must first look for the closing brace (perhaps preceded by white space)
4487 in order to terminate the recursion, and returning remaining text.
4490 \begin_layout Standard
4491 \begin_inset listings
4495 \begin_layout Plain Layout
4500 \begin_layout Plain Layout
4504 "", "delimiters" ]="
4511 \begin_layout Plain Layout
4515 "", "terminators"]="
4520 \begin_layout Plain Layout
4522 modes["{", "delimiters" ]="
4539 \begin_layout Plain Layout
4541 modes["{", "terminators"]="}";
4544 \begin_layout Plain Layout
4546 modes["[", "delimiters" ]="
4567 \begin_layout Plain Layout
4569 modes["[", "terminators"]="]";
4572 \begin_layout Plain Layout
4574 modes["(", "delimiters" ]="
4591 \begin_layout Plain Layout
4593 modes["(", "terminators"]=")";
4596 \begin_layout Plain Layout
4598 modes["'", "delimiters" ]="
4605 \begin_layout Plain Layout
4607 modes["'", "terminators"]="'";
4610 \begin_layout Plain Layout
4612 modes["/*", "terminators"]="*/";
4615 \begin_layout Plain Layout
4617 modes["//", "terminators"]="
4622 \begin_layout Plain Layout
4624 modes["", "delimiters" ]="
4641 \begin_layout Plain Layout
4646 \begin_layout Plain Layout
4650 \begin_layout Plain Layout
4652 delimiters=modes[mode, "delimiters"];
4655 \begin_layout Plain Layout
4659 \begin_layout Plain Layout
4661 while(length(text)) {
4664 \begin_layout Plain Layout
4666 if match(text, "(" delimiters ")", a) {
4669 \begin_layout Plain Layout
4671 if (a[1] == modes[mode, "terminator"]) return result a[1];
4674 \begin_layout Plain Layout
4679 \begin_layout Plain Layout
4681 #check if new_mode is defined
4684 \begin_layout Plain Layout
4686 if (! (new_mode, "terminators") in modes) {
4689 \begin_layout Plain Layout
4691 error("Delimiter %s set unknown mode in text: %s", new_mode, text);
4694 \begin_layout Plain Layout
4699 \begin_layout Plain Layout
4701 text = substr(text, RSTART));
4704 \begin_layout Plain Layout
4706 result = result substr(text, 1, RSTART -1) RECURSE(text,,new_mode);
4709 \begin_layout Plain Layout
4714 \begin_layout Plain Layout
4716 result = result text;
4719 \begin_layout Plain Layout
4724 \begin_layout Plain Layout
4729 \begin_layout Plain Layout
4734 \begin_layout Plain Layout
4744 \begin_layout Standard
4745 We can test this function like this:
4752 \begin_layout Standard
4753 \begin_inset listings
4757 \begin_layout Plain Layout
4761 chunkref{get_chunk_args()}>
4764 \begin_layout Plain Layout
4769 \begin_layout Plain Layout
4774 \begin_layout Plain Layout
4778 \begin_layout Plain Layout
4780 print parse_chunk_args("things[x, y], get_other_things(a,
4787 \begin_layout Plain Layout
4792 \begin_layout Plain Layout
4794 print "a[" b "] => " a[b];
4797 \begin_layout Plain Layout
4802 \begin_layout Plain Layout
4812 \begin_layout Standard
4813 which should give this output:
4817 pca-test.awk-results
4820 \begin_layout Standard
4821 \begin_inset listings
4825 \begin_layout Plain Layout
4827 a[foo.quux.quirk] =>
4830 \begin_layout Plain Layout
4832 a[foo.quux.a] => fleeg
4835 \begin_layout Plain Layout
4840 \begin_layout Plain Layout
4845 \begin_layout Plain Layout
4855 \begin_layout Section
4856 Expanding parameters
4859 \begin_layout Standard
4860 \begin_inset CommandInset label
4862 name "Here-we-split"
4866 Here we split the text on
4867 \begin_inset Flex CharStyle:Code
4870 \begin_layout Plain Layout
4876 which means that all parts except the first will begin with a parameter
4878 The split function will consume the literal
4879 \begin_inset Flex CharStyle:Code
4882 \begin_layout Plain Layout
4895 \begin_layout Standard
4896 \begin_inset listings
4900 \begin_layout Plain Layout
4902 function expand_chunk_args(text, params, args,
4905 \begin_layout Plain Layout
4907 p, text_array, next_text, v, t, l)
4910 \begin_layout Plain Layout
4915 \begin_layout Plain Layout
4917 if (split(text, text_array, "
4924 \begin_layout Plain Layout
4928 chunkref{substitute-chunk-args}>
4931 \begin_layout Plain Layout
4936 \begin_layout Plain Layout
4941 \begin_layout Plain Layout
4951 \begin_layout Standard
4952 First, we produce an associative array of substitution values indexed by
4957 substitute-chunk-args
4960 \begin_layout Standard
4961 \begin_inset listings
4965 \begin_layout Plain Layout
4970 \begin_layout Plain Layout
4972 v[params[p]]=args[p];
4975 \begin_layout Plain Layout
4985 \begin_layout Standard
4986 We accumulate substituted text in the variable
4987 \begin_inset Flex CharStyle:Code
4990 \begin_layout Plain Layout
4997 As the first part of the split function is the part before the delimiter
4999 \begin_inset Flex CharStyle:Code
5002 \begin_layout Plain Layout
5008 in our case --- this part will never contain a parameter reference, so
5009 we assign this directly to the result kept in
5010 \begin_inset Flex CharStyle:Code
5013 \begin_layout Plain Layout
5020 \begin_inset listings
5024 \begin_layout Plain Layout
5034 \begin_layout Standard
5035 We then iterate over the remaining values in the array
5039 \begin_layout Plain Layout
5040 I don't know why I think that it will enumerate the array in order, but
5047 \begin_inset Note Note
5050 \begin_layout Plain Layout
5051 So fix it or porve it
5056 , and substitute each reference for it's argument.
5059 \begin_layout Standard
5060 \begin_inset listings
5064 \begin_layout Plain Layout
5066 for(t in text_array) if (t>1) {
5069 \begin_layout Plain Layout
5073 chunkref{substitute-chunk-arg}>
5076 \begin_layout Plain Layout
5086 \begin_layout Standard
5088 \begin_inset Flex CharStyle:Code
5091 \begin_layout Plain Layout
5097 a valid parameter reference will consist of valid parameter name terminated
5099 \begin_inset Flex CharStyle:Code
5102 \begin_layout Plain Layout
5109 A valid character name begins with the underscore or a letter, and may
5110 contain letters, digits or underscores.
5113 \begin_layout Standard
5114 A valid looking reference that is not actually the name of a parameter will
5115 be and not substituted.
5116 This is good because there is nothing to substitute anyway, and it avoids
5117 clashes when writing code for languages where ${\SpecialChar \ldots{}
5118 } is a valid construct
5119 --- such constructs will not be interfered with unless the parameter name
5124 substitute-chunk-arg
5127 \begin_layout Standard
5128 \begin_inset listings
5132 \begin_layout Plain Layout
5134 if (match(text_array[t], "^([a-zA-Z_][a-zA-Z0-9_]*)}", l) &&
5137 \begin_layout Plain Layout
5142 \begin_layout Plain Layout
5147 \begin_layout Plain Layout
5149 text = text v[l[1]] substr(text_array[t], length(l[1])+2);
5152 \begin_layout Plain Layout
5157 \begin_layout Plain Layout
5159 text = text "${" text_array[t];
5162 \begin_layout Plain Layout
5172 \begin_layout Chapter
5176 \begin_layout Standard
5177 Newfangle recognizes noweb chunks, but as we also want better LaTeX integration
5178 we will recognize any of these:
5181 \begin_layout Itemize
5182 notangle chunks matching the pattern
5183 \begin_inset Flex CharStyle:Code
5186 \begin_layout Plain Layout
5188 \begin_inset space \hspace*{}
5193 \begin_inset space \hspace*{}
5205 \begin_layout Itemize
5206 a chunks beginning with
5207 \begin_inset Flex CharStyle:Code
5210 \begin_layout Plain Layout
5220 Chunk{\SpecialChar \ldots{}
5221 } on the previous line
5224 \begin_layout Itemize
5225 an older form I have used, beginning with
5226 \begin_inset Flex CharStyle:Code
5229 \begin_layout Plain Layout
5232 begin{Chunk}[options]
5237 --- also more suitable for plain LaTeX users
5241 \begin_layout Plain Layout
5242 Is there such a thing as plain LaTeX?
5250 \begin_layout Section
5254 \begin_layout Standard
5256 \begin_inset Flex CharStyle:Code
5259 \begin_layout Plain Layout
5265 is used to signify that we are processing a code chunk and not document.
5266 In such a state, input lines will be assigned to the current chunk; otherwise
5270 \begin_layout Subsection
5274 \begin_layout Standard
5275 Our current scheme is to recognize the new lstlisting chunks, but these
5276 may be preceded by a
5277 \begin_inset Flex CharStyle:Code
5280 \begin_layout Plain Layout
5288 command which in LyX is a more convenient way to pass the chunk name to
5290 \begin_inset Flex CharStyle:Code
5293 \begin_layout Plain Layout
5301 command, and a more visible way to specify other
5302 \begin_inset Flex CharStyle:Code
5305 \begin_layout Plain Layout
5314 \begin_layout Standard
5315 The arguments to the
5316 \begin_inset Flex CharStyle:Code
5319 \begin_layout Plain Layout
5327 command are a name, and then a comma-seperated list of key-value pairs
5329 \begin_inset Flex CharStyle:Code
5332 \begin_layout Plain Layout
5341 (In fact within the LaTeX
5342 \begin_inset Flex CharStyle:Code
5345 \begin_layout Plain Layout
5354 \begin_inset CommandInset ref
5356 reference "sub:The-chunk-command"
5361 \begin_inset Flex CharStyle:Code
5364 \begin_layout Plain Layout
5370 is prefixed to the argument which is then literally passed to
5371 \begin_inset Flex CharStyle:Code
5374 \begin_layout Plain Layout
5389 \begin_layout Standard
5390 \begin_inset listings
5394 \begin_layout Plain Layout
5403 \begin_layout Plain Layout
5413 Chunk{ *([^ ,}]*),?(.*)}", line)) {
5416 \begin_layout Plain Layout
5418 next_chunk_name = line[1];
5421 \begin_layout Plain Layout
5423 get_chunk_args(line[2], next_chunk_args);
5426 \begin_layout Plain Layout
5431 \begin_layout Plain Layout
5436 \begin_layout Plain Layout
5446 \begin_layout Standard
5447 We also make a basic attempt to parse the name out of the
5448 \begin_inset Flex CharStyle:Code
5451 \begin_layout Plain Layout
5455 \begin_inset space \hspace{}
5464 text, otherwise we fall back to the name found in the previous chunk command.
5465 This attempt is very basic and doesn't support commas or spaces or square
5466 brackets as part of the chunkname.
5468 \begin_inset Flex CharStyle:Code
5471 \begin_layout Plain Layout
5479 which is convenient for some users
5483 \begin_layout Plain Layout
5484 but not yet supported in the LaTeX macros
5490 \begin_inset Note Note
5493 \begin_layout Plain Layout
5502 \begin_layout Standard
5503 \begin_inset listings
5507 \begin_layout Plain Layout
5520 \begin_layout Plain Layout
5522 if (match($0, "}.*[[,] *name= *{? *([^], }]*)", line)) {
5525 \begin_layout Plain Layout
5530 \begin_layout Plain Layout
5535 \begin_layout Plain Layout
5537 new_chunk(next_chunk_name, next_chunk_args);
5540 \begin_layout Plain Layout
5545 \begin_layout Plain Layout
5550 \begin_layout Plain Layout
5555 \begin_layout Plain Layout
5565 \begin_layout Subsection
5569 \begin_layout Standard
5570 We recognize notangle style chunks too:
5577 \begin_layout Standard
5578 \begin_inset listings
5582 \begin_layout Plain Layout
5587 \begin_layout Plain Layout
5589 if (match($0, "^[<]<(.*)[>]>= *$", line)) {
5592 \begin_layout Plain Layout
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
5627 \begin_layout Section
5631 \begin_layout Standard
5632 Likewise, we need to recognize when a chunk ends.
5635 \begin_layout Subsection
5639 \begin_layout Standard
5641 \begin_inset Flex CharStyle:Code
5644 \begin_layout Plain Layout
5651 \begin_inset Flex CharStyle:Code
5654 \begin_layout Plain Layout
5660 is surrounded by square brackets so that when this document is processed,
5661 this chunk doesn't terminate early when the lstlistings package recognizes
5662 it's own end-string!
5663 \begin_inset Note Greyedout
5666 \begin_layout Plain Layout
5667 This doesn't make sense as the regex is anchored with ^, which this line
5668 does not begin with!
5674 \begin_inset Note Note
5677 \begin_layout Plain Layout
5690 \begin_layout Standard
5691 \begin_inset listings
5695 \begin_layout Plain Layout
5708 \begin_layout Plain Layout
5713 \begin_layout Plain Layout
5718 \begin_layout Plain Layout
5723 \begin_layout Plain Layout
5733 \begin_layout Subsection
5741 \begin_layout Standard
5742 \begin_inset listings
5746 \begin_layout Plain Layout
5751 \begin_layout Plain Layout
5756 \begin_layout Plain Layout
5761 \begin_layout Plain Layout
5771 \begin_layout Standard
5772 All other recognizers are only of effect if we are chunking; there's no
5773 point in looking at lines if they aren't part of a chunk, so we just ignore
5774 them as efficiently as we can.
5781 \begin_layout Standard
5782 \begin_inset listings
5786 \begin_layout Plain Layout
5788 ! chunking { next; }
5796 \begin_layout Section
5800 \begin_layout Standard
5801 Chunk contents are any lines read while
5802 \begin_inset Flex CharStyle:Code
5805 \begin_layout Plain Layout
5812 Some chunk contents are special in that they refer to other chunks, and
5813 will be replaced by the contents of these chunks when the file is generated.
5816 \begin_layout Standard
5817 \begin_inset CommandInset label
5819 name "sub:ORS-chunk-text"
5823 We add the output record separator
5824 \begin_inset Flex CharStyle:Code
5827 \begin_layout Plain Layout
5833 to the line now, because we will set
5834 \begin_inset Flex CharStyle:Code
5837 \begin_layout Plain Layout
5843 to the empty string when we generate the output
5847 \begin_layout Plain Layout
5848 So that we can print partial lines using
5849 \begin_inset Flex CharStyle:Code
5852 \begin_layout Plain Layout
5859 \begin_inset Flex CharStyle:Code
5862 \begin_layout Plain Layout
5880 \begin_layout Standard
5881 \begin_inset listings
5885 \begin_layout Plain Layout
5887 length(active_chunk) {
5890 \begin_layout Plain Layout
5894 chunkref{process-chunk-tabs}>
5897 \begin_layout Plain Layout
5901 chunkref{process-chunk}>
5904 \begin_layout Plain Layout
5914 \begin_layout Standard
5915 If a chunk just consisted of plain text, we could handle the chunk like
5920 process-chunk-simple
5923 \begin_layout Standard
5924 \begin_inset listings
5928 \begin_layout Plain Layout
5930 chunk_line(active_chunk, $0 ORS);
5938 \begin_layout Standard
5939 but in fact a chunk can include references to other chunks.
5940 Chunk includes are traditionally written as
5941 \begin_inset Flex CharStyle:Code
5944 \begin_layout Plain Layout
5950 , but we support other variations.
5953 \begin_layout Standard
5954 However, we also process tabs at this point, a tab at input can be replaced
5955 by a number of spaces defined by the
5956 \begin_inset Flex CharStyle:Code
5959 \begin_layout Plain Layout
5965 variable, set by the
5966 \begin_inset Flex CharStyle:Code
5969 \begin_layout Plain Layout
5976 Of course this is poor tab behaviour, we should probably have the option
5977 to use proper counted tab-stops and process this on output.
5984 \begin_layout Standard
5985 \begin_inset listings
5989 \begin_layout Plain Layout
5994 \begin_layout Plain Layout
6001 \begin_layout Plain Layout
6011 \begin_layout Subsection
6012 \begin_inset CommandInset label
6014 name "sub:lstlistings-includes"
6021 \begin_layout Standard
6023 \begin_inset Flex CharStyle:Code
6026 \begin_layout Plain Layout
6029 lstset{escapeinside={=<}{>}}
6034 is set, then we can use
6035 \begin_inset Flex CharStyle:Code
6038 \begin_layout Plain Layout
6042 \begin_inset space \hspace{}
6053 \begin_inset Flex CharStyle:Code
6056 \begin_layout Plain Layout
6065 \begin_layout Enumerate
6066 it is a better mnemonic than
6067 \begin_inset Flex CharStyle:Code
6070 \begin_layout Plain Layout
6076 in that the = sign signifies equivalent or substitutability,
6079 \begin_layout Enumerate
6080 and because =< is not valid in C or in any language I can think of
6083 \begin_layout Enumerate
6084 and also because lstlistings doesn't like
6085 \begin_inset Flex CharStyle:Code
6088 \begin_layout Plain Layout
6094 as an end delimiter for the
6098 escape, so we must make do with a single
6099 \begin_inset Flex CharStyle:Code
6102 \begin_layout Plain Layout
6108 , which is better matched by
6109 \begin_inset Flex CharStyle:Code
6112 \begin_layout Plain Layout
6119 \begin_inset Flex CharStyle:Code
6122 \begin_layout Plain Layout
6131 \begin_layout Standard
6132 As each chunk line may contain more than one chunk include, we will split
6133 out chunk includes in an iterative fashion
6137 \begin_layout Plain Layout
6138 Contrary to our use of
6139 \begin_inset Flex CharStyle:Code
6142 \begin_layout Plain Layout
6148 when substituting parameters in chapter
6149 \begin_inset CommandInset ref
6151 reference "Here-we-split"
6163 \begin_layout Standard
6164 First, as long as the chunk contains a
6165 \begin_inset Flex CharStyle:Code
6168 \begin_layout Plain Layout
6176 command we take as much as we can up to the first
6177 \begin_inset Flex CharStyle:Code
6180 \begin_layout Plain Layout
6195 \begin_layout Standard
6196 \begin_inset listings
6200 \begin_layout Plain Layout
6205 \begin_layout Plain Layout
6210 \begin_layout Plain Layout
6215 \begin_layout Plain Layout
6233 )|)>|<<([a-zA-Z_][-a-zA-Z0-9_]*)>>)",
6236 \begin_layout Plain Layout
6243 \begin_layout Plain Layout
6248 \begin_layout Plain Layout
6250 chunklet = substr(chunk, 1, RSTART - 1);
6258 \begin_layout Standard
6259 We keep track of the indent count, by counting the number of literal characters
6261 We can then preserve this indent on each output line when multi-line chunks
6265 \begin_layout Standard
6266 We then process this first part literal text, and set the chunk which is
6267 still to be processed to be the text after the
6268 \begin_inset Flex CharStyle:Code
6271 \begin_layout Plain Layout
6279 command, which we will process next as we continue around the loop.
6282 \begin_layout Standard
6283 \begin_inset listings
6287 \begin_layout Plain Layout
6289 indent += length(chunklet);
6292 \begin_layout Plain Layout
6294 chunk_line(active_chunk, chunklet);
6297 \begin_layout Plain Layout
6299 chunk = substr(chunk, RSTART + RLENGTH);
6307 \begin_layout Standard
6308 We then consider the type of chunk command we have found, whether it is
6309 the newfangle style command beginning with
6310 \begin_inset Flex CharStyle:Code
6313 \begin_layout Plain Layout
6319 or the older notangle style beginning with
6320 \begin_inset Flex CharStyle:Code
6323 \begin_layout Plain Layout
6333 \begin_layout Standard
6334 Newfangle chunks may have parameters contained within square brackets.
6335 These will be matched in
6336 \begin_inset Flex CharStyle:Code
6339 \begin_layout Plain Layout
6345 and are considered at this stage of processing to be part of the name of
6346 the chunk to be included.
6349 \begin_layout Standard
6350 \begin_inset listings
6354 \begin_layout Plain Layout
6356 if (substr(line[1], 1, 1) == "=") {
6359 \begin_layout Plain Layout
6361 # chunk name up to }
6364 \begin_layout Plain Layout
6366 chunk_include(active_chunk, line[2] line[3], indent);
6369 \begin_layout Plain Layout
6371 } else if (substr(line[1], 1, 1) == "<") {
6374 \begin_layout Plain Layout
6376 chunk_include(active_chunk, line[4], indent);
6379 \begin_layout Plain Layout
6384 \begin_layout Plain Layout
6386 error("Unknown chunk fragment: " line[1]);
6389 \begin_layout Plain Layout
6399 \begin_layout Standard
6400 The loop will continue until there are no more chunkref statements in the
6401 text, at which point we process the final part of the chunk.
6404 \begin_layout Standard
6405 \begin_inset listings
6409 \begin_layout Plain Layout
6414 \begin_layout Plain Layout
6416 chunk_line(active_chunk, chunk);
6424 \begin_layout Standard
6425 \begin_inset CommandInset label
6431 We add the newline character as a chunklet on it's own, to make it easier
6432 to detect new lines and thus manage indentation when processing the output.
6435 \begin_layout Standard
6436 \begin_inset listings
6440 \begin_layout Plain Layout
6442 chunk_line(active_chunk, "
6452 \begin_layout Standard
6453 We will also permit a chunk-part number to follow in square brackets, so
6455 \begin_inset Flex CharStyle:Code
6458 \begin_layout Plain Layout
6461 chunkref{chunk-name[1]}>
6466 will refer to the first part only.
6467 This can make it easy to include a C function prototype in a header file,
6468 if the first part of the chunk is just the function prototype without the
6469 trailing semi-colon.
6470 The header file would include the prototype with the trailing semi-colon,
6474 \begin_layout LyX-Code
6477 chunkref{chunk-name[1]}>;
6480 \begin_layout Standard
6481 This is handled in section
6482 \begin_inset CommandInset ref
6484 reference "sub:Chunk-parts"
6491 \begin_layout Standard
6492 We should perhaps introduce a notion of language specific chunk options;
6493 so that perhaps we could specify:
6496 \begin_layout LyX-Code
6499 chunkref{chunk-name[function-declaration]}>;
6502 \begin_layout Standard
6503 which applies a transform
6504 \begin_inset Flex CharStyle:Code
6507 \begin_layout Plain Layout
6508 function-declaration
6513 to the chunk --- which in this case would extract a function prototype
6515 \begin_inset Note Note
6518 \begin_layout Plain Layout
6527 \begin_layout Chapter
6531 \begin_layout Standard
6532 At the start, first we set the default options.
6539 \begin_layout Standard
6540 \begin_inset listings
6544 \begin_layout Plain Layout
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
6579 \begin_layout Standard
6580 Then we use getopt the standard way, and null out ARGV afterwards in the
6588 \begin_layout Standard
6589 \begin_inset listings
6593 \begin_layout Plain Layout
6595 Optind = 1 # skip ARGV[0]
6598 \begin_layout Plain Layout
6600 while(getopt(ARGC, ARGV, "R:LdT:hr")!=-1) {
6603 \begin_layout Plain Layout
6607 chunkref{handle-options}>
6610 \begin_layout Plain Layout
6615 \begin_layout Plain Layout
6617 for (i=1; i<Optind; i++) { ARGV[i]=""; }
6625 \begin_layout Standard
6626 This is how we handle our options:
6633 \begin_layout Standard
6634 \begin_inset listings
6638 \begin_layout Plain Layout
6640 if (Optopt == "R") root = Optarg;
6643 \begin_layout Plain Layout
6645 else if (Optopt == "r") root="";
6648 \begin_layout Plain Layout
6650 else if (Optopt == "L") linenos = 1;
6653 \begin_layout Plain Layout
6655 else if (Optopt == "d") debug = 1;
6658 \begin_layout Plain Layout
6660 else if (Optopt == "T") tabs = indent_string(Optarg+0);
6663 \begin_layout Plain Layout
6665 else if (Optopt == "h") help();
6668 \begin_layout Plain Layout
6670 else if (Optopt == "?") help();
6678 \begin_layout Standard
6679 We do all of this at the beginning of the program
6686 \begin_layout Standard
6687 \begin_inset listings
6691 \begin_layout Plain Layout
6696 \begin_layout Plain Layout
6700 chunkref{constants}>
6703 \begin_layout Plain Layout
6707 chunkref{default-options}>
6710 \begin_layout Plain Layout
6714 \begin_layout Plain Layout
6718 chunkref{read-options}>
6721 \begin_layout Plain Layout
6731 \begin_layout Standard
6732 And have a simple help function
6739 \begin_layout Standard
6740 \begin_inset listings
6744 \begin_layout Plain Layout
6749 \begin_layout Plain Layout
6754 \begin_layout Plain Layout
6756 print " newfangle [-L] -R<rootname> [source.tex ...]"
6759 \begin_layout Plain Layout
6761 print " newfangle -r [source.tex ...]"
6764 \begin_layout Plain Layout
6766 print " If the filename, source.tex is not specified then stdin is used"
6769 \begin_layout Plain Layout
6774 \begin_layout Plain Layout
6776 print "-L causes the C statement: #line <lineno>
6783 \begin_layout Plain Layout
6785 print "-R causes the named root to be written to stdout"
6788 \begin_layout Plain Layout
6790 print "-r lists all roots in the file (even those used elsewhere)"
6793 \begin_layout Plain Layout
6798 \begin_layout Plain Layout
6808 \begin_layout Chapter
6809 Chunk Language Modes
6812 \begin_layout Standard
6813 \begin_inset CommandInset label
6820 \begin_inset Note Greyedout
6823 \begin_layout Plain Layout
6824 This feature is in-development and does not work yet
6830 \begin_inset Note Note
6833 \begin_layout Plain Layout
6842 \begin_layout Standard
6843 lstlistings and newfangle both recognize source languages, and perform some
6845 lstlistings can detect strings and comments within a language definition
6846 and perform suitable rendering, such as italics for comments, and visible-space
6850 \begin_layout Standard
6851 Newfangle similarly can recognize strings, and comments, etc, within a language,
6852 so that any chunks included with
6853 \begin_inset Flex CharStyle:Code
6856 \begin_layout Plain Layout
6864 can be suitably quoted.
6867 \begin_layout Standard
6868 For instance, consider this chunk with
6869 \begin_inset Flex CharStyle:Code
6872 \begin_layout Plain Layout
6882 example-perl,language=perl
6885 \begin_layout Standard
6886 \begin_inset listings
6890 \begin_layout Plain Layout
6900 \begin_layout Standard
6901 If it were included in a chunk with
6902 \begin_inset Flex CharStyle:Code
6905 \begin_layout Plain Layout
6915 example-sh,language=sh
6918 \begin_layout Standard
6919 \begin_inset listings
6923 \begin_layout Plain Layout
6927 chunkref{example-perl}>"
6935 \begin_layout Standard
6936 would need to generate output like this if it were to work:
6939 \begin_layout LyX-Code
6947 \begin_layout Standard
6948 See that the double quote " as part of the regex has been quoted with a
6949 slash to protect it from shell interpretation.
6952 \begin_layout Standard
6953 If that were then included in a chunk with
6954 \begin_inset Flex CharStyle:Code
6957 \begin_layout Plain Layout
6967 example-makefile,language=make
6970 \begin_layout Standard
6971 \begin_inset listings
6975 \begin_layout Plain Layout
6980 \begin_layout Plain Layout
6984 chunkref{example-sh}>
6992 \begin_layout Standard
6993 We would need the output to look like this --- note the $$:
6996 \begin_layout LyX-Code
7000 \begin_layout LyX-Code
7008 \begin_layout Standard
7009 In order to make this work, we need to define a mode-tracker for each supported
7010 language, that can detect the various quoting modes, and provide a transformati
7011 on that must be applied to any included text so that included text will
7012 be interpreted correctly after the additional interpolation that it will
7013 be subject to at run-time.
7016 \begin_layout Standard
7017 For example, the transformation for text to be inserted into sh double-quoted
7018 strings would be something like:
7021 \begin_layout LyX-Code
7045 \begin_layout Standard
7047 \begin_inset Flex CharStyle:Code
7050 \begin_layout Plain Layout
7061 \begin_layout Standard
7062 \begin_inset Note Note
7065 \begin_layout Plain Layout
7066 I don't think this example is true
7071 The mode tracker must also track nested mode-changes, as in this
7072 \begin_inset Flex CharStyle:Code
7075 \begin_layout Plain Layout
7084 \begin_layout LyX-Code
7085 echo "hello `id **`"
7088 \begin_layout Standard
7089 Any literal text inserted at the point marked ** would need to be escaped
7090 in all kinds of ways, including
7091 \begin_inset Flex CharStyle:Code
7094 \begin_layout Plain Layout
7101 First it would need escaping for the back-ticks `, and then for the double-quot
7105 \begin_layout Standard
7106 Escaping need not occur if the format and mode of the included chunk matches
7107 that of the including chunk, which would suggest that any back-ticks might
7108 need to be part of the included chunk and not including chunk
7109 \begin_inset Note Note
7112 \begin_layout Plain Layout
7113 or is it the other way around?
7121 \begin_layout Standard
7122 As each chunk is output a new mode tracker for that language is initialized
7123 in it's normal state.
7124 As text is output for that chunk the output mode is tracked.
7125 When a new chunk is included, a transformation appropriate to that mode
7126 is selected and pushed onto a stack of transformations.
7127 Any text to be output is first passed through this stack of transformations.
7130 \begin_layout Standard
7131 It remains to consider if the chunk-include function should return it's
7132 generated text so that the caller can apply any transformations (and formatting
7133 ), or if it should apply the stack of transformations itself.
7136 \begin_layout Standard
7137 Note that the transformed text should have the property of not being able
7138 to change the mode in the current chunk.
7141 \begin_layout Standard
7142 \begin_inset Note Note
7145 \begin_layout Plain Layout
7146 Note chunk parameters should probably also be transformed
7158 \begin_layout Standard
7159 \begin_inset listings
7163 \begin_layout Plain Layout
7165 function new_mode(language, mode) {
7168 \begin_layout Plain Layout
7170 mode["language"] = language;
7173 \begin_layout Plain Layout
7178 \begin_layout Plain Layout
7188 \begin_layout Standard
7189 Because awk functions cannot return an array, we must create the array first
7194 new-mode,params=language;mode
7197 \begin_layout Standard
7198 \begin_inset listings
7202 \begin_layout Plain Layout
7206 chunkref{awk-delete-array}(${mode})>
7209 \begin_layout Plain Layout
7211 new_mode(${language}, ${mode});
7219 \begin_layout Standard
7220 And for tracking modes, we dispatch to a mode-tracker action based on the
7228 \begin_layout Standard
7229 \begin_inset listings
7233 \begin_layout Plain Layout
7235 function track_mode(mode, text) {
7238 \begin_layout Plain Layout
7240 if (mode["language"] == "C") {
7243 \begin_layout Plain Layout
7247 chunkref{track-mode-C}>
7250 \begin_layout Plain Layout
7255 \begin_layout Plain Layout
7260 \begin_layout Plain Layout
7270 \begin_layout Standard
7271 For each mode, we look for a character that has the power to change the
7275 \begin_layout Standard
7280 \labelwidthstring 00.00.0000
7281 \begin_inset Quotes eld
7284 enters double-quote mode
7288 \labelwidthstring 00.00.0000
7289 ' enters single-quote mode
7293 \labelwidthstring 00.00.0000
7296 enters multi-line mode
7300 \labelwidthstring 00.00.0000
7301 # enters #define sub-mode, needs
7303 escaping end of line too
7307 \labelwidthstring 00.00.0000
7308 /* enters comment mode
7311 \begin_layout Standard
7312 In double-quote mode, escape
7315 \begin_inset Quotes eld
7321 \begin_layout Standard
7325 \begin_inset Quotes eld
7331 \begin_layout Standard
7332 \begin_inset Quotes eld
7338 \begin_layout Standard
7339 newline needs to close and re-open string or something
7342 \begin_layout Standard
7343 in single-quote mode escape
7346 \begin_inset Quotes eld
7356 \begin_layout Standard
7357 \begin_inset listings
7361 \begin_layout Plain Layout
7374 \begin_layout Standard
7375 \begin_inset listings
7379 \begin_layout Plain Layout
7383 chunkref{new_mode()}>
7391 \begin_layout Chapter
7392 Generating the output
7395 \begin_layout Standard
7396 We generate output by calling output_chunk, or listing the chunk names.
7403 \begin_layout Standard
7404 \begin_inset listings
7408 \begin_layout Plain Layout
7410 if (length(root)) output_chunk(root);
7413 \begin_layout Plain Layout
7415 else output_chunk_names();
7423 \begin_layout Standard
7424 We also have some other output debugging:
7431 \begin_layout Standard
7432 \begin_inset listings
7436 \begin_layout Plain Layout
7441 \begin_layout Plain Layout
7443 print "------ chunk names "
7446 \begin_layout Plain Layout
7448 output_chunk_names();
7451 \begin_layout Plain Layout
7453 print "====== chunks"
7456 \begin_layout Plain Layout
7461 \begin_layout Plain Layout
7463 print "++++++ debug"
7466 \begin_layout Plain Layout
7471 \begin_layout Plain Layout
7473 print a "=" chunks[a];
7476 \begin_layout Plain Layout
7481 \begin_layout Plain Layout
7491 \begin_layout Standard
7492 We do both of these at the end.
7494 \begin_inset Flex CharStyle:Code
7497 \begin_layout Plain Layout
7503 because each chunklet is not necessarily a complete line, and we already
7505 \begin_inset Flex CharStyle:Code
7508 \begin_layout Plain Layout
7514 to each input line in section
7515 \begin_inset CommandInset ref
7517 reference "sub:ORS-chunk-text"
7528 \begin_layout Standard
7529 \begin_inset listings
7533 \begin_layout Plain Layout
7538 \begin_layout Plain Layout
7542 chunkref{debug-output}>
7545 \begin_layout Plain Layout
7550 \begin_layout Plain Layout
7554 chunkref{generate-output}>
7557 \begin_layout Plain Layout
7567 \begin_layout Standard
7568 We write chunk names like this.
7569 If we seem to be running in notangle compatibility mode, then we enclose
7571 \begin_inset Flex CharStyle:Code
7574 \begin_layout Plain Layout
7580 the same way notangle does:
7584 output_chunk_names()
7587 \begin_layout Standard
7588 \begin_inset listings
7592 \begin_layout Plain Layout
7594 function output_chunk_names( c, prefix, suffix)
7597 \begin_layout Plain Layout
7602 \begin_layout Plain Layout
7604 if (notangle_mode) {
7607 \begin_layout Plain Layout
7612 \begin_layout Plain Layout
7617 \begin_layout Plain Layout
7622 \begin_layout Plain Layout
7624 for (c in chunk_names) {
7627 \begin_layout Plain Layout
7629 print prefix c suffix "
7634 \begin_layout Plain Layout
7639 \begin_layout Plain Layout
7649 \begin_layout Standard
7650 This function would write out all chunks
7657 \begin_layout Standard
7658 \begin_inset listings
7662 \begin_layout Plain Layout
7664 function output_chunks( a)
7667 \begin_layout Plain Layout
7672 \begin_layout Plain Layout
7674 for (a in chunk_names) {
7677 \begin_layout Plain Layout
7679 output_chunk(chunk_names[a]);
7682 \begin_layout Plain Layout
7687 \begin_layout Plain Layout
7692 \begin_layout Plain Layout
7696 \begin_layout Plain Layout
7698 function output_chunk(chunk) {
7701 \begin_layout Plain Layout
7706 \begin_layout Plain Layout
7708 lineno_needed = linenos;
7711 \begin_layout Plain Layout
7715 \begin_layout Plain Layout
7720 \begin_layout Plain Layout
7725 \begin_layout Plain Layout
7734 \begin_layout Section
7735 Assembling the chunks
7738 \begin_layout Standard
7739 \begin_inset Flex CharStyle:Code
7742 \begin_layout Plain Layout
7748 holds a string consisting of the names of all the chunks that resulted
7749 in this chunk being output.
7751 \begin_inset Note Note
7754 \begin_layout Plain Layout
7755 Make sure it includes the line numbers too...
7761 It should probably also contain the source line numbers at which each inclusion
7766 write_chunk(),emph={chunk_path}
7769 \begin_layout Standard
7770 \begin_inset listings
7774 \begin_layout Plain Layout
7776 function write_chunk(chunk_name, indent, tail,
7779 \begin_layout Plain Layout
7784 \begin_layout Plain Layout
7786 chunk_path, chunk_args,
7789 \begin_layout Plain Layout
7794 \begin_layout Plain Layout
7796 part, max_part, part_line, frag, max_frag, text,
7799 \begin_layout Plain Layout
7801 chunklet, only_part, call_chunk_args, mode)
7804 \begin_layout Plain Layout
7814 \begin_layout Subsection
7815 \begin_inset CommandInset label
7817 name "sub:Chunk-parts"
7824 \begin_layout Standard
7825 As mentioned in section
7826 \begin_inset CommandInset ref
7828 reference "sub:lstlistings-includes"
7832 , a chunk name may contain a part specifier in square brackets, limiting
7833 the parts that should be emitted.
7836 \begin_layout Standard
7837 \begin_inset listings
7841 \begin_layout Plain Layout
7843 if (match(chunk_name, "^(.*)
7851 ]$", chunk_name_parts)) {
7854 \begin_layout Plain Layout
7856 chunk_name = chunk_name_parts[1];
7859 \begin_layout Plain Layout
7861 only_part = chunk_name_parts[2];
7864 \begin_layout Plain Layout
7874 \begin_layout Standard
7875 We first create the mode tracker for this chunk.
7878 \begin_layout Standard
7881 chunkref{awk-delete-array}(mode)>
7884 \begin_layout Standard
7885 \begin_inset listings
7889 \begin_layout Plain Layout
7894 \begin_layout Plain Layout
7896 new_mode(chunks[chunk_name, "language"], mode);
7904 \begin_layout Standard
7907 chunkref{new-mode}(chunks[chunk_name, "language"], mode)>
7910 \begin_layout Standard
7912 \begin_inset Flex CharStyle:Code
7915 \begin_layout Plain Layout
7921 the names of the parameters that this chunk accepts, whose values were
7922 (optionally) passed in
7923 \begin_inset Flex CharStyle:Code
7926 \begin_layout Plain Layout
7935 \begin_layout Standard
7936 \begin_inset listings
7940 \begin_layout Plain Layout
7942 split(chunks[chunk_name, "params"], chunk_params, " *; *");
7950 \begin_layout Standard
7951 To assemble a chunk, we write out each part.
7958 \begin_layout Standard
7959 \begin_inset listings
7963 \begin_layout Plain Layout
7965 if (! (chunk_name in chunk_names)) {
7968 \begin_layout Plain Layout
7970 error(sprintf(_"The root module <<%s>> was not defined.
7977 \begin_layout Plain Layout
7979 chunk_name, chunk_path));
7982 \begin_layout Plain Layout
7987 \begin_layout Plain Layout
7991 \begin_layout Plain Layout
7993 max_part = chunks[chunk_name, "part"];
7996 \begin_layout Plain Layout
7998 for(part = 1; part <= max_part; part++) {
8001 \begin_layout Plain Layout
8003 if (! only_part || part == only_part) {
8006 \begin_layout Plain Layout
8010 chunkref{write-part}>
8013 \begin_layout Plain Layout
8018 \begin_layout Plain Layout
8023 \begin_layout Plain Layout
8033 \begin_layout Standard
8034 A part can either be a chunklet of lines, or an include of another chunk.
8037 \begin_layout Standard
8038 Chunks may also have parameters, specified in LaTeX style with braces after
8039 the chunk name --- looking like this in the document:
8040 \begin_inset Flex CharStyle:Code
8043 \begin_layout Plain Layout
8044 chunkname{param1, param2}
8050 Arguments are passed in square brackets:
8051 \begin_inset Flex CharStyle:Code
8054 \begin_layout Plain Layout
8057 chunkref{chunkname}[arg1, arg2]
8065 \begin_layout Standard
8066 Before we process each part, we check that the source position hasn't changed
8067 unexpectedly, so that we can know if we need to output a new file-line
8075 \begin_layout Standard
8076 \begin_inset listings
8080 \begin_layout Plain Layout
8084 chunkref{check-source-jump}>
8087 \begin_layout Plain Layout
8091 \begin_layout Plain Layout
8093 chunklet = chunks[chunk_name, "part", part];
8096 \begin_layout Plain Layout
8098 if (chunks[chunk_name, "part", part, "type"] == part_type_chunk) {
8101 \begin_layout Plain Layout
8105 chunkref{write-included-chunk}>
8108 \begin_layout Plain Layout
8110 } else if (chunklet SUBSEP "line" in chunks) {
8113 \begin_layout Plain Layout
8117 chunkref{write-chunklets}>
8120 \begin_layout Plain Layout
8125 \begin_layout Plain Layout
8127 # empty last chunklet
8130 \begin_layout Plain Layout
8140 \begin_layout Standard
8141 To write an included chunk, we must detect any optional chunk arguments
8143 Then we recurse calling
8144 \begin_inset Flex Chunkref
8147 \begin_layout Plain Layout
8157 write-included-chunk
8160 \begin_layout Standard
8161 \begin_inset listings
8165 \begin_layout Plain Layout
8167 if (match(chunklet, "^([^
8179 )$", chunklet_parts)) {
8182 \begin_layout Plain Layout
8184 chunklet = chunklet_parts[1];
8187 \begin_layout Plain Layout
8189 # parse_chunk_args(chunklet_parts[2], chunk_args);
8192 \begin_layout Plain Layout
8194 # TO BE parse_chunk_args SOON
8197 \begin_layout Plain Layout
8199 split(chunklet_parts[2], call_chunk_args, " *, *");
8202 \begin_layout Plain Layout
8204 for (c in call_chunk_args) {
8207 \begin_layout Plain Layout
8209 call_chunk_args[c] = expand_chunk_args(call_chunk_args[c], chunk_params,
8213 \begin_layout Plain Layout
8218 \begin_layout Plain Layout
8223 \begin_layout Plain Layout
8225 split("", call_chunk_args);
8228 \begin_layout Plain Layout
8233 \begin_layout Plain Layout
8235 write_chunk(chunklet,
8238 \begin_layout Plain Layout
8240 chunks[chunk_name, "part", part, "indent"] indent,
8243 \begin_layout Plain Layout
8245 chunks[chunk_name, "part", part, "tail"],
8248 \begin_layout Plain Layout
8255 \begin_layout Plain Layout
8265 \begin_layout Standard
8266 Before we output a chunklet of lines, we first emit the file and line number
8267 if we have one, and if it is safe to do so.
8271 \begin_layout Standard
8272 Chunklets are generally broken up by includes, so the start of a chunklet
8273 is a good place to do this.
8274 Then we output each line of the chunklet.
8277 \begin_layout Standard
8278 When it is not safe, such as in the middle of a multi-line macro definition,
8280 \begin_inset Flex CharStyle:Code
8283 \begin_layout Plain Layout
8289 is set to true, and in such a case we note that we want to emit the line
8290 statement when it is next safe.
8297 \begin_layout Standard
8298 \begin_inset listings
8302 \begin_layout Plain Layout
8304 max_frag = chunks[chunklet, "line"];
8307 \begin_layout Plain Layout
8309 for(frag = 1; frag <= max_frag; frag++) {
8312 \begin_layout Plain Layout
8316 chunkref{write-file-line}>
8324 \begin_layout Standard
8325 We then extract the chunklet text and expand any arguments.
8328 \begin_layout Standard
8329 \begin_inset listings
8333 \begin_layout Plain Layout
8337 \begin_layout Plain Layout
8339 text = chunks[chunklet, frag];
8342 \begin_layout Plain Layout
8347 \begin_layout Plain Layout
8352 \begin_layout Plain Layout
8354 text = expand_chunk_args(text, chunk_params, chunk_args);
8362 \begin_layout Standard
8363 If the text is a single newline (which we keep separate - see
8364 \begin_inset CommandInset ref
8366 reference "lone-newline"
8370 ) then we increment the line number.
8371 In the case where this is the last line of a chunk and it is not a top-level
8372 chunk we replace the newline with an empty string --- because the chunk
8373 that included this chunk will have the newline at the end of the line that
8374 included this chunk.
8377 \begin_layout Standard
8379 \begin_inset Flex CharStyle:Code
8382 \begin_layout Plain Layout
8388 that we have started a new line, so that indentation can be managed with
8389 the following piece of text.
8392 \begin_layout Standard
8393 \begin_inset listings
8397 \begin_layout Plain Layout
8401 \begin_layout Plain Layout
8408 \begin_layout Plain Layout
8413 \begin_layout Plain Layout
8415 if (part == max_part && frag == max_frag && length(chunk_path)) {
8418 \begin_layout Plain Layout
8423 \begin_layout Plain Layout
8428 \begin_layout Plain Layout
8433 \begin_layout Plain Layout
8438 \begin_layout Plain Layout
8448 \begin_layout Standard
8449 If this text does not represent a newline, but we see that we are the first
8450 piece of text on a newline, then we prefix our text with the current indent.
8452 \begin_inset Flex CharStyle:Code
8455 \begin_layout Plain Layout
8461 is a global output-state variable, but the
8462 \begin_inset Flex CharStyle:Code
8465 \begin_layout Plain Layout
8475 \begin_layout Standard
8476 \begin_inset listings
8480 \begin_layout Plain Layout
8485 \begin_layout Plain Layout
8487 if (newline) text = indent text;
8490 \begin_layout Plain Layout
8495 \begin_layout Plain Layout
8500 \begin_layout Plain Layout
8509 \begin_layout Standard
8510 Tail will soon no longer be relevant once mode-detection is in place.
8513 \begin_layout Standard
8514 \begin_inset listings
8518 \begin_layout Plain Layout
8523 \begin_layout Plain Layout
8525 # track_mode(mode, text);
8528 \begin_layout Plain Layout
8538 \begin_layout Standard
8539 If a line ends in a backslash --- suggesting continuation --- then we supress
8540 outputting file-line as it would probably break the continued lines.
8544 \begin_layout Standard
8545 \begin_inset listings
8549 \begin_layout Plain Layout
8554 \begin_layout Plain Layout
8556 lineno_suppressed = substr(lastline, length(lastline)) == "
8563 \begin_layout Plain Layout
8568 \begin_layout Plain Layout
8578 \begin_layout Standard
8579 Of course there is no point in actually outputting the source filename and
8580 line number (file-line) if they don't say anything new! We only need to
8581 emit them if they aren't what is expected, or if we we not able to emit
8582 one when they had changed.
8589 \begin_layout Standard
8590 \begin_inset listings
8594 \begin_layout Plain Layout
8596 if (newline && lineno_needed && ! lineno_suppressed) {
8599 \begin_layout Plain Layout
8601 filename = a_filename;
8604 \begin_layout Plain Layout
8609 \begin_layout Plain Layout
8611 print "#line " lineno "
8620 \begin_layout Plain Layout
8625 \begin_layout Plain Layout
8635 \begin_layout Standard
8636 We check if a new file-line is needed by checking if the source line matches
8637 what we (or a compiler) would expect.
8645 \begin_layout Standard
8646 \begin_inset listings
8650 \begin_layout Plain Layout
8652 if (linenos && (chunk_name SUBSEP "part" SUBSEP part SUBSEP "FILENAME" in
8656 \begin_layout Plain Layout
8658 a_filename = chunks[chunk_name, "part", part, "FILENAME"];
8661 \begin_layout Plain Layout
8663 a_lineno = chunks[chunk_name, "part", part, "LINENO"];
8666 \begin_layout Plain Layout
8668 if (a_filename != filename || a_lineno != lineno) {
8671 \begin_layout Plain Layout
8676 \begin_layout Plain Layout
8681 \begin_layout Plain Layout
8691 \begin_layout Chapter
8695 \begin_layout Standard
8696 Awk has pretty limited data structures, so we will use two main hashes.
8697 Uninterrupted sequences of a chunk will be stored in
8698 \begin_inset Flex CharStyle:Code
8701 \begin_layout Plain Layout
8707 and the chunklets used in a chunk will be stored in
8708 \begin_inset Flex CharStyle:Code
8711 \begin_layout Plain Layout
8724 \begin_layout Standard
8725 \begin_inset listings
8729 \begin_layout Plain Layout
8739 \begin_layout Standard
8741 \begin_inset Flex CharStyle:Code
8744 \begin_layout Plain Layout
8750 mentioned are not chunk parameters for parameterized chunks, as mentioned
8752 \begin_inset CommandInset ref
8754 reference "cha:Chunk Arguments"
8758 , but the lstlistings style parameters used in the
8759 \begin_inset Flex CharStyle:Code
8762 \begin_layout Plain Layout
8774 \begin_layout Plain Layout
8776 \begin_inset Flex CharStyle:Code
8779 \begin_layout Plain Layout
8785 parameter is used to hold the parameters for parameterized chunks
8794 chunk-storage-functions
8797 \begin_layout Standard
8798 \begin_inset listings
8802 \begin_layout Plain Layout
8804 function new_chunk(chunk_name, params,
8807 \begin_layout Plain Layout
8812 \begin_layout Plain Layout
8817 \begin_layout Plain Layout
8822 \begin_layout Plain Layout
8824 # HACK WHILE WE CHANGE TO ( ) for PARAM CHUNKS
8827 \begin_layout Plain Layout
8837 )$", "", chunk_name);
8840 \begin_layout Plain Layout
8842 active_chunk = chunk_name;
8845 \begin_layout Plain Layout
8847 if (! (chunk_name in chunk_names)) {
8850 \begin_layout Plain Layout
8852 if (debug) print "New chunk " chunk_name;
8855 \begin_layout Plain Layout
8857 chunk_names[chunk_name];
8860 \begin_layout Plain Layout
8865 \begin_layout Plain Layout
8867 chunks[chunk_name, p] = params[p];
8870 \begin_layout Plain Layout
8875 \begin_layout Plain Layout
8880 \begin_layout Plain Layout
8882 prime_chunk(chunk_name);
8885 \begin_layout Plain Layout
8895 \begin_layout Standard
8896 \begin_inset listings
8900 \begin_layout Plain Layout
8904 \begin_layout Plain Layout
8906 function prime_chunk(chunk_name)
8909 \begin_layout Plain Layout
8914 \begin_layout Plain Layout
8916 chunks[chunk_name, "part", ++chunks[chunk_name, "part"] ] =
8921 \begin_layout Plain Layout
8923 chunk_name SUBSEP "chunklet" SUBSEP "" ++chunks[chunk_name, "chunklet"]
8927 \begin_layout Plain Layout
8929 chunks[chunk_name, "part", chunks[chunk_name, "part"], "FILENAME"] = FILENAME;
8932 \begin_layout Plain Layout
8934 chunks[chunk_name, "part", chunks[chunk_name, "part"], "LINENO"] = FNR
8938 \begin_layout Plain Layout
8943 \begin_layout Plain Layout
8947 \begin_layout Plain Layout
8949 function chunk_line(chunk_name, line){
8952 \begin_layout Plain Layout
8954 chunks[chunk_name, "chunklet", chunks[chunk_name, "chunklet"],
8957 \begin_layout Plain Layout
8959 ++chunks[chunk_name, "chunklet", chunks[chunk_name, "chunklet"],
8963 \begin_layout Plain Layout
8968 \begin_layout Plain Layout
8977 \begin_layout Standard
8978 Chunk include represents a
8982 statement, and stores the requirement to include another chunk.
8983 The parameter indent represents the quanity of literal text characters
8988 statement and therefore by how much additional lines of the included chunk
8992 \begin_layout Standard
8993 \begin_inset listings
8997 \begin_layout Plain Layout
8999 function chunk_include(chunk_name, chunk_ref, indent, tail)
9002 \begin_layout Plain Layout
9007 \begin_layout Plain Layout
9009 chunks[chunk_name, "part", ++chunks[chunk_name, "part"] ] = chunk_ref;
9012 \begin_layout Plain Layout
9014 chunks[chunk_name, "part", chunks[chunk_name, "part"], "type" ] = part_type_ch
9018 \begin_layout Plain Layout
9020 chunks[chunk_name, "part", chunks[chunk_name, "part"], "indent" ] = indent_str
9024 \begin_layout Plain Layout
9026 chunks[chunk_name, "part", chunks[chunk_name, "part"], "tail" ] = tail;
9029 \begin_layout Plain Layout
9031 prime_chunk(chunk_name);
9034 \begin_layout Plain Layout
9039 \begin_layout Plain Layout
9048 \begin_layout Standard
9049 The indent is calculated by indent_string, which may in future convert some
9050 spaces into tab characters.
9051 This function works by generating a printf padded format string, like
9052 \begin_inset Flex CharStyle:Code
9055 \begin_layout Plain Layout
9061 for an indent of 22, and then printing an empty string using that format.
9064 \begin_layout Standard
9065 \begin_inset listings
9069 \begin_layout Plain Layout
9071 function indent_string(indent) {
9074 \begin_layout Plain Layout
9076 return sprintf("%" indent "s", "");
9079 \begin_layout Plain Layout
9089 \begin_layout Chapter
9090 \begin_inset CommandInset label
9099 \begin_layout Standard
9100 I use Arnold Robbins public domain getopt (1993 revision).
9101 This is probably the same one that is covered in chapter 12 of
9102 \begin_inset Quotes eld
9105 Edition 3 of GAWK: Effective AWK Programming: A User's Guide for GNU Awk
9106 \begin_inset Quotes erd
9109 but as that is licensed under the GNU Free Documentation License, Version
9110 1.3, which conflicts with the GPL3, I can't use it from there (or it's accompany
9111 ing explanations), so I do my best to explain how it works here.
9114 \begin_layout Standard
9115 The getopt.awk header is:
9119 getopt.awk-header,language=awk,morestring=[b]{/},morekeywords=else
9122 \begin_layout Standard
9123 \begin_inset listings
9127 \begin_layout Plain Layout
9129 # getopt.awk --- do C library getopt(3) function in awk
9132 \begin_layout Plain Layout
9137 \begin_layout Plain Layout
9139 # Arnold Robbins, arnold@skeeve.com, Public Domain
9142 \begin_layout Plain Layout
9147 \begin_layout Plain Layout
9149 # Initial version: March, 1991
9152 \begin_layout Plain Layout
9154 # Revised: May, 1993
9162 \begin_layout Standard
9163 The provided explanation is:
9170 \begin_layout Standard
9171 \begin_inset listings
9175 \begin_layout Plain Layout
9177 # External variables:
9180 \begin_layout Plain Layout
9182 # Optind -- index in ARGV of first nonoption argument
9185 \begin_layout Plain Layout
9187 # Optarg -- string value of argument to current option
9190 \begin_layout Plain Layout
9192 # Opterr -- if nonzero, print our own diagnostic
9195 \begin_layout Plain Layout
9197 # Optopt -- current option letter
9200 \begin_layout Plain Layout
9204 \begin_layout Plain Layout
9209 \begin_layout Plain Layout
9211 # -1 at end of options
9214 \begin_layout Plain Layout
9216 # ? for unrecognized option
9219 \begin_layout Plain Layout
9221 # <c> a character representing the current option
9224 \begin_layout Plain Layout
9228 \begin_layout Plain Layout
9233 \begin_layout Plain Layout
9235 # _opti -- index in multi-flag option, e.g., -abc
9243 \begin_layout Standard
9244 The function follows.
9245 The final two parameters,
9246 \begin_inset Flex CharStyle:Code
9249 \begin_layout Plain Layout
9256 \begin_inset Flex CharStyle:Code
9259 \begin_layout Plain Layout
9265 are local variables and not parameters --- as indicated by the multiple
9266 spaces preceding them.
9267 Awk doesn't care, the multiple spaces are a convention to help us humans.
9274 \begin_layout Standard
9275 \begin_inset listings
9279 \begin_layout Plain Layout
9281 function getopt(argc, argv, options, thisopt, i)
9284 \begin_layout Plain Layout
9289 \begin_layout Plain Layout
9291 if (length(options) == 0) # no options given
9294 \begin_layout Plain Layout
9299 \begin_layout Plain Layout
9301 if (argv[Optind] == "--") { # all done
9304 \begin_layout Plain Layout
9309 \begin_layout Plain Layout
9314 \begin_layout Plain Layout
9319 \begin_layout Plain Layout
9321 } else if (argv[Optind] !~ /^-[^:
9336 \begin_layout Plain Layout
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
9363 thisopt = substr(argv[Optind], _opti, 1)
9366 \begin_layout Plain Layout
9371 \begin_layout Plain Layout
9373 i = index(options, thisopt)
9376 \begin_layout Plain Layout
9381 \begin_layout Plain Layout
9386 \begin_layout Plain Layout
9388 printf("%c -- invalid option
9393 \begin_layout Plain Layout
9395 thisopt) > "/dev/stderr"
9398 \begin_layout Plain Layout
9400 if (_opti >= length(argv[Optind])) {
9403 \begin_layout Plain Layout
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
9438 \begin_layout Standard
9439 At this point, the option has been found and we need to know if it takes
9443 \begin_layout Standard
9444 \begin_inset listings
9448 \begin_layout Plain Layout
9450 if (substr(options, i + 1, 1) == ":") {
9453 \begin_layout Plain Layout
9455 # get option argument
9458 \begin_layout Plain Layout
9460 if (length(substr(argv[Optind], _opti + 1)) > 0)
9463 \begin_layout Plain Layout
9465 Optarg = substr(argv[Optind], _opti + 1)
9468 \begin_layout Plain Layout
9473 \begin_layout Plain Layout
9475 Optarg = argv[++Optind]
9478 \begin_layout Plain Layout
9483 \begin_layout Plain Layout
9488 \begin_layout Plain Layout
9493 \begin_layout Plain Layout
9495 if (_opti == 0 || _opti >= length(argv[Optind])) {
9498 \begin_layout Plain Layout
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
9530 A test program is built in, too
9537 \begin_layout Standard
9538 \begin_inset listings
9542 \begin_layout Plain Layout
9547 \begin_layout Plain Layout
9549 Opterr = 1 # default is to diagnose
9552 \begin_layout Plain Layout
9554 Optind = 1 # skip ARGV[0]
9557 \begin_layout Plain Layout
9562 \begin_layout Plain Layout
9567 \begin_layout Plain Layout
9569 while ((_go_c = getopt(ARGC, ARGV, "ab:cd")) != -1)
9572 \begin_layout Plain Layout
9574 printf("c = <%c>, optarg = <%s>
9579 \begin_layout Plain Layout
9584 \begin_layout Plain Layout
9586 printf("non-option arguments:
9591 \begin_layout Plain Layout
9593 for (; Optind < ARGC; Optind++)
9596 \begin_layout Plain Layout
9605 \begin_layout Plain Layout
9607 Optind, ARGV[Optind])
9610 \begin_layout Plain Layout
9615 \begin_layout Plain Layout
9625 \begin_layout Standard
9626 The entire getopt.awk is made out of these chunks in order
9633 \begin_layout Standard
9634 \begin_inset listings
9638 \begin_layout Plain Layout
9642 chunkref{getopt.awk-header}>
9645 \begin_layout Plain Layout
9649 \begin_layout Plain Layout
9653 chunkref{getopt.awk-notes}>
9656 \begin_layout Plain Layout
9660 chunkref{getopt.awk-getopt()}>
9663 \begin_layout Plain Layout
9667 chunkref{getopt.awk-begin}>
9675 \begin_layout Standard
9676 Although we only want the header and function:
9683 \begin_layout Standard
9684 \begin_inset listings
9688 \begin_layout Plain Layout
9690 # try: locate getopt.awk for the full original file
9693 \begin_layout Plain Layout
9695 # as part of your standard awk installation
9698 \begin_layout Plain Layout
9702 chunkref{getopt.awk-header}>
9705 \begin_layout Plain Layout
9709 \begin_layout Plain Layout
9713 chunkref{getopt.awk-getopt()}>
9721 \begin_layout Chapter
9722 Newfangle LaTeX source code
9725 \begin_layout Section
9729 \begin_layout Standard
9730 Here we define a Lyx .module file that makes it convenient to use LyX for
9731 writing such literate programs.
9734 \begin_layout Standard
9736 \begin_inset Flex CharStyle:Code
9739 \begin_layout Plain Layout
9745 can be installed in your personal
9746 \begin_inset Flex CharStyle:Code
9749 \begin_layout Plain Layout
9756 You will need to Tools Reconfigure so that LyX notices it.
9757 It adds a new format Chunk, which should precede every listing and contain
9763 ./newfangle.module,language=
9766 \begin_layout Standard
9767 \begin_inset listings
9771 \begin_layout Plain Layout
9775 DeclareLyXModule{Newfangle Literate Listings}
9778 \begin_layout Plain Layout
9783 \begin_layout Plain Layout
9785 # Newfangle literate listings allow one to write
9788 \begin_layout Plain Layout
9790 # literate programs after the fashion of noweb, but without having
9793 \begin_layout Plain Layout
9795 # to use noweave to generate the documentation.
9796 Instead the listings
9799 \begin_layout Plain Layout
9801 # package is extended in conjunction with the noweb package to implement
9804 \begin_layout Plain Layout
9806 # to code formating directly as latex.
9809 \begin_layout Plain Layout
9811 # The newfangle awk script
9814 \begin_layout Plain Layout
9819 \begin_layout Plain Layout
9823 \begin_layout Plain Layout
9828 \begin_layout Plain Layout
9832 \begin_layout Plain Layout
9837 \begin_layout Plain Layout
9841 chunkref{./newfangle.sty}>
9844 \begin_layout Plain Layout
9849 \begin_layout Plain Layout
9853 \begin_layout Plain Layout
9857 chunkref{chunkstyle}>
9860 \begin_layout Plain Layout
9864 \begin_layout Plain Layout
9876 \begin_layout Subsection
9880 \begin_layout Standard
9885 style is to make it easier for LyX users to provide the name to
9886 \begin_inset Flex CharStyle:Code
9889 \begin_layout Plain Layout
9898 Normally this requires right-clicking on the listing, choosing settings,
9899 advanced, and then typing
9900 \begin_inset Flex CharStyle:Code
9903 \begin_layout Plain Layout
9910 This has the further disadvantage that the name (and other options) are
9911 not generally visible during document editing.
9914 \begin_layout Standard
9915 The chunk style is defined as a LaTeX command, so that all text on the same
9916 line is passed to the LaTeX command
9917 \begin_inset Flex CharStyle:Code
9920 \begin_layout Plain Layout
9927 This makes it easy to parse using
9928 \begin_inset Flex CharStyle:Code
9931 \begin_layout Plain Layout
9937 , and easy to pass these options on to the listings package.
9938 The first word in a chunk section should be the chunk name, and will have
9940 \begin_inset Flex CharStyle:Code
9943 \begin_layout Plain Layout
9950 Any other words are accepted arguments to
9951 \begin_inset Flex CharStyle:Code
9954 \begin_layout Plain Layout
9965 \begin_layout Standard
9966 We set PassThru to 1 because the user is actually entering raw latex.
9973 \begin_layout Standard
9974 \begin_inset listings
9978 \begin_layout Plain Layout
9983 \begin_layout Plain Layout
9988 \begin_layout Plain Layout
9993 \begin_layout Plain Layout
9995 Margin First_Dynamic
9998 \begin_layout Plain Layout
10000 LeftMargin Chunk:xxx
10003 \begin_layout Plain Layout
10008 \begin_layout Plain Layout
10013 \begin_layout Plain Layout
10015 LabelString "Chunk:"
10018 \begin_layout Plain Layout
10023 \begin_layout Plain Layout
10028 \begin_layout Plain Layout
10037 \begin_layout Standard
10038 To make the label very visible we choose a larger font coloured red.
10041 \begin_layout Standard
10042 \begin_inset listings
10046 \begin_layout Plain Layout
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
10091 \begin_layout Subsection
10095 \begin_layout Standard
10096 We also define the Chunkref style which can be used to express cross references
10100 \begin_layout Chunk
10104 \begin_layout Standard
10105 \begin_inset listings
10109 \begin_layout Plain Layout
10111 InsetLayout Chunkref
10114 \begin_layout Plain Layout
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
10164 \begin_layout Section
10165 \begin_inset CommandInset label
10167 name "sec:Latex-Macros"
10174 \begin_layout Standard
10188 As noweb defines it's own
10189 \begin_inset Flex CharStyle:Code
10192 \begin_layout Plain Layout
10200 environment, we re-define the one that LyX logical markup module expects
10204 \begin_layout Chunk
10205 ./newfangle.sty,language=tex,basicstyle=
10210 \begin_layout Standard
10211 \begin_inset listings
10215 \begin_layout Plain Layout
10219 usepackage{listings}%
10222 \begin_layout Plain Layout
10229 \begin_layout Plain Layout
10236 \begin_layout Plain Layout
10252 \begin_layout Standard
10254 \begin_inset Flex CharStyle:Code
10257 \begin_layout Plain Layout
10264 \begin_inset Flex CharStyle:Code
10267 \begin_layout Plain Layout
10275 which will need renaming to
10276 \begin_inset Flex CharStyle:Code
10279 \begin_layout Plain Layout
10287 when I can do this without clashing with
10288 \begin_inset Flex CharStyle:Code
10291 \begin_layout Plain Layout
10302 \begin_layout Standard
10303 \begin_inset listings
10307 \begin_layout Plain Layout
10311 lstnewenvironment{Chunk}{
10323 \begin_layout Standard
10324 We also define a suitable
10325 \begin_inset Flex CharStyle:Code
10328 \begin_layout Plain Layout
10336 of parameters that suit the literate programming style after the fashion
10344 \begin_layout Standard
10345 \begin_inset listings
10349 \begin_layout Plain Layout
10353 lstset{numbers=left, stepnumber=5, numbersep=5pt,
10356 \begin_layout Plain Layout
10358 breaklines=false,basicstyle=
10363 \begin_layout Plain Layout
10375 \begin_layout Standard
10376 We also define a notangle-like mechanism for
10380 to LaTeX from the listing, and by which we can refer to other listings.
10382 \begin_inset Flex CharStyle:Code
10385 \begin_layout Plain Layout
10386 =<\SpecialChar \ldots{}
10392 sequence to contain LaTeX code, and include another like this chunk:
10393 \begin_inset Flex CharStyle:Code
10396 \begin_layout Plain Layout
10399 chunkref{chunkname}>
10406 \begin_inset Flex CharStyle:Code
10409 \begin_layout Plain Layout
10410 =<\SpecialChar \ldots{}
10416 is already defined to contain LaTeX code for this document --- this is
10421 document after all --- the code fragment below effectively contains the
10423 \begin_inset Flex CharStyle:Code
10426 \begin_layout Plain Layout
10433 To avoid problems with document generation, I had to declare an lstlistings
10435 \begin_inset Flex CharStyle:Code
10438 \begin_layout Plain Layout
10444 for this listing only; which in LyX was done by right-clicking the listings
10446 \begin_inset Flex CharStyle:Code
10449 \begin_layout Plain Layout
10455 \SpecialChar \menuseparator
10457 \begin_inset Flex CharStyle:Code
10460 \begin_layout Plain Layout
10469 \begin_layout Standard
10470 \begin_inset Note Note
10473 \begin_layout Plain Layout
10474 =< isn't enjoyed literally here, in a listing when the escape sequence is
10475 already defined as shown...
10476 we need to somehow escape this representation...
10484 \begin_layout Standard
10485 \begin_inset listings
10486 lstparams "escapeinside={}"
10490 \begin_layout Plain Layout
10494 lstset{escapeinside={=<}{>}}%
10502 \begin_layout Standard
10503 Although our macros will contain the @ symbol, they will be included in
10505 \begin_inset Flex CharStyle:Code
10508 \begin_layout Plain Layout
10516 section by LyX; however we keep the commented out
10517 \begin_inset Flex CharStyle:Code
10520 \begin_layout Plain Layout
10529 The listings package likes to centre the titles, but noweb titles are specially
10530 formatted and must be left aligned.
10531 The simplest way to do this turned out to be by removing the definition
10533 \begin_inset Flex CharStyle:Code
10536 \begin_layout Plain Layout
10545 This may interact badly if other listings want a regular title or caption.
10546 We remember the old maketitle in case we need it.
10549 \begin_layout Standard
10550 \begin_inset listings
10554 \begin_layout Plain Layout
10561 \begin_layout Plain Layout
10563 %somehow re-defining maketitle gives us a left-aligned title
10566 \begin_layout Plain Layout
10568 %which is extactly what our specially formatted title needs!
10571 \begin_layout Plain Layout
10579 newfangle@lst@maketitle
10584 \begin_layout Plain Layout
10600 \begin_layout Subsection
10601 \begin_inset CommandInset label
10603 name "sub:The-chunk-command"
10610 \begin_layout Standard
10611 Our chunk command accepts one argument, and calls
10612 \begin_inset Flex CharStyle:Code
10615 \begin_layout Plain Layout
10625 \begin_inset Flex CharStyle:Code
10628 \begin_layout Plain Layout
10636 will note the name, this is erased when the next
10637 \begin_inset Flex CharStyle:Code
10640 \begin_layout Plain Layout
10648 starts, so we make a note of this in
10649 \begin_inset Flex CharStyle:Code
10652 \begin_layout Plain Layout
10660 and restore in in lstlistings Init hook.
10663 \begin_layout Standard
10664 \begin_inset listings
10668 \begin_layout Plain Layout
10677 \begin_layout Plain Layout
10683 newfanglecaption},name=#1}%
10686 \begin_layout Plain Layout
10699 \begin_layout Plain Layout
10704 \begin_layout Plain Layout
10720 \begin_layout Subsubsection
10724 \begin_layout Standard
10725 Newfangle permits parameterized chunks, and requires the paramters to be
10726 specified as listings options.
10727 The newfangle script uses this, and although we don't do anything with
10728 these in the LaTeX code right now, we need to stop the listings package
10732 \begin_layout Standard
10733 \begin_inset listings
10737 \begin_layout Plain Layout
10747 newfangle@chunk@params{#1}}%
10755 \begin_layout Subsection
10756 The noweb styled caption
10759 \begin_layout Standard
10760 We define a public macro
10761 \begin_inset Flex CharStyle:Code
10764 \begin_layout Plain Layout
10772 which can be set as a regular title.
10774 \begin_inset Flex CharStyle:Code
10777 \begin_layout Plain Layout
10786 \begin_inset Flex CharStyle:Code
10789 \begin_layout Plain Layout
10797 at the appriate time when the caption is emitted.
10800 \begin_layout Standard
10801 \begin_inset listings
10805 \begin_layout Plain Layout
10815 newfangle@caption}%
10823 \begin_layout Standard
10824 \begin_inset Float figure
10830 \begin_layout Plain Layout
10831 \begin_inset Box Boxed
10840 height_special "totalheight"
10843 \begin_layout Plain Layout
10845 \begin_inset space \qquad{}
10853 \begin_inset Formula $\equiv+$
10857 \begin_inset space \qquad{}
10861 \begin_inset space \qquad{}
10865 \begin_inset space \qquad{}
10869 \begin_inset Formula $\triangleleft$
10873 \begin_inset space \quad{}
10877 \begin_inset Formula $\triangleright$
10883 \begin_layout Plain Layout
10886 In this example, the current chunk is 22c, and therefore the third chunk
10890 \begin_layout Plain Layout
10901 \begin_layout Plain Layout
10904 The first chunk with this name (19b) occurs as the second chunk on page
10908 \begin_layout Plain Layout
10911 The previous chunk (22d) with the same name is the second chunk on page
10915 \begin_layout Plain Layout
10918 The next chunk (24d) is the fourth chunk on page 24.
10921 \begin_layout Plain Layout
10922 \begin_inset Caption
10924 \begin_layout Plain Layout
10940 The general noweb output format compactly identifies the current chunk,
10941 and references to the first chunk, and the previous and next chunks that
10942 have the same name.
10946 \begin_layout Standard
10947 This means that we need to keep a counter for each chunk-name, that we use
10948 to count chunks of the same name.
10952 \begin_layout Subsection
10956 \begin_layout Standard
10957 It would be natural to have a counter for each chunk name, but TeX would
10958 soon run out of counters
10962 \begin_layout Plain Layout
10963 \SpecialChar \ldots{}
10968 run out of counters and so I had to re-write the LaTeX macros to share
10969 a counter as described here
10974 , so we have one counter which we save at the end of a chunk and restore
10975 at the beginning of a chunk.
10978 \begin_layout Standard
10979 \begin_inset listings
10983 \begin_layout Plain Layout
10987 newcounter{newfangle@chunkcounter}%
10995 \begin_layout Standard
10996 We construct the name of this variable to store the counter to be the text
10998 \begin_inset Flex CharStyle:Code
11001 \begin_layout Plain Layout
11007 prefixed onto the chunks own name, and store it in
11008 \begin_inset Flex CharStyle:Code
11011 \begin_layout Plain Layout
11023 \begin_layout Standard
11024 We save the counter like this:
11027 \begin_layout Chunk
11031 \begin_layout Standard
11032 \begin_inset listings
11036 \begin_layout Plain Layout
11052 arabic{newfangle@chunkcounter}}%
11060 \begin_layout Standard
11061 and restore the counter like this:
11064 \begin_layout Chunk
11068 \begin_layout Standard
11069 \begin_inset listings
11073 \begin_layout Plain Layout
11077 setcounter{newfangle@chunkcounter}{
11091 \begin_layout Chunk
11095 \begin_layout Standard
11096 If there does not already exist a variable whose name is stored in
11097 \begin_inset Flex CharStyle:Code
11100 \begin_layout Plain Layout
11108 , then we know we are the first chunk with this name, and then define a
11113 \begin_layout Standard
11114 Although chunks of the same name share a common counter, they must still
11116 We use is the internal name of the listing, suffixed by the counter value.
11117 So the first chunk might be
11118 \begin_inset Flex CharStyle:Code
11121 \begin_layout Plain Layout
11127 and the second chunk be
11128 \begin_inset Flex CharStyle:Code
11131 \begin_layout Plain Layout
11140 \begin_layout Standard
11141 We also calculate the name of the previous chunk if we can (before we increment
11142 the chunk counter).
11143 If this is the first chunk of that name, then
11144 \begin_inset Flex CharStyle:Code
11147 \begin_layout Plain Layout
11156 \begin_inset Flex CharStyle:Code
11159 \begin_layout Plain Layout
11167 which the noweb package will interpret as not existing.
11170 \begin_layout Standard
11171 \begin_inset listings
11175 \begin_layout Plain Layout
11181 newfangle@caption{%
11184 \begin_layout Plain Layout
11190 chunkcount{lst-chunk-
11195 \begin_layout Plain Layout
11204 \begin_layout Plain Layout
11219 \begin_layout Plain Layout
11223 setcounter{newfangle@chunkcounter}{
11232 \begin_layout Plain Layout
11243 \begin_layout Plain Layout
11248 \begin_layout Plain Layout
11252 setcounter{newfangle@chunkcounter}{
11261 \begin_layout Plain Layout
11271 arabic{newfangle@chunkcounter}}%
11274 \begin_layout Plain Layout
11284 \begin_layout Standard
11285 After incrementing the chunk counter, we then define the name of this chunk,
11286 as well as the name of the first chunk.
11289 \begin_layout Standard
11290 \begin_inset listings
11294 \begin_layout Plain Layout
11298 addtocounter{newfangle@chunkcounter}{1}%
11301 \begin_layout Plain Layout
11317 arabic{newfangle@chunkcounter}}%
11320 \begin_layout Plain Layout
11330 arabic{newfangle@chunkcounter}}%
11333 \begin_layout Plain Layout
11349 \begin_layout Standard
11350 We now need to calculate the name of the next chunk.
11351 We do this by temporarily skipping the counter on by one; however there
11352 may not actually be another chunk with this name! We detect this by also
11353 defining a label for each chunk based on the chunkname.
11354 If there is a next chunkname then it will define a label with that name.
11355 As labels are persistent, we can at least tell the second time LaTeX is
11357 If we don't find such a defined label then we define
11358 \begin_inset Flex CharStyle:Code
11361 \begin_layout Plain Layout
11370 \begin_inset Flex CharStyle:Code
11373 \begin_layout Plain Layout
11384 \begin_layout Standard
11385 \begin_inset listings
11389 \begin_layout Plain Layout
11393 addtocounter{newfangle@chunkcounter}{1}%
11396 \begin_layout Plain Layout
11406 arabic{newfangle@chunkcounter}}%
11409 \begin_layout Plain Layout
11413 @ifundefined{r@label-
11429 \begin_layout Standard
11430 The noweb package requires that we define a
11431 \begin_inset Flex CharStyle:Code
11434 \begin_layout Plain Layout
11442 for every chunk, with a unique name, which is then used to print out it's
11446 \begin_layout Standard
11447 We also define a regular label for this chunk, as was mentioned above when
11449 \begin_inset Flex CharStyle:Code
11452 \begin_layout Plain Layout
11461 This requires LaTeX to be run at least twice after new chunk sections are
11462 added --- but noweb requried that anyway.
11465 \begin_layout Standard
11466 \begin_inset listings
11470 \begin_layout Plain Layout
11479 \begin_layout Plain Layout
11481 % define this label for every chunk instance, so we
11484 \begin_layout Plain Layout
11486 % can tell when we are the last chunk of this name
11489 \begin_layout Plain Layout
11503 \begin_layout Standard
11504 We also try and add the chunk to the list of listings, but I'm afraid we
11505 don't do very well.
11506 We want each chunk name listing once, with all of it's references.
11509 \begin_layout Standard
11510 \begin_inset listings
11514 \begin_layout Plain Layout
11518 addcontentsline{lol}{lstlisting}{
11534 \begin_layout Standard
11535 We then call the noweb output macros in the same way that noweave generates
11536 them, except that we don't need to call
11537 \begin_inset Flex CharStyle:Code
11540 \begin_layout Plain Layout
11543 nwstartdeflinemarkup
11549 \begin_inset Flex CharStyle:Code
11552 \begin_layout Plain Layout
11560 -- and if we do it messes up the output somewhat.
11563 \begin_layout Standard
11564 \begin_inset listings
11568 \begin_layout Plain Layout
11575 \begin_layout Plain Layout
11580 \begin_layout Plain Layout
11587 \begin_layout Plain Layout
11596 \begin_layout Plain Layout
11601 \begin_layout Plain Layout
11606 \begin_layout Plain Layout
11611 \begin_layout Plain Layout
11618 \begin_layout Plain Layout
11625 \begin_layout Plain Layout
11630 \begin_layout Plain Layout
11639 \begin_layout Plain Layout
11643 @ifundefined{newfangle@chunk@params}{}{%
11646 \begin_layout Plain Layout
11650 newfangle@chunk@params)%
11653 \begin_layout Plain Layout
11658 \begin_layout Plain Layout
11669 \begin_layout Plain Layout
11678 \begin_layout Plain Layout
11683 \begin_layout Plain Layout
11688 \begin_layout Plain Layout
11693 \begin_layout Plain Layout
11712 \begin_layout Plain Layout
11716 nwstartdeflinemarkup%
11719 \begin_layout Plain Layout
11730 \begin_layout Plain Layout
11734 nwenddeflinemarkup%
11737 \begin_layout Plain Layout
11747 \begin_layout Standard
11748 Originally this was developed as a
11749 \begin_inset Flex CharStyle:Code
11752 \begin_layout Plain Layout
11758 aspect, in the Init hook, but it was found easier to affect the title without
11760 \begin_inset Flex CharStyle:Code
11763 \begin_layout Plain Layout
11766 lst@AddToHookExe{PreSet}
11771 is still required to set the listings name to the name passed to the
11772 \begin_inset Flex CharStyle:Code
11775 \begin_layout Plain Layout
11786 \begin_layout Standard
11787 \begin_inset listings
11791 \begin_layout Plain Layout
11795 lst@BeginAspect{newfangle}
11798 \begin_layout Plain Layout
11802 lst@Key{newfangle}{true}[t]{
11804 lstKV@SetIf{#1}{true}}
11807 \begin_layout Plain Layout
11811 lst@AddToHookExe{PreSet}{
11822 \begin_layout Plain Layout
11826 lst@AddToHook{Init}{}%
11831 \begin_layout Plain Layout
11843 \begin_layout Subsection
11847 \begin_layout Standard
11850 chunkref command which makes it easy to generate visual references to different
11854 \begin_layout Standard
11855 \begin_inset Tabular
11856 <lyxtabular version="3" rows="4" columns="2">
11858 <column alignment="center" valignment="top" width="0">
11859 <column alignment="center" valignment="top" width="0">
11861 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
11864 \begin_layout Plain Layout
11870 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
11873 \begin_layout Plain Layout
11881 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
11884 \begin_layout Plain Layout
11892 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
11895 \begin_layout Plain Layout
11899 \begin_layout Plain Layout
11915 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
11918 \begin_layout Plain Layout
11921 chunkref[3]{preamble}
11926 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
11929 \begin_layout Plain Layout
11933 \begin_layout Plain Layout
11937 chunkref[3]{preamble}
11949 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
11952 \begin_layout Plain Layout
11955 chunkref{preamble}[arg1, arg2]
11960 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
11963 \begin_layout Plain Layout
11967 \begin_layout Plain Layout
11971 chunkref{preamble}[arg1, arg2]
11989 \begin_layout Standard
11990 Chunkref can also be used within a code chunk to include another code chunk.
11991 The third optional parameter to chunkref is a comma sepatarated list of
11992 arguments, which will replace defined parameters in the chunkref.
11993 \begin_inset Note Note
11996 \begin_layout Plain Layout
11997 Darn it, if I have: =<
11999 chunkref{new-mode}[{chunks[chunk_name, "language"]},{mode}]> the inner braces
12000 (inside [ ]) cause _ to signify subscript even though we have lst@ReplaceIn
12008 \begin_layout Standard
12009 \begin_inset listings
12013 \begin_layout Plain Layout
12022 \begin_layout Plain Layout
12031 \begin_layout Plain Layout
12042 \begin_layout Plain Layout
12049 \begin_layout Plain Layout
12060 \begin_layout Plain Layout
12065 \begin_layout Plain Layout
12074 \begin_layout Plain Layout
12080 chunkref@i{#1}{#2}}{
12082 chunkref@i{#1}{#2}()}%
12085 \begin_layout Plain Layout
12090 \begin_layout Plain Layout
12096 chunkref@i#1#2(#3){%
12099 \begin_layout Plain Layout
12108 \begin_layout Plain Layout
12117 \begin_layout Plain Layout
12126 \begin_layout Plain Layout
12135 \begin_layout Plain Layout
12146 \begin_layout Plain Layout
12155 \begin_layout Plain Layout
12162 \begin_layout Plain Layout
12173 \begin_layout Plain Layout
12180 \begin_layout Plain Layout
12191 \begin_layout Plain Layout
12202 \begin_layout Plain Layout
12211 \begin_layout Plain Layout
12218 \begin_layout Plain Layout
12223 \begin_layout Plain Layout
12232 \begin_layout Plain Layout
12243 \begin_layout Plain Layout
12250 \begin_layout Plain Layout
12257 \begin_layout Plain Layout
12264 \begin_layout Plain Layout
12275 \begin_layout Plain Layout
12282 \begin_layout Plain Layout
12286 chunkref@args #3,)%
12289 \begin_layout Plain Layout
12296 \begin_layout Plain Layout
12305 \begin_layout Plain Layout
12310 \begin_layout Plain Layout
12315 \begin_layout Plain Layout
12324 \begin_layout Plain Layout
12334 \begin_layout Subsection
12338 \begin_layout Standard
12339 \begin_inset listings
12343 \begin_layout Plain Layout
12348 \begin_layout Plain Layout
12360 \begin_layout Chapter
12361 Extracting newfangle
12364 \begin_layout Section
12365 Extracting from Lyx
12368 \begin_layout Standard
12369 To extract from LyX, you will need to configure LyX as explained in section
12371 \begin_inset CommandInset ref
12373 reference "sub:Configuring-the-build"
12380 \begin_layout Standard
12381 \begin_inset CommandInset label
12383 name "lyx-build-script"
12387 And this lyx-build scrap will extract newfangle for me.
12390 \begin_layout Chunk
12391 lyx-build,language=sh
12394 \begin_layout Standard
12395 \begin_inset listings
12399 \begin_layout Plain Layout
12404 \begin_layout Plain Layout
12409 \begin_layout Plain Layout
12413 \begin_layout Plain Layout
12417 chunkref{lyx-build-helper}>
12420 \begin_layout Plain Layout
12422 cd $PROJECT_DIR || exit 1
12425 \begin_layout Plain Layout
12429 \begin_layout Plain Layout
12431 /usr/local/bin/newfangle -R./newfangle $TEX_SRC > ./newfangle
12434 \begin_layout Plain Layout
12436 /usr/local/bin/newfangle -R./newfangle.module $TEX_SRC > ./newfangle.module
12444 \begin_layout Standard
12445 With a lyx-build-helper
12448 \begin_layout Chunk
12449 lyx-build-helper,language=sh
12452 \begin_layout Standard
12453 \begin_inset listings
12457 \begin_layout Plain Layout
12459 PROJECT_DIR="$LYX_r"
12462 \begin_layout Plain Layout
12464 LYX_SRC="$PROJECT_DIR/${LYX_i%.tex}.lyx"
12467 \begin_layout Plain Layout
12472 \begin_layout Plain Layout
12474 TEX_SRC="$TEX_DIR/$LYX_i"
12482 \begin_layout Section
12483 Extracting from the command line
12486 \begin_layout Standard
12487 First you will need the tex output, then you can extract:
12490 \begin_layout Chunk
12491 lyx-build-manual,language=sh
12494 \begin_layout Standard
12495 \begin_inset listings
12499 \begin_layout Plain Layout
12501 lyx -e latex newfangle.lyx
12504 \begin_layout Plain Layout
12506 newfangle -R./newfangle newfangle.tex > ./newfangle
12509 \begin_layout Plain Layout
12511 newfangle -R./newfangle.module newfangle.tex > ./newfangle.module
12523 \begin_layout Chapter
12527 \begin_layout Chunk
12528 tests-sub,params=THING;colour
12531 \begin_layout Standard
12532 \begin_inset listings
12536 \begin_layout Plain Layout
12538 I see a ${THING} of
12541 \begin_layout Plain Layout
12546 \begin_layout Plain Layout
12550 chunkref{tests-sub-sub}(${colour})>
12558 \begin_layout Chunk
12559 tests-sub-sub,params=colour
12562 \begin_layout Standard
12563 \begin_inset listings
12567 \begin_layout Plain Layout
12569 a funny shade of ${colour}
12577 \begin_layout Chunk
12581 \begin_layout Standard
12582 \begin_inset listings
12586 \begin_layout Plain Layout
12588 What do you see? "=<
12590 chunkref{tests-sub}(joe, red)>"
12593 \begin_layout Plain Layout
12603 \begin_layout Standard
12604 Should generate output:
12607 \begin_layout Chunk
12611 \begin_layout Standard
12612 \begin_inset listings
12616 \begin_layout Plain Layout
12618 What do you see? "I see a joe of
12621 \begin_layout Plain Layout
12626 \begin_layout Plain Layout
12628 looking closer a funny shade of red"
12631 \begin_layout Plain Layout
12636 \begin_layout Plain Layout