From f60c2c93c50a174b6f9fb879c7363038a97fa6fe Mon Sep 17 00:00:00 2001 From: Karl Berry Date: Mon, 30 Jan 2012 00:35:07 +0000 Subject: context-filter (28jan12) git-svn-id: svn://tug.org/texlive/trunk@25229 c570f23f-e606-0410-a88d-b1316a301751 --- .../texmf-dist/doc/context/third/filter/filter.txt | 94 ++++------ .../tex/context/third/filter/t-filter.mkii | 106 ++++++----- .../tex/context/third/filter/t-filter.mkiv | 204 +++++++++++---------- 3 files changed, 200 insertions(+), 204 deletions(-) diff --git a/Master/texmf-dist/doc/context/third/filter/filter.txt b/Master/texmf-dist/doc/context/third/filter/filter.txt index 396596cec36..13e1acc4898 100644 --- a/Master/texmf-dist/doc/context/third/filter/filter.txt +++ b/Master/texmf-dist/doc/context/third/filter/filter.txt @@ -49,7 +49,7 @@ To verify, check if returns a meaningful path. If not, you have to manually install the module. Download the latest version of the module from -[http://github.com/adityam/filter/downloads](http://github.com/adityam/filter/downloads) +[http://modules.contextgarden.net/filter](http://modules.contextgarden.net/filter) and unzip it either `$TEXMFHOME` or `$TEXMFLOCAL`. Run mktexlsr @@ -67,8 +67,7 @@ will return the path where you stored the file. Unfortunately, that is not enough. For the module to work, TeX must be able to call an external program. This feature is a potential security risk and is -disabled by default on most TeX distributions. To enable this feature, you must -set +disabled by default on most TeX distributions. To enable this feature, set shell_escape=t @@ -104,9 +103,9 @@ Using this filter from within ConTeXt is pretty simple: [filtercommand={pandoc -t context -o \externalfilteroutputfile\space \externalfilterinputfile}] Yes, its that easy! The only thing to note is that TeX macros gobble spaces, so -we have to manually insert a space after `\externalfilteroutputfile`. +I inserted a manual space after `\externalfilteroutputfile`. -This defines four things: +The above `\defineexternalfilter` macro defines: 1. An environment @@ -148,11 +147,11 @@ Dealing with slow filters The above definition of a markdown filter creates two additional files: an "input" file and an "output" file, *irrespective of the number of times the environment is called*. For each markdown environment, -ConTeXt overwrites the input file and pandoc overwrites the output file. This -behavior is the default as I do not want to clutter the current directory with -temporary files. The trade off is that for each document run, the filter is +ConTeXt overwrites the input file and pandoc overwrites the output +file; as a result, the current directory is not cluttered with temporary files. +The trade off is that for each document run, the filter is invoked as many times as the number of markdown environments. Since getting -cross-referencing right normally takes two or three runs, effectively the filter +cross-referencing right normally takes two to three runs, effectively the filter is run two or three times more than required. A filter like `pandoc` is fairly fast, so these extra runs are not noticeable. But some filters, like the R-programming language for which simply startup and exit takes about 0.3 @@ -160,28 +159,25 @@ seconds, are slow. In such cases, the additional runs start adding up. A better trade off is to store the contents of each environment in a separate file and invoke the filter only if a file *changes in between successive runes*. -The second behavior is achieved by adding `continue=yes` option to the +The second behavior is achieved by adding `cache=yes` option to the definition: \defineexternalfilter [...] [... - continue=yes, + cache=yes, ...] -Sometimes you want to force a rerun of all filters, even when `continue=yes` is -set. This could be because the filters depend on an external script that might -have changed. To force a rerun of all filters, enable the -[mode](http://wiki.contextgarden.net/Modes) `force` either by adding -`mode=force` to the compiler: +Sometimes you want to force the rerun of a filter, even if the content of the +environment has not changed. This could be because the filters depend on an +external script that might have changed. To force a rerun of a filter use - context --mode=force filename -or adding - - \enablemode[force] - -somewhere near the top of your file. + \defineexternalfilter + [...] + [... + cache=force, + ...] Reading the input ---------------- @@ -213,10 +209,10 @@ Names of temporary files ------------------------ By default, `\externalfilterinputfile` is set to `\jobname-temp-.tmp`, where -`` is the first argument of `\defineexternalfilter`. When `continue=yes` +`` is the first argument of `\defineexternalfilter`. When `cache=yes` is set, `\externalfilterinputfile` equals `\jobname-temp--.tmp`, where -`` is the number of filter environments that have appeared so far. In this -case, a `\jobname-temp--.tmp.md5` file, which stores the `md5` sum of the +`` is the number of filter environments that have appeared so far. In MkII, +a `\jobname-temp--.tmp.md5` file, which stores the `md5` sum of the input file is also created. A macro `\externalfilterbasefile` stores the name of the input file without the @@ -231,15 +227,7 @@ key. For example [filtercommand={...}, output={\externalfilterbasefile.png}] -changes the output extension to `.png`. We also need to either set - - \defineexternalfilter - [...] - [.... - read=no, - ...] - -or set +changes the output extension to `.png`. To read the generated PNG file, set: \defineexternalfilter [...] @@ -255,7 +243,7 @@ Output Directory ---------------- This module creates a lot of temporary files that clutter the current directory. -If you prefer the temporary files to be created in another directory, specify +If you prefer the temporary files to be created in another directory, use the `directory` option, e.g., \defineexternalfilter @@ -289,13 +277,10 @@ Disabling filters Adding `state=stop` option disables the filters. The `\externalfilterinputfile` is still written, but the filter is not run. -When used in conjunction with `continue=yes` and `directory=...`, this +When used in conjunction with `cache=yes` and `directory=...`, this is useful for sharing your files with others who do not have the external program that you are using. -Enabling the `reuse` mode (before the `filter` module is loaded) sets -`state=stop` as the default value. - Deleting temporary files ------------------------ @@ -317,7 +302,7 @@ Standard options - `before` and `after`: to set the spacing of the environment or enclose the output in a frame, etc. - `style` and `color`: to set the color and style of the output. -- `indentnext`: Should the next line be indented? +- `indentnext`: specify if the next line is indented - `setups`: specify a list of setups (defined using `\startsetups`). These setups may be used to define commands that are needed inside the environment. @@ -342,7 +327,7 @@ R-code [R] [filtercommand={R CMD BATCH -q \externalfilterinputfile\space \externalfilteroutputfile}, output=\externalfilterbasefile.out, - continue=yes] + cache=yes] I can hide the output of a particular R-environment by @@ -368,7 +353,7 @@ of all options. The current defaults are [before=, after=, setups=, - continue=no, + cache=no, read=yes, readcommand=\ReadFile, output=\externalfilterbasefile.tex, @@ -519,8 +504,8 @@ such snippets. Define the boilerplate code in ConTeXt buffers and then use bufferafter={...list of buffers...}, ] -For example, suppose you want to generate images using a latex package that does -not work well with ConTeXt, say shak. One way to use this is as follows: first +For example, suppose you want to generate images using a LaTeX package that does +not work well with ConTeXt, say `shak`. One way to use this is as follows: first define a file that processes its content using `latex`. \defineexternalfilter @@ -578,7 +563,7 @@ GNU barcode to draw barcodes. One way to do this is [barcode] [encoding=code128, output=\externalfilterbasefile.eps, - continue=yes, + cache=yes, filtercommand=\barcodefiltercommand, readcommand=\barcodereadcommand] @@ -643,8 +628,8 @@ for this. For example, in the above barcode example, use Limitations ------------ -- In MkII, the option `continue=yes` does not work correctly with filters that have a - pipe `|` in their definition. This is because internally `continue=yes` calls +- In MkII, the option `cache=yes` does not work correctly with filters that have a + pipe `|` in their definition. This is because internally `cache=yes` calls mtxrun --ifchanged=filename --direct filtercommand @@ -655,7 +640,7 @@ Limitations MTXrun | MTXrun | - In MkIV, `continue=yes` calls + In MkIV, `cache=yes` calls \ctxlua{job.files.run("filename", "filtercommand")} @@ -669,9 +654,9 @@ Messages and Tracing The filter module outputs some diagnostic information on the console output to indicate what is happening. Loading of the module is indicated by: - loading : ConTeXt User Module / Filter + loading : ConTeXt User Module / Filter (ver: ) -Whenever a filter is executed, the expanded name of the command is displayed. +Whenever a filter is defined the expanded name of the command is displayed. For example, for the markdown filter we get: t-filter > command : pandoc -w context -o markdown-temp-markdown.tex markdown-temp-markdown.tmp @@ -697,15 +682,12 @@ information add in your tex file. This shows the name of the filters when they are defined. In MkIV, `\traceexternalfilters` also enables the trackers for `graphic.run`, so -when `continue=yes` is used, message like +when `cache=yes` is used, message like graphics > run > processing file, no changes in '-temp--.tmp', not processed are shown. - - - Version History -------------- @@ -760,3 +742,7 @@ Version History - Use `job.files.run` instead of `mtxrun --ifchanged` in MkIV. - **2011.12.17** - Split into `.mkii` and `.mkiv` versions +- **2012.01.26** + - Renamed `continue` to `cache`. Using `continue=yes` still works + - Removed `force` and `reuse` modes (too easy to clash with user modes). + - Functionality of force mode implemented using `cache=force`. diff --git a/Master/texmf-dist/tex/context/third/filter/t-filter.mkii b/Master/texmf-dist/tex/context/third/filter/t-filter.mkii index 9735eab750c..de772ec3bd3 100644 --- a/Master/texmf-dist/tex/context/third/filter/t-filter.mkii +++ b/Master/texmf-dist/tex/context/third/filter/t-filter.mkii @@ -1,6 +1,6 @@ %D \module %D [ file=t-filter, -%D version=2011.12.17, +%D version=2012.01.26, %D title=\CONTEXT\ User Module, %D subtitle=Filter, %D author=Aditya Mahajan, @@ -9,10 +9,22 @@ %D email=adityam ieee org, %D license=Simplified BSD License] -\writestatus{loading}{Filter (ver: 2011.12.17)} +\writestatus{loading}{Filter (ver: 2012.01.26)} \ifx\undefined\normalexpanded \let\normalexpanded\expanded \fi +% Make \doifinset expandable in MkII + +\def\p!doifinsetelse#1#2#3#4% + {\donefalse + \edef\!!stringa{#3}% + \ifx\!!stringa\empty + \else + \processcommacommand[#4]\p!docheckiteminset + \fi + \ifdone\expandafter#1\else\expandafter#2\fi} + + \startmodule [filter] \usemodule [module-catcodes] @@ -24,14 +36,14 @@ %D the module definition, and thereby reduces the risk of a typo. %D Currently, only English names are provided. If someone wants a %D multi-lingual interface, let me know and I will add other language -%D names as well, +%D names as well, \startinterface all \setinterfaceconstant {filter} {filter} \setinterfaceconstant {filtercommand} {filtercommand} - \setinterfaceconstant {output} {output} - \setinterfaceconstant {read} {read} - \setinterfaceconstant {readcommand} {readcommand} + \setinterfaceconstant {output} {output} + \setinterfaceconstant {read} {read} + \setinterfaceconstant {readcommand} {readcommand} \stopinterface @@ -63,7 +75,6 @@ \setinterfacemessage\m!externalfilter{forbidden} {Fatal Error: Cannot use absolute path -- as directory} \setinterfacemessage\m!externalfilter{slash} {Appending / to directory -- } \setinterfacemessage\m!externalfilter{reuse} {\c!state=\v!stop : Not running filter on file --} -\setinterfacemessage\m!externalfilter{force} {mode 'force' enabled: Forcing running of filters} %D \subject {Tracing Macros} @@ -104,7 +115,7 @@ \setupexternalfilter[#1][\s!parent=\externalfilter@namespace,#2] \edef\externalfilter@name{#1} - \doif{\externalfilterparameter\c!continue}\v!yes + \doifinset{\externalfilterparameter\c!cache}{\v!yes,\v!force} {\expandafter\newcounter\csname\externalfilter@count\endcsname} \setvalue{\e!start#1}{\bgroup\obeylines\dodoubleargument\externalfilter@start[#1]} @@ -116,10 +127,10 @@ \stoptexdefinition -\starttexdefinition externalfilter@start [#1][#2] +\starttexdefinition externalfilter@start [#1][#2] % #1 = filter % #2 = options - \egroup %\bgroup in \start#1 + \egroup %\bgroup in \start#1 \edef\externalfilter@name{#1} @@ -142,13 +153,13 @@ \setupexternalfilter[#1][\c!name=,#2] \externalfilter@set_directory - + \edef\externalfilter@input_file{#3} \splitfilename{#3} %NOTE: \edef doesn not work because \splitoffname is not expandable \def\externalfilter@base_file {\splitoffname} - % The output is always in the directory specified by + % The output is always in the directory specified by % \c!directory; even if the input is from some other directory \def\externalfilter@output_file{\externalfilter@get_directory\externalfilterparameter\c!output} @@ -171,24 +182,24 @@ \fi \externalfilter@set_directory - + \ifthirdargument \edef\externalfilter@buffer_name{#3} \else \edef\externalfilter@buffer_name{#2} \fi - + \externalfilter@set_filenames_extras % In MkII, the above function sets the wrong value of % \type{\externalfilter@input_file}. So, we reset that name here. \edef\externalfilter@input_file {\externalfilter@base_file.\f!temporaryextension} \iftraceexternalfilters \externalfilter@show_filenames \fi - + \externalfilter@process_filter - + \stoptexdefinition - + \starttexdefinition externalfilter@inline [#1][#2] \edef\externalfilter@name{#1} @@ -240,7 +251,7 @@ \externalfilter@read_processed_file % Finalization - \doif{\externalfilterparameter\c!continue}\v!yes + \doifinset{\externalfilterparameter\c!cache}{\v!yes,\v!force} {\doglobal\expandafter\increment\csname\externalfilter@count\endcsname} \endgroup \stoptexdefinition @@ -281,7 +292,7 @@ \edef\externalfilter@get_directory{\externalfilterparameter\c!directory} \doifsomething{\externalfilter@get_directory}\externalfilter@set_directory_indeed \stoptexdefinition - + \starttexdefinition externalfilter@set_directory_indeed \doif{\externalfilter@get_first_character\externalfilter@get_directory}{/} {\writeline @@ -294,20 +305,20 @@ {\showmessage\m!externalfilter{slash}\externalfilter@get_directory \edef\externalfilter@get_directory{\externalfilter@get_directory/}} \stoptexdefinition - + %D \subsubject {Set file names} %D %D \type{\externalfilter@base_file} is the name of the temporary file without -%D extension. Its actual value depends on the state of \type{continue} key as +%D extension. Its actual value depends on the state of \type{cache} key as %D well as the value of \type{name} key. \starttexdefinition externalfilter@set_filenames \externalfilter@set_directory % Set the name of temp file for the filter - \doifelse{\externalfilterparameter\c!continue}\v!yes + \doifinsetelse{\externalfilterparameter\c!cache}{\v!yes,\v!force} {\edef\externalfilter@buffer_name{\externalfilter@temp_prefix-\externalfilter@name-\csname\externalfilter@count\endcsname}} {\edef\externalfilter@buffer_name{\externalfilter@temp_prefix-\externalfilter@name}} \doifsomething{\externalfilterparameter\c!name} @@ -321,24 +332,20 @@ \starttexdefinition externalfilter@set_filenames_extras % The following macros are useful for filter= and filtercommand= options - % The basename of the external file + % The basename of the external file \edef\externalfilter@base_file {\jobname-\externalfilter@buffer_name} - % In MkII, the buffer output is written to \TEXbufferfile{buffername} where - % the macro \TEXbufferfile is defined as - % - % \def\TEXbufferfile #1{\bufferprefix#1.\f!temporaryextension} - % - % We redefine bufferprefix to include the directory name. - \edef\bufferprefix{\externalfilter@get_directory\jobname-} - - % In MkIV, we do not need to do such jugglary, because we can specify the - % name of the file where the buffer has to be saved. This file is - % \externalfilter@input_file (because it is the input to the filter). + % Append directory name to the name of the input file \edef\externalfilter@input_file {\externalfilter@get_directory\externalfilter@base_file.\f!temporaryextension} % Append directory name to the name of the output file \edef\externalfilter@output_file{\externalfilter@get_directory\externalfilterparameter\c!output} + + % In MkII, the buffer output is written to \TEXbufferfile{buffername}. So we + % redefine \TEXbufferfile to + + \edef\TEXbufferfile##1{\externalfilter@input_file} + \stoptexdefinition @@ -350,35 +357,35 @@ \starttexdefinition externalfilter@process_filter \externalfilter@execute_filter \externalfilter@read_processed_file - \endgroup + \endgroup % Finalization - \doif{\externalfilterparameter\c!continue}\v!yes + \doifinset{\externalfilterparameter\c!cache}{\v!yes,\v!force} {\doglobal\expandafter\increment\csname\externalfilter@count\endcsname} \expanded{\checknextindentation[\externalfilterparameter\c!indentnext]} \dorechecknextindentation \stoptexdefinition -%D \subsubject {Execute Filter} +%D \subsubject {Execute Filter} \starttexdefinition externalfilter@execute_filter \processcommacommand[\externalfilterparameter{\c!filter\c!setups}]\directsetup \externalfilter@show_filtercommand - \doifelse{\externalfilterparameter\c!continue}\v!yes + \doifelse{\externalfilterparameter\c!cache}\v!yes {\doifelse{\externalfilterparameter\c!state}\v!stop {\showmessage\m!externalfilter{reuse}\externalfilter@input_file} {\doifmode{*first} - {\doifmodeelse{force} - {\showmessage\m!externalfilter{force} - \executesystemcommand - {mtxrun --direct \externalfilterparameter\c!filtercommand}} - {\executesystemcommand - {mtxrun --ifchanged=\externalfilter@input_file\space - --direct \externalfilterparameter\c!filtercommand}}}}} - {\executesystemcommand - {\externalfilterparameter\c!filtercommand}} + {\executesystemcommand + {mtxrun --ifchanged=\externalfilter@input_file\space + --direct \externalfilterparameter\c!filtercommand}}}} + {\doifelse{\externalfilterparameter\c!cache}\v!force + {\doifmode{*first} + {\executesystemcommand + {mtxrun --direct \externalfilterparameter\c!filtercommand}}} + {\executesystemcommand + {\externalfilterparameter\c!filtercommand}}} \stoptexdefinition %D \subsubject {Read output} @@ -387,7 +394,7 @@ \doif{\externalfilterparameter\c!read}\v!yes {\doiffileelse{\externalfilter@output_file} {\externalfilter@read_processed_file_indeed} - {\showmessage\m!externalfilter{notfound}\externalfilter@output_file + {\showmessage\m!externalfilter{notfound}\externalfilter@output_file \externalfilter@show_filenames \blank {\tttf [[\getmessage\m!externalfilter{missing}]]} @@ -418,6 +425,7 @@ \c!indentnext=\v!auto, \c!setups=, \c!continue=\v!no, + \c!cache=\externalfilterparameter\c!continue, % for backward compatibility \c!read=\v!yes, \c!readcommand=\ReadFile, \c!directory=, @@ -440,6 +448,6 @@ % Default value \def\externalfilter@input_file {} \def\externalfilter@output_file{} - + \protectmodulecatcodes \stopmodule diff --git a/Master/texmf-dist/tex/context/third/filter/t-filter.mkiv b/Master/texmf-dist/tex/context/third/filter/t-filter.mkiv index c4565a2af7a..74998c2e18c 100644 --- a/Master/texmf-dist/tex/context/third/filter/t-filter.mkiv +++ b/Master/texmf-dist/tex/context/third/filter/t-filter.mkiv @@ -1,6 +1,6 @@ %D \module %D [ file=t-filter, -%D version=2011.12.27, +%D version=2012.01.26, %D title=\CONTEXT\ User Module, %D subtitle=Filter, %D author=Aditya Mahajan, @@ -9,13 +9,14 @@ %D email=adityam ieee org, %D license=Simplified BSD License] -\writestatus{loading}{Filter (ver: 2011.12.27)} +\writestatus{loading}{Filter (ver: 2012.01.26)} -\ifx\undefined\normalexpanded \let\normalexpanded\expanded \fi +% For backward compatibility +\ifx\grabbufferdata\undefined \let\grabbufferdata \dostartbuffer \fi \startmodule [filter] \usemodule [module-catcodes] -\unprotectmodulecatcodes +\unprotect %D \subject {Interface} %D @@ -23,15 +24,15 @@ %D the module definition, and thereby reduces the risk of a typo. %D Currently, only English names are provided. If someone wants a %D multi-lingual interface, let me know and I will add other language -%D names as well, +%D names as well, \startinterface all \setinterfaceconstant {filter} {filter} \setinterfaceconstant {filtercommand} {filtercommand} - \setinterfaceconstant {output} {output} - \setinterfaceconstant {read} {read} - \setinterfaceconstant {readcommand} {readcommand} - \setinterfaceconstant {taglabel} {taglabel} + \setinterfaceconstant {output} {output} + \setinterfaceconstant {read} {read} + \setinterfaceconstant {readcommand} {readcommand} + \setinterfaceconstant {taglabel} {taglabel} \stopinterface @@ -40,16 +41,29 @@ %D We use logical names to easily catch typos. \def\externalfilter@id {externalfilter} -\def\externalfilter@namespace {@@@@\externalfilter@id} -\def\externalfilter@name {} \def\externalfilter@temp_prefix {temp} -\def\externalfilter@count {\externalfilter@namespace-\externalfilter@name-counter} - -\installparameterhandler \externalfilter@namespace \externalfilter@id -\installparameterhashhandler \externalfilter@namespace \externalfilter@id -\installsetuphandler \externalfilter@namespace \externalfilter@id -\installstyleandcolorhandler \externalfilter@namespace \externalfilter@id +\def\externalfilter@count {\????externalfilter-\currentexternalfilter-counter} + +\definenamespace + [externalfilter] + [\c!type=module, + \c!name=externalfilter, + \c!command=\v!yes, + setup=\v!list, + \c!style=\v!yes, + \s!parent=externalfilter] + +\appendtoks + \externalfilter@show_status{defining filter : \currentexternalfilter}% + \doifinset{\externalfilterparameter\c!cache}{\v!yes,\v!force} + {\expandafter\newcounter\csname\externalfilter@count\endcsname}% + \setevalue{\e!start\currentexternalfilter}{\externalfilter@start[\currentexternalfilter]}% + \setvalue {\e!stop\currentexternalfilter}{\externalfilter@process_filter}% + \setevalue{process\currentexternalfilter file}{\externalfilter@process_file[\currentexternalfilter]}% + \setevalue{process\currentexternalfilter buffer}{\externalfilter@process_buffer[\currentexternalfilter]}% + \setevalue{inline\currentexternalfilter}{\externalfilter@inline[\currentexternalfilter]}% +\to \everydefineexternalfilter % For backward compatibility \let\setupexternalfilters \setupexternalfilter @@ -64,7 +78,6 @@ \setinterfacemessage\m!externalfilter{forbidden} {Fatal Error: Cannot use absolute path -- as directory} \setinterfacemessage\m!externalfilter{slash} {Appending / to directory -- } \setinterfacemessage\m!externalfilter{reuse} {\c!state=\v!stop : Not running filter on file --} -\setinterfacemessage\m!externalfilter{force} {mode 'force' enabled: Forcing running of filters} %D \subject {Tracing Macros} @@ -73,10 +86,10 @@ \def\traceexternalfilters {\traceexternalfilterstrue - \doifmode\s!mkiv{\enabletrackers[graphic.runfile]}} + \enabletrackers[graphic.runfile]} \starttexdefinition externalfilter@show_filenames - \writestatus\m!externalfilter{current filter : \externalfilter@name} + \writestatus\m!externalfilter{current filter : \currentexternalfilter} \writestatus\m!externalfilter{base file : \externalfilter@base_file} \writestatus\m!externalfilter{input file : \externalfilter@input_file} \writestatus\m!externalfilter{output file : \externalfilter@output_file} @@ -90,40 +103,20 @@ \starttexdefinition externalfilter@show_filtercommand \writestatus\m!externalfilter{command : \externalfilterparameter\c!filtercommand} - \iftraceexternalfilters \writestatus\m!externalfilter{state : \externalfilterparameter\c!state} \fi + \writestatus\m!externalfilter{state : \externalfilterparameter\c!state} \stoptexdefinition %D \section {The main user macros} -%D \subsubject {Define a new filter} - -\def\defineexternalfilter - {\dodoubleargument\externalfilter@define} - -\starttexdefinition externalfilter@define [#1][#2] - \externalfilter@show_status{defining filter : #1} - - \setupexternalfilter[#1][\s!parent=\externalfilter@namespace,#2] - \edef\externalfilter@name{#1} - - \doif{\externalfilterparameter\c!continue}\v!yes - {\expandafter\newcounter\csname\externalfilter@count\endcsname} - - \setvalue{\e!start#1}{\bgroup\obeylines\dodoubleargument\externalfilter@start[#1]} - \setvalue {\e!stop#1}{\externalfilter@process_filter} +\unexpanded\def\externalfilter@start + {\bgroup\obeylines\dodoubleargument\externalfilter@start_indeed} - \setvalue{process#1file}{\dodoubleargument\externalfilter@process_file[#1]} - \setvalue{process#1buffer}{\dotripleargument\externalfilter@process_buffer[#1]} - \setvalue{inline#1}{\dodoubleargument\externalfilter@inline[#1]} - -\stoptexdefinition - -\starttexdefinition externalfilter@start [#1][#2] +\starttexdefinition externalfilter@start_indeed [#1][#2] % #1 = filter % #2 = options - \egroup %\bgroup in \start#1 + \egroup %\bgroup in \externalfilter@start - \edef\externalfilter@name{#1} + \edef\currentexternalfilter{#1} \begingroup % to keep assignments local \setupexternalfilter[#1][\c!name=,#2] @@ -131,26 +124,29 @@ \externalfilter@set_filenames % Capture the contents of the buffer - \dostartbuffer[\externalfilter@buffer_name][\e!start#1][\e!stop#1] + \grabbufferdata[\externalfilter@buffer_name][\e!start#1][\e!stop#1] \stoptexdefinition -\starttexdefinition externalfilter@process_file [#1][#2]#3 +\unexpanded\def\externalfilter@process_file + {\dodoubleargument\externalfilter@process_file_indeed} + +\starttexdefinition externalfilter@process_file_indeed [#1][#2]#3 % #1 = filter % #2 = options % #3 = filename \begingroup - \edef\externalfilter@name{#1} + \edef\currentexternalfilter{#1} \setupexternalfilter[#1][\c!name=,#2] \externalfilter@set_directory - + \edef\externalfilter@input_file{#3} \splitfilename{#3} %NOTE: \edef doesn not work because \splitoffname is not expandable \def\externalfilter@base_file {\splitoffname} - % The output is always in the directory specified by + % The output is always in the directory specified by % \c!directory; even if the input is from some other directory \def\externalfilter@output_file{\externalfilter@get_directory\externalfilterparameter\c!output} @@ -161,35 +157,41 @@ \endgroup \stoptexdefinition -\starttexdefinition externalfilter@process_buffer [#1][#2][#3] +\unexpanded\def\externalfilter@process_buffer + {\dotripleargument\externalfilter@process_buffer_indeed} + +\starttexdefinition externalfilter@process_buffer_indeed [#1][#2][#3] % #1 = filter % #2 = options % #3 = buffer \begingroup - \edef\externalfilter@name{#1} + \edef\currentexternalfilter{#1} \ifthirdargument \setupexternalfilter[#1][\c!name=,#2] \fi \externalfilter@set_directory - + \ifthirdargument - \edef\externalfilter@buffer_name{#3} + \edef\externalfilter@buffer_name{\externalfilter@temp_prefix-\currentexternalfilter-#3} \else - \edef\externalfilter@buffer_name{#2} + \edef\externalfilter@buffer_name{\externalfilter@temp_prefix-\currentexternalfilter-#2} \fi - + \externalfilter@set_filenames_extras \iftraceexternalfilters \externalfilter@show_filenames \fi - + \externalfilter@process_filter - + \stoptexdefinition - -\starttexdefinition externalfilter@inline [#1][#2] - \edef\externalfilter@name{#1} + +\unexpanded\def\externalfilter@inline + {\dodoubleargument\externalfilter@inline_indeed} + +\starttexdefinition externalfilter@inline_indeed [#1][#2] + \edef\currentexternalfilter{#1} \begingroup % to keep assignments local \setupexternalfilter[#1][\c!numbering=,\c!name=,\c!before=,\c!after=,#2] @@ -197,7 +199,7 @@ \externalfilter@set_filenames \pushcatcodetable - \futurelet\next\externalfilter@inline_indeed + \futurelet\next\externalfilter@inline_grabcontent \stoptexdefinition %D \subsubject {Write argument to file verbatim} @@ -205,7 +207,7 @@ %D Surprisingly, there is nothing in the core to define a function that write its %D argument to a file verbatim. I basically copied the \type{\type} macro. -\starttexdefinition externalfilter@inline_indeed +\starttexdefinition externalfilter@inline_grabcontent \ifx\next\bgroup \expandafter\externalfilter@inline_group \else @@ -239,7 +241,7 @@ \externalfilter@read_processed_file % Finalization - \doif{\externalfilterparameter\c!continue}\v!yes + \doifinset{\externalfilterparameter\c!cache}{\v!yes,\v!force} {\doglobal\expandafter\increment\csname\externalfilter@count\endcsname} \endgroup \stoptexdefinition @@ -276,7 +278,7 @@ \edef\externalfilter@get_directory{\externalfilterparameter\c!directory} \doifsomething{\externalfilter@get_directory}\externalfilter@set_directory_indeed \stoptexdefinition - + \starttexdefinition externalfilter@set_directory_indeed \doif{\externalfilter@get_first_character\externalfilter@get_directory}{/} {\writeline @@ -289,24 +291,24 @@ {\iftraceexternalfilters \showmessage\m!externalfilter{slash}\externalfilter@get_directory \fi \edef\externalfilter@get_directory{\externalfilter@get_directory/}} \stoptexdefinition - + %D \subsubject {Set file names} %D %D \type{\externalfilter@base_file} is the name of the temporary file without -%D extension. Its actual value depends on the state of \type{continue} key as +%D extension. Its actual value depends on the state of \type{cache} key as %D well as the value of \type{name} key. \starttexdefinition externalfilter@set_filenames \externalfilter@set_directory % Set the name of temp file for the filter - \doifelse{\externalfilterparameter\c!continue}\v!yes - {\edef\externalfilter@buffer_name{\externalfilter@temp_prefix-\externalfilter@name-\csname\externalfilter@count\endcsname}} - {\edef\externalfilter@buffer_name{\externalfilter@temp_prefix-\externalfilter@name}} + \doifinsetelse{\externalfilterparameter\c!cache}{\v!yes,\v!force} + {\edef\externalfilter@buffer_name{\externalfilter@temp_prefix-\currentexternalfilter-\csname\externalfilter@count\endcsname}} + {\edef\externalfilter@buffer_name{\externalfilter@temp_prefix-\currentexternalfilter}} \doifsomething{\externalfilterparameter\c!name} - {\edef\externalfilter@buffer_name{\externalfilter@temp_prefix-\externalfilter@name-\externalfilterparameter\c!name}} + {\edef\externalfilter@buffer_name{\externalfilter@temp_prefix-\currentexternalfilter-\externalfilterparameter\c!name}} \externalfilter@set_filenames_extras @@ -316,12 +318,10 @@ \starttexdefinition externalfilter@set_filenames_extras % The following macros are useful for filter= and filtercommand= options - % The basename of the external file + % The basename of the external file \edef\externalfilter@base_file {\jobname-\externalfilter@buffer_name} - % In MkIV, we can specify the name of the file where the buffer has - % to be saved. This file is \externalfilter@input_file (because it is - % the input to the filter). + % Append directory name to the name of the input file \edef\externalfilter@input_file {\externalfilter@get_directory\externalfilter@base_file.\f!temporaryextension} % Append directory name to the name of the output file @@ -336,37 +336,43 @@ \starttexdefinition externalfilter@process_filter % By defualt, buffers are in memory in MkIV. So, we save them to disk - % To imitate the behavior of MkII, we need % % \savebuffer[\externalfilter@buffer_name][\externalfilter@input_file] % - % However, in MkIV, we can save a list of buffers to a file. The empty + % We can also save a list of buffers to a file. The empty % elements of the list are ignored. So, instead we use the following - % \savebuffer[\externalfilterparameter{\c!buffer\c!before},\externalfilter@buffer_name,\externalfilterparameter{\c!buffer\c!after}] + % + % \savebuffer[\externalfilterparameter{\c!buffer\c!before}, + % \externalfilter@buffer_name, + % \externalfilterparameter{\c!buffer\c!after}] % [\externalfilter@input_file]} + % + % but using this method we cannot save the file in another directory. + % So, we simply write the file in the current directory and then move it. \savebuffer[\externalfilterparameter{\c!buffer\c!before}, \externalfilter@buffer_name, \externalfilterparameter{\c!buffer\c!after}] [\externalfilter@id] \startluacode - %% -- On Windows, os.rename does not overwrite files :( + %% -- On Windows, os.rename does not overwrite files :( So we copy and delete files file.copy("\jobname-\externalfilter@id.\f!temporaryextension", "\externalfilter@input_file") + os.remove("\jobname-\externalfilter@id.\f!temporaryextension") \stopluacode - + \externalfilter@execute_filter \externalfilter@read_processed_file - \endgroup + \endgroup % Finalization - \doif{\externalfilterparameter\c!continue}\v!yes + \doifinset{\externalfilterparameter\c!cache}{\v!yes,\v!force} {\doglobal\expandafter\increment\csname\externalfilter@count\endcsname} \expanded{\checknextindentation[\externalfilterparameter\c!indentnext]} \dorechecknextindentation \stoptexdefinition -%D \subsubject {Execute Filter} +%D \subsubject {Execute Filter} % In MkIV, we use job.files.run to check if a file has changed. This function % writes the md5 sum to the tuc file rather than to an external file. So, we @@ -375,19 +381,16 @@ \starttexdefinition externalfilter@execute_filter \processcommacommand[\externalfilterparameter{\c!filter\c!setups}]\directsetup - \externalfilter@show_filtercommand + \iftraceexternalfilters \externalfilter@show_filtercommand \fi - \doifelse{\externalfilterparameter\c!continue}\v!yes + \doifelse{\externalfilterparameter\c!cache}\v!yes {\doifelse{\externalfilterparameter\c!state}\v!stop {\showmessage\m!externalfilter{reuse}\externalfilter@input_file} - {\doifmodeelse{force} - {\showmessage\m!externalfilter{force}\empty - \executesystemcommand - {\externalfilterparameter\c!filtercommand}} - {\ctxlua{job.files.run(\!!bs\externalfilter@input_file\!!es, - \!!bs\externalfilterparameter\c!filtercommand\!!es)}}}} + {\ctxlua{job.files.run(\!!bs\externalfilter@input_file\!!es, + \!!bs\externalfilterparameter\c!filtercommand\!!es)}}} {\executesystemcommand {\externalfilterparameter\c!filtercommand}} + \iftraceexternalfilters \else \ctxlua{os.remove(\!!bs\externalfilter@input_file\!!es)} \fi \stoptexdefinition %D \subsubject {Read output} @@ -396,7 +399,7 @@ \doif{\externalfilterparameter\c!read}\v!yes {\doiffileelse{\externalfilter@output_file} {\externalfilter@read_processed_file_indeed} - {\showmessage\m!externalfilter{notfound}\externalfilter@output_file + {\showmessage\m!externalfilter{notfound}\externalfilter@output_file \externalfilter@show_filenames \blank {\tttf [[\getmessage\m!externalfilter{missing}]]} @@ -407,7 +410,7 @@ \externalfilterparameter\c!before \begingroup - \dostarttagged{\externalfilterparameter\c!taglabel}\externalfilter@name + \dostarttagged{\externalfilterparameter\c!taglabel}\currentexternalfilter \externalfilter@attributes_start \externalfilter@id \c!style \c!color \processcommacommand[\externalfilterparameter\c!setups]\directsetup \externalfilterparameter\c!readcommand\externalfilter@output_file @@ -429,6 +432,7 @@ \c!indentnext=\v!auto, \c!setups=, \c!continue=\v!no, + \c!cache=\externalfilterparameter\c!continue, % for backward compatibility \c!read=\v!yes, \c!readcommand=\ReadFile, \c!directory=, @@ -440,18 +444,16 @@ \c!taglabel=\externalfilter@id, ] -\doifmodeelse{reuse} - {\setupexternalfilters[state=stop]} - {\setupexternalfilters[state=start]} - \def\externalfilterbasefile {\externalfilter@base_file} \def\externalfilterinputfile {\externalfilter@input_file} \def\externalfilteroutputfile{\externalfilter@output_file} -\def\currentexternalfilter {\externalfilter@name} + +% t-syntax-groups still uses this. +\def\externalfilter@name {\currentexternalfilter} % Default value \def\externalfilter@input_file {} \def\externalfilter@output_file{} - -\protectmodulecatcodes + +\protect \stopmodule -- cgit v1.2.3