From 29b2689e22f68c5235c3732f341e89ba586d9754 Mon Sep 17 00:00:00 2001 From: Sam Liddicott Date: Wed, 8 Jun 2011 21:57:08 +0100 Subject: [PATCH] Update file to use newer texmacs fangle format with explicit for new lines --- fangle.tm | 2594 +++++++++++++++++++++++++++++++------------------------------ 1 file changed, 1314 insertions(+), 1280 deletions(-) diff --git a/fangle.tm b/fangle.tm index bb6aedd..f66092c 100644 --- a/fangle.tm +++ b/fangle.tm @@ -81,37 +81,40 @@ not be too hard. <\nf-chunk|gpl3-copyright> - fangle - fully featured notangle replacement in awk + fangle - fully featured notangle replacement in awk - \; + - Copyright (C) 2009-2010 Sam Liddicott \sam@liddicott.com\ + Copyright (C) 2009-2010 Sam Liddicott + \sam@liddicott.com\ - \; + - This program is free software: you can redistribute it and/or modify + This program is free software: you can redistribute it and/or + modify - it under the terms of the GNU General Public License as published by + it under the terms of the GNU General Public License as published + by - the Free Software Foundation, either version 3 of the License, or + the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. + (at your option) any later version. - \; + - This program is distributed in the hope that it will be useful, + This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of + but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. \ See the + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. \ See the - GNU General Public License for more details. + GNU General Public License for more details. - \; + - You should have received a copy of the GNU General Public License + You should have received a copy of the GNU General Public License - along with this program. \ If not, see + along with this program. \ If not, see \http://www.gnu.org/licenses/\. @@ -741,23 +744,23 @@ In my pre-amble I usually specialise my code format with: <\nf-chunk|document-preamble> - \\lstset{ + \\lstset{ - numbers=left, stepnumber=1, numbersep=5pt, + numbers=left, stepnumber=1, numbersep=5pt, - breaklines=false, + breaklines=false, - basicstyle=\\footnotesize\\ttfamily, + basicstyle=\\footnotesize\\ttfamily, - numberstyle=\\tiny, + numberstyle=\\tiny, - language=C, + language=C, - columns=fullflexible, + columns=fullflexible, - numberfirstline=true + numberfirstline=true - } + } \; @@ -819,38 +822,38 @@ probable Lyx filename from the noweb file that Lyx generated. <\nf-chunk|lyx-build-helper> - PROJECT_DIR="$LYX_r" + PROJECT_DIR="$LYX_r" - LYX_SRC="$PROJECT_DIR/${LYX_i%.tex}.lyx" + LYX_SRC="$PROJECT_DIR/${LYX_i%.tex}.lyx" - TEX_DIR="$LYX_p" + TEX_DIR="$LYX_p" - TEX_SRC="$TEX_DIR/$LYX_i" + TEX_SRC="$TEX_DIR/$LYX_i" And then we can define a lyx-build fragment similar to the autoboot fragment <\nf-chunk|lyx-build> - #! /bin/sh + #! /bin/sh - =\\\chunkref{lyx-build-helper}\ + =\\\chunkref{lyx-build-helper}\ - cd $PROJECT_DIR \|\| exit 1 + cd $PROJECT_DIR \|\| exit 1 - \; + - #/usr/bin/fangle -filter ./notanglefix-filter \\ + #/usr/bin/fangle -filter ./notanglefix-filter \\ - # \ -R./Makefile.inc "../../noweb-lyx/noweb-lyx3.lyx" \\ + # \ -R./Makefile.inc "../../noweb-lyx/noweb-lyx3.lyx" \\ - # \ \| sed '/NOWEB_SOURCE=/s/=.*/=samba4-dfs.lyx/' \\ + # \ \| sed '/NOWEB_SOURCE=/s/=.*/=samba4-dfs.lyx/' \\ - # \ \ ./Makefile.inc + # \ \ ./Makefile.inc - # + # - #make -f ./Makefile.inc fangle_sources + #make -f ./Makefile.inc fangle_sources \; @@ -909,16 +912,16 @@ which are included in below. <\nf-chunk|./Makefile.inc> - + - + We first define a placeholder for to hold the name of this document. This will normally be passed on the command line. <\nf-chunk|Makefile.inc-vars> - LITERATE_SOURCE= + LITERATE_SOURCE= Fangle cannot process or documents directly, so the first @@ -947,24 +950,24 @@ have installed. <\nf-chunk|Makefile.inc-vars> - TEX_SOURCE=$(LYX_SOURCE:.lyx=.tex) + TEX_SOURCE=$(LYX_SOURCE:.lyx=.tex) - EXTRA_DIST+=$(TEX_SOURCE) + EXTRA_DIST+=$(TEX_SOURCE) We then specify that the source is to be generated from the source. <\nf-chunk|Makefile.inc-targets> - $(TEX_SOURCE): $(LYX_SOURCE) + $(TEX_SOURCE): $(LYX_SOURCE) - lyx -e latex $\ + lyx -e latex $\ - clean_tex: + clean_tex: - rm -f -- $(TEX_SOURCE) + rm -f -- $(TEX_SOURCE) - clean: clean_tex + clean: clean_tex > @@ -982,23 +985,23 @@ have installed. <\nf-chunk|Makefile.inc-vars> - TXT_SOURCE=$(LITERATE_SOURCE:.tm=.txt) + TXT_SOURCE=$(LITERATE_SOURCE:.tm=.txt) - EXTRA_DIST+=$(TXT_SOURCE) + EXTRA_DIST+=$(TXT_SOURCE) so multiple targets can be specified> <\nf-chunk|Makefile.inc-targets> - $(TXT_SOURCE): $(LITERATE_SOURCE) + $(TXT_SOURCE): $(LITERATE_SOURCE) - texmacs -c $\ $(TXT_SOURCE) -q + texmacs -c $\ $(TXT_SOURCE) -q - clean_txt: + clean_txt: - rm -f -- $(TXT_SOURCE) + rm -f -- $(TXT_SOURCE) - clean: clean_txt + clean: clean_txt @@ -1009,7 +1012,7 @@ . <\nf-chunk|Makefile.inc-vars> - FANGLE_SOURCE=$(TEX_SOURCE) $(TXT_SOURCE) + FANGLE_SOURCE=$(TEX_SOURCE) $(TXT_SOURCE) The literate document can result in any number of source files, but not all @@ -1035,21 +1038,21 @@ mount \ that I was using. <\nf-chunk|Makefile.inc-vars> - FANGLE_SOURCE_STAMP=$(FANGLE_SOURCE).stamp + FANGLE_SOURCE_STAMP=$(FANGLE_SOURCE).stamp <\nf-chunk|Makefile.inc-targets> - $(FANGLE_SOURCE_STAMP): $(FANGLE_SOURCE) \\ + $(FANGLE_SOURCE_STAMP): $(FANGLE_SOURCE) \\ - \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ $(FANGLE_SOURCES) ; \\ + \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ $(FANGLE_SOURCES) ; \\ - echo -n \ $(FANGLE_SOURCE_STAMP) + echo -n \ $(FANGLE_SOURCE_STAMP) - clean_stamp: + clean_stamp: - rm -f $(FANGLE_SOURCE_STAMP) + rm -f $(FANGLE_SOURCE_STAMP) - clean: clean_stamp + clean: clean_stamp @@ -1077,25 +1080,25 @@ know what to extact!> <\nf-chunk|Makefile.inc-vars> - FANGLE_PREFIX:=\\.\\/ + FANGLE_PREFIX:=\\.\\/ - FANGLE_SOURCES:=$(shell \\ + FANGLE_SOURCES:=$(shell \\ - \ \ fangle -r $(FANGLE_SOURCE) \|\\ + \ fangle -r $(FANGLE_SOURCE) \|\\ - \ \ sed -e 's/^[\][\]//;s/[\][\]$$//;/^$(FANGLE_PREFIX)/!d' + \ sed -e 's/^[\][\]//;s/[\][\]$$//;/^$(FANGLE_PREFIX)/!d' \\ - \ \ \ \ \ \ -e 's/^$(FANGLE_PREFIX)/\\.\\//' ) + \ \ \ \ \ -e 's/^$(FANGLE_PREFIX)/\\.\\//' ) The target below, is a helpful debugging target and shows the names of the files that would be extracted. <\nf-chunk|Makefile.inc-targets> - .PHONY: echo_fangle_sources + .PHONY: echo_fangle_sources - echo_fangle_sources: ; @echo $(FANGLE_SOURCES) + echo_fangle_sources: ; @echo $(FANGLE_SOURCES) We define a convenient target called so that @@ -1103,19 +1106,19 @@ literate document has been updated.\ <\nf-chunk|Makefile.inc-targets> - .PHONY: fangle_sources + .PHONY: fangle_sources - fangle_sources: $(FANGLE_SOURCE_STAMP) + fangle_sources: $(FANGLE_SOURCE_STAMP) And also a convenient target to remove extracted sources. <\nf-chunk|Makefile.inc-targets> - .PHONY: clean_fangle_sources + .PHONY: clean_fangle_sources - clean_fangle_sources: ; \\ + clean_fangle_sources: ; \\ - \ \ \ \ \ \ \ \ rm -f -- $(FANGLE_SOURCE_STAMP) $(FANGLE_SOURCES) + \ \ \ \ \ \ \ rm -f -- $(FANGLE_SOURCE_STAMP) $(FANGLE_SOURCES) We now look at the extraction of the source files. @@ -1127,7 +1130,7 @@ . <\nf-chunk|Makefile.inc-vars> - if_extension=$(if $(findstring $(suffix $(1)),$(2)),$(3),$(4)) + if_extension=$(if $(findstring $(suffix $(1)),$(2)),$(3),$(4)) For some source files like C files, we want to output the line number and @@ -1143,7 +1146,7 @@ this. <\nf-chunk|Makefile.inc-vars> - C_EXTENSIONS=.c .h + C_EXTENSIONS=.c .h We can then use the macro to define a macro which @@ -1152,11 +1155,11 @@ document.\ <\nf-chunk|Makefile.inc-vars> - TABS=8 + TABS=8 - nf_line=-L -T$(TABS) + nf_line=-L -T$(TABS) - fangle=fangle $(call if_extension,$(2),$(C_EXTENSIONS),$(nf_line)) + fangle=fangle $(call if_extension,$(2),$(C_EXTENSIONS),$(nf_line)) -R"$(2)" $(1) @@ -1166,9 +1169,9 @@ indent=> <\nf-chunk|Makefile.inc-vars> - indent_options=-npro -kr -i8 -ts8 -sob -l80 -ss -ncs + indent_options=-npro -kr -i8 -ts8 -sob -l80 -ss -ncs - indent=$(call if_extension,$(1),$(C_EXTENSIONS), \| indent + indent=$(call if_extension,$(1),$(C_EXTENSIONS), \| indent $(indent_options)) @@ -1179,15 +1182,15 @@ or if none or a few C source files have changed. <\nf-chunk|Makefile.inc-vars> - fangle_extract=@mkdir -p $(dir $(1)) && \\ + fangle_extract=@mkdir -p $(dir $(1)) && \\ - \ \ $(call fangle,$(2),$(1)) \ "$(1).tmp" && \\ + \ $(call fangle,$(2),$(1)) \ "$(1).tmp" && \\ - \ \ cat "$(1).tmp" $(indent) \| cpif "$(1)" \\ + \ cat "$(1).tmp" $(indent) \| cpif "$(1)" \\ - \ \ && rm -- "$(1).tmp" \|\| \\ + \ && rm -- "$(1).tmp" \|\| \\ - \ \ (echo error newfangling $(1) from $(2) ; exit 1) + \ (echo error newfangling $(1) from $(2) ; exit 1) We define a target which will extract or update all sources. To do this we @@ -1195,26 +1198,26 @@ the document. <\nf-chunk|Makefile.inc-vars> - define FANGLE_template + define FANGLE_template - \ \ $(1): $(2) + \ $(1): $(2) - $$(call fangle_extract,$(1),$(2)) + $$(call fangle_extract,$(1),$(2)) - \ \ FANGLE_TARGETS+=$(1) + \ FANGLE_TARGETS+=$(1) - endef + endef We then enumerate the discovered to generate a makefile rule for each one using the makefile template we defined above. <\nf-chunk|Makefile.inc-targets> - $(foreach source,$(FANGLE_SOURCES),\\ + $(foreach source,$(FANGLE_SOURCES),\\ - \ \ $(eval $(call FANGLE_template,$(source),$(FANGLE_SOURCE))) \\ + \ $(eval $(call FANGLE_template,$(source),$(FANGLE_SOURCE))) \\ - ) + ) These will all be built with . @@ -1222,7 +1225,7 @@ We also remove the generated sources on a make distclean. <\nf-chunk|Makefile.inc-targets> - _distclean: clean_fangle_sources + _distclean: clean_fangle_sources @@ -1237,7 +1240,7 @@ We produce a pdf file from the tex file. <\nf-chunk|Makefile.inc-vars> - FANGLE_PDF=$(TEX_SOURCE:.tex=.pdf) + FANGLE_PDF=$(TEX_SOURCE:.tex=.pdf) We run pdflatex twice to be sure that the contents and aux files are up to @@ -1245,17 +1248,17 @@ these files do not exist. <\nf-chunk|Makefile.inc-targets> - $(FANGLE_PDF): $(TEX_SOURCE) + $(FANGLE_PDF): $(TEX_SOURCE) - pdflatex $\ && pdflatex $\ + pdflatex $\ && pdflatex $\ - \; + - clean_pdf: + clean_pdf: - rm -f -- $(FANGLE_PDF) $(TEX_SOURCE:.tex=.toc) \\ + rm -f -- $(FANGLE_PDF) $(TEX_SOURCE:.tex=.toc) \\ - \ $(TEX_SOURCE:.tex=.log) $(TEX_SOURCE:.tex=.aux) + \ $(TEX_SOURCE:.tex=.log) $(TEX_SOURCE:.tex=.aux) > @@ -1263,7 +1266,7 @@ can produce a PDF file directly. <\nf-chunk|Makefile.inc-vars> - FANGLE_PDF=$(TEX_SOURCE:.tm=.pdf) + FANGLE_PDF=$(TEX_SOURCE:.tm=.pdf) <\todo> @@ -1278,15 +1281,15 @@ <\nf-chunk|Makefile.inc-targets> - $(FANGLE_PDF): $(TEXMACS_SOURCE) + $(FANGLE_PDF): $(TEXMACS_SOURCE) - texmacs -c $(TEXMACS_SOURCE) $\ -q + texmacs -c $(TEXMACS_SOURCE) $\ -q - \; + - clean_pdf: + clean_pdf: - rm -f -- $(FANGLE_PDF) + rm -f -- $(FANGLE_PDF) @@ -1295,34 +1298,34 @@ may later hold other output formats. <\nf-chunk|Makefile.inc-vars> - FANGLE_DOCS=$(FANGLE_PDF) + FANGLE_DOCS=$(FANGLE_PDF) We also define as a convenient phony target. <\nf-chunk|Makefile.inc-targets> - .PHONY: fangle_docs + .PHONY: fangle_docs - fangle_docs: $(FANGLE_DOCS) + fangle_docs: $(FANGLE_DOCS) - docs: fangle_docs + docs: fangle_docs And define a convenient which we add to the regular clean target <\nf-chunk|Makefile.inc-targets> - .PHONEY: clean_fangle_docs + .PHONEY: clean_fangle_docs - clean_fangle_docs: clean_tex clean_pdf + clean_fangle_docs: clean_tex clean_pdf - clean: clean_fangle_docs + clean: clean_fangle_docs - \; + - distclean_fangle_docs: clean_tex clean_fangle_docs + distclean_fangle_docs: clean_tex clean_fangle_docs - distclean: clean distclean_fangle_docs + distclean: clean distclean_fangle_docs @@ -1355,29 +1358,29 @@ <\nf-chunk|*> - #! /bin/sh + #! /bin/sh - \; + - MAKE_SRC="${1:-${NW_LYX:-../../noweb-lyx/noweb-lyx3.lyx}}" + MAKE_SRC="${1:-${NW_LYX:-../../noweb-lyx/noweb-lyx3.lyx}}" - MAKE_SRC=\0dirname "$MAKE_SRC"\0/\0basename "$MAKE_SRC" .lyx\0 + MAKE_SRC=\0dirname "$MAKE_SRC"\0/\0basename "$MAKE_SRC" .lyx\0 - NOWEB_SRC="${2:-${NOWEB_SRC:-$MAKE_SRC.lyx}}" + NOWEB_SRC="${2:-${NOWEB_SRC:-$MAKE_SRC.lyx}}" - lyx -e latex $MAKE_SRC + lyx -e latex $MAKE_SRC - \; + - fangle -R./Makefile.inc ${MAKE_SRC}.tex \\ + fangle -R./Makefile.inc ${MAKE_SRC}.tex \\ - \ \ \| sed "/FANGLE_SOURCE=/s/^/#/;T;aNOWEB_SOURCE=$FANGLE_SRC" \\ + \ \| sed "/FANGLE_SOURCE=/s/^/#/;T;aNOWEB_SOURCE=$FANGLE_SRC" \\ - \ \ \| cpif ./Makefile.inc + \ \| cpif ./Makefile.inc - \; + - make -f ./Makefile.inc fangle_sources + make -f ./Makefile.inc fangle_sources The general Makefile can be invoked with and can also @@ -1426,11 +1429,11 @@ by the projects Makefile. <\nf-chunk|makefile-glue> - module_srcdir=modules/module + module_srcdir=modules/module - MODULE_SOURCE=module.tm + MODULE_SOURCE=module.tm - MODULE_STAMP=$(MODULE_SOURCE).stamp + MODULE_STAMP=$(MODULE_SOURCE).stamp The existing build system may already have a build target for @@ -1442,7 +1445,7 @@ . <\nf-chunk|makefile-glue> - $(module_srcdir)/module.o: $(module_srcdir)/$(MODULE_STAMP) + $(module_srcdir)/module.o: $(module_srcdir)/$(MODULE_STAMP) The target for this new pre-requisite will be generated by a recursive make @@ -1450,9 +1453,9 @@ date, before it is built by the main projects makefile. <\nf-chunk|makefile-glue> - $(module_srcdir)/$(MODULE_STAMP): $(module_srcdir)/$(MODULE_SOURCE) + $(module_srcdir)/$(MODULE_STAMP): $(module_srcdir)/$(MODULE_SOURCE) - $(MAKE) -C $(module_srcdir) -f Makefile.inc fangle_sources + $(MAKE) -C $(module_srcdir) -f Makefile.inc fangle_sources LITERATE_SOURCE=$(MODULE_SOURCE) @@ -1461,35 +1464,35 @@ must use the same in our glue. <\nf-chunk|makefile-glue> - docs:: docs_module + docs:: docs_module - .PHONY: docs_module + .PHONY: docs_module - docs_module: + docs_module: - $(MAKE) -C $(module_srcdir) -f Makefile.inc docs + $(MAKE) -C $(module_srcdir) -f Makefile.inc docs LITERATE_SOURCE=$(MODULE_SOURCE) - \; + - clean:: clean_module + clean:: clean_module - .PHONEY: clean_module + .PHONEY: clean_module - clean_module: + clean_module: - $(MAKE) -C $(module_srcdir) -f Makefile.inc clean + $(MAKE) -C $(module_srcdir) -f Makefile.inc clean LITERATE_SOURCE=$(MODULE_SOURCE) - \; + - distclean:: distclean_module + distclean:: distclean_module - .PHONY: distclean_module + .PHONY: distclean_module - distclean_module: + distclean_module: - $(MAKE) -C $(module_srcdir) -f Makefile.inc distclean + $(MAKE) -C $(module_srcdir) -f Makefile.inc distclean LITERATE_SOURCE=$(MODULE_SOURCE) @@ -1502,9 +1505,9 @@ We use the copyright notice from chapter . <\nf-chunk|./fangle> - #! /usr/bin/awk -f + #! /usr/bin/awk -f - # + # We also use code from public domain getopt (1993 @@ -1512,46 +1515,46 @@ this appropriately. <\nf-chunk|./fangle> - \; + - # NOTE: Arnold Robbins public domain getopt for awk is also used: + # NOTE: Arnold Robbins public domain getopt for awk is also used: - + - \; + - + - \; + And include the following chunks (which are explained further on) to make up the program: <\nf-chunk|./fangle> - + - + - + - + - + - + - + - + - \; + - + - + - + @@ -1565,15 +1568,16 @@ an array to , and so this macro is also useful. <\nf-chunk|dump-array> - print "\\nDump: \\n--------\\n" \ "/dev/stderr"; + print "\\nDump: \\n--------\\n" \ + "/dev/stderr"; - for (_x in ) { + for (_x in ) { - \ \ print _x "=" [_x] "\\n" \ "/dev/stderr"; + \ print _x "=" [_x] "\\n" \ "/dev/stderr"; - } + } - print "========\\n" \ "/dev/stderr"; + print "========\\n" \ "/dev/stderr"; > @@ -1581,29 +1585,31 @@ Fatal errors are issued with the error function: <\nf-chunk|error()> - function error(message) + function error(message) - { + { - \ \ print "ERROR: " FILENAME ":" FNR " " message \ "/dev/stderr"; + \ print "ERROR: " FILENAME ":" FNR " " message \ + "/dev/stderr"; - \ \ exit 1; + \ exit 1; - } + } and likewise for non-fatal warnings: <\nf-chunk|error()> - function warning(message) + function warning(message) - { + { - \ \ print "WARNING: " FILENAME ":" FNR " " message \ "/dev/stderr"; + \ print "WARNING: " FILENAME ":" FNR " " message \ + "/dev/stderr"; - \ \ warnings++; + \ warnings++; - } + } @@ -1688,19 +1694,19 @@ multi-dimensional array path. <\nf-chunk|./fangle> - =\\\chunkref{get_chunk_args()}\ + =\\\chunkref{get_chunk_args()}\ <\nf-chunk|get_chunk_args()> - function get_chunk_args(text, values, + function get_chunk_args(text, values, - \ \ # optional parameters + \ # optional parameters - \ \ path, # hierarchical precursors + \ path, # hierarchical precursors - \ \ # local vars + \ # local vars - \ \ a, name) + \ a, name) The strategy is to parse the name, and then look for a value. If the value @@ -1712,36 +1718,36 @@ returning remaining text. <\nf-chunk|get_chunk_args()> - { + { - \ \ split("", next_chunk_args); + \ split("", next_chunk_args); - \ \ while(length(text)) { + \ while(length(text)) { - \ \ \ \ if (match(text, "^ *}(.*)", a)) { + \ \ \ if (match(text, "^ *}(.*)", a)) { - \ \ \ \ \ \ return a[1]; + \ \ \ \ \ return a[1]; - \ \ \ \ } + \ \ \ } - \ \ \ \ =\\\chunkref{parse-chunk-args}\ + \ \ \ =\\\chunkref{parse-chunk-args}\ - \ \ } + \ } - \ \ return text; + \ return text; - } + } We can see that the text could be inspected with this regex: <\nf-chunk|parse-chunk-args> - if (! match(text, " *([^,=]*[^,= ]) *(([,=]) *(([^,}]*) *,* *(.*))\|)$", - a)) { + if (! match(text, " *([^,=]*[^,= ]) *(([,=]) *(([^,}]*) *,* + *(.*))\|)$", a)) { - \ \ return text; + \ return text; - } + } and that will have the following values: @@ -1761,66 +1767,67 @@ that we need to recurse: <\nf-chunk|parse-chunk-args> - name=a[1]; + name=a[1]; - if (a[3] == "=") { + if (a[3] == "=") { - \ \ if (substr(a[4],1,1) == "{") { + \ if (substr(a[4],1,1) == "{") { - \ \ \ \ text = get_chunk_args(substr(a[4],2), values, path name SUBSEP); + \ \ \ text = get_chunk_args(substr(a[4],2), values, path name + SUBSEP); - \ \ } else { + \ } else { - \ \ \ \ values[path name]=a[5]; + \ \ \ values[path name]=a[5]; - \ \ \ \ text = a[6]; + \ \ \ text = a[6]; - \ \ } + \ } - } else { + } else { - \ \ values[path name]=""; + \ values[path name]=""; - \ \ text = a[2]; + \ text = a[2]; - } + } We can test this function like this: <\nf-chunk|gca-test.awk> - =\\\chunkref{get_chunk_args()}\ + =\\\chunkref{get_chunk_args()}\ - BEGIN { + BEGIN { - \ \ SUBSEP="."; + \ SUBSEP="."; - \; + - \ \ print get_chunk_args("name=freddie, foo={bar=baz, quux={quirk, + \ print get_chunk_args("name=freddie, foo={bar=baz, quux={quirk, a=fleeg}}, etc", a); - \ \ for (b in a) { + \ for (b in a) { - \ \ \ \ print "a[" b "] =\ " a[b]; + \ \ \ print "a[" b "] =\ " a[b]; - \ \ } + \ } - } + } which should give this output: <\nf-chunk|gca-test.awk-results> - a[foo.quux.quirk] =\\ + a[foo.quux.quirk] =\\ - a[foo.quux.a] =\ fleeg + a[foo.quux.a] =\ fleeg - a[foo.bar] =\ baz + a[foo.bar] =\ baz - a[etc] =\\ + a[etc] =\\ - a[name] =\ freddie + a[name] =\ freddie @@ -1875,29 +1882,30 @@ and used here with simplicity. <\nf-chunk|parse_chunk_args> - function parse_chunk_args(language, text, values, mode, + function parse_chunk_args(language, text, values, mode, - \ \ # local vars + \ # local vars - \ \ c, context, rest) + \ c, context, rest) - { + { - \ \ =\\\chunkref{new-mode-tracker}(context, language, mode)\ + \ =\\\chunkref{new-mode-tracker}(context, language, + mode)\ - \ \ rest = mode_tracker(context, text, values); + \ rest = mode_tracker(context, text, values); - \ \ # extract values + \ # extract values - \ \ for(c=1; c \= context[0, "values"]; c++) { + \ for(c=1; c \= context[0, "values"]; c++) { - \ \ \ \ values[c] = context[0, "values", c]; + \ \ \ values[c] = context[0, "values", c]; - \ \ } + \ } - \ \ return rest; + \ return rest; - } + } @@ -1919,23 +1927,23 @@ each case. <\nf-chunk|expand_chunk_args()> - function expand_chunk_args(text, params, args, \ + function expand_chunk_args(text, params, args, \ - \ \ p, text_array, next_text, v, t, l) + \ p, text_array, next_text, v, t, l) - { + { - \ \ if (split(text, text_array, "\\\\${")) { + \ if (split(text, text_array, "\\\\${")) { - \ \ \ \ =\\\chunkref{substitute-chunk-args}\ + \ \ \ =\\\chunkref{substitute-chunk-args}\ - \ \ } + \ } - \; + - \ \ return text; + \ return text; - } + } First, we produce an associative array of substitution values indexed by @@ -1943,11 +1951,11 @@ replacement values as we extract each name. <\nf-chunk|substitute-chunk-args> - for(p in params) { + for(p in params) { - \ \ v[params[p]]=args[p]; + \ v[params[p]]=args[p]; - } + } We accumulate substituted text in the variable text. As the first part of @@ -1957,7 +1965,7 @@ . <\nf-chunk-more> - text=text_array[1]; + text=text_array[1]; We then iterate over the remaining values in the array<\footnote> @@ -1967,11 +1975,11 @@ argument. <\nf-chunk|substitute-chunk-args> - for(t=2; t in text_array; t++) { + for(t=2; t in text_array; t++) { - \ \ =\\\chunkref{substitute-chunk-arg}\ + \ =\\\chunkref{substitute-chunk-arg}\ - } + } After the split on a valid parameter reference will consist @@ -1986,19 +1994,19 @@ interfered with unless the parameter name also matches. <\nf-chunk|substitute-chunk-arg> - if (match(text_array[t], "^([a-zA-Z_][a-zA-Z0-9_]*)}", l) && + if (match(text_array[t], "^([a-zA-Z_][a-zA-Z0-9_]*)}", l) && - \ \ \ \ l[1] in v)\ + \ \ \ l[1] in v)\ - { + { - \ \ text = text v[l[1]] substr(text_array[t], length(l[1])+2); + \ text = text v[l[1]] substr(text_array[t], length(l[1])+2); - } else { + } else { - \ \ text = text "${" text_array[t]; + \ text = text "${" text_array[t]; - } + } @@ -2066,9 +2074,9 @@ If that were then included in a chunk with language=make, like this: <\nf-chunk|example-makefile> - target: pre-req + target: pre-req - =\\\chunkref{example-sh}\ + =\\\chunkref{example-sh}\ We would need the output to look like this --- note the : @@ -2144,53 +2152,54 @@ <\nf-chunk|common-mode-definitions> - modes[${language}, "", \ "submodes" ]="\\\\\\\\\|\\"\|'\|{\|\\\\(\|\\\\["; + modes[${language}, "", \ "submodes" + ]="\\\\\\\\\|\\"\|'\|{\|\\\\(\|\\\\["; In the default mode, a comma surrounded by un-important white space is a delimiter of language items. <\nf-chunk|common-mode-definitions> - modes[${language}, "", \ "delimiters"]=" *, *"; + modes[${language}, "", \ "delimiters"]=" *, *"; and should pass this test: <\nf-chunk|test:mode-definitions> - parse_chunk_args("c-like", "1,2,3", a, ""); + parse_chunk_args("c-like", "1,2,3", a, ""); - if (a[1] != "1") e++; + if (a[1] != "1") e++; - if (a[2] != "2") e++; + if (a[2] != "2") e++; - if (a[3] != "3") e++; + if (a[3] != "3") e++; - if (length(a) != 3) e++; + if (length(a) != 3) e++; - =\\\chunkref{pca-test.awk:summary}\ + =\\\chunkref{pca-test.awk:summary}\ - \; + - parse_chunk_args("c-like", "joe, red", a, ""); + parse_chunk_args("c-like", "joe, red", a, ""); - if (a[1] != "joe") e++; + if (a[1] != "joe") e++; - if (a[2] != "red") e++; + if (a[2] != "red") e++; - if (length(a) != 2) e++; + if (length(a) != 2) e++; - =\\\chunkref{pca-test.awk:summary}\ + =\\\chunkref{pca-test.awk:summary}\ - \; + - parse_chunk_args("c-like", "${colour}", a, ""); + parse_chunk_args("c-like", "${colour}", a, ""); - if (a[1] != "${colour}") e++; + if (a[1] != "${colour}") e++; - if (length(a) != 1) e++; + if (length(a) != 1) e++; - =\\\chunkref{pca-test.awk:summary}\ + =\\\chunkref{pca-test.awk:summary}\ Nested modes are identified by a backslash, a double or single quote, @@ -2228,14 +2237,14 @@ the string. <\nf-chunk|mode:common-string> - modes[${language}, "\\\\", "terminators"]="."; + modes[${language}, "\\\\", "terminators"]="."; Otherwise, the string will be terminated by the same character that commenced it. <\nf-chunk|mode:common-string> - modes[${language}, ${quote}, "terminators"]=${quote}; + modes[${language}, ${quote}, "terminators"]=${quote}; In C type languages, certain escape sequences exist in strings. We need to @@ -2252,10 +2261,10 @@ literal . <\nf-chunk-more> - escapes[${language}, ${quote}, ++escapes[${language}, ${quote}], + escapes[${language}, ${quote}, ++escapes[${language}, ${quote}], "s"]="\\\\\\\\"; - escapes[${language}, ${quote}, \ \ escapes[${language}, ${quote}], + escapes[${language}, ${quote}, \ \ escapes[${language}, ${quote}], "r"]="\\\\\\\\"; @@ -2263,20 +2272,20 @@ backslash, otherwise it would terminate the string unexpectedly. <\nf-chunk-more> - escapes[${language}, ${quote}, ++escapes[${language}, ${quote}], + escapes[${language}, ${quote}, ++escapes[${language}, ${quote}], "s"]=${quote}; - escapes[${language}, ${quote}, \ \ escapes[${language}, ${quote}], + escapes[${language}, ${quote}, \ \ escapes[${language}, ${quote}], "r"]="\\\\" ${quote}; Any newlines in the string, must be replaced by . <\nf-chunk-more> - escapes[${language}, ${quote}, ++escapes[${language}, ${quote}], + escapes[${language}, ${quote}, ++escapes[${language}, ${quote}], "s"]="\\n"; - escapes[${language}, ${quote}, \ \ escapes[${language}, ${quote}], + escapes[${language}, ${quote}, \ \ escapes[${language}, ${quote}], "r"]="\\\\n"; @@ -2284,25 +2293,26 @@ quotes. <\nf-chunk|common-mode-definitions> - =\\\chunkref{mode:common-string}(${language}, + =\\\chunkref{mode:common-string}(${language}, "\\textbackslash{}"")\ - =\\\chunkref{mode:common-string}(${language}, "'")\ + =\\\chunkref{mode:common-string}(${language}, "'")\ Working strings should pass this test: <\nf-chunk|test:mode-definitions> - parse_chunk_args("c-like", "say \\"I said, \\\\\\"Hello, how are + parse_chunk_args("c-like", "say \\"I said, \\\\\\"Hello, how are you\\\\\\".\\", for me", a, ""); - if (a[1] != "say \\"I said, \\\\\\"Hello, how are you\\\\\\".\\"") e++; + if (a[1] != "say \\"I said, \\\\\\"Hello, how are you\\\\\\".\\"") + e++; - if (a[2] != "for me") e++; + if (a[2] != "for me") e++; - if (length(a) != 2) e++; + if (length(a) != 2) e++; - =\\\chunkref{pca-test.awk:summary}\ + =\\\chunkref{pca-test.awk:summary}\ @@ -2311,39 +2321,41 @@ braces are closed by an alternate character. <\nf-chunk|mode:common-brackets> - modes[, , \ "submodes" + modes[, , \ "submodes" ]="\\\\\\\\\|\\"\|{\|\\\\(\|\\\\[\|'\|/\\\\*"; - modes[, , \ "delimiters"]=" *, *"; + modes[, , \ "delimiters"]=" *, *"; - modes[, , \ "terminators"]=; + modes[, , + \ "terminators"]=; > Note that the open is NOT a regex but the close token IS. <\nf-chunk|common-mode-definitions> - =\\\chunkref{mode:common-brackets}(${language}, "{", "}")\ + =\\\chunkref{mode:common-brackets}(${language}, "{", + "}")\ - =\\\chunkref{mode:common-brackets}(${language}, "[", + =\\\chunkref{mode:common-brackets}(${language}, "[", "\\textbackslash{}\\textbackslash{}]")\ - =\\\chunkref{mode:common-brackets}(${language}, "(", + =\\\chunkref{mode:common-brackets}(${language}, "(", "\\textbackslash{}\\textbackslash{})")\ <\nf-chunk|mode:add-submode> - modes[${language}, ${mode}, "submodes"] = modes[${language}, ${mode}, - "submodes"] "\|" ${submode}; + modes[${language}, ${mode}, "submodes"] = modes[${language}, + ${mode}, "submodes"] "\|" ${submode}; > <\nf-chunk|mode:add-escapes> - escapes[${language}, ${mode}, ++escapes[${language}, ${mode}], + escapes[${language}, ${mode}, ++escapes[${language}, ${mode}], "s"]=${search}; - escapes[${language}, ${mode}, \ \ escapes[${language}, ${mode}], + escapes[${language}, ${mode}, \ \ escapes[${language}, ${mode}], "r"]=${replace}; > @@ -2355,18 +2367,18 @@ style comments to be added to any language: <\nf-chunk|mode:multi-line-comments> - =\\\chunkref{mode:add-submode}(${language}, "", + =\\\chunkref{mode:add-submode}(${language}, "", "/\\textbackslash{}\\textbackslash{}*")\ - modes[${language}, "/*", "terminators"]="\\\\*/"; + modes[${language}, "/*", "terminators"]="\\\\*/"; > <\nf-chunk|mode:single-line-slash-comments> - =\\\chunkref{mode:add-submode}(${language}, "", "//")\ + =\\\chunkref{mode:add-submode}(${language}, "", "//")\ - modes[${language}, "//", "terminators"]="\\n"; + modes[${language}, "//", "terminators"]="\\n"; - =\\\chunkref{mode:add-escapes}(${language}, "//", + =\\\chunkref{mode:add-escapes}(${language}, "//", "\\textbackslash{}n", "\\textbackslash{}n//")\ @@ -2377,11 +2389,12 @@ hacky work-arounds in the parser for now> <\nf-chunk|mode:add-hash-comments> - =\\\chunkref{mode:add-submode}(${language}, "", "\\#")\ + =\\\chunkref{mode:add-submode}(${language}, "", + "\\#")\ - modes[${language}, "#", "terminators"]="\\n"; + modes[${language}, "#", "terminators"]="\\n"; - =\\\chunkref{mode:add-escapes}(${language}, "\\#", + =\\\chunkref{mode:add-escapes}(${language}, "\\#", "\\textbackslash{}n", "\\textbackslash{}n\\#")\ > @@ -2389,46 +2402,47 @@ multi-line <\nf-chunk|mode:add-hash-defines> - =\\\chunkref{mode:add-submode}(${language}, "", "\\#")\ + =\\\chunkref{mode:add-submode}(${language}, "", + "\\#")\ - modes[${language}, "#", "submodes" ]="\\\\\\\\"; + modes[${language}, "#", "submodes" ]="\\\\\\\\"; - modes[${language}, "#", "terminators"]="\\n"; + modes[${language}, "#", "terminators"]="\\n"; - =\\\chunkref{mode:add-escapes}(${language}, "\\#", + =\\\chunkref{mode:add-escapes}(${language}, "\\#", "\\textbackslash{}n", "\\textbackslash{}\\textbackslash{}\\textbackslash{}\\textbackslash{}\\textbackslash{}n")\ > <\nf-chunk|mode:quote-dollar-escape> - escapes[${language}, ${quote}, ++escapes[${language}, ${quote}], + escapes[${language}, ${quote}, ++escapes[${language}, ${quote}], "s"]="\\\\$"; - escapes[${language}, ${quote}, \ \ escapes[${language}, ${quote}], + escapes[${language}, ${quote}, \ \ escapes[${language}, ${quote}], "r"]="\\\\$"; > We can add these definitions to various languages <\nf-chunk|mode-definitions> - > + > - \; + - > + > - =\\\chunkref{mode:multi-line-comments}("c")\ + =\\\chunkref{mode:multi-line-comments}("c")\ - =\\\chunkref{mode:single-line-slash-comments}("c")\ + =\\\chunkref{mode:single-line-slash-comments}("c")\ - =\\\chunkref{mode:add-hash-defines}("c")\ + =\\\chunkref{mode:add-hash-defines}("c")\ - \; + - =\\\chunkref{common-mode-definitions}("awk")\ + =\\\chunkref{common-mode-definitions}("awk")\ - =\\\chunkref{mode:add-hash-comments}("awk")\ + =\\\chunkref{mode:add-hash-comments}("awk")\ - =\\\chunkref{mode:add-naked-regex}("awk")\ + =\\\chunkref{mode:add-naked-regex}("awk")\ The awk definitions should allow a comment block like this: @@ -2437,31 +2451,31 @@ =\\\chunkref{test:comment-text}\|awk|> <\nf-chunk|test:comment-text> - Now is the time for + Now is the time for - the quick brown fox to bring lemonade + the quick brown fox to bring lemonade - to the party + to the party to come out like this: <\nf-chunk|test:comment-quote:result> - # Comment: Now is the time for + # Comment: Now is the time for - #the quick brown fox to bring lemonade + #the quick brown fox to bring lemonade - #to the party + #to the party The C definition for such a block should have it come out like this: <\nf-chunk|test:comment-quote:C-result> - # Comment: Now is the time for\\ + # Comment: Now is the time for\\ - the quick brown fox to bring lemonade\\ + the quick brown fox to bring lemonade\\ - to the party + to the party @@ -2476,20 +2490,20 @@ character, but some other more fully qualified name. <\nf-chunk|mode:add-naked-regex> - =\\\chunkref{mode:add-submode}(${language}, "", + =\\\chunkref{mode:add-submode}(${language}, "", "/\\textbackslash{}\\textbackslash{}\\^")\ - modes[${language}, "/^", "terminators"]="/"; + modes[${language}, "/^", "terminators"]="/"; > <\nf-chunk|mode-definitions> - =\\\chunkref{common-mode-definitions}("perl")\ + =\\\chunkref{common-mode-definitions}("perl")\ - =\\\chunkref{mode:multi-line-comments}("perl")\ + =\\\chunkref{mode:multi-line-comments}("perl")\ - =\\\chunkref{mode:add-hash-comments}("perl")\ + =\\\chunkref{mode:add-hash-comments}("perl")\ Still need to add add , submode , terminate both @@ -2499,16 +2513,16 @@ <\nf-chunk|mode-definitions> - =\\\chunkref{common-mode-definitions}("sh")\ + =\\\chunkref{common-mode-definitions}("sh")\ - #\\\chunkref{mode:common-string}("sh", + #\\\chunkref{mode:common-string}("sh", "\\textbackslash{}"")\ - #\\\chunkref{mode:common-string}("sh", "'")\ + #\\\chunkref{mode:common-string}("sh", "'")\ - =\\\chunkref{mode:add-hash-comments}("sh")\ + =\\\chunkref{mode:add-hash-comments}("sh")\ - =\\\chunkref{mode:quote-dollar-escape}("sh", "\\"")\ + =\\\chunkref{mode:quote-dollar-escape}("sh", "\\"")\ @@ -2517,36 +2531,36 @@ processed due to a mode terminator being found. <\nf-chunk|test:mode-definitions> - rest = parse_chunk_args("c-like", "1, 2, 3) spare", a, "("); + rest = parse_chunk_args("c-like", "1, 2, 3) spare", a, "("); - if (a[1] != 1) e++; + if (a[1] != 1) e++; - if (a[2] != 2) e++; + if (a[2] != 2) e++; - if (a[3] != 3) e++; + if (a[3] != 3) e++; - if (length(a) != 3) e++; + if (length(a) != 3) e++; - if (rest != " spare") e++; + if (rest != " spare") e++; - =\\\chunkref{pca-test.awk:summary}\ + =\\\chunkref{pca-test.awk:summary}\ We must also be able to parse the example given earlier. <\nf-chunk|test:mode-definitions> - parse_chunk_args("c-like", "things[x, y], get_other_things(a, + parse_chunk_args("c-like", "things[x, y], get_other_things(a, \\"(all)\\"), 99", a, "("); - if (a[1] != "things[x, y]") e++; + if (a[1] != "things[x, y]") e++; - if (a[2] != "get_other_things(a, \\"(all)\\")") e++; + if (a[2] != "get_other_things(a, \\"(all)\\")") e++; - if (a[3] != "99") e++; + if (a[3] != "99") e++; - if (length(a) != 3) e++; + if (length(a) != 3) e++; - =\\\chunkref{pca-test.awk:summary}\ + =\\\chunkref{pca-test.awk:summary}\ @@ -2557,24 +2571,24 @@ when passed an empty hash will intialize it. <\nf-chunk|new-mode-tracker()> - function new_mode_tracker(context, language, mode) { + function new_mode_tracker(context, language, mode) { - \ \ context[""] = 0; + \ context[""] = 0; - \ \ context[0, "language"] = language; + \ context[0, "language"] = language; - \ \ context[0, "mode"] = mode; + \ context[0, "mode"] = mode; - } + } Because awk functions cannot return an array, we must create the array first and pass it in, so we have a fangle macro to do this: <\nf-chunk|new-mode-tracker> - =\\\chunkref{awk-delete-array}(${context})\ + =\\\chunkref{awk-delete-array}(${context})\ - new_mode_tracker(${context}, ${language}, ${mode}); + new_mode_tracker(${context}, ${language}, ${mode}); > @@ -2583,119 +2597,119 @@ current language <\nf-chunk|mode_tracker> - function push_mode_tracker(context, language, mode, + function push_mode_tracker(context, language, mode, - \ \ # local vars + \ # local vars - \ \ top) + \ top) - { + { - \ \ if (! ("" in context)) { + \ if (! ("" in context)) { - \ \ \ \ =\\\chunkref{new-mode-tracker}(context, language, + \ \ \ =\\\chunkref{new-mode-tracker}(context, language, mode)\ - \ \ } else { + \ } else { - \ \ \ \ top = context[""]; + \ \ \ top = context[""]; - \ \ \ \ if (context[top, "language"] == language && mode=="") mode = + \ \ \ if (context[top, "language"] == language && mode=="") mode = context[top, "mode"]; - \ \ \ \ top++; + \ \ \ top++; - \ \ \ \ context[top, "language"] = language; + \ \ \ context[top, "language"] = language; - \ \ \ \ context[top, "mode"] = mode; + \ \ \ context[top, "mode"] = mode; - \ \ \ \ context[""] = top; + \ \ \ context[""] = top; - \ \ } + \ } - } + } <\nf-chunk|mode_tracker> - function dump_mode_tracker(context, \ + function dump_mode_tracker(context, \ - \ \ c, d) + \ c, d) - { + { - \ \ for(c=0; c \= context[""]; c++) { + \ for(c=0; c \= context[""]; c++) { - \ \ \ \ printf(" %2d \ \ %s:%s\\n", c, context[c, "language"], context[c, - "mode"]) \ "/dev/stderr"; + \ \ \ printf(" %2d \ \ %s:%s\\n", c, context[c, "language"], + context[c, "mode"]) \ "/dev/stderr"; - \ \ \ \ for(d=1; ( (c, "values", d) in context); d++) { + \ \ \ for(d=1; ( (c, "values", d) in context); d++) { - \ \ \ \ \ \ printf(" \ \ %2d %s\\n", d, context[c, "values", d]) \ - "/dev/stderr"; + \ \ \ \ \ printf(" \ \ %2d %s\\n", d, context[c, "values", d]) + \ "/dev/stderr"; - \ \ \ \ } + \ \ \ } - \ \ } + \ } - } + } <\nf-chunk|mode_tracker> - function finalize_mode_tracker(context) + function finalize_mode_tracker(context) - { + { - \ \ if ( ("" in context) && context[""] != 0) return 0; + \ if ( ("" in context) && context[""] != 0) return 0; - \ \ return 1; + \ return 1; - } + } This implies that any chunk must be syntactically whole; for instance, this is fine: <\nf-chunk|test:whole-chunk> - if (1) { + if (1) { - \ \ =\\\chunkref{test:say-hello}\ + \ =\\\chunkref{test:say-hello}\ - } + } <\nf-chunk|test:say-hello> - print "hello"; + print "hello"; But this is not fine; the chunk is not properly cromulent. <\nf-chunk|test:partial-chunk> - if (1) { + if (1) { - \ \ =\\\chunkref{test:hidden-else}\ + \ =\\\chunkref{test:hidden-else}\ - } + } <\nf-chunk|test:hidden-else> - \ \ print "I'm fine"; + \ print "I'm fine"; - } else { + } else { - \ \ print "I'm not"; + \ print "I'm not"; These tests will check for correct behaviour: <\nf-chunk|test:cromulence> - echo Cromulence test + echo Cromulence test - passtest $FANGLE -Rtest:whole-chunk $TEX_SRC &\/dev/null \|\| ( - echo "Whole chunk failed" && exit 1 ) + passtest $FANGLE -Rtest:whole-chunk $TEX_SRC &\/dev/null \|\| + ( echo "Whole chunk failed" && exit 1 ) - failtest $FANGLE -Rtest:partial-chunk $TEX_SRC &\/dev/null \|\| ( - echo "Partial chunk failed" && exit 1 ) + failtest $FANGLE -Rtest:partial-chunk $TEX_SRC &\/dev/null + \|\| ( echo "Partial chunk failed" && exit 1 ) @@ -2706,79 +2720,79 @@ psuedo-recursion using our own stack based on a hash. <\nf-chunk|mode_tracker()> - function mode_tracker(context, text, values,\ + function mode_tracker(context, text, values,\ - \ \ # optional parameters + \ # optional parameters - \ \ # local vars + \ # local vars - \ \ mode, submodes, language, + \ mode, submodes, language, - \ \ cindex, c, a, part, item, name, result, new_values, new_mode,\ + \ cindex, c, a, part, item, name, result, new_values, new_mode,\ - \ \ delimiters, terminators) + \ delimiters, terminators) - { + { We could be re-commencing with a valid context, so we need to setup the state according to the last context. <\nf-chunk|mode_tracker()> - \ \ cindex = context[""] + 0; + \ cindex = context[""] + 0; - \ \ mode = context[cindex, "mode"]; + \ mode = context[cindex, "mode"]; - \ \ language = context[cindex, "language" ]; + \ language = context[cindex, "language" ]; First we construct a single large regex combining the possible sub-modes for the current mode along with the terminators for the current mode. <\nf-chunk|parse_chunk_args-reset-modes> - \ \ submodes=modes[language, mode, "submodes"]; + \ submodes=modes[language, mode, "submodes"]; - \; + - \ \ if ((language, mode, "delimiters") in modes) { + \ if ((language, mode, "delimiters") in modes) { - \ \ \ \ delimiters = modes[language, mode, "delimiters"]; + \ \ \ delimiters = modes[language, mode, "delimiters"]; - \ \ \ \ if (length(submodes)\0) submodes = submodes "\|"; + \ \ \ if (length(submodes)\0) submodes = submodes "\|"; - \ \ \ \ submodes=submodes delimiters; + \ \ \ submodes=submodes delimiters; - \ \ } else delimiters=""; + \ } else delimiters=""; - \ \ if ((language, mode, "terminators") in modes) { + \ if ((language, mode, "terminators") in modes) { - \ \ \ \ terminators = modes[language, mode, "terminators"]; + \ \ \ terminators = modes[language, mode, "terminators"]; - \ \ \ \ if (length(submodes)\0) submodes = submodes "\|"; + \ \ \ if (length(submodes)\0) submodes = submodes "\|"; - \ \ \ \ submodes=submodes terminators; + \ \ \ submodes=submodes terminators; - \ \ } else terminators=""; + \ } else terminators=""; If we don't find anything to match on --- probably because the language is not supported --- then we return the entire text without matching anything. <\nf-chunk|parse_chunk_args-reset-modes> - \ if (! length(submodes)) return text; + if (! length(submodes)) return text; <\nf-chunk|mode_tracker()> - =\\\chunkref{parse_chunk_args-reset-modes}\ + =\\\chunkref{parse_chunk_args-reset-modes}\ We then iterate the text (until there is none left) looking for sub-modes or terminators in the regex. <\nf-chunk|mode_tracker()> - \ \ while((cindex \= 0) && length(text)) { + \ while((cindex \= 0) && length(text)) { - \ \ \ \ if (match(text, "(" submodes ")", a)) { + \ \ \ if (match(text, "(" submodes ")", a)) { A bug that creeps in regularly during development is bad regexes of zero @@ -2786,15 +2800,15 @@ catch that right away with this test. <\nf-chunk|mode_tracker()> - \ \ \ \ \ \ if (RLENGTH\1) { + \ \ \ \ \ if (RLENGTH\1) { - \ \ \ \ \ \ \ \ error(sprintf("Internal error, matched zero length + \ \ \ \ \ \ \ error(sprintf("Internal error, matched zero length submode, should be impossible - likely regex computation error\\n" \\ - \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ "Language=%s\\nmode=%s\\nmatch=%s\\n", + \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ "Language=%s\\nmode=%s\\nmatch=%s\\n", language, mode, submodes)); - \ \ \ \ \ \ } + \ \ \ \ \ } part is defined as the text up to the sub-mode or terminator, and this is @@ -2806,66 +2820,68 @@ \ >> <\nf-chunk|mode_tracker()> - \ \ \ \ \ \ part = substr(text, 1, RSTART -1); + \ \ \ \ \ part = substr(text, 1, RSTART -1); - \ \ \ \ \ \ item = item part; + \ \ \ \ \ item = item part; We must now determine what was matched. If it was a terminator, then we must restore the previous mode. <\nf-chunk|mode_tracker()> - \ \ \ \ \ \ if (match(a[1], "^" terminators "$")) { + \ \ \ \ \ if (match(a[1], "^" terminators "$")) { - #printf("%2d EXIT \ MODE [%s] by [%s] [%s]\\n", cindex, mode, a[1], text) - \ "/dev/stderr" + #printf("%2d EXIT \ MODE [%s] by [%s] [%s]\\n", cindex, mode, a[1], + text) \ "/dev/stderr" - \ \ \ \ \ \ \ \ context[cindex, "values", ++context[cindex, "values"]] = - item; + \ \ \ \ \ \ \ context[cindex, "values", ++context[cindex, + "values"]] = item; - \ \ \ \ \ \ \ \ delete context[cindex]; + \ \ \ \ \ \ \ delete context[cindex]; - \ \ \ \ \ \ \ \ context[""] = --cindex; + \ \ \ \ \ \ \ context[""] = --cindex; - \ \ \ \ \ \ \ \ if (cindex\=0) { + \ \ \ \ \ \ \ if (cindex\=0) { - \ \ \ \ \ \ \ \ \ \ mode = context[cindex, "mode"]; + \ \ \ \ \ \ \ \ \ mode = context[cindex, "mode"]; - \ \ \ \ \ \ \ \ \ \ language = context[cindex, "language"]; + \ \ \ \ \ \ \ \ \ language = context[cindex, "language"]; - \ \ \ \ \ \ \ \ \ \ =\\\chunkref{parse_chunk_args-reset-modes}\ + \ \ \ \ \ \ \ \ \ =\\\chunkref{parse_chunk_args-reset-modes}\ - \ \ \ \ \ \ \ \ } + \ \ \ \ \ \ \ } - \ \ \ \ \ \ \ \ item = item a[1]; + \ \ \ \ \ \ \ item = item a[1]; - \ \ \ \ \ \ \ \ text = substr(text, 1 + length(part) + length(a[1])); + \ \ \ \ \ \ \ text = substr(text, 1 + length(part) + + length(a[1])); - \ \ \ \ \ \ } + \ \ \ \ \ } If a delimiter was matched, then we must store the current item in the parsed values array, and reset the item. <\nf-chunk|mode_tracker()> - \ \ \ \ \ \ else if (match(a[1], "^" delimiters "$")) { + \ \ \ \ \ else if (match(a[1], "^" delimiters "$")) { - \ \ \ \ \ \ \ \ if (cindex==0) { + \ \ \ \ \ \ \ if (cindex==0) { - \ \ \ \ \ \ \ \ \ \ context[cindex, "values", ++context[cindex, + \ \ \ \ \ \ \ \ \ context[cindex, "values", ++context[cindex, "values"]] = item; - \ \ \ \ \ \ \ \ \ \ item = ""; + \ \ \ \ \ \ \ \ \ item = ""; - \ \ \ \ \ \ \ \ } else { + \ \ \ \ \ \ \ } else { - \ \ \ \ \ \ \ \ \ \ item = item a[1]; + \ \ \ \ \ \ \ \ \ item = item a[1]; - \ \ \ \ \ \ \ \ } + \ \ \ \ \ \ \ } - \ \ \ \ \ \ \ \ text = substr(text, 1 + length(part) + length(a[1])); + \ \ \ \ \ \ \ text = substr(text, 1 + length(part) + + length(a[1])); - \ \ \ \ \ \ } + \ \ \ \ \ } otherwise, if a new submode is detected (all submodes have terminators), we @@ -2873,37 +2889,39 @@ mode. <\nf-chunk|mode_tracker()> - \ else if ((language, a[1], "terminators") in modes) { + else if ((language, a[1], "terminators") in modes) { - \ \ \ \ \ \ \ \ #check if new_mode is defined + \ \ \ \ \ \ \ #check if new_mode is defined - \ \ \ \ \ \ \ \ item = item a[1]; + \ \ \ \ \ \ \ item = item a[1]; - #printf("%2d ENTER MODE [%s] in [%s]\\n", cindex, a[1], text) \ - "/dev/stderr" + #printf("%2d ENTER MODE [%s] in [%s]\\n", cindex, a[1], text) + \ "/dev/stderr" - \ \ \ \ \ \ \ \ text = substr(text, 1 + length(part) + length(a[1])); + \ \ \ \ \ \ \ text = substr(text, 1 + length(part) + + length(a[1])); - \ \ \ \ \ \ \ \ context[""] = ++cindex; + \ \ \ \ \ \ \ context[""] = ++cindex; - \ \ \ \ \ \ \ \ context[cindex, "mode"] = a[1]; + \ \ \ \ \ \ \ context[cindex, "mode"] = a[1]; - \ \ \ \ \ \ \ \ context[cindex, "language"] = language; + \ \ \ \ \ \ \ context[cindex, "language"] = language; - \ \ \ \ \ \ \ \ mode = a[1]; + \ \ \ \ \ \ \ mode = a[1]; - \ \ \ \ \ \ \ \ =\\\chunkref{parse_chunk_args-reset-modes}\ + \ \ \ \ \ \ \ =\\\chunkref{parse_chunk_args-reset-modes}\ - \ \ \ \ \ \ } else { + \ \ \ \ \ } else { - \ \ \ \ \ \ \ \ error(sprintf("Submode '%s' set unknown mode in text: - %s\\nLanguage %s Mode %s\\n", a[1], text, language, mode)); + \ \ \ \ \ \ \ error(sprintf("Submode '%s' set unknown mode in + text: %s\\nLanguage %s Mode %s\\n", a[1], text, language, mode)); - \ \ \ \ \ \ \ \ text = substr(text, 1 + length(part) + length(a[1])); + \ \ \ \ \ \ \ text = substr(text, 1 + length(part) + + length(a[1])); - \ \ \ \ \ \ } + \ \ \ \ \ } - \ \ \ \ } + \ \ \ } In the final case, we parsed to the end of the string. If the string was @@ -2913,31 +2931,31 @@ are split over two fragments. <\nf-chunk|mode_tracker()> - else { + else { - \ \ \ \ \ \ context[cindex, "values", ++context[cindex, "values"]] = item - text; + \ \ \ \ \ context[cindex, "values", ++context[cindex, "values"]] = + item text; - \ \ \ \ \ \ text = ""; + \ \ \ \ \ text = ""; - \ \ \ \ \ \ item = ""; + \ \ \ \ \ item = ""; - \ \ \ \ } + \ \ \ } - \ \ } + \ } - \; + - \ \ context["item"] = item; + \ context["item"] = item; - \; + - \ \ if (length(item)) context[cindex, "values", ++context[cindex, + \ if (length(item)) context[cindex, "values", ++context[cindex, "values"]] = item; - \ \ return text; + \ return text; - } + } @@ -2945,9 +2963,9 @@ All the mode tracker chunks are referred to here: <\nf-chunk|mode-tracker> - =\\\chunkref{new_mode_tracker()}\ + =\\\chunkref{new_mode_tracker()}\ - =\\\chunkref{mode_tracker()}\ + =\\\chunkref{mode_tracker()}\ @@ -2955,59 +2973,59 @@ We can test this function like this: <\nf-chunk|pca-test.awk> - =\\\chunkref{error()}\ + =\\\chunkref{error()}\ - =\\\chunkref{mode-tracker}\ + =\\\chunkref{mode-tracker}\ - =\\\chunkref{parse_chunk_args()}\ + =\\\chunkref{parse_chunk_args()}\ - BEGIN { + BEGIN { - \ \ SUBSEP="."; + \ SUBSEP="."; - \ \ =\\\chunkref{mode-definitions}\ + \ =\\\chunkref{mode-definitions}\ - \; + - \ \ =\\\chunkref{test:mode-definitions}\ + \ =\\\chunkref{test:mode-definitions}\ - } + } <\nf-chunk|pca-test.awk:summary> - if (e) { + if (e) { - \ \ printf "Failed " e + \ printf "Failed " e - \ \ for (b in a) { + \ for (b in a) { - \ \ \ \ print "a[" b "] =\ " a[b]; + \ \ \ print "a[" b "] =\ " a[b]; - \ \ } + \ } - } else { + } else { - \ \ print "Passed" + \ print "Passed" - } + } - split("", a); + split("", a); - e=0; + e=0; which should give this output: <\nf-chunk|pca-test.awk-results> - a[foo.quux.quirk] =\\ + a[foo.quux.quirk] =\\ - a[foo.quux.a] =\ fleeg + a[foo.quux.a] =\ fleeg - a[foo.bar] =\ baz + a[foo.bar] =\ baz - a[etc] =\\ + a[etc] =\\ - a[name] =\ freddie + a[name] =\ freddie @@ -3018,85 +3036,85 @@ This code can perform transforms <\nf-chunk|mode_tracker> - function transform_escape(s, r, text, + function transform_escape(s, r, text, - \ \ \ \ # optional + \ \ \ # optional - \ \ \ \ max,\ + \ \ \ max,\ - \ \ \ \ \ \ \ \ # local vars + \ \ \ \ \ \ \ # local vars - \ \ \ \ \ \ \ \ c) + \ \ \ \ \ \ \ c) - { + { - \ \ for(c=1; c \= max && (c in s); c++) { + \ for(c=1; c \= max && (c in s); c++) { - \ \ \ \ gsub(s[c], r[c], text); + \ \ \ gsub(s[c], r[c], text); - \ \ } + \ } - \ \ return text; + \ return text; - } + } This function must append from index c onwards, and escape transforms from the supplied context, and return c + number of new transforms. <\nf-chunk|mode_tracker> - function mode_escaper(context, s, r, src, + function mode_escaper(context, s, r, src, - \ \ c, cp, cpl) + \ c, cp, cpl) - { + { - \ \ \ \ \ \ \ \ for(c = context[""]; c \= 0; c--) { + \ \ \ \ \ \ \ for(c = context[""]; c \= 0; c--) { - \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ if ( (context[c, "language"], context[c, - "mode"]) in escapes) { + \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ if ( (context[c, "language"], + context[c, "mode"]) in escapes) { - \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ cpl = escapes[context[c, - "language"], context[c, "mode"]]; + \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ cpl = + escapes[context[c, "language"], context[c, "mode"]]; - \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ for (cp = 1; cp \= - cpl; cp ++) { + \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ for (cp = 1; cp + \= cpl; cp ++) { - \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ++src; + \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ++src; - \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ s[src] = - escapes[context[c, "language"], context[c, "mode"], cp, "s"]; + \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ s[src] + = escapes[context[c, "language"], context[c, "mode"], cp, "s"]; - \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ r[src] = - escapes[context[c, "language"], context[c, "mode"], cp, "r"]; + \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ r[src] + = escapes[context[c, "language"], context[c, "mode"], cp, "r"]; - \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ } + \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ } - \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ } + \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ } - \ \ \ \ \ \ \ \ } + \ \ \ \ \ \ \ } - \ \ \ \ \ \ \ \ return src; + \ \ \ \ \ \ \ return src; - } + } - function dump_escaper(c, s, r, cc) { + function dump_escaper(c, s, r, cc) { - \ \ for(cc=1; cc\=c; cc++) { + \ for(cc=1; cc\=c; cc++) { - \ \ \ \ printf("%2d s[%s] r[%s]\\n", cc, s[cc], r[cc]) \ + \ \ \ printf("%2d s[%s] r[%s]\\n", cc, s[cc], r[cc]) \ "/dev/stderr" - \ \ } + \ } - } + } <\nf-chunk|test:escapes> - echo escapes test + echo escapes test - passtest $FANGLE -Rtest:comment-quote $TEX_SRC &\/dev/null \|\| ( - echo "Comment-quote failed" && exit 1 ) + passtest $FANGLE -Rtest:comment-quote $TEX_SRC &\/dev/null + \|\| ( echo "Comment-quote failed" && exit 1 ) @@ -3140,19 +3158,19 @@ ). <\nf-chunk|recognize-chunk> - /^\\\\Chunk{/ { + /^\\\\Chunk{/ { - \ \ if (match($0, "^\\\\\\\\Chunk{ *([^ ,}]*),?(.*)}", line)) { + \ if (match($0, "^\\\\\\\\Chunk{ *([^ ,}]*),?(.*)}", line)) { - \ \ \ \ next_chunk_name = line[1]; + \ \ \ next_chunk_name = line[1]; - \ \ \ \ get_chunk_args(line[2], next_chunk_args); + \ \ \ get_chunk_args(line[2], next_chunk_args); - \ \ } + \ } - \ \ next; + \ next; - } + } We also make a basic attempt to parse the name out of the @@ -3165,23 +3183,23 @@ . <\nf-chunk|recognize-chunk> - /^\\\\begin{lstlisting}\|^\\\\begin{Chunk}/ { + /^\\\\begin{lstlisting}\|^\\\\begin{Chunk}/ { - \ \ if (match($0, "}.*[[,] *name= *{? *([^], }]*)", line)) { + \ if (match($0, "}.*[[,] *name= *{? *([^], }]*)", line)) { - \ \ \ \ new_chunk(line[1]); + \ \ \ new_chunk(line[1]); - \ \ } else { + \ } else { - \ \ \ \ new_chunk(next_chunk_name, next_chunk_args); + \ \ \ new_chunk(next_chunk_name, next_chunk_args); - \ \ } + \ } - \ \ chunking=1; + \ chunking=1; - \ \ next; + \ next; - } + } @@ -3189,21 +3207,22 @@ We recognize notangle style chunks too: <\nf-chunk|recognize-chunk> - /^[\]\.*[\]\=/ { + /^[\]\.*[\]\=/ { - \ \ if (match($0, "^[\]\(.*)[\]\= *$", line)) { + \ if (match($0, "^[\]\(.*)[\]\= *$", + line)) { - \ \ \ \ chunking=1; + \ \ \ chunking=1; - \ \ \ \ notangle_mode=1; + \ \ \ notangle_mode=1; - \ \ \ \ new_chunk(line[1]); + \ \ \ new_chunk(line[1]); - \ \ \ \ next; + \ \ \ next; - \ \ } + \ } - } + } @@ -3221,27 +3240,27 @@ <\nf-chunk|recognize-chunk> - /^\\\\[e]nd{lstlisting}\|^\\\\[e]nd{Chunk}/ { + /^\\\\[e]nd{lstlisting}\|^\\\\[e]nd{Chunk}/ { - \ \ chunking=0; + \ chunking=0; - \ \ active_chunk=""; + \ active_chunk=""; - \ \ next; + \ next; - } + } <\nf-chunk|recognize-chunk> - /^@ *$/ { + /^@ *$/ { - \ \ chunking=0; + \ chunking=0; - \ \ active_chunk=""; + \ active_chunk=""; - } + } All other recognizers are only of effect if we are chunking; there's no @@ -3249,7 +3268,7 @@ them as efficiently as we can. <\nf-chunk|recognize-chunk> - ! chunking { next; } + ! chunking { next; } @@ -3266,20 +3285,20 @@ . <\nf-chunk|recognize-chunk> - length(active_chunk) { + length(active_chunk) { - \ \ =\\\chunkref{process-chunk-tabs}\ + \ =\\\chunkref{process-chunk-tabs}\ - \ \ =\\\chunkref{process-chunk}\ + \ =\\\chunkref{process-chunk}\ - } + } If a chunk just consisted of plain text, we could handle the chunk like this: <\nf-chunk|process-chunk-simple> - chunk_line(active_chunk, $0 ORS); + chunk_line(active_chunk, $0 ORS); but in fact a chunk can include references to other chunks. Chunk includes @@ -3294,11 +3313,11 @@ on output. <\nf-chunk|process-chunk-tabs> - if (length(tabs)) { + if (length(tabs)) { - \ \ gsub("\\t", tabs); + \ gsub("\\t", tabs); - } + } @@ -3331,13 +3350,13 @@ it is to remove these from any arguments parsed by fangle. <\nf-chunk|delatex> - # FILTHY HACK + # FILTHY HACK - gsub("\\\\\\\\#", "#", ${text}); + gsub("\\\\\\\\#", "#", ${text}); - gsub("\\\\\\\\textbackslash{}", "\\\\", ${text}); + gsub("\\\\\\\\textbackslash{}", "\\\\", ${text}); - gsub("\\\\\\\\\\\\^", "^", ${text}); + gsub("\\\\\\\\\\\\^", "^", ${text}); > As each chunk line may contain more than one chunk include, we will split @@ -3350,19 +3369,19 @@ take as much as we can up to the first command. <\nf-chunk|process-chunk> - chunk = $0; + chunk = $0; - indent = 0; + indent = 0; - while(match(chunk,\ + while(match(chunk,\ - \ \ \ \ \ \ \ \ \ \ \ \ "([=]\\\\\\\\\chunkref{([^}\]*)}(\\\\(.*\\\\)\|)\\|\\([a-zA-Z_][-a-zA-Z0-9_]*)\\)",\ + \ \ \ \ \ \ \ \ \ \ \ "([=]\\\\\\\\\chunkref{([^}\]*)}(\\\\(.*\\\\)\|)\\|\\([a-zA-Z_][-a-zA-Z0-9_]*)\\)",\ - \ \ \ \ \ \ \ \ \ \ \ \ line)\\ + \ \ \ \ \ \ \ \ \ \ \ line)\\ - ) { + ) { - \ \ chunklet = substr(chunk, 1, RSTART - 1); + \ chunklet = substr(chunk, 1, RSTART - 1); We keep track of the indent count, by counting the number of literal @@ -3374,11 +3393,11 @@ command, which we will process next as we continue around the loop. <\nf-chunk|process-chunk> - \ \ indent += length(chunklet); + \ indent += length(chunklet); - \ \ chunk_line(active_chunk, chunklet); + \ chunk_line(active_chunk, chunklet); - \ \ chunk = substr(chunk, RSTART + RLENGTH); + \ chunk = substr(chunk, RSTART + RLENGTH); We then consider the type of chunk command we have found, whether it is the @@ -3390,36 +3409,36 @@ processing to be part of the name of the chunk to be included. <\nf-chunk|process-chunk> - \ \ if (substr(line[1], 1, 1) == "=") { + \ if (substr(line[1], 1, 1) == "=") { - \ \ \ \ # chunk name up to } + \ \ \ # chunk name up to } - \ \ \ \ \ \ \ \ =\\\chunkref{delatex}(line[3])\ + \ \ \ \ \ \ \ =\\\chunkref{delatex}(line[3])\ - \ \ \ \ chunk_include(active_chunk, line[2] line[3], indent); + \ \ \ chunk_include(active_chunk, line[2] line[3], indent); - \ \ } else if (substr(line[1], 1, 1) == "\") { + \ } else if (substr(line[1], 1, 1) == "\") { - \ \ \ \ chunk_include(active_chunk, line[4], indent); + \ \ \ chunk_include(active_chunk, line[4], indent); - \ \ } else { + \ } else { - \ \ \ \ error("Unknown chunk fragment: " line[1]); + \ \ \ error("Unknown chunk fragment: " line[1]); - \ \ } + \ } <|nf-chunk> \; - \; + The loop will continue until there are no more chunkref statements in the text, at which point we process the final part of the chunk. <\nf-chunk|process-chunk> - } + } - chunk_line(active_chunk, chunk); + chunk_line(active_chunk, chunk); We add the newline character as a chunklet on it's own, @@ -3427,7 +3446,7 @@ processing the output. <\nf-chunk|process-chunk> - chunk_line(active_chunk, "\n"); + chunk_line(active_chunk, "\n"); <|nf-chunk> \; @@ -3457,94 +3476,96 @@ At the start, first we set the default options. <\nf-chunk|default-options> - debug=0; + debug=0; - linenos=0; + linenos=0; - notangle_mode=0; + notangle_mode=0; - root="*"; + root="*"; - tabs = ""; + tabs = ""; Then we use getopt the standard way, and null out ARGV afterwards in the normal AWK fashion. <\nf-chunk|read-options> - Optind = 1 \ \ \ # skip ARGV[0] + Optind = 1 \ \ \ # skip ARGV[0] - while(getopt(ARGC, ARGV, "R:LdT:hr")!=-1) { + while(getopt(ARGC, ARGV, "R:LdT:hr")!=-1) { - \ \ =\\\chunkref{handle-options}\ + \ =\\\chunkref{handle-options}\ - } + } - for (i=1; i\Optind; i++) { ARGV[i]=""; } + for (i=1; i\Optind; i++) { ARGV[i]=""; } This is how we handle our options: <\nf-chunk|handle-options> - if (Optopt == "R") root = Optarg; + if (Optopt == "R") root = Optarg; - else if (Optopt == "r") root=""; + else if (Optopt == "r") root=""; - else if (Optopt == "L") linenos = 1; + else if (Optopt == "L") linenos = 1; - else if (Optopt == "d") debug = 1; + else if (Optopt == "d") debug = 1; - else if (Optopt == "T") tabs = indent_string(Optarg+0); + else if (Optopt == "T") tabs = indent_string(Optarg+0); - else if (Optopt == "h") help(); + else if (Optopt == "h") help(); - else if (Optopt == "?") help(); + else if (Optopt == "?") help(); We do all of this at the beginning of the program <\nf-chunk|begin> - BEGIN { + BEGIN { - \ \ =\\\chunkref{constants}\ + \ =\\\chunkref{constants}\ - \ \ =\\\chunkref{mode-definitions}\ + \ =\\\chunkref{mode-definitions}\ - \ \ =\\\chunkref{default-options}\ + \ =\\\chunkref{default-options}\ - \; + - \ \ =\\\chunkref{read-options}\ + \ =\\\chunkref{read-options}\ - } + } And have a simple help function <\nf-chunk|help()> - function help() { + function help() { - \ \ print "Usage:" + \ print "Usage:" - \ \ print " \ fangle [-L] -R\rootname\ [source.tex ...]" + \ print " \ fangle [-L] -R\rootname\ [source.tex + ...]" - \ \ print " \ fangle -r [source.tex ...]" + \ print " \ fangle -r [source.tex ...]" - \ \ print " \ If the filename, source.tex is not specified then stdin is - used" + \ print " \ If the filename, source.tex is not specified then + stdin is used" - \ \ print + \ print - \ \ print "-L causes the C statement: #line \lineno\ + \ print "-L causes the C statement: #line \lineno\ \\"filename\\"" to be issued" - \ \ print "-R causes the named root to be written to stdout" + \ print "-R causes the named root to be written to stdout" - \ \ print "-r lists all roots in the file (even those used elsewhere)" + \ print "-r lists all roots in the file (even those used + elsewhere)" - \ \ exit 1; + \ exit 1; - } + } @@ -3552,33 +3573,33 @@ We generate output by calling output_chunk, or listing the chunk names. <\nf-chunk|generate-output> - if (length(root)) output_chunk(root); + if (length(root)) output_chunk(root); - else output_chunk_names(); + else output_chunk_names(); We also have some other output debugging: <\nf-chunk|debug-output> - if (debug) { + if (debug) { - \ \ print "------ chunk names " + \ print "------ chunk names " - \ \ output_chunk_names(); + \ output_chunk_names(); - \ \ print "====== chunks" + \ print "====== chunks" - \ \ output_chunks(); + \ output_chunks(); - \ \ print "++++++ debug" + \ print "++++++ debug" - \ \ for (a in chunks) { + \ for (a in chunks) { - \ \ \ \ print a "=" chunks[a]; + \ \ \ print a "=" chunks[a]; - \ \ } + \ } - } + } We do both of these at the end. We also set because each @@ -3587,15 +3608,15 @@ . <\nf-chunk|end> - END { + END { - \ \ =\\\chunkref{debug-output}\ + \ =\\\chunkref{debug-output}\ - \ \ ORS=""; + \ ORS=""; - \ \ =\\\chunkref{generate-output}\ + \ =\\\chunkref{generate-output}\ - } + } We write chunk names like this. If we seem to be running in notangle @@ -3603,57 +3624,57 @@ \name\\> the same way notangle does: <\nf-chunk|output_chunk_names()> - function output_chunk_names( \ \ c, prefix, suffix)\ + function output_chunk_names( \ \ c, prefix, suffix)\ - { + { - \ \ if (notangle_mode) { + \ if (notangle_mode) { - \ \ \ \ prefix="\\"; + \ \ \ prefix="\\"; - \ \ \ \ suffix="\\"; + \ \ \ suffix="\\"; - \ \ } + \ } - \ \ for (c in chunk_names) { + \ for (c in chunk_names) { - \ \ \ \ print prefix c suffix "\\n"; + \ \ \ print prefix c suffix "\\n"; - \ \ } + \ } - } + } This function would write out all chunks <\nf-chunk|output_chunks()> - function output_chunks( \ a)\ + function output_chunks( \ a)\ - { + { - \ \ for (a in chunk_names) { + \ for (a in chunk_names) { - \ \ \ \ output_chunk(chunk_names[a]); + \ \ \ output_chunk(chunk_names[a]); - \ \ } + \ } - } + } - \; + - function output_chunk(chunk) { + function output_chunk(chunk) { - \ \ newline = 1; + \ newline = 1; - \ \ lineno_needed = linenos; + \ lineno_needed = linenos; - \; + - \ \ write_chunk(chunk); + \ write_chunk(chunk); - } + } - \; + @@ -3665,31 +3686,31 @@ We first initialize the mode tracker for this chunk. <\nf-chunk|write_chunk()> - function write_chunk(chunk_name) { + function write_chunk(chunk_name) { - \ \ =\\\chunkref{awk-delete-array}(context)\ + \ =\\\chunkref{awk-delete-array}(context)\ - \ \ return write_chunk_r(chunk_name, context); + \ return write_chunk_r(chunk_name, context); - } + } - \; + - function write_chunk_r(chunk_name, context, indent, tail, + function write_chunk_r(chunk_name, context, indent, tail, - \ \ # optional vars + \ # optional vars - \ \ , chunk_args,\ + \ , chunk_args,\ - \ \ s, r, src, new_src,\ + \ s, r, src, new_src,\ - \ \ # local vars + \ # local vars - \ \ chunk_params, part, max_part, part_line, frag, max_frag, text,\ + \ chunk_params, part, max_part, part_line, frag, max_frag, text,\ - \ \ chunklet, only_part, call_chunk_args, new_context) + \ chunklet, only_part, call_chunk_args, new_context) - { + { @@ -3699,20 +3720,20 @@ should be emitted. <\nf-chunk|write_chunk()> - \ \ if (match(chunk_name, "^(.*)\\\\[([0-9]*)\\\\]$", chunk_name_parts)) - { + \ if (match(chunk_name, "^(.*)\\\\[([0-9]*)\\\\]$", + chunk_name_parts)) { - \ \ \ \ chunk_name = chunk_name_parts[1]; + \ \ \ chunk_name = chunk_name_parts[1]; - \ \ \ \ only_part = chunk_name_parts[2]; + \ \ \ only_part = chunk_name_parts[2]; - \ \ } + \ } We then create a mode tracker <\nf-chunk|write_chunk()> - \ =\\\chunkref{new-mode-tracker}(context, chunks[chunk_name, + =\\\chunkref{new-mode-tracker}(context, chunks[chunk_name, "language"], "")\ @@ -3721,45 +3742,45 @@ . <\nf-chunk|write_chunk()> - \ split(chunks[chunk_name, "params"], chunk_params, " *; *"); + split(chunks[chunk_name, "params"], chunk_params, " *; *"); To assemble a chunk, we write out each part. <\nf-chunk|write_chunk()> - \ \ if (! (chunk_name in chunk_names)) { + \ if (! (chunk_name in chunk_names)) { - \ \ \ \ error(sprintf(_"The root module \\%s\\ - was not defined.\\nUsed by: %s",\\ + \ \ \ error(sprintf(_"The root module + \\%s\\ was not defined.\\nUsed by: %s",\\ - \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ chunk_name, chunk_path)); + \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ chunk_name, chunk_path)); - \ \ } + \ } - \; + - \ \ max_part = chunks[chunk_name, "part"]; + \ max_part = chunks[chunk_name, "part"]; - \ \ for(part = 1; part \= max_part; part++) { + \ for(part = 1; part \= max_part; part++) { - \ \ \ \ if (! only_part \|\| part == only_part) { + \ \ \ if (! only_part \|\| part == only_part) { - \ \ \ \ \ \ =\\\chunkref{write-part}\ + \ \ \ \ \ =\\\chunkref{write-part}\ - \ \ \ \ } + \ \ \ } - \ \ } + \ } - \ \ if (! finalize_mode_tracker(context)) { + \ if (! finalize_mode_tracker(context)) { - \ \ \ \ dump_mode_tracker(context); + \ \ \ dump_mode_tracker(context); - \ \ \ \ error(sprintf(_"Module %s did not close context properly.\\nUsed - by: %s\\n", chunk_name, chunk_path)); + \ \ \ error(sprintf(_"Module %s did not close context + properly.\\nUsed by: %s\\n", chunk_name, chunk_path)); - \ \ } + \ } - } + } A part can either be a chunklet of lines, or an include of another chunk. @@ -3774,69 +3795,71 @@ file-line directive. <\nf-chunk|write-part> - =\\\chunkref{check-source-jump}\ + =\\\chunkref{check-source-jump}\ - \; + - chunklet = chunks[chunk_name, "part", part]; + chunklet = chunks[chunk_name, "part", part]; - if (chunks[chunk_name, "part", part, "type"] == part_type_chunk) { + if (chunks[chunk_name, "part", part, "type"] == part_type_chunk) { - \ \ =\\\chunkref{write-included-chunk}\ + \ =\\\chunkref{write-included-chunk}\ - } else if (chunklet SUBSEP "line" in chunks) { + } else if (chunklet SUBSEP "line" in chunks) { - \ \ =\\\chunkref{write-chunklets}\ + \ =\\\chunkref{write-chunklets}\ - } else { + } else { - \ \ # empty last chunklet + \ # empty last chunklet - } + } To write an included chunk, we must detect any optional chunk arguments in parenthesis. Then we recurse calling . <\nf-chunk|write-included-chunk> - if (match(chunklet, "^([^\\\\[\\\\(]*)\\\\((.*)\\\\)$", chunklet_parts)) - { + if (match(chunklet, "^([^\\\\[\\\\(]*)\\\\((.*)\\\\)$", + chunklet_parts)) { - \ \ chunklet = chunklet_parts[1]; + \ chunklet = chunklet_parts[1]; - \ \ parse_chunk_args("c-like", chunklet_parts[2], call_chunk_args, "("); + \ parse_chunk_args("c-like", chunklet_parts[2], call_chunk_args, + "("); - \ \ for (c in call_chunk_args) { + \ for (c in call_chunk_args) { - \ \ \ \ call_chunk_args[c] = expand_chunk_args(call_chunk_args[c], + \ \ \ call_chunk_args[c] = expand_chunk_args(call_chunk_args[c], chunk_params, chunk_args); - \ \ } + \ } - } else { + } else { - \ \ split("", call_chunk_args); + \ split("", call_chunk_args); - } + } - # update the transforms arrays + # update the transforms arrays - new_src = mode_escaper(context, s, r, src); + new_src = mode_escaper(context, s, r, src); - =\\\chunkref{awk-delete-array}(new_context)\ + =\\\chunkref{awk-delete-array}(new_context)\ - write_chunk_r(chunklet, new_context, + write_chunk_r(chunklet, new_context, - \ \ \ \ \ \ \ \ \ \ \ \ chunks[chunk_name, "part", part, "indent"] + \ \ \ \ \ \ \ \ \ \ \ chunks[chunk_name, "part", part, "indent"] indent, - \ \ \ \ \ \ \ \ \ \ \ \ chunks[chunk_name, "part", part, "tail"], + \ \ \ \ \ \ \ \ \ \ \ chunks[chunk_name, "part", part, "tail"], - \ \ \ \ \ \ \ \ \ \ \ \ chunk_path "\\n \ \ \ \ \ \ \ \ " chunk_name, + \ \ \ \ \ \ \ \ \ \ \ chunk_path "\\n \ \ \ \ \ \ \ \ " + chunk_name, - \ \ \ \ \ \ \ \ \ \ \ \ call_chunk_args, + \ \ \ \ \ \ \ \ \ \ \ call_chunk_args, - \ \ \ \ \ \ \ \ \ \ \ \ s, r, new_src); + \ \ \ \ \ \ \ \ \ \ \ s, r, new_src); Before we output a chunklet of lines, we first emit the file and line @@ -3850,25 +3873,25 @@ we note that we want to emit the line statement when it is next safe. <\nf-chunk|write-chunklets> - max_frag = chunks[chunklet, "line"]; + max_frag = chunks[chunklet, "line"]; - for(frag = 1; frag \= max_frag; frag++) { + for(frag = 1; frag \= max_frag; frag++) { - \ \ =\\\chunkref{write-file-line}\ + \ =\\\chunkref{write-file-line}\ We then extract the chunklet text and expand any arguments. <\nf-chunk|write-chunklets> - \; + - \ \ text = chunks[chunklet, frag]; + \ text = chunks[chunklet, frag]; - \ + \ - \ \ /* check params */ + \ /* check params */ - \ \ text = expand_chunk_args(text, chunk_params, chunk_args); + \ text = expand_chunk_args(text, chunk_params, chunk_args); If the text is a single newline (which we keep separate - see @@ -3882,23 +3905,24 @@ that indentation can be managed with the following piece of text. <\nf-chunk|write-chunklets> - \; + - \ if (text == "\\n") { + if (text == "\\n") { - \ \ \ \ lineno++; + \ \ \ lineno++; - \ \ \ \ if (part == max_part && frag == max_frag && length(chunk_path)) { + \ \ \ if (part == max_part && frag == max_frag && + length(chunk_path)) { - \ \ \ \ \ \ text = ""; + \ \ \ \ \ text = ""; - \ \ \ \ \ \ break; + \ \ \ \ \ break; - \ \ \ \ } else { + \ \ \ } else { - \ \ \ \ \ \ newline = 1; + \ \ \ \ \ newline = 1; - \ \ \ \ } + \ \ \ } If this text does not represent a newline, but we see that we are the first @@ -3911,25 +3935,25 @@ <\nf-chunk|write-chunklets> - \ \ } else if (length(text) \|\| length(tail)) { + \ } else if (length(text) \|\| length(tail)) { - \ \ \ \ if (newline) text = indent text; + \ \ \ if (newline) text = indent text; - \ \ \ \ newline = 0; + \ \ \ newline = 0; - \ \ } + \ } - \; + Tail will soon no longer be relevant once mode-detection is in place. <\nf-chunk|write-chunklets> - \ \ text = text tail; + \ text = text tail; - \ \ mode_tracker(context, text); + \ mode_tracker(context, text); - \ \ print transform_escape(s, r, text, src); + \ print transform_escape(s, r, text, src); If a line ends in a backslash --- suggesting continuation --- then we @@ -3937,13 +3961,14 @@ lines. <\nf-chunk|write-chunklets> - \ \ if (linenos) { + \ if (linenos) { - \ \ \ \ lineno_suppressed = substr(lastline, length(lastline)) == "\\\\"; + \ \ \ lineno_suppressed = substr(lastline, length(lastline)) == + "\\\\"; - \ \ } + \ } - } + } Of course there is no point in actually outputting the source filename and @@ -3952,37 +3977,37 @@ when they had changed. <\nf-chunk|write-file-line> - if (newline && lineno_needed && ! lineno_suppressed) { + if (newline && lineno_needed && ! lineno_suppressed) { - \ \ filename = a_filename; + \ filename = a_filename; - \ \ lineno = a_lineno; + \ lineno = a_lineno; - \ \ print "#line " lineno " \\"" filename "\\"\\n" + \ print "#line " lineno " \\"" filename "\\"\\n" - \ \ lineno_needed = 0; + \ lineno_needed = 0; - } + } We check if a new file-line is needed by checking if the source line matches what we (or a compiler) would expect. <\nf-chunk|check-source-jump> - if (linenos && (chunk_name SUBSEP "part" SUBSEP part SUBSEP "FILENAME" in - chunks)) { + if (linenos && (chunk_name SUBSEP "part" SUBSEP part SUBSEP + "FILENAME" in chunks)) { - \ \ a_filename = chunks[chunk_name, "part", part, "FILENAME"]; + \ a_filename = chunks[chunk_name, "part", part, "FILENAME"]; - \ \ a_lineno = chunks[chunk_name, "part", part, "LINENO"]; + \ a_lineno = chunks[chunk_name, "part", part, "LINENO"]; - \ \ if (a_filename != filename \|\| a_lineno != lineno) { + \ if (a_filename != filename \|\| a_lineno != lineno) { - \ \ \ \ lineno_needed++; + \ \ \ lineno_needed++; - \ \ } + \ } - } + } @@ -3992,9 +4017,9 @@ chunklets used in a chunk will be stored in . <\nf-chunk|constants> - part_type_chunk=1; + part_type_chunk=1; - SUBSEP=","; + SUBSEP=","; The params mentioned are not chunk parameters for parameterized chunks, as @@ -4005,90 +4030,90 @@ . <\nf-chunk|chunk-storage-functions> - function new_chunk(chunk_name, params, + function new_chunk(chunk_name, params, - \ \ # local vars + \ # local vars - \ \ p, append ) + \ p, append ) - { + { - \ \ # HACK WHILE WE CHANGE TO ( ) for PARAM CHUNKS + \ # HACK WHILE WE CHANGE TO ( ) for PARAM CHUNKS - \ \ gsub("\\\\(\\\\)$", "", chunk_name); + \ gsub("\\\\(\\\\)$", "", chunk_name); - \ \ if (! (chunk_name in chunk_names)) { + \ if (! (chunk_name in chunk_names)) { - \ \ \ \ if (debug) print "New chunk " chunk_name; + \ \ \ if (debug) print "New chunk " chunk_name; - \ \ \ \ chunk_names[chunk_name]; + \ \ \ chunk_names[chunk_name]; - \ \ \ \ for (p in params) { + \ \ \ for (p in params) { - \ \ \ \ \ \ chunks[chunk_name, p] = params[p]; + \ \ \ \ \ chunks[chunk_name, p] = params[p]; - \ \ \ \ } + \ \ \ } - \ \ \ \ if ("append" in params) { + \ \ \ if ("append" in params) { - \ \ \ \ \ \ append=params["append"]; + \ \ \ \ \ append=params["append"]; - \ \ \ \ \ \ if (! (append in chunk_names)) { + \ \ \ \ \ if (! (append in chunk_names)) { - \ \ \ \ \ \ \ \ warning("Chunk " chunk_name " is appended to chunk " + \ \ \ \ \ \ \ warning("Chunk " chunk_name " is appended to chunk " append " which is not defined yet"); - \ \ \ \ \ \ \ \ new_chunk(append); + \ \ \ \ \ \ \ new_chunk(append); - \ \ \ \ \ \ } + \ \ \ \ \ } - \ \ \ \ \ \ chunk_include(append, chunk_name); + \ \ \ \ \ chunk_include(append, chunk_name); - \ \ \ \ \ \ chunk_line(append, ORS); + \ \ \ \ \ chunk_line(append, ORS); - \ \ \ \ } + \ \ \ } - \ \ } + \ } - \ \ active_chunk = chunk_name; + \ active_chunk = chunk_name; - \ \ prime_chunk(chunk_name); + \ prime_chunk(chunk_name); - } + } <\nf-chunk|chunk-storage-functions> - \; + - function prime_chunk(chunk_name) + function prime_chunk(chunk_name) - { + { - \ \ chunks[chunk_name, "part", ++chunks[chunk_name, "part"] ] = \\ + \ chunks[chunk_name, "part", ++chunks[chunk_name, "part"] ] = \\ - \ \ \ \ \ \ \ \ \ chunk_name SUBSEP "chunklet" SUBSEP "" + \ \ \ \ \ \ \ \ chunk_name SUBSEP "chunklet" SUBSEP "" ++chunks[chunk_name, "chunklet"]; - \ \ chunks[chunk_name, "part", chunks[chunk_name, "part"], "FILENAME"] = - FILENAME; + \ chunks[chunk_name, "part", chunks[chunk_name, "part"], + "FILENAME"] = FILENAME; - \ \ chunks[chunk_name, "part", chunks[chunk_name, "part"], "LINENO"] = - FNR + 1; + \ chunks[chunk_name, "part", chunks[chunk_name, "part"], "LINENO"] + = FNR + 1; - } + } - \; + - function chunk_line(chunk_name, line){ + function chunk_line(chunk_name, line){ - \ \ chunks[chunk_name, "chunklet", chunks[chunk_name, "chunklet"], + \ chunks[chunk_name, "chunklet", chunks[chunk_name, "chunklet"], - \ \ \ \ \ \ \ \ \ ++chunks[chunk_name, "chunklet", chunks[chunk_name, - "chunklet"], "line"] \ ] = line; + \ \ \ \ \ \ \ \ ++chunks[chunk_name, "chunklet", + chunks[chunk_name, "chunklet"], "line"] \ ] = line; - } + } - \; + Chunk include represents a statement, and stores the @@ -4098,27 +4123,27 @@ should be indented. <\nf-chunk|chunk-storage-functions> - function chunk_include(chunk_name, chunk_ref, indent, tail) + function chunk_include(chunk_name, chunk_ref, indent, tail) - { + { - \ \ chunks[chunk_name, "part", ++chunks[chunk_name, "part"] ] = + \ chunks[chunk_name, "part", ++chunks[chunk_name, "part"] ] = chunk_ref; - \ \ chunks[chunk_name, "part", chunks[chunk_name, "part"], "type" ] = - part_type_chunk; + \ chunks[chunk_name, "part", chunks[chunk_name, "part"], "type" ] + = part_type_chunk; - \ \ chunks[chunk_name, "part", chunks[chunk_name, "part"], "indent" ] = - indent_string(indent); + \ chunks[chunk_name, "part", chunks[chunk_name, "part"], "indent" + ] = indent_string(indent); - \ \ chunks[chunk_name, "part", chunks[chunk_name, "part"], "tail" ] = - tail; + \ chunks[chunk_name, "part", chunks[chunk_name, "part"], "tail" ] + = tail; - \ \ prime_chunk(chunk_name); + \ prime_chunk(chunk_name); - } + } - \; + The indent is calculated by indent_string, which may in future convert some @@ -4127,11 +4152,11 @@ printing an empty string using that format. <\nf-chunk|chunk-storage-functions> - function indent_string(indent) { + function indent_string(indent) { - \ \ return sprintf("%" indent "s", ""); + \ return sprintf("%" indent "s", ""); - } + } @@ -4146,52 +4171,52 @@ The getopt.awk header is: <\nf-chunk|getopt.awk-header> - # getopt.awk --- do C library getopt(3) function in awk + # getopt.awk --- do C library getopt(3) function in awk - # + # - # Arnold Robbins, arnold@skeeve.com, Public Domain + # Arnold Robbins, arnold@skeeve.com, Public Domain - # + # - # Initial version: March, 1991 + # Initial version: March, 1991 - # Revised: May, 1993 + # Revised: May, 1993 - \; + The provided explanation is: <\nf-chunk|getopt.awk-notes> - # External variables: + # External variables: - # \ \ \ Optind -- index in ARGV of first nonoption argument + # \ \ \ Optind -- index in ARGV of first nonoption argument - # \ \ \ Optarg -- string value of argument to current option + # \ \ \ Optarg -- string value of argument to current option - # \ \ \ Opterr -- if nonzero, print our own diagnostic + # \ \ \ Opterr -- if nonzero, print our own diagnostic - # \ \ \ Optopt -- current option letter + # \ \ \ Optopt -- current option letter - \; + - # Returns: + # Returns: - # \ \ \ -1 \ \ \ \ at end of options + # \ \ \ -1 \ \ \ \ at end of options - # \ \ \ ? \ \ \ \ \ for unrecognized option + # \ \ \ ? \ \ \ \ \ for unrecognized option - # \ \ \ \c\ \ \ \ a character representing the current + # \ \ \ \c\ \ \ \ a character representing the current option - \; + - # Private Data: + # Private Data: - # \ \ \ _opti \ -- index in multi-flag option, e.g., -abc + # \ \ \ _opti \ -- index in multi-flag option, e.g., -abc - \; + The function follows. The final two parameters, and @@ -4200,162 +4225,163 @@ convention to help us humans. <\nf-chunk|getopt.awk-getopt()> - function getopt(argc, argv, options, \ \ \ thisopt, i) + function getopt(argc, argv, options, \ \ \ thisopt, i) - { + { - \ \ \ \ if (length(options) == 0) \ \ \ # no options given + \ \ \ if (length(options) == 0) \ \ \ # no options given - \ \ \ \ \ \ \ \ return -1 + \ \ \ \ \ \ \ return -1 - \ \ \ \ if (argv[Optind] == "--") { \ # all done + \ \ \ if (argv[Optind] == "--") { \ # all done - \ \ \ \ \ \ \ \ Optind++ + \ \ \ \ \ \ \ Optind++ - \ \ \ \ \ \ \ \ _opti = 0 + \ \ \ \ \ \ \ _opti = 0 - \ \ \ \ \ \ \ \ return -1 + \ \ \ \ \ \ \ return -1 - \ \ \ \ } else if (argv[Optind] !~ /^-[^: \\t\\n\\f\\r\\v\\b]/) { + \ \ \ } else if (argv[Optind] !~ /^-[^: \\t\\n\\f\\r\\v\\b]/) { - \ \ \ \ \ \ \ \ _opti = 0 + \ \ \ \ \ \ \ _opti = 0 - \ \ \ \ \ \ \ \ return -1 + \ \ \ \ \ \ \ return -1 - \ \ \ \ } + \ \ \ } - \ \ \ \ if (_opti == 0) + \ \ \ if (_opti == 0) - \ \ \ \ \ \ \ \ _opti = 2 + \ \ \ \ \ \ \ _opti = 2 - \ \ \ \ thisopt = substr(argv[Optind], _opti, 1) + \ \ \ thisopt = substr(argv[Optind], _opti, 1) - \ \ \ \ Optopt = thisopt + \ \ \ Optopt = thisopt - \ \ \ \ i = index(options, thisopt) + \ \ \ i = index(options, thisopt) - \ \ \ \ if (i == 0) { + \ \ \ if (i == 0) { - \ \ \ \ \ \ \ \ if (Opterr) + \ \ \ \ \ \ \ if (Opterr) - \ \ \ \ \ \ \ \ \ \ \ \ printf("%c -- invalid option\\n", + \ \ \ \ \ \ \ \ \ \ \ printf("%c -- invalid option\\n", - \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ thisopt) + \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ thisopt) \ "/dev/stderr" - \ \ \ \ \ \ \ \ if (_opti \= length(argv[Optind])) { + \ \ \ \ \ \ \ if (_opti \= length(argv[Optind])) { - \ \ \ \ \ \ \ \ \ \ \ \ Optind++ + \ \ \ \ \ \ \ \ \ \ \ Optind++ - \ \ \ \ \ \ \ \ \ \ \ \ _opti = 0 + \ \ \ \ \ \ \ \ \ \ \ _opti = 0 - \ \ \ \ \ \ \ \ } else + \ \ \ \ \ \ \ } else - \ \ \ \ \ \ \ \ \ \ \ \ _opti++ + \ \ \ \ \ \ \ \ \ \ \ _opti++ - \ \ \ \ \ \ \ \ return "?" + \ \ \ \ \ \ \ return "?" - \ \ \ \ } + \ \ \ } At this point, the option has been found and we need to know if it takes any arguments. <\nf-chunk|getopt.awk-getopt()> - \ \ \ \ if (substr(options, i + 1, 1) == ":") { + \ \ \ if (substr(options, i + 1, 1) == ":") { - \ \ \ \ \ \ \ \ # get option argument + \ \ \ \ \ \ \ # get option argument - \ \ \ \ \ \ \ \ if (length(substr(argv[Optind], _opti + 1)) \ 0) + \ \ \ \ \ \ \ if (length(substr(argv[Optind], _opti + 1)) \ + 0) - \ \ \ \ \ \ \ \ \ \ \ \ Optarg = substr(argv[Optind], _opti + 1) + \ \ \ \ \ \ \ \ \ \ \ Optarg = substr(argv[Optind], _opti + 1) - \ \ \ \ \ \ \ \ else + \ \ \ \ \ \ \ else - \ \ \ \ \ \ \ \ \ \ \ \ Optarg = argv[++Optind] + \ \ \ \ \ \ \ \ \ \ \ Optarg = argv[++Optind] - \ \ \ \ \ \ \ \ _opti = 0 + \ \ \ \ \ \ \ _opti = 0 - \ \ \ \ } else + \ \ \ } else - \ \ \ \ \ \ \ \ Optarg = "" + \ \ \ \ \ \ \ Optarg = "" - \ \ \ \ if (_opti == 0 \|\| _opti \= length(argv[Optind])) { + \ \ \ if (_opti == 0 \|\| _opti \= length(argv[Optind])) { - \ \ \ \ \ \ \ \ Optind++ + \ \ \ \ \ \ \ Optind++ - \ \ \ \ \ \ \ \ _opti = 0 + \ \ \ \ \ \ \ _opti = 0 - \ \ \ \ } else + \ \ \ } else - \ \ \ \ \ \ \ \ _opti++ + \ \ \ \ \ \ \ _opti++ - \ \ \ \ return thisopt + \ \ \ return thisopt - } + } A test program is built in, too <\nf-chunk|getopt.awk-begin> - BEGIN { + BEGIN { - \ \ \ \ Opterr = 1 \ \ \ # default is to diagnose + \ \ \ Opterr = 1 \ \ \ # default is to diagnose - \ \ \ \ Optind = 1 \ \ \ # skip ARGV[0] + \ \ \ Optind = 1 \ \ \ # skip ARGV[0] - \ \ \ \ # test program + \ \ \ # test program - \ \ \ \ if (_getopt_test) { + \ \ \ if (_getopt_test) { - \ \ \ \ \ \ \ \ while ((_go_c = getopt(ARGC, ARGV, "ab:cd")) != -1) + \ \ \ \ \ \ \ while ((_go_c = getopt(ARGC, ARGV, "ab:cd")) != -1) - \ \ \ \ \ \ \ \ \ \ \ \ printf("c = \%c\, optarg = + \ \ \ \ \ \ \ \ \ \ \ printf("c = \%c\, optarg = \%s\\\n", - \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ _go_c, + \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ _go_c, Optarg) - \ \ \ \ \ \ \ \ printf("non-option arguments:\\n") + \ \ \ \ \ \ \ printf("non-option arguments:\\n") - \ \ \ \ \ \ \ \ for (; Optind \ ARGC; Optind++) + \ \ \ \ \ \ \ for (; Optind \ ARGC; Optind++) - \ \ \ \ \ \ \ \ \ \ \ \ printf("\\tARGV[%d] = \%s\\\n", + \ \ \ \ \ \ \ \ \ \ \ printf("\\tARGV[%d] = \%s\\\n", - \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ Optind, + \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ Optind, ARGV[Optind]) - \ \ \ \ } + \ \ \ } - } + } The entire getopt.awk is made out of these chunks in order <\nf-chunk|getopt.awk> - =\\\chunkref{getopt.awk-header}\ + =\\\chunkref{getopt.awk-header}\ - \; + - =\\\chunkref{getopt.awk-notes}\ + =\\\chunkref{getopt.awk-notes}\ - =\\\chunkref{getopt.awk-getopt()}\ + =\\\chunkref{getopt.awk-getopt()}\ - =\\\chunkref{getopt.awk-begin}\ + =\\\chunkref{getopt.awk-begin}\ Although we only want the header and function: <\nf-chunk|getopt> - # try: locate getopt.awk for the full original file + # try: locate getopt.awk for the full original file - # as part of your standard awk installation + # as part of your standard awk installation - =\\\chunkref{getopt.awk-header}\ + =\\\chunkref{getopt.awk-header}\ - \; + - =\\\chunkref{getopt.awk-getopt()}\ + =\\\chunkref{getopt.awk-getopt()}\ @@ -4371,48 +4397,50 @@ listing and contain the chunk name. <\nf-chunk|./fangle.module> - #\\DeclareLyXModule{Fangle Literate Listings} + #\\DeclareLyXModule{Fangle Literate Listings} - #DescriptionBegin + #DescriptionBegin - # \ Fangle literate listings allow one to write + # \ Fangle literate listings allow one to write - # \ \ literate programs after the fashion of noweb, but without having + # \ \ literate programs after the fashion of noweb, but without + having - # \ \ to use noweave to generate the documentation. Instead the listings + # \ \ to use noweave to generate the documentation. Instead the + listings - # \ \ package is extended in conjunction with the noweb package to + # \ \ package is extended in conjunction with the noweb package to implement - # \ \ to code formating directly as latex. + # \ \ to code formating directly as latex. - # \ The fangle awk script + # \ The fangle awk script - #DescriptionEnd + #DescriptionEnd - \; + - =\\\chunkref{gpl3-copyright.hashed}\ + =\\\chunkref{gpl3-copyright.hashed}\ - \; + - Format 11 + Format 11 - \; + - AddToPreamble + AddToPreamble - =\\\chunkref{./fangle.sty}\ + =\\\chunkref{./fangle.sty}\ - EndPreamble + EndPreamble - \; + - =\\\chunkref{chunkstyle}\ + =\\\chunkref{chunkstyle}\ - \; + - =\\\chunkref{chunkref}\ + =\\\chunkref{chunkref}\ Because modules are not yet a language supported by fangle or @@ -4420,9 +4448,9 @@ line of the GPL3 license commence with a # <\nf-chunk|gpl3-copyright.hashed> - #=\\\chunkref{gpl3-copyright}\ + #=\\\chunkref{gpl3-copyright}\ - \; + @@ -4443,47 +4471,47 @@ We set PassThru to 1 because the user is actually entering raw latex. <\nf-chunk|chunkstyle> - Style Chunk + Style Chunk - \ \ LatexType \ \ \ \ \ \ \ \ \ \ \ \ Command + \ LatexType \ \ \ \ \ \ \ \ \ \ \ \ Command - \ \ LatexName \ \ \ \ \ \ \ \ \ \ \ \ Chunk + \ LatexName \ \ \ \ \ \ \ \ \ \ \ \ Chunk - \ \ Margin \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ First_Dynamic + \ Margin \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ First_Dynamic - \ \ LeftMargin \ \ \ \ \ \ \ \ \ \ \ Chunk:xxx + \ LeftMargin \ \ \ \ \ \ \ \ \ \ \ Chunk:xxx - \ \ LabelSep \ \ \ \ \ \ \ \ \ \ \ \ \ xx + \ LabelSep \ \ \ \ \ \ \ \ \ \ \ \ \ xx - \ \ LabelType \ \ \ \ \ \ \ \ \ \ \ \ Static + \ LabelType \ \ \ \ \ \ \ \ \ \ \ \ Static - \ \ LabelString \ \ \ \ \ \ \ \ \ \ "Chunk:" + \ LabelString \ \ \ \ \ \ \ \ \ \ "Chunk:" - \ \ Align \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ Left + \ Align \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ Left - \ \ PassThru \ \ \ \ \ \ \ \ \ \ \ \ \ 1 + \ PassThru \ \ \ \ \ \ \ \ \ \ \ \ \ 1 - \; + To make the label very visible we choose a larger font coloured red. <\nf-chunk|chunkstyle> - \ \ LabelFont + \ LabelFont - \ \ \ \ Family \ \ \ \ \ \ \ \ \ \ \ \ \ Sans + \ \ \ Family \ \ \ \ \ \ \ \ \ \ \ \ \ Sans - \ \ \ \ Size \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ Large + \ \ \ Size \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ Large - \ \ \ \ Series \ \ \ \ \ \ \ \ \ \ \ \ \ Bold + \ \ \ Series \ \ \ \ \ \ \ \ \ \ \ \ \ Bold - \ \ \ \ Shape \ \ \ \ \ \ \ \ \ \ \ \ \ \ Italic + \ \ \ Shape \ \ \ \ \ \ \ \ \ \ \ \ \ \ Italic - \ \ \ \ Color \ \ \ \ \ \ \ \ \ \ \ \ \ \ red + \ \ \ Color \ \ \ \ \ \ \ \ \ \ \ \ \ \ red - \ \ EndFont + \ EndFont - End + End @@ -4492,25 +4520,25 @@ references to chunks. <\nf-chunk|chunkref> - InsetLayout Chunkref + InsetLayout Chunkref - \ \ LyxType \ \ \ \ \ \ \ \ \ \ \ \ \ \ charstyle + \ LyxType \ \ \ \ \ \ \ \ \ \ \ \ \ \ charstyle - \ \ LatexType \ \ \ \ \ \ \ \ \ \ \ \ Command + \ LatexType \ \ \ \ \ \ \ \ \ \ \ \ Command - \ \ LatexName \ \ \ \ \ \ \ \ \ \ \ \ chunkref + \ LatexName \ \ \ \ \ \ \ \ \ \ \ \ chunkref - \ \ PassThru \ \ \ \ \ \ \ \ \ \ \ \ \ 1 + \ PassThru \ \ \ \ \ \ \ \ \ \ \ \ \ 1 - \ \ LabelFont \ \ \ \ \ \ \ \ \ \ \ \ + \ LabelFont \ \ \ \ \ \ \ \ \ \ \ \ - \ \ \ \ Shape \ \ \ \ \ \ \ \ \ \ \ \ \ \ Italic + \ \ \ Shape \ \ \ \ \ \ \ \ \ \ \ \ \ \ Italic - \ \ \ \ Color \ \ \ \ \ \ \ \ \ \ \ \ \ \ red + \ \ \ Color \ \ \ \ \ \ \ \ \ \ \ \ \ \ red - \ \ EndFont + \ EndFont - End + End @@ -4520,13 +4548,13 @@ markup module expects here. <\nf-chunk|./fangle.sty> - \\usepackage{listings}% + \\usepackage{listings}% - \\usepackage{noweb}% + \\usepackage{noweb}% - \\usepackage{xargs}% + \\usepackage{xargs}% - \\renewcommand{\\code}[1]{\\texttt{#1}}% + \\renewcommand{\\code}[1]{\\texttt{#1}}% We also define a macro, for use as: @@ -4535,18 +4563,18 @@ . <\nf-chunk|./fangle.sty> - \\lstnewenvironment{Chunk}{\\relax}{\\relax}% + \\lstnewenvironment{Chunk}{\\relax}{\\relax}% We also define a suitable of parameters that suit the literate programming style after the fashion of . <\nf-chunk|./fangle.sty> - \\lstset{numbers=left, stepnumber=5, numbersep=5pt, + \\lstset{numbers=left, stepnumber=5, numbersep=5pt, - \ \ \ \ \ \ \ \ breaklines=false,basicstyle=\\ttfamily, + \ \ \ \ \ \ \ breaklines=false,basicstyle=\\ttfamily, - \ \ \ \ \ \ \ \ numberstyle=\\tiny, language=C}% + \ \ \ \ \ \ \ numberstyle=\\tiny, language=C}% We also define a notangle-like mechanism for escaping to from the @@ -4564,7 +4592,7 @@ shown... we need to somehow escape this representation... <\nf-chunk|./fangle.sty> - \\lstset{escapeinside={=\}{\}}% + \\lstset{escapeinside={=\}{\}}% Although our macros will contain the symbol, they will be @@ -4577,15 +4605,15 @@ remember the old maketitle in case we need it. <\nf-chunk|./fangle.sty> - %\\makeatletter + %\\makeatletter - %somehow re-defining maketitle gives us a left-aligned title + %somehow re-defining maketitle gives us a left-aligned title - %which is extactly what our specially formatted title needs! + %which is extactly what our specially formatted title needs! - \\global\\let\\fangle@lst@maketitle\\lst@maketitle% + \\global\\let\\fangle@lst@maketitle\\lst@maketitle% - \\global\\def\\lst@maketitle{}% + \\global\\def\\lst@maketitle{}% @@ -4596,15 +4624,15 @@ and restore in in lstlistings Init hook. <\nf-chunk|./fangle.sty> - \\def\\Chunk#1{% + \\def\\Chunk#1{% - \ \ \\lstset{title={\\fanglecaption},name=#1}% + \ \\lstset{title={\\fanglecaption},name=#1}% - \ \ \\global\\edef\\lst@chunkname{\\lst@intname}% + \ \\global\\edef\\lst@chunkname{\\lst@intname}% - }% + }% - \\def\\lst@chunkname{\\empty}% + \\def\\lst@chunkname{\\empty}% @@ -4615,7 +4643,7 @@ the listings package complaining. <\nf-chunk|./fangle.sty> - \\lst@Key{params}\\relax{\\def\\fangle@chunk@params{#1}}% + \\lst@Key{params}\\relax{\\def\\fangle@chunk@params{#1}}% As it is common to define a chunk which then needs appending to another @@ -4623,7 +4651,7 @@ include, we support an append= option. <\nf-chunk|./fangle.sty> - \\lst@Key{append}\\relax{\\def\\fangle@chunk@append{#1}}% + \\lst@Key{append}\\relax{\\def\\fangle@chunk@append{#1}}% @@ -4672,7 +4700,7 @@ restore at the beginning of a chunk. <\nf-chunk|./fangle.sty> - \\newcounter{fangle@chunkcounter}% + \\newcounter{fangle@chunkcounter}% We construct the name of this variable to store the counter to be the text @@ -4704,41 +4732,41 @@ package will interpret as not existing. <\nf-chunk|./fangle.sty> - \\def\\fangle@caption{% + \\def\\fangle@caption{% - \ \ \\edef\\chunkcount{lst-chunk-\\lst@intname}% + \ \\edef\\chunkcount{lst-chunk-\\lst@intname}% - \ \ \\@ifundefined{\\chunkcount}{% + \ \\@ifundefined{\\chunkcount}{% - \ \ \ \ \\expandafter\\gdef\\csname \\chunkcount\\endcsname{0}% + \ \ \ \\expandafter\\gdef\\csname \\chunkcount\\endcsname{0}% - \ \ \ \ \\setcounter{fangle@chunkcounter}{\\csname + \ \ \ \\setcounter{fangle@chunkcounter}{\\csname \\chunkcount\\endcsname}% - \ \ \ \ \\let\\prevchunkname\\relax% + \ \ \ \\let\\prevchunkname\\relax% - \ \ }{% + \ }{% - \ \ \ \ \\setcounter{fangle@chunkcounter}{\\csname + \ \ \ \\setcounter{fangle@chunkcounter}{\\csname \\chunkcount\\endcsname}% - \ \ \ \ \\edef\\prevchunkname{\\lst@intname-\\arabic{fangle@chunkcounter}}% + \ \ \ \\edef\\prevchunkname{\\lst@intname-\\arabic{fangle@chunkcounter}}% - \ \ }% + \ }% After incrementing the chunk counter, we then define the name of this chunk, as well as the name of the first chunk. <\nf-chunk|./fangle.sty> - \ \ \\addtocounter{fangle@chunkcounter}{1}% + \ \\addtocounter{fangle@chunkcounter}{1}% - \ \ \\global\\expandafter\\edef\\csname + \ \\global\\expandafter\\edef\\csname \\chunkcount\\endcsname{\\arabic{fangle@chunkcounter}}% - \ \ \\edef\\chunkname{\\lst@intname-\\arabic{fangle@chunkcounter}}% + \ \\edef\\chunkname{\\lst@intname-\\arabic{fangle@chunkcounter}}% - \ \ \\edef\\firstchunkname{\\lst@intname-1}% + \ \\edef\\firstchunkname{\\lst@intname-1}% We now need to calculate the name of the next chunk. We do this by @@ -4750,11 +4778,11 @@ label then we define to . <\nf-chunk|./fangle.sty> - \ \ \\addtocounter{fangle@chunkcounter}{1}% + \ \\addtocounter{fangle@chunkcounter}{1}% - \ \ \\edef\\nextchunkname{\\lst@intname-\\arabic{fangle@chunkcounter}}% + \ \\edef\\nextchunkname{\\lst@intname-\\arabic{fangle@chunkcounter}}% - \ \ \\@ifundefined{r@label-\\nextchunkname}{\\let\\nextchunkname\\relax}{}% + \ \\@ifundefined{r@label-\\nextchunkname}{\\let\\nextchunkname\\relax}{}% The noweb package requires that we define a for every @@ -4767,13 +4795,13 @@ that anyway. <\nf-chunk|./fangle.sty> - \ \ \\sublabel{\\chunkname}% + \ \\sublabel{\\chunkname}% - % define this label for every chunk instance, so we + % define this label for every chunk instance, so we - % can tell when we are the last chunk of this name + % can tell when we are the last chunk of this name - \ \ \\label{label-\\chunkname}% + \ \\label{label-\\chunkname}% We also try and add the chunk to the list of listings, but I'm afraid we @@ -4781,7 +4809,7 @@ references. <\nf-chunk|./fangle.sty> - \ \ \\addcontentsline{lol}{lstlisting}{\\lst@name~[\\protect\\subpageref{\\chunkname}]}% + \ \\addcontentsline{lol}{lstlisting}{\\lst@name~[\\protect\\subpageref{\\chunkname}]}% We then call the noweb output macros in the same way that noweave generates @@ -4790,67 +4818,67 @@ output somewhat. <\nf-chunk|./fangle.sty> - \ \ \\nwmargintag{% + \ \\nwmargintag{% - \ \ \ \ {% + \ \ \ {% - \ \ \ \ \ \ \\nwtagstyle{}% + \ \ \ \ \ \\nwtagstyle{}% - \ \ \ \ \ \ \\subpageref{\\chunkname}% + \ \ \ \ \ \\subpageref{\\chunkname}% - \ \ \ \ }% + \ \ \ }% - \ \ }% + \ }% - % + % - \ \ \\moddef{% + \ \\moddef{% - \ \ \ \ {\\lst@name}% + \ \ \ {\\lst@name}% - \ \ \ \ {% + \ \ \ {% - \ \ \ \ \ \ \\nwtagstyle{}\\/% + \ \ \ \ \ \\nwtagstyle{}\\/% - \ \ \ \ \ \ \\@ifundefined{fangle@chunk@params}{}{% + \ \ \ \ \ \\@ifundefined{fangle@chunk@params}{}{% - \ \ \ \ \ \ \ \ (\\fangle@chunk@params)% + \ \ \ \ \ \ \ (\\fangle@chunk@params)% - \ \ \ \ \ \ }% + \ \ \ \ \ }% - \ \ \ \ \ \ [\\csname \\chunkcount\\endcsname]~% + \ \ \ \ \ [\\csname \\chunkcount\\endcsname]~% - \ \ \ \ \ \ \\subpageref{\\firstchunkname}% + \ \ \ \ \ \\subpageref{\\firstchunkname}% - \ \ \ \ }% + \ \ \ }% - \ \ \ \ \\@ifundefined{fangle@chunk@append}{}{% + \ \ \ \\@ifundefined{fangle@chunk@append}{}{% - \ \ \ \ \\ifx{}\\fangle@chunk@append{x}\\else% + \ \ \ \\ifx{}\\fangle@chunk@append{x}\\else% - \ \ \ \ \ \ \ \ ,~add~to~\\fangle@chunk@append% + \ \ \ \ \ \ \ ,~add~to~\\fangle@chunk@append% - \ \ \ \ \\fi% + \ \ \ \\fi% - \ \ \ \ }% + \ \ \ }% - \\global\\def\\fangle@chunk@append{}% + \\global\\def\\fangle@chunk@append{}% - \\lstset{append=x}% + \\lstset{append=x}% - \ \ }% + \ }% - % + % - \ \ \\ifx\\relax\\prevchunkname\\endmoddef\\else\\plusendmoddef\\fi% + \ \\ifx\\relax\\prevchunkname\\endmoddef\\else\\plusendmoddef\\fi% - % \ \\nwstartdeflinemarkup% + % \ \\nwstartdeflinemarkup% - \ \ \\nwprevnextdefs{\\prevchunkname}{\\nextchunkname}% + \ \\nwprevnextdefs{\\prevchunkname}{\\nextchunkname}% - % \ \\nwenddeflinemarkup% + % \ \\nwenddeflinemarkup% - }% + }% Originally this was developed as a aspect, in the Init @@ -4859,15 +4887,15 @@ listings name to the name passed to the command, though. <\nf-chunk|./fangle.sty> - %\\lst@BeginAspect{fangle} + %\\lst@BeginAspect{fangle} - %\\lst@Key{fangle}{true}[t]{\\lstKV@SetIf{#1}{true}} + %\\lst@Key{fangle}{true}[t]{\\lstKV@SetIf{#1}{true}} - \\lst@AddToHookExe{PreSet}{\\global\\let\\lst@intname\\lst@chunkname} + \\lst@AddToHookExe{PreSet}{\\global\\let\\lst@intname\\lst@chunkname} - \\lst@AddToHook{Init}{}%\\fangle@caption} + \\lst@AddToHook{Init}{}%\\fangle@caption} - %\\lst@EndAspect + %\\lst@EndAspect @@ -4889,89 +4917,89 @@ <\nf-chunk|./fangle.sty> - \\def\\chunkref@args#1,{% + \\def\\chunkref@args#1,{% - \ \ \\def\\arg{#1}% + \ \\def\\arg{#1}% - \ \ \\lst@ReplaceIn\\arg\\lst@filenamerpl% + \ \\lst@ReplaceIn\\arg\\lst@filenamerpl% - \ \ \\arg% + \ \\arg% - \ \ \\@ifnextchar){\\relax}{, \\chunkref@args}% + \ \\@ifnextchar){\\relax}{, \\chunkref@args}% - }% + }% - \\newcommand\\chunkref[2][0]{% + \\newcommand\\chunkref[2][0]{% - \ \ \\@ifnextchar({\\chunkref@i{#1}{#2}}{\\chunkref@i{#1}{#2}()}% + \ \\@ifnextchar({\\chunkref@i{#1}{#2}}{\\chunkref@i{#1}{#2}()}% - }% + }% - \\def\\chunkref@i#1#2(#3){% + \\def\\chunkref@i#1#2(#3){% - \ \ \\def\\zero{0}% + \ \\def\\zero{0}% - \ \ \\def\\chunk{#2}% + \ \\def\\chunk{#2}% - \ \ \\def\\chunkno{#1}% + \ \\def\\chunkno{#1}% - \ \ \\def\\chunkargs{#3}% + \ \\def\\chunkargs{#3}% - \ \ \\ifx\\chunkno\\zero% + \ \\ifx\\chunkno\\zero% - \ \ \ \ \\def\\chunkname{#2-1}% + \ \ \ \\def\\chunkname{#2-1}% - \ \ \\else% + \ \\else% - \ \ \ \ \\def\\chunkname{#2-\\chunkno}% + \ \ \ \\def\\chunkname{#2-\\chunkno}% - \ \ \\fi% + \ \\fi% - \ \ \\let\\lst@arg\\chunk% + \ \\let\\lst@arg\\chunk% - \ \ \\lst@ReplaceIn\\chunk\\lst@filenamerpl% + \ \\lst@ReplaceIn\\chunk\\lst@filenamerpl% - \ \ \\LA{%\\moddef{% + \ \\LA{%\\moddef{% - \ \ \ \ {\\chunk}% + \ \ \ {\\chunk}% - \ \ \ \ {% + \ \ \ {% - \ \ \ \ \ \ \\nwtagstyle{}\\/% + \ \ \ \ \ \\nwtagstyle{}\\/% - \ \ \ \ \ \ \\ifx\\chunkno\\zero% + \ \ \ \ \ \\ifx\\chunkno\\zero% - \ \ \ \ \ \ \\else% + \ \ \ \ \ \\else% - \ \ \ \ \ \ [\\chunkno]% + \ \ \ \ \ [\\chunkno]% - \ \ \ \ \ \ \\fi% + \ \ \ \ \ \\fi% - \ \ \ \ \ \ \\ifx\\chunkargs\\empty% + \ \ \ \ \ \\ifx\\chunkargs\\empty% - \ \ \ \ \ \ \\else% + \ \ \ \ \ \\else% - \ \ \ \ \ \ \ \ (\\chunkref@args #3,)% + \ \ \ \ \ \ \ (\\chunkref@args #3,)% - \ \ \ \ \ \ \\fi% + \ \ \ \ \ \\fi% - \ \ \ \ \ \ ~\\subpageref{\\chunkname}% + \ \ \ \ \ ~\\subpageref{\\chunkname}% - \ \ \ \ }% + \ \ \ }% - \ \ }% + \ }% - \ \ \\RA%\\endmoddef% + \ \\RA%\\endmoddef% - }% + }% <\nf-chunk|./fangle.sty> - % + % - %\\makeatother + %\\makeatother @@ -4985,106 +5013,109 @@ me. <\nf-chunk|lyx-build> - #! /bin/sh + #! /bin/sh - set -x + set -x - \; + - =\\\chunkref{lyx-build-helper}\ + =\\\chunkref{lyx-build-helper}\ - cd $PROJECT_DIR \|\| exit 1 + cd $PROJECT_DIR \|\| exit 1 - \; + - /usr/local/bin/fangle -R./fangle $TEX_SRC \ ./fangle + /usr/local/bin/fangle -R./fangle $TEX_SRC \ ./fangle - /usr/local/bin/fangle -R./fangle.module $TEX_SRC \ ./fangle.module + /usr/local/bin/fangle -R./fangle.module $TEX_SRC \ + ./fangle.module - \; + - =\\\chunkref{test:helpers}\ + =\\\chunkref{test:helpers}\ - export FANGLE=./fangle + export FANGLE=./fangle - export TMP=${TMP:-/tmp} + export TMP=${TMP:-/tmp} - =\\\chunkref{test:run-tests}\ + =\\\chunkref{test:run-tests}\ - # Now check that we can extract a fangle that also passes the tests! + # Now check that we can extract a fangle that also passes the + tests! - $FANGLE -R./fangle $TEX_SRC \ ./new-fangle + $FANGLE -R./fangle $TEX_SRC \ ./new-fangle - export FANGLE=./new-fangle + export FANGLE=./new-fangle - =\\\chunkref{test:run-tests}\ + =\\\chunkref{test:run-tests}\ <\nf-chunk|test:run-tests> - # run tests + # run tests - $FANGLE -Rpca-test.awk $TEX_SRC \| awk -f - \|\| exit 1 + $FANGLE -Rpca-test.awk $TEX_SRC \| awk -f - \|\| exit 1 - =\\\chunkref{test:cromulence}\ + =\\\chunkref{test:cromulence}\ - =\\\chunkref{test:escapes}\ + =\\\chunkref{test:escapes}\ - =\\\chunkref{test:chunk-params}\ + =\\\chunkref{test:chunk-params}\ With a lyx-build-helper <\nf-chunk|lyx-build-helper> - PROJECT_DIR="$LYX_r" + PROJECT_DIR="$LYX_r" - LYX_SRC="$PROJECT_DIR/${LYX_i%.tex}.lyx" + LYX_SRC="$PROJECT_DIR/${LYX_i%.tex}.lyx" - TEX_DIR="$LYX_p" + TEX_DIR="$LYX_p" - TEX_SRC="$TEX_DIR/$LYX_i" + TEX_SRC="$TEX_DIR/$LYX_i" <\nf-chunk|./gen-www> - #python -m elyxer --css lyx.css $LYX_SRC \| \\ + #python -m elyxer --css lyx.css $LYX_SRC \| \\ - # \ iconv -c -f utf-8 -t ISO-8859-1//TRANSLIT \| \\ + # \ iconv -c -f utf-8 -t ISO-8859-1//TRANSLIT \| \\ - # \ sed 's/UTF-8"\\(.\\)\/ISO-8859-1"\\1\/' \ + # \ sed 's/UTF-8"\\(.\\)\/ISO-8859-1"\\1\/' \ www/docs/fangle.html - \; + - python -m elyxer --css lyx.css --iso885915 --html --destdirectory + python -m elyxer --css lyx.css --iso885915 --html --destdirectory www/docs/fangle.e \\ - \ \ \ \ \ \ \ fangle.lyx \ www/docs/fangle.e/fangle.html + \ \ \ \ \ \ fangle.lyx \ www/docs/fangle.e/fangle.html - \; + - ( mkdir -p www/docs/fangle && cd www/docs/fangle && \\ + ( mkdir -p www/docs/fangle && cd www/docs/fangle && \\ - \ \ lyx -e latex ../../../fangle.lyx && \\ + \ lyx -e latex ../../../fangle.lyx && \\ - \ \ htlatex ../../../fangle.tex "xhtml,fn-in" && \\ + \ htlatex ../../../fangle.tex "xhtml,fn-in" && \\ - \ \ sed -i -e 's/\!--l\\. [0-9][0-9]* *--\//g' fangle.html + \ sed -i -e 's/\!--l\\. [0-9][0-9]* *--\//g' + fangle.html - ) + ) - \; + - ( mkdir -p www/docs/literate && cd www/docs/literate && \\ + ( mkdir -p www/docs/literate && cd www/docs/literate && \\ - \ \ lyx -e latex ../../../literate.lyx && \\ + \ lyx -e latex ../../../literate.lyx && \\ - \ \ htlatex ../../../literate.tex "xhtml,fn-in" && \\ + \ htlatex ../../../literate.tex "xhtml,fn-in" && \\ - \ \ sed -i -e 's/\!--l\\. [0-9][0-9]* *--\$//g' + \ sed -i -e 's/\!--l\\. [0-9][0-9]* *--\$//g' literate.html - ) + ) @@ -5092,45 +5123,45 @@ First you will need the tex output, then you can extract: <\nf-chunk|lyx-build-manual> - lyx -e latex fangle.lyx + lyx -e latex fangle.lyx - fangle -R./fangle fangle.tex \ ./fangle + fangle -R./fangle fangle.tex \ ./fangle - fangle -R./fangle.module fangle.tex \ ./fangle.module + fangle -R./fangle.module fangle.tex \ ./fangle.module <\nf-chunk|test:helpers> - passtest() { + passtest() { - \ \ if "$@" + \ if "$@" - \ \ then echo "Passed" + \ then echo "Passed" - \ \ else echo "Failed" + \ else echo "Failed" - \ \ \ \ \ \ \ return 1 + \ \ \ \ \ \ return 1 - \ \ fi + \ fi - } + } - \; + - failtest() { + failtest() { - \ \ if ! "$@" + \ if ! "$@" - \ \ then echo "Passed" + \ then echo "Passed" - \ \ else echo "Failed" + \ else echo "Failed" - \ \ \ \ \ \ \ return 1 + \ \ \ \ \ \ return 1 - \ \ fi + \ fi - } + } @@ -5138,155 +5169,158 @@ <\nf-chunk|test:chunk-params:sub> - I see a ${THING}, + I see a ${THING}, - a ${THING} of colour ${colour},\ + a ${THING} of colour ${colour},\ - and looking closer =\\\chunkref{test:chunk-params:sub:sub}(${colour})\ + and looking closer =\\\chunkref{test:chunk-params:sub:sub}(${colour})\ > <\nf-chunk|test:chunk-params:sub:sub> - a funny shade of ${colour} + a funny shade of ${colour} > <\nf-chunk|test:chunk-params:text> - What do you see? "=\\\chunkref{test:chunk-params:sub}(joe, + What do you see? "=\\\chunkref{test:chunk-params:sub}(joe, red)\" - Well, fancy! + Well, fancy! Should generate output: <\nf-chunk|test:chunk-params:result> - What do you see? "I see a joe, + What do you see? "I see a joe, - \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ a joe of colour red,\ + \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ a joe of colour red,\ - \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ and looking closer a funny shade of - red" + \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ and looking closer a funny shade + of red" - Well, fancy! + Well, fancy! And this chunk will perform the test: <\nf-chunk|test:chunk-params> - $FANGLE -Rtest:chunk-params:result $TEX_SRC \ $TMP/answer \|\| exit - 1 + $FANGLE -Rtest:chunk-params:result $TEX_SRC \ $TMP/answer + \|\| exit 1 - $FANGLE -Rtest:chunk-params:text $TEX_SRC \ $TMP/result \|\| exit 1 + $FANGLE -Rtest:chunk-params:text $TEX_SRC \ $TMP/result \|\| + exit 1 - passtest diff $TMP/answer $TMP/result \|\| (echo test:chunk-params:text - failed ; exit 1) + passtest diff $TMP/answer $TMP/result \|\| (echo + test:chunk-params:text failed ; exit 1) <\nf-chunk|Chunk: ./compile-log-lyx> - #! /bin/sh + #! /bin/sh - # can't use gtkdialog -i, cos it uses the "source" command which ubuntu - sh doesn't have + # can't use gtkdialog -i, cos it uses the "source" command which + ubuntu sh doesn't have - \; + - main() { + main() { - \ \ errors="/tmp/compile.log.$$" + \ errors="/tmp/compile.log.$$" - # \ if grep '^[^ ]*:\\( In \\\|[0-9][0-9]*: [^ ]*:\\)' \ $errors - - if grep '^[^ ]*(\\([0-9][0-9]*\\)) *: *\\(error\\\|warning\\)' \ + # \ if grep '^[^ ]*:\\( In \\\|[0-9][0-9]*: [^ ]*:\\)' \ $errors - \ \ then + if grep '^[^ ]*(\\([0-9][0-9]*\\)) *: *\\(error\\\|warning\\)' + \ $errors + + \ then - \ \ \ \ sed -i -e 's/^[^ ]*[/\\\\]\\([^/\\\\]*\\)(\\([ 0-9][ 0-9]*\\)) *: - */\\1:\\2\|\\2\|/' $errors + \ \ \ sed -i -e 's/^[^ ]*[/\\\\]\\([^/\\\\]*\\)(\\([ 0-9][ + 0-9]*\\)) *: */\\1:\\2\|\\2\|/' $errors - \ \ \ \ COMPILE_DIALOG=' + \ \ \ COMPILE_DIALOG=' - \ \vbox\ + \vbox\ - \ \ \text\ + \ \text\ - \ \ \ \ \label\Compiler errors:\/label\ + \ \ \ \label\Compiler errors:\/label\ - \ \ \/text\ + \ \/text\ - \ \ \tree exported_column="0"\ + \ \tree exported_column="0"\ - \ \ \ \ \variable\LINE\/variable\ + \ \ \ \variable\LINE\/variable\ - \ \ \ \ \height\400\/height\\width\800\/width\ + \ \ \ \height\400\/height\\width\800\/width\ - \ \ \ \ \label\File \| Line \| Message\/label\ + \ \ \ \label\File \| Line \| + Message\/label\ - \ \ \ \ \action\'". $SELF ; "'lyxgoto + \ \ \ \action\'". $SELF ; "'lyxgoto $LINE\/action\ - \ \ \ \ \input\'"cat $errors"'\/input\ + \ \ \ \input\'"cat $errors"'\/input\ - \ \ \/tree\ + \ \/tree\ - \ \ \hbox\ + \ \hbox\ - \ \ \ \button\\label\Build\/label\ + \ \ \button\\label\Build\/label\ - \ \ \ \ \ \action\lyxclient -c "LYXCMD:build-program" + \ \ \ \ \action\lyxclient -c "LYXCMD:build-program" &\/action\ - \ \ \ \/button\ + \ \ \/button\ - \ \ \ \button ok\\/button\ + \ \ \button ok\\/button\ - \ \ \/hbox\ + \ \/hbox\ - \ \/vbox\ + \/vbox\ - ' + ' - \ \ \ \ export COMPILE_DIALOG + \ \ \ export COMPILE_DIALOG - \ \ \ \ ( gtkdialog --program=COMPILE_DIALOG ; rm $errors ) & + \ \ \ ( gtkdialog --program=COMPILE_DIALOG ; rm $errors ) & - \ \ else + \ else - \ \ \ \ rm $errors + \ \ \ rm $errors - \ \ fi + \ fi - } + } - \; + - lyxgoto() { + lyxgoto() { - \ \ file="${LINE%:*}" + \ file="${LINE%:*}" - \ \ line="${LINE##*:}" + \ line="${LINE##*:}" - \ \ extraline=\0cat $file \| head -n $line \| tac \| sed + \ extraline=\0cat $file \| head -n $line \| tac \| sed '/^\\\\\\\\begin{lstlisting}/q' \| wc -l\0 - \ \ extraline=\0expr $extraline - 1\0 + \ extraline=\0expr $extraline - 1\0 - \ \ lyxclient -c "LYXCMD:command-sequence server-goto-file-row $file + \ lyxclient -c "LYXCMD:command-sequence server-goto-file-row $file $line ; char-forward ; repeat $extraline paragraph-down ; paragraph-up-select" - } + } - \; + - SELF="$0" + SELF="$0" - if test -z "$COMPILE_DIALOG" + if test -z "$COMPILE_DIALOG" - then main "$@"\ + then main "$@"\ - fi + fi \; -- 2.11.4.GIT