summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Master/texmf-dist/doc/luatex/interpreter/README8
-rw-r--r--Master/texmf-dist/doc/luatex/interpreter/interpreter-doc.pdfbin102479 -> 110003 bytes
-rw-r--r--Master/texmf-dist/doc/luatex/interpreter/interpreter-doc.tex4
-rw-r--r--Master/texmf-dist/doc/luatex/interpreter/interpreter-doc.txt185
-rw-r--r--Master/texmf-dist/tex/luatex/interpreter/interpreter.lua165
-rw-r--r--Master/texmf-dist/tex/luatex/interpreter/interpreter.sty4
-rw-r--r--Master/texmf-dist/tex/luatex/interpreter/interpreter.tex2
7 files changed, 186 insertions, 182 deletions
diff --git a/Master/texmf-dist/doc/luatex/interpreter/README b/Master/texmf-dist/doc/luatex/interpreter/README
index c91f26a1d59..f3e1c56c528 100644
--- a/Master/texmf-dist/doc/luatex/interpreter/README
+++ b/Master/texmf-dist/doc/luatex/interpreter/README
@@ -2,15 +2,15 @@ This is the README file for the Interpreter package.
Author: Paul Isambert.
E-mail: zappathustra AT free DOT fr
Comments and suggestions are welcome.
-Date: December 2011.
-Version: 1.1.
+Date: June 2012.
+Version: 1.2.
Interpreter preprocesses input files on the fly (no external program) and
manipulates input lines, e.g. to turn some markup into proper TeX syntax.
Interpreter doesn't work with ConTeXt.
-LuaTeX is required, as is, since version 1.1, the Lua side of the
-Gates package (i.e. gates.lua).
+LuaTeX is required, and the Lua side of the Gates package (i.e. gates.lua),
+version at least 0.2.
Relevant information can be found in interpreter-doc.pdf
or interpreter-doc.txt (source of the doc readable in a text editor).
diff --git a/Master/texmf-dist/doc/luatex/interpreter/interpreter-doc.pdf b/Master/texmf-dist/doc/luatex/interpreter/interpreter-doc.pdf
index ea76a6c65cd..2dcc32ea485 100644
--- a/Master/texmf-dist/doc/luatex/interpreter/interpreter-doc.pdf
+++ b/Master/texmf-dist/doc/luatex/interpreter/interpreter-doc.pdf
Binary files differ
diff --git a/Master/texmf-dist/doc/luatex/interpreter/interpreter-doc.tex b/Master/texmf-dist/doc/luatex/interpreter/interpreter-doc.tex
index 8a1ab383a81..30a1da52ba4 100644
--- a/Master/texmf-dist/doc/luatex/interpreter/interpreter-doc.tex
+++ b/Master/texmf-dist/doc/luatex/interpreter/interpreter-doc.tex
@@ -1,7 +1,7 @@
% This is the master file producing interpreter-doc.pdf. The version of the
% documentation readable in a text editor is interpreter-doc.txt (input below).
%
-% Paul Isambert - zappathustra AT free DOT fr - December 2011
+% Paul Isambert - zappathustra AT free DOT fr - June 2012
\input pitex
@@ -97,7 +97,7 @@ end
% Title
\vbox to 3\baselineskip{
\hbox to \hsize{\big Interpreter\hfil\normalsize Paul Isambert}
-\hbox to \hsize{v.1.1, December 2011 \hfil \tcode{zappathustra AT free DOT fr}}
+\hbox to \hsize{v.1.2, June 2012 \hfil \tcode{zappathustra AT free DOT fr}}
\vfil
}
diff --git a/Master/texmf-dist/doc/luatex/interpreter/interpreter-doc.txt b/Master/texmf-dist/doc/luatex/interpreter/interpreter-doc.txt
index 0156c3e07d8..6257aa6733e 100644
--- a/Master/texmf-dist/doc/luatex/interpreter/interpreter-doc.txt
+++ b/Master/texmf-dist/doc/luatex/interpreter/interpreter-doc.txt
@@ -578,27 +578,13 @@ which is why it is so heavy; it receives a file handle:
. . . check_direct
. . . insert_line
. . apply_classes
- . . . initialize
. . . pass_class
. . . . pass_pattern
- . . . . . pass_line
- . . . . . . check_index
- . . . . . . . call
- . . . . . . . replace
- . . . . . . . protect
- . . . . . . increment_line
- . . . . . increment_pattern
- . . . . increment_class
- . . . apply_class0
- . . . . initialize0
- . . . . pass_pattern
- . . . . . pass_line
- . . . . . . check_index
- . . . . . . . call
- . . . . . . . replace
- . . . . . . . protect
- . . . . . . increment_line
- . . . . . increment_pattern
+ . . . . . process_lines
+ . . . . . . switch
+ . . . . . . call
+ . . . . . . replace
+ . . . . . . protect
. . . unprotect
. . . . undo_protected
. . . . unprotect_lines
@@ -641,64 +627,65 @@ which is why it is so heavy; it receives a file handle:
"interpreter.core.lines" shouldn't be empty, and "interpreter.active"
should be true.
-> initialize () [m-gate]
- Returns "1, 1, 1, 1"; it simply starts the following loop.
-
-> pass_class (<class>) [l-gate]
- An l-gate called as long as "interpreter.core.reader.protected" isn't
- a boolean value (see "unprotect" below) and <class> isn't larger than
- "#interpreter.core.classes"; see "increment_class" below, which returns
- "<class>+1". In other words, "pass_class" will be repeated for each
- class.
+> pass_class () [l-gate]
+ This gate iterates on all classes in "interpreter.core.classes" and
+ then on class 0. On each iteration it checks beforehand whether the
+ paragraph is protected, i.e. "interpreter.core.reader.protected" isn't
+ a boolean (see "unprotecte" below). On each iteration, the class
+ number and the class itself are returned. (This behavior is
+ implemented with a Gates iterator.)
-> pass_pattern (<class>, <pattern>) [l-gate]
+> pass_pattern (<ignored>, <class>) [l-gate]
Same as "pass_class", except it iterates on the patterns in "class":
- it is executed as long as "interpreter.core.reader.protected" isn't
- a boolean and "<pattern>" isn't larger than "#interpreter.core.classes[<class>]".
- See "increment_pattern" below. In other words, it will be repeated
- for each pattern in <class>.
-
-> pass_line (<class>, <pattern>, <line>), [l-gate]
- Here we go again, except we check, besides protection, that <line>
- isn't larger than "#interpreter.core.lines". See "increment_line"
- below.
-
-> check_index (<class>, <pattern>, <line>, <index>) [l-gate]
- This time we check that "interpreter.core.classes[<class>][<pattern>].pattern"
- occurs in "interpreter.core.lines[<line>]", starting at <index>.
- Protection is checked too, as is the type of "interpreter.core.lines[<line>]";
- indeed, individual lines are protected by turning them into tables
- (with a single entry, the line itself), see "protect" below. The
- occurrence of the pattern in the line is checked with
- "interpreter.core.tools.get_index".
-
-> call (<class>, <pattern>, <line>, <index>) [m-gate]
- This is executed if and only if the pattern table (i.e.
- "interpreter.core.classes[<class>][<pattern>]") has a "call" entry.
- The index where the pattern occurs is retrieved with
- "interpreter.core.tools.get_index" and stored in <newindex>, and then
- the "call" entry is executed as:
-
- call (interpreter.core.lines,
- <line>, <newindex>, <pattern table>)
-
- where <pattern table> is defined as above; if call returns one value,
- it is assigned to <index>; if it returns two, they are assigned to
- <line> and <index>. The gate returns the four arguments.
-
-> replace (<class>, <pattern>, <line>, <index>) [m-gate]
- This is executed only if the pattern table, as defined above, has a
- "replace" field and no "call" field; it applies "interpreter.core.tools.xsub"
- as:
+ it is executed as long as "interpreter.core.reader.protected" and
+ returns the patter number and the pattern itself. (The <ignored>
+ argument isn't used; it is for the "pass_class" iterator; the same
+ holds for the following gates.)
+
+> process_lines (<ignored>, <pattern>) [l-gate]
+ Again, this calls an iterator. It browses each line in "interpreter.core.lines"
+ and returns the line's number (provided it is valid, i.e. not a table,
+ see "protect" below), <pattern> and the current index in that line.
+ To keep track of the current line and index, two internal numbers are
+ used: "interpreter.core.reader.current_line" and
+ "interpreter.core.reader.current_index".
+
+> switch (<line>, <pattern>, <index>) [m-gate]
+ If <pattern> has a "call" entry, it sets the "call" gate below to
+ "ajar"; otherwise, if <pattern> has a "replace" entry, it sets the
+ "replace" gate to "ajar".
+
+> call (<line>, <pattern>, <index>) [m-gate]
+ This gate is closed by default and set to "ajar" by "switch" above.
+ If, starting at <index>, the <pattern>'s "pattern" entry can be
+ found in <line> with "interpreter.core.tools.get_index" (which makes
+ sure that protectors are obeyed and returns <newindex>, where the
+ pattern is found if it occurs), the <pattern>'s "call" entry is
+ applied as
+
+ <pattern>.call(interpreter.core.lines,
+ <line>, <newindex>, <pattern>)
+
+ This may returned zero, one or two values. If nothing is returned,
+ "interpreter.core.reader.current_index" is set to 0, which makes
+ the "process_lines" iterator consider the next line. If one value is
+ returned, it is the new current index and "process_lines" will not
+ update the line number. If two values are returned, the first is the
+ new current line number and the second the new current index.
+
+> replace (<line>, <pattern>, <index>) [m-gate]
+ This gate is closed by default and set to "ajar" by "switch" above.
+ This tries to find the <pattern>'s "pattern" like "call" above, and if
+ it is found, it applies "interpreter.core.tools.xsub" as:
xsub (interpreter.core.lines[<line>],
- <newindex>, <pattern table>.pattern,
- <pattern table>.replace)
+ <newindex>, <pattern>.pattern, <pattern>.replace)
where <newindex> is defined as in "call". The return value of "xsub"
- is assigned to "interpreter.core.lines[<line>]". The gate returns
- its four argument, with <index> incremented by the value of the
- "offset" entry of the pattern, if any.
+ is assigned to "interpreter.core.lines[<line>]", and the current
+ index is set to <index> plus the <pattern>'s "offset" if any. If the
+ pattern wasn't found, the current index is set to 0, which makes
+ "process_lines" turn to the next line as explained in "call".
> protect () [m-gate]
The "interpreter.protect()" function can either protect the whole
@@ -707,48 +694,13 @@ which is why it is so heavy; it receives a file handle:
takes the value "true", which is checked in various gates above. In
the second case, "interpreter.core.tools.protected" is a table with
each index indicating a line to be protected. This gate implements
- the protection in that case: for each entry in the table, it protects
- the line with the same index in "interpreter.core.lines" by transforming
- it into a table (with a single entry, the string representing the
- original line); the type of the line is checked in "check_index"
- above. This gate is executed if and only if "interpreter.core.tools.protected"
- is a table. The four arguments returned by "call" or "replace" are
- automatically returned, so that "check_index" is reexecuted if its
- "loop" conditional evaluates to "true".
-
-> increment_line (<class>, <pattern>, <line>, <index>) [m-gate]
- Returns <class>, <pattern>, <line> + 1, <index>, so "pass_line" is
- reexecuted if its "loop" conditional evaluates to "true".
-
-> increment_pattern (<class>, <pattern>, <line>, <index>) [m-gate]
- Returns <class>, <pattern> + 1, <line>, <index>, so "pass_pattern"
- is reexecuted if its "loop" conditional evaluates to "true".
-
-> increment_class (<class>, <pattern>, <line>, <index>) [m-gate]
- Returns <class> + 1, <pattern>, <line>, <index>, so "pass_class" is
- reexecuted if its "loop" conditional evaluates to "true".
-
-> apply_class0 () [l-gate]
- The l-gate that does roughly the same job as "apply_classes", but
- with class 0. It is called if and only if "interpreter.core.reader.protected"
- isn't a boolean.
-
-> initialize0 () [m-gate]
- The same as "initialize", except it returns "0, 1, 1, 1", since
- we're interested in class 0.
-
-> pass_pattern (<class>, <pattern>) [l-gate]
- The same as above. (Note that this version of the gate doesn't occur
- in the same l-gate as the previous one, so its local "loop" is also
- different.)
-
-There is one important difference between "apply_class" and "apply_class0":
-the latter has "pass_pattern" as its immediate subgate, without
-"pass_class" as an intermediary l-gate. That makes sense, since we don't
-want to loop on all the classes here (as that was done in "apply_class"),
-but we're only interested in class 0. Apart from that, the "pass_pattern"
-gate is really the same in both, so all the subgates of "pass_pattern"
-are also reapplied here; I won't describe them again.
+ the protection in that case: it iterates on all entries in the table
+ with "pairs" and protects the line with the same index in
+ "interpreter.core.lines" by transforming it into a table (with a
+ single entry, the string representing the original line); the type
+ of the line is checked in the "process_lines" iterator above. The
+ gate's iterator doesn't take arguments, but the function itself is
+ defined as taking a number (the line).
> unprotect () [l-gate]
Now all the patterns in all the classes have been applied to the
@@ -757,10 +709,13 @@ are also reapplied here; I won't describe them again.
> undo_protected () [m-gate]
Simply sets "interpreter.core.tools.protected" to "nil" so it is
- ready for the next paragraph.
+ ready for the next paragraph.
> unprotect_lines () [m-gate]
- Restore all the lines in "interpreter.core.lines" as simple strings.
+ Restores all the lines in "interpreter.core.lines" as simple strings.
+ The gate uses an iterator that simply runs "ipairs" on "interpreter.core.lines",
+ so the function's definition actually takes the line's number and
+ the line itself as arguments.
> remove_escape () [m-gate]
If "interpreter.escape" is defined, removes all its occurrences in
diff --git a/Master/texmf-dist/tex/luatex/interpreter/interpreter.lua b/Master/texmf-dist/tex/luatex/interpreter/interpreter.lua
index 2a87d979195..05de6eb791f 100644
--- a/Master/texmf-dist/tex/luatex/interpreter/interpreter.lua
+++ b/Master/texmf-dist/tex/luatex/interpreter/interpreter.lua
@@ -1,6 +1,6 @@
-- This is the main Lua file for the Interpreter package.
-- Further information in interpreter-doc.pdf or interpreter-doc.txt.
--- Paul Isambert - zappathustra AT free DOT fr - December 2011
+-- Paul Isambert - zappathustra AT free DOT fr - June 2012
--
-- Beware, this is written with Gates. Please read the Gates doc if
-- you want to understand something.
@@ -8,7 +8,12 @@
local find, gsub, match, sub = string.find, string.gsub, string.match, string.sub
local insert, sort, remove = table.insert, table.sort, table.remove
local io_open = io.open
+local ipairs, pairs, type = ipairs, pairs, type
require("gates.lua")
+if not gates.iterator then
+ tex.error("Interpreter error: Your version of Gates should be at least v.0.2. I quit. Expect chaos")
+ return
+end
interpreter = gates.new("interpreter")
@@ -251,7 +256,8 @@ interpreter.direct = "%%%%I%s+"
-- At last, the function to be registered in open_read_file, defining the
-- function that reads a file.
-
+interpreter.core.reader.current_line = 0
+interpreter.core.reader.current_line = 0
interpreter.core.reader.list{"read_file",
{"make_paragraph", conditional = function () return #interpreter.core.lines == 0 end,
@@ -274,71 +280,114 @@ interpreter.core.reader.list{"read_file",
insert(interpreter.core.lines, line)
end}},
{"apply_classes", conditional = function () return #interpreter.core.lines > 0 and interpreter.active end,
- {"initialize",
- function ()
- return 1, 1, 1, 1
- end},
- {"pass_class", loop = function (c) return type(interpreter.core.reader.protected) ~= "boolean"
- and c <= #interpreter.core.classes end,
- {"pass_pattern", loop = function (c, p) return type(interpreter.core.reader.protected) ~= "boolean"
- and p <= #interpreter.core.classes[c] end,
- {"pass_line", loop = function (c, p, l) return type(interpreter.core.reader.protected) ~= "boolean"
- and l <= #interpreter.core.lines end,
- {"check_index", loop = function (c, p, l, i)
- return (type(interpreter.core.lines[l]) == "string" and type(interpreter.core.reader.protected) ~= "boolean")
- and interpreter.core.tools.get_index(interpreter.core.lines[l], interpreter.core.classes[c][p].pattern, i)
- end,
- {"call", conditional = function (c, p) return interpreter.core.classes[c][p].call end,
- function(c, p, l, i)
- local line, pattern = interpreter.core.lines[l], interpreter.core.classes[c][p]
- local index = interpreter.core.tools.get_index(line, pattern.pattern, i)
- local L, O = pattern.call(interpreter.core.lines, l, index, pattern)
- if O then
- l, i = L, O
- elseif L then
- i = L
+ {"pass_class", iterator = function ()
+ local done_zero
+ local function f (t, i)
+ if type(interpreter.core.reader.protected) ~= "boolean" then
+ if not done_zero then
+ i = i+1
+ local v = t[i]
+ if v then
+ return i, v
+ else
+ done_zero = true
+ return 0, t[0]
+ end
+ end
+ end
+ end
+ return f, interpreter.core.classes, 0
+ end,
+ {"pass_pattern", iterator = function (_, class)
+ local function f (t, i)
+ if type(interpreter.core.reader.protected) ~= "boolean" then
+ i = i+1
+ local v = t[i]
+ if v then
+ return i, v
+ end
+ end
+ end
+ return f, class, 0
+ end,
+ {"process_lines", iterator = function (_, pattern)
+ interpreter.core.reader.current_line = 0
+ interpreter.core.reader.current_index = 0
+ return function ()
+ if type(interpreter.core.reader.protected) ~= "boolean" then
+ local l = interpreter.core.reader.current_line
+ local i = interpreter.core.reader.current_index
+ if i == 0 then
+ l, i = l + 1, 1
+ end
+ line = interpreter.core.lines[l]
+ -- When protected, a line is a table.
+ while type(line) == "table" do
+ l, i = l+1, 1
+ line = interpreter.core.lines[l]
+ end
+ if line then
+ interpreter.core.reader.current_line = l
+ interpreter.core.reader.current_index = i
+ return l, pattern, i
+ end
+ end
+ end
+ end,
+ {"switch", autoreturn = true,
+ function (_, pattern)
+ if pattern.call then
+ interpreter.core.reader.ajar("call", "process_lines")
+ elseif pattern.replace then
+ interpreter.core.reader.ajar("replace", "process_lines")
end
- return c, p, l, i
- end},
- {"replace", conditional = function (c, p) return not interpreter.core.classes[c][p].call
- and interpreter.core.classes[c][p].replace end,
- function(c, p, l, i)
- local line, pattern = interpreter.core.lines[l], interpreter.core.classes[c][p]
- local index = interpreter.core.tools.get_index(line, pattern.pattern, i)
- interpreter.core.lines[l] = interpreter.core.tools.xsub(line, index, pattern.pattern, pattern.replace)
- i = index + (pattern.offset or 0)
- return c, p, l, i
end},
- {"protect", conditional = function () return type(interpreter.core.reader.protected) == "table" end,
- autoreturn = true,
- function ()
- for n, _ in pairs(interpreter.core.reader.protected) do
- if type(interpreter.core.lines[n]) == "string" then
- interpreter.core.lines[n] = {interpreter.core.lines[n]}
+ {"call", status = "close",
+ function(i, pattern, ind)
+ local line = interpreter.core.lines[i]
+ local index = interpreter.core.tools.get_index(line, pattern.pattern, ind)
+ if index then
+ local L, O = pattern.call(interpreter.core.lines, i, index, pattern)
+ if O then
+ interpreter.core.reader.current_line = L
+ interpreter.core.reader.current_index = O
+ elseif L then
+ interpreter.core.reader.current_index = L
end
+ else
+ interpreter.core.reader.current_index = 0
end
- end}},
- {"increment_line", function (c, p, l, i) return c, p, l+1, 1 end}},
- {"increment_pattern", function (c, p, l) return c, p+1, 1, 1 end}},
- {"increment_class", function (c) return c+1, 1, 1, 1 end}},
- {"apply_class0", conditional = function () return type(interpreter.core.reader.protected) ~= "boolean" end,
- {"initialize0",
- function ()
- return 0, 1, 1, 1
- end},
- {"pass_pattern", loop = function (c, p) return type(interpreter.core.reader.protected) ~= "boolean"
- and p <= #interpreter.core.classes[c] end}},
+ end},
+ {"replace", status = "close",
+ function(i, pattern, ind)
+ local line = interpreter.core.lines[i]
+ local index = interpreter.core.tools.get_index(line, pattern.pattern, ind)
+ if index then
+ interpreter.core.lines[i] = interpreter.core.tools.xsub(line, index, pattern.pattern, pattern.replace)
+ interpreter.core.reader.current_index = index + (pattern.offset or 0)
+ else
+ interpreter.core.reader.current_index = 0
+ end
+ end},
+ {"protect", iterator = function ()
+ if type(interpreter.core.reader.protected) == "table" then
+ return pairs(interpreter.core.reader.protected)
+ end
+ end,
+ function (n)
+ if type(interpreter.core.lines[n]) == "string" then
+ interpreter.core.lines[n] = {interpreter.core.lines[n]}
+ end
+ end}}}},
{"unprotect",
{"undo_protected",
function ()
interpreter.core.reader.protected = nil
end},
- {"unprotect_lines",
- function ()
- for n, l in ipairs(interpreter.core.lines) do
- if type(l) == "table" then
- interpreter.core.lines[n] = l[1]
- end
+ {"unprotect_lines", iterator = function () return ipairs(interpreter.core.lines) end,
+ function (i, l)
+ if type(l) == "table" then
+ interpreter.core.lines[i] = l[1]
end
end}},
{"remove_escape", conditional = function () return interpreter.escape end,
diff --git a/Master/texmf-dist/tex/luatex/interpreter/interpreter.sty b/Master/texmf-dist/tex/luatex/interpreter/interpreter.sty
index 94f94443ad9..ba16a86256f 100644
--- a/Master/texmf-dist/tex/luatex/interpreter/interpreter.sty
+++ b/Master/texmf-dist/tex/luatex/interpreter/interpreter.sty
@@ -5,10 +5,10 @@
% Author: Paul Isambert.
% E-mail: zappathustra AT free DOT fr
% Comments and suggestions are welcome.
-% Date: December 2011.
+% Date: June 2012.
\NeedsTeXFormat{LaTeX2e}
-\ProvidesPackage{interpreter}[2011/12/03 v.1.1 Preprocessing input files on the fly.]
+\ProvidesPackage{interpreter}[2012/06/10 v.1.2 Preprocessing input files on the fly.]
% Needed to prevent LaTeX check input, which would call open_read_file and
% thus remove Interpreter's main function (which is removed as soon as it is
% used).
diff --git a/Master/texmf-dist/tex/luatex/interpreter/interpreter.tex b/Master/texmf-dist/tex/luatex/interpreter/interpreter.tex
index 3f58083dd72..3568fc90e9d 100644
--- a/Master/texmf-dist/tex/luatex/interpreter/interpreter.tex
+++ b/Master/texmf-dist/tex/luatex/interpreter/interpreter.tex
@@ -1,7 +1,7 @@
% This is the main TeX file for the Interpreter package.
% Further information in interpreter-doc.pdf or interpreter-doc.txt.
%
-% Paul Isambert - zappathustra AT free DOT fr - December 2011
+% Paul Isambert - zappathustra AT free DOT fr - June 2012
%
\csname Oh no, Interpreter won't be loaded twice!\endcsname
\expandafter\let\csname Oh no, Interpreter won't be loaded twice!\endcsname\endinput