divertr
v1.0.4
Published
Text Diversion Filter
Downloads
11
Maintainers
Readme
Divertr
Text Diversion Filter
About
Divertr (Text Diversion Filter) is a small JavaScript function which applies a 2-pass diversion filter to its input. In pass 1 all diversion locations are accumulated and in pass 2 these locations are recursively expanded at their dump positions. The diversion filter is controlled by directives found in the input data:
-{name}-
This defines the dump position of the locationname
. All accumulated data which finally has to been diverted toname
is inserted at this data position. Notice: the final data of a locationname
has not to be known at this point, because the expansion of such location dumps are done in pass 2. You can also dump a location more than once, but the contents is always the same, independent of the data position where the location dump tag stays. Thename
can be any symbolic name matching[a-zA-Z][a-zA-Z0-9_]*
.-{name:
This enters the locationname
(or diverts the data flow to it, hence the name for this filter). In other words: the data flow now goes on at locationname
. All following data (up to end of file or the next location leave tag) gets appended to locationname
. You can nest diversions by entering other locations at any point, because the locations are remembered on a stack. The default entered location is namedmain
. The top most location is namednull
which neither can be entered nor leaved explicitly. But of course thenull
diversion can be manually dumped, for instance when using it for error messages.There are two special features for diverting data which are con‐ trolled by the
!
characters preceding or following thename
identifier:!name
This sets the data flow position to the begin of locationname
, i.e. it actually discards the current (already diverted) contents of location NAME before entering it. Use this to overwrite a locations contents.name!
This marks this location entry as overwritable, i.e. it enters locationname
but when the corresponding leave tag is found, the data-flow position forname
gets automatically reset to its begin. Use this if you want to set the default contents for a location which only gets used if no other diversions occur to it (because any following diversions to this location will be overwrite the contents). This feature is usually used for a template scheme.!name!
Just the combination of the above two features. Use this to both discard the current contents of locationname
and set a new default for it.
:name}-
or:}-
If noname
is given, it just leaves the current location and enters again the location which was active when this location was previously entered. Ifname
is given it leaves the locationname
and all locations on the stack above it. There is no need to leave all locations at the end of the input data. All still entered locations are automatically left at end of file because this is essential for a template scheme.
Notice that there are two ways of using (and thinking) about the filtering mechanism this library provides:
Macro Mechanism: Here you are thinking of the mechanism as a macro mechanism where you expand a macro at one data position while you define it via begin and end tags at other locations.
Diversion Mechanism: Here you are thinking of the mechanism as a diversion mechanism where you dump a location at one data position while you divert to it by entering end leaving the location at other positions.
Installation
$ npm install divertr
Example
Script:
var divertr = require("divertr")
console.log(divertr(
`section { -{s1}- } section { -{s2}- } section { -{s3}- }
-{s1:foo:}--{s2:bar:}--{s3!:quux:}--{s1:foo2:}--{!s2:bar2:}--{s3:quux2:}-`))
Output:
section { foofoo2 } section { bar2 } section { quux2 }
Application Programming Interface (API)
interface API {
(
input: String,
options?: {
syntax?: ({
regexDump: (RegExp | String);
regexEnter: (RegExp | String);
regexLeave: (RegExp | String);
} | String);
debug?: Boolean;
}
): String;
}
declare var Divertr: API;
Pre-Defined Syntax
std
(the default):{ regexDump: /-\{([a-zA-Z][a-zA-Z0-9_]*)\}-/, /* -{foo}- */ regexEnter: /-\{(\!?)([a-zA-Z][a-zA-Z0-9_]*)(\!?):/, /* -{foo: */ regexLeave: /:((?:[a-zA-Z][a-zA-Z0-9_]*)?)\}-/ /* :foo}- */ }
alt
:{ regexDump: /-\{([a-zA-Z][a-zA-Z0-9_]*)\}-/, /* -{foo}- */ regexEnter: /-(\!?)([a-zA-Z][a-zA-Z0-9_]*)(\!?)->/, /* -foo-> */ regexLeave: /<-((?:[a-zA-Z][a-zA-Z0-9_]*)?)-/ /* <-foo- */ }
xml
:{ regexDump: /<([a-zA-Z][a-zA-Z0-9_]*)\/>/, /* <foo/> */ regexEnter: /<(\!?)([a-zA-Z][a-zA-Z0-9_]*)(\!?)>/, /* <foo> */ regexLeave: /<\/((?:[a-zA-Z][a-zA-Z0-9_]*)?)>/ /* </foo> */ }
mustache
{ regexDump: /\{\{([a-zA-Z][a-zA-Z0-9_]*)\}\}/, /* {{foo}} */ regexEnter: /\{\{#(\!?)([a-zA-Z][a-zA-Z0-9_]*)(\!?)\}\}/, /* {{#foo}} */ regexLeave: /\{\{\/((?:[a-zA-Z][a-zA-Z0-9_]*)?)\}\}/ /* {{/foo}} */ }
rpm
:{ regexDump: /%\{([a-zA-Z][a-zA-Z0-9_]*)\}/, /* %{foo} */ regexEnter: /%\{(\!?)([a-zA-Z][a-zA-Z0-9_]*)(\!?):/, /* %{foo: */ regexLeave: /:((?:[a-zA-Z][a-zA-Z0-9_]*)?)\}/ /* :foo} */ }
wml-macro
:{ regexDump: /\{#([a-zA-Z][a-zA-Z0-9_]*)#\}/, /* {#foo#} */ regexEnter: /\{#(\!?)([a-zA-Z][a-zA-Z0-9_]*)(\!?)#:/, /* {#foo#: */ regexLeave: /:#((?:[a-zA-Z][a-zA-Z0-9_]*)?)#\}/ /* :#foo#} */ }
wml-diversion
{ regexDump: /<<([a-zA-Z][a-zA-Z0-9_]*)>>/, /* <<foo>> */ regexEnter: /\.\.(\!?)([a-zA-Z][a-zA-Z0-9_]*)(\!?)>>/, /* ..foo>> */ regexLeave: /<<((?:[a-zA-Z][a-zA-Z0-9_]*)?)\.\./ /* <<foo.. */ }
History
The functionality is derived from my Unix tool divert(1), as written 1997 by me in Perl for my Website META Language (WML). In 2016 I've converted the functionality from Perl to JavaScript and replaced the ad-hoc regular expression based parser with one based on my Tokenizr library and wrapped the functionality into a single JavaScript function for reuse as a library.
License
Copyright (c) 1997-2021 Dr. Ralf S. Engelschall (http://engelschall.com/)
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.