From 584c65e596bdc44bd5a9a4a3b6bd02847b48b981 Mon Sep 17 00:00:00 2001 From: Philipp Gesang Date: Wed, 22 Sep 2010 20:32:42 +0200 Subject: setups and directives now occupy their own files --- rst_context.lua | 549 +---------------------------------------------------- rst_directives.lua | 242 +++++++++++++++++++++++ rst_parser.lua | 1 + rst_setups.lua | 327 +++++++++++++++++++++++++++++++ 4 files changed, 576 insertions(+), 543 deletions(-) create mode 100644 rst_directives.lua create mode 100644 rst_setups.lua diff --git a/rst_context.lua b/rst_context.lua index 5f700f7..77e0966 100644 --- a/rst_context.lua +++ b/rst_context.lua @@ -2,9 +2,6 @@ -------------------------------------------------------------------------------- -- FILE: rst_context.lua -- USAGE: ./rst_context.lua --- DESCRIPTION: --- OPTIONS: --- --- REQUIREMENTS: --- -- AUTHOR: Philipp Gesang (Phg), -- VERSION: 1.0 -- CREATED: 31/08/10 19:35:15 CEST @@ -20,6 +17,7 @@ require "lpeg" help = require "rst_helpers" +rst_directives = require "rst_directives" local dbg_write = help.dbg_writef @@ -45,7 +43,7 @@ local err = function(str) end end -local rst_context = {} +rst_context = {} rst_context.collected_adornments = {} rst_context.last_section_level = 0 @@ -474,6 +472,8 @@ local inline_parser = P{ url_path = V"slash" * (V"url_path_char"^1 * V"slash"^-1)^1, } +rst_context.inline_parser = inline_parser + function rst_context.paragraph (data) local str if not data then @@ -1091,9 +1091,9 @@ function rst_context.substitution_definition (subtext, directive, data) return "" end --- not to be confused with the directive definition table rst_context.directives +-- not to be confused with the directive definition table rst_directives function rst_context.directive(directive, ...) - local rd = rst_context.directives + local rd = rst_directives rst_context.addsetups("directive") local data = {...} local result = "" @@ -1103,541 +1103,4 @@ function rst_context.directive(directive, ...) return result end -optional_setups = {} -function optional_setups.footnote_symbol () - local setup = [[ -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% Footnotes with symbol conversion % -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -\definenote[symbolnote][footnote] -\setupnote [symbolnote][way=bypage,numberconversion=set 2] -]] - return setup -end - -function optional_setups.footnotes () - local tf = state.footnotes - local fn = [[ - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% Footnotes % -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -]] - local buffer = [[ - -%% %s -\startbuffer[%s] -%s\stopbuffer -]] - - for nf, note in next, tf.numbered do - fn = fn .. string.format(buffer, "Autonumbered footnote", "__footnote_number_"..nf, note) - end - for nf, note in next, tf.autolabel do - fn = fn .. string.format(buffer, "Labeled footnote", "__footnote_label_"..nf, note) - end - for nf, note in next, tf.symbol do - fn = fn .. string.format(buffer, "Symbol footnote", "__footnote_symbol_"..nf, note) - end - return fn -end - -function optional_setups.references () - local refs = rst_context.collected_references - local crefs = rst_context.context_references - local arefs = rst_context.anonymous_set - - local function urlescape (str) - return str:gsub("#", "\\#") - end - - local function resolve_indirect (r) - if r and r:match(".*_$") then -- pointing elsewhere - local look_me_up = r:match("^`?([^`]*)`?_$") - local result = resolve_indirect (refs[look_me_up]) - if result then - return result - else - if rst_context.structure_references[look_me_up] then - -- Internal link, no useURL etc. - return false - end - end - end - return r - end - - local refsection = [[ - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% References % -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -]] - local references = {} - local ref_keys = {} - for ref, target in next, refs do - ref_keys[#ref_keys+1] = [[__target_]] .. rst_context.whitespace_to_underscore(ref) - target = resolve_indirect(target) - if target ~= false then - ref_text = ref - if arefs[ref_text] then - ref_text = rst_context.anonymous_links[tonumber(arefs[ref_text])] - end - references[#references+1] = string.format([[ -\useURL[__target_%s] [%s] [] [%s] ]], rst_context.whitespace_to_underscore(ref), urlescape(target), ref_text) - end - end - refsection = refsection .. table.concat(references, "\n") - -- this is needed in order to select the right reference command later - refsection = refsection .. "\n\n" .. [[\def \RSTexternalreferences{]] .. table.concat(ref_keys, ",") .. [[} - -% #1 target name, #2 link text -\def\RSTchoosegoto#1#2{% - \rawdoifinsetelse{#1}{\RSTexternalreferences}% - {\from[#1]}% - {\goto{#2}[#1]}% -} -]] - - return refsection -end - --------------------------------------------------------------------------------- --- Directives for use with |substitutions| --------------------------------------------------------------------------------- - -rst_context.directives = {} -rst_context.directives.anonymous = 0 -rst_context.directives.images = {} -rst_context.directives.images.done = {} -rst_context.directives.images.values = {} - -rst_context.directives.images.keys = { - ["width"] = "width", - ["size"] = "width", - ["caption"] = "caption", - ["alt"] = "caption", - ["scale"] = "scale", -} - -rst_context.directives.images.values.scale = function (orig) - -- http://wiki.contextgarden.net/Reference/en/useexternalfigure - -- scale=1000 is original size; to get 72%, use scale=720. - return tonumber(orig) * 1000 -end - -rst_context.directives.images.values.width = { - ["fit"] = "\\hsize", - ["hsize"] = "\\hsize", - ["broad"] = "\\hsize", - ["normal"] = "local", - ["normal"] = "local", -} - --- we won't allow passing arbitrary setups to context -rst_context.directives.images.permitted_setups = { - "width", "scale" -} - -local function img_setup (properties) - local result = "" - for _, prop in next, rst_context.directives.images.permitted_setups do - if properties[prop] then - result = result .. prop .. "=" .. properties[prop] .. "," - end - end - if result ~= "" then - result = "[" .. result .. "]" - end - return result -end - -rst_context.directives.image = function(name, data) - local properties = {} - local anon = false - local rd = rst_context.directives - if not data then -- this makes the “name” argument optional - data = name - rd.anonymous = rd.anonymous + 1 - anon = true -- indicates a nameless picture - name = "anonymous" .. rd.anonymous - end - properties.caption = name - --properties.width = "\\local" - - local processed = "" -- stub; TODO do something useful with optional dimension specifications - if type(data) == "table" then -- should always be true - local p = helpers.patterns - for _, str in ipairs(data) do - local key, val - key, val = p.colon_keyval:match(str) - local rdi = rst_context.directives.images - if key and val then - key = rdi.keys[key] -- sanitize key expression - if type(rdi.values[key]) == "table" then - val = rdi.values[key][val] - elseif type(rdi.values[key]) == "function" then - val = rdi.values[key](val) - end - properties[key] = val - else - processed = processed .. (str and str ~= "" and string.strip(str)) - end - end - end - properties.setup = img_setup(properties) or "" - data = processed - processed = nil - local img = "" - local images_done = rd.images.done - if not anon then - if not images_done[name] then - img = img .. string.format([[ - -\useexternalfigure[%s][%s][] -]], name, data) - images_done[name] = true - end - img = img .. string.format([[ -\def\RSTsubstitution%s{%% - \placefigure[here]{%s}{\externalfigure[%s]%s} -} -]], name, rst_context.escape(inline_parser:match(properties.caption)), name, properties.setup) - else -- image won't be referenced but used instantly - img = img .. string.format([[ - -\placefigure[here]{%s}{\externalfigure[%s]%s} -]], rst_context.escape(inline_parser:match(properties.caption)), data, properties.setup) - end - return img -end - -rst_context.directives.caution = function(raw) - rst_context.addsetups("dbend") - rst_context.addsetups("caution") - local text - local first = true - for _, line in ipairs(raw) do - if not helpers.patterns.spacesonly:match(line) then - if first then - text = line - first = false - else - text = text .. " " .. line - end - end - end - text = rst_context.escape(helpers.string.wrapat(inline_parser:match(text))) - return string.format([[ -\startRSTcaution -%s -\stopRSTcaution -]], text) -end - -rst_context.directives.danger = function(raw) - rst_context.addsetups("dbend") - rst_context.addsetups("danger") - local text - local first = true - for _, line in ipairs(raw) do - if not helpers.patterns.spacesonly:match(line) then - if first then - text = line - first = false - else - text = text .. " " .. line - end - end - end - text = rst_context.escape(helpers.string.wrapat(inline_parser:match(text))) - return string.format([[ -\startRSTdanger -%s -\stopRSTdanger -]], text) -end - --- http://docutils.sourceforge.net/docs/ref/rst/directives.html -rst_context.directives.DANGER = function(addendum) - local result = "" - for _,str in ipairs(addendum) do - result = result .. (string.strip(str)) - end - return string.format([[ - -%% The Rabbit of Caerbannog -\startlinecorrection -\blank[force,big] -\framed[frame=on, - corner=round, - rulethickness=5pt, - align=middle, - width=\hsize, - frameoffset=.5em, - backgroundoffset=1em, - background=color, - backgroundcolor=red, - foreground=color, - foregroundcolor=black]{%% - \language[en-gb]\tfb\bf - Follow only if ye be men of valour, for the entrance to this cave is guarded - by a creature so foul, so cruel that no man yet has fought with it and lived. - Bones of full fifty men lie strewn about its lair. So, brave knights, if you - do doubt your courage or your strength, come no further, for death awaits you - all with nasty, big, pointy teeth.%% - \blank[force,big] - %s%% -} -\blank[force,big] -\stoplinecorrection -]], result) -end - -rst_context.directives.ctx = function(name, data) - local ctx = string.format([[ - -\startbuffer[%s] -%s -\stopbuffer -\def\RSTsubstitution%s{%% - \getbuffer[%s] -} -]], name, data, name, name) - return ctx -end - -rst_context.directives.lua = function(name, data) - local luacode = string.format([[ - -\startbuffer[%s] -\startluacode -%s -\stopluacode -\stopbuffer -\def\RSTsubstitution%s{%% - \getbuffer[%s]%% -} -]], name, data, name, name) - return luacode -end - -rst_context.directives.replace = function(name, data) - return string.format([[ - -\def\RSTsubstitution%s{%s} -]], name, data) -end - -function optional_setups.substitutions () - local directives = rst_context.directives - local substitutions = [[ - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% Substitutions % -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -]] - local rs = rst_context.substitutions - for name, content in next, rs do - local directive, data = content.directive, content.data - name, data = name:gsub("%s", ""), string.strip(data) - if directives[directive] then - substitutions = substitutions .. directives[directive](name, data) - else - err(directive .. " does not exist.") - end - end - return substitutions -end - -function optional_setups.directive () - --local directives = rst_context.directives - --local dirstr = [[ - ---%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% ---% Directives % ---%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% ---]] - --return dirstr - return "" -end - -function optional_setups.blockquote () - return [[ - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% Blockquotes % -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -\setupdelimitedtext [blockquote][style={\tfx}] % awful placeholder -\definedelimitedtext[attribution][blockquote] -\setupdelimitedtext [attribution][style={\tfx\it}] -]] -end - -function optional_setups.deflist () - return [[ - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% Definitionlist % -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -\def\startRSTdefinitionlist{ - \bgroup - \def \RSTdeflistterm##1{{\bf ##1}} - \def\RSTdeflistclassifier##1{\hbox to 1em{\it ##1}} - \def\RSTdeflistdefinition##1{% - \startnarrower[left] - ##1% - \stopnarrower} - \def\RSTdeflistparagraph ##1{% - \startparagraph{% - \noindentation ##1 - \stopparagraph} - } -} - -\let\stopRSTdefinitionlist\egroup -]] -end - -function optional_setups.lines () - return [[ - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% Lines environment (line blocks) % -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\setuplines[% - space=on,% - before={\startlinecorrection\blank[small]},% - after={\blank[small]\stoplinecorrection},% -] -]] -end - -function optional_setups.breaks () - return [[ - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% Fancy transitions % -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\usemodule[fancybreak] -\setupfancybreak[symbol=star] -]] -end - -function optional_setups.fieldlist () - return [[ - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% Fieldlists % -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\def\startRSTfieldlist{% - \bgroup% - \unexpanded\def\RSTfieldname##1{\bTR\bTC ##1\eTC} - \unexpanded\def\RSTfieldbody##1{\bTC ##1\eTC\eTR} -% - \setupTABLE[c][first] [background=color, backgroundcolor=grey, style=\bf] - \setupTABLE[c][2] [align=right] - \setupTABLE[c][each] [frame=off] - \setupTABLE[r][each] [frame=off] - \bTABLE[split=yes,option=stretch] - \bTABLEhead - \bTR - \bTH Field \eTH - \bTH Body \eTH - \eTR - \eTABLEhead - \bTABLEbody -} - -\def\stopRSTfieldlist{% - %\eTABLEbody % doesn't work, temporarily moved to rst_context.field_list() - \eTABLE - \egroup% -} -]] -end - -function optional_setups.dbend () - -- There's just no reason for not providing this. - optional_setups.dbend_done = true - return [[ -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% Dangerous bend % -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\loadmapfile [manfnt.map] -\definefontsynonym [bends] [manfnt] - -\def\GetSym#1{\getglyph{bends}{\char#1}} - -\startsymbolset [Dangerous Bends] - \definesymbol [dbend] [\GetSym{127}] - \definesymbol [lhdbend] [\GetSym{126}] - \definesymbol [lhdbend] [\GetSym{0}] -\stopsymbolset - -\setupsymbolset [Dangerous Bends] - -]] -end - -function optional_setups.caution () - local result = "" - --if not optional_setups.dbend_done then - --result = result .. optional_setups.dbend() - --end - return result .. [[ -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% Caution directive % -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\usemodule[lettrine] - -\setbox0=\hbox{\symbol[dbend]} -\newskip\RSTbendskip -\RSTbendskip=\wd0 -\advance\RSTbendskip by 1em % These two lines should add -\advance\RSTbendskip by 1pt % 13.4pt in mkiv and 13.14983pt in mkii - % to make the indent equal to the indent - % of the “danger” directive. - % (2*(width)dbend + (kern)1pt + 1em - -\def\startRSTcaution{% -\startparagraph -\dontleavehmode\lettrine[Lines=2,Raise=.6,Findent=\RSTbendskip,Nindent=0pt]{\symbol[dbend]}{}% -} - -\let\stopRSTcaution\stopparagraph - -]] - -end - -function optional_setups.danger () - local result = "" - --if not optional_setups.dbend_done then - --result = result .. optional_setups.dbend() - --end - return result .. [[ -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% Danger directive % -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\usemodule[lettrine] - -\def\startRSTdanger{% -\startparagraph -\lettrine[Lines=2,Raise=.6,Findent=1em,Nindent=0pt]{\symbol[dbend]\kern 1pt\symbol[dbend]}{}% -} - -\let\stopRSTdanger\stopparagraph - -]] - -end - return rst_context diff --git a/rst_directives.lua b/rst_directives.lua new file mode 100644 index 0000000..0b042df --- /dev/null +++ b/rst_directives.lua @@ -0,0 +1,242 @@ +#!/usr/bin/env texlua +-------------------------------------------------------------------------------- +-- FILE: rst_directives.lua +-- USAGE: ./rst_directives.lua +-- AUTHOR: Philipp Gesang (Phg), +-- VERSION: 1.0 +-- CREATED: 22/09/10 20:26:40 CEST +-------------------------------------------------------------------------------- +-- + +-------------------------------------------------------------------------------- +-- Directives for use with |substitutions| +-------------------------------------------------------------------------------- + +rst_directives = {} +rst_directives.anonymous = 0 +rst_directives.images = {} +rst_directives.images.done = {} +rst_directives.images.values = {} + + +rst_directives.images.keys = { + ["width"] = "width", + ["size"] = "width", + ["caption"] = "caption", + ["alt"] = "caption", + ["scale"] = "scale", +} + +rst_directives.images.values.scale = function (orig) + -- http://wiki.contextgarden.net/Reference/en/useexternalfigure + -- scale=1000 is original size; to get 72%, use scale=720. + return tonumber(orig) * 1000 +end + +rst_directives.images.values.width = { + ["fit"] = "\\hsize", + ["hsize"] = "\\hsize", + ["broad"] = "\\hsize", + ["normal"] = "local", + ["normal"] = "local", +} + +-- we won't allow passing arbitrary setups to context +rst_directives.images.permitted_setups = { + "width", "scale" +} + +local function img_setup (properties) + local result = "" + for _, prop in next, rst_directives.images.permitted_setups do + if properties[prop] then + result = result .. prop .. "=" .. properties[prop] .. "," + end + end + if result ~= "" then + result = "[" .. result .. "]" + end + return result +end + +rst_directives.image = function(name, data) + local inline_parser = rst_context.inline_parser + local properties = {} + local anon = false + local rd = rst_directives + if not data then -- this makes the “name” argument optional + data = name + rd.anonymous = rd.anonymous + 1 + anon = true -- indicates a nameless picture + name = "anonymous" .. rd.anonymous + end + properties.caption = name + --properties.width = "\\local" + + local processed = "" -- stub; TODO do something useful with optional dimension specifications + if type(data) == "table" then -- should always be true + local p = helpers.patterns + for _, str in ipairs(data) do + local key, val + key, val = p.colon_keyval:match(str) + local rdi = rst_directives.images + if key and val then + key = rdi.keys[key] -- sanitize key expression + if type(rdi.values[key]) == "table" then + val = rdi.values[key][val] + elseif type(rdi.values[key]) == "function" then + val = rdi.values[key](val) + end + properties[key] = val + else + processed = processed .. (str and str ~= "" and string.strip(str)) + end + end + end + properties.setup = img_setup(properties) or "" + data = processed + processed = nil + local img = "" + local images_done = rd.images.done + if not anon then + if not images_done[name] then + img = img .. string.format([[ + +\useexternalfigure[%s][%s][] +]], name, data) + images_done[name] = true + end + img = img .. string.format([[ +\def\RSTsubstitution%s{%% + \placefigure[here]{%s}{\externalfigure[%s]%s} +} +]], name, rst_context.escape(inline_parser:match(properties.caption)), name, properties.setup) + else -- image won't be referenced but used instantly + img = img .. string.format([[ + +\placefigure[here]{%s}{\externalfigure[%s]%s} +]], rst_context.escape(inline_parser:match(properties.caption)), data, properties.setup) + end + return img +end + +rst_directives.caution = function(raw) + local inline_parser = rst_context.inline_parser + rst_context.addsetups("dbend") + rst_context.addsetups("caution") + local text + local first = true + for _, line in ipairs(raw) do + if not helpers.patterns.spacesonly:match(line) then + if first then + text = line + first = false + else + text = text .. " " .. line + end + end + end + text = rst_context.escape(helpers.string.wrapat(inline_parser:match(text))) + return string.format([[ +\startRSTcaution +%s +\stopRSTcaution +]], text) +end + +rst_directives.danger = function(raw) + local inline_parser = rst_context.inline_parser + rst_context.addsetups("dbend") + rst_context.addsetups("danger") + local text + local first = true + for _, line in ipairs(raw) do + if not helpers.patterns.spacesonly:match(line) then + if first then + text = line + first = false + else + text = text .. " " .. line + end + end + end + text = rst_context.escape(helpers.string.wrapat(inline_parser:match(text))) + return string.format([[ +\startRSTdanger +%s +\stopRSTdanger +]], text) +end + +-- http://docutils.sourceforge.net/docs/ref/rst/directives.html +rst_directives.DANGER = function(addendum) + local result = "" + for _,str in ipairs(addendum) do + result = result .. (string.strip(str)) + end + return string.format([[ + +%% The Rabbit of Caerbannog +\startlinecorrection +\blank[force,big] +\framed[frame=on, + corner=round, + rulethickness=5pt, + align=middle, + width=\hsize, + frameoffset=.5em, + backgroundoffset=1em, + background=color, + backgroundcolor=red, + foreground=color, + foregroundcolor=black]{%% + \language[en-gb]\tfb\bf + Follow only if ye be men of valour, for the entrance to this cave is guarded + by a creature so foul, so cruel that no man yet has fought with it and lived. + Bones of full fifty men lie strewn about its lair. So, brave knights, if you + do doubt your courage or your strength, come no further, for death awaits you + all with nasty, big, pointy teeth.%% + \blank[force,big] + %s%% +} +\blank[force,big] +\stoplinecorrection +]], result) +end + +rst_directives.ctx = function(name, data) + local ctx = string.format([[ + +\startbuffer[%s] +%s +\stopbuffer +\def\RSTsubstitution%s{%% + \getbuffer[%s] +} +]], name, data, name, name) + return ctx +end + +rst_directives.lua = function(name, data) + local luacode = string.format([[ + +\startbuffer[%s] +\startluacode +%s +\stopluacode +\stopbuffer +\def\RSTsubstitution%s{%% + \getbuffer[%s]%% +} +]], name, data, name, name) + return luacode +end + +rst_directives.replace = function(name, data) + return string.format([[ + +\def\RSTsubstitution%s{%s} +]], name, data) +end + +return rst_directives diff --git a/rst_parser.lua b/rst_parser.lua index 1adffb9..bbe1f15 100644 --- a/rst_parser.lua +++ b/rst_parser.lua @@ -14,6 +14,7 @@ --require "lpeg" rst = require "rst_context" helpers = require "rst_helpers" +optional_setups = require "rst_setups" local rst_debug = true diff --git a/rst_setups.lua b/rst_setups.lua new file mode 100644 index 0000000..1b2428a --- /dev/null +++ b/rst_setups.lua @@ -0,0 +1,327 @@ +#!/usr/bin/env texlua +-------------------------------------------------------------------------------- +-- FILE: rst_setups.lua +-- USAGE: ./rst_setups.lua +-- DESCRIPTION: Setups for rstcontext +-- OPTIONS: --- +-- REQUIREMENTS: --- +-- AUTHOR: Philipp Gesang (Phg), +-- VERSION: 1.0 +-- CREATED: 22/09/10 20:21:01 CEST +-------------------------------------------------------------------------------- +-- + +rst_directives = require "rst_directives" + +local optional_setups = {} + +function optional_setups.footnote_symbol () + local setup = [[ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Footnotes with symbol conversion % +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\definenote[symbolnote][footnote] +\setupnote [symbolnote][way=bypage,numberconversion=set 2] +]] + return setup +end + +function optional_setups.footnotes () + local tf = state.footnotes + local fn = [[ + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Footnotes % +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +]] + local buffer = [[ + +%% %s +\startbuffer[%s] +%s\stopbuffer +]] + + for nf, note in next, tf.numbered do + fn = fn .. string.format(buffer, "Autonumbered footnote", "__footnote_number_"..nf, note) + end + for nf, note in next, tf.autolabel do + fn = fn .. string.format(buffer, "Labeled footnote", "__footnote_label_"..nf, note) + end + for nf, note in next, tf.symbol do + fn = fn .. string.format(buffer, "Symbol footnote", "__footnote_symbol_"..nf, note) + end + return fn +end + +function optional_setups.references () + local refs = rst_context.collected_references + local crefs = rst_context.context_references + local arefs = rst_context.anonymous_set + + local function urlescape (str) + return str:gsub("#", "\\#") + end + + local function resolve_indirect (r) + if r and r:match(".*_$") then -- pointing elsewhere + local look_me_up = r:match("^`?([^`]*)`?_$") + local result = resolve_indirect (refs[look_me_up]) + if result then + return result + else + if rst_context.structure_references[look_me_up] then + -- Internal link, no useURL etc. + return false + end + end + end + return r + end + + local refsection = [[ + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% References % +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +]] + local references = {} + local ref_keys = {} + for ref, target in next, refs do + ref_keys[#ref_keys+1] = [[__target_]] .. rst_context.whitespace_to_underscore(ref) + target = resolve_indirect(target) + if target ~= false then + ref_text = ref + if arefs[ref_text] then + ref_text = rst_context.anonymous_links[tonumber(arefs[ref_text])] + end + references[#references+1] = string.format([[ +\useURL[__target_%s] [%s] [] [%s] ]], rst_context.whitespace_to_underscore(ref), urlescape(target), ref_text) + end + end + refsection = refsection .. table.concat(references, "\n") + -- this is needed in order to select the right reference command later + refsection = refsection .. "\n\n" .. [[\def \RSTexternalreferences{]] .. table.concat(ref_keys, ",") .. [[} + +% #1 target name, #2 link text +\def\RSTchoosegoto#1#2{% + \rawdoifinsetelse{#1}{\RSTexternalreferences}% + {\from[#1]}% + {\goto{#2}[#1]}% +} +]] + + return refsection +end + +function optional_setups.substitutions () + local directives = rst_directives + local substitutions = [[ + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Substitutions % +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +]] + local rs = rst_context.substitutions + for name, content in next, rs do + local directive, data = content.directive, content.data + name, data = name:gsub("%s", ""), string.strip(data) + if directives[directive] then + substitutions = substitutions .. directives[directive](name, data) + else + err(directive .. " does not exist.") + end + end + return substitutions +end + +function optional_setups.directive () + --local dirstr = [[ + +--%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +--% Directives % +--%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +--]] + --return dirstr + return "" +end + +function optional_setups.blockquote () + return [[ + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Blockquotes % +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\setupdelimitedtext [blockquote][style={\tfx}] % awful placeholder +\definedelimitedtext[attribution][blockquote] +\setupdelimitedtext [attribution][style={\tfx\it}] +]] +end + +function optional_setups.deflist () + return [[ + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Definitionlist % +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\def\startRSTdefinitionlist{ + \bgroup + \def \RSTdeflistterm##1{{\bf ##1}} + \def\RSTdeflistclassifier##1{\hbox to 1em{\it ##1}} + \def\RSTdeflistdefinition##1{% + \startnarrower[left] + ##1% + \stopnarrower} + \def\RSTdeflistparagraph ##1{% + \startparagraph{% + \noindentation ##1 + \stopparagraph} + } +} + +\let\stopRSTdefinitionlist\egroup +]] +end + +function optional_setups.lines () + return [[ + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Lines environment (line blocks) % +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\setuplines[% + space=on,% + before={\startlinecorrection\blank[small]},% + after={\blank[small]\stoplinecorrection},% +] +]] +end + +function optional_setups.breaks () + return [[ + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Fancy transitions % +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\usemodule[fancybreak] +\setupfancybreak[symbol=star] +]] +end + +function optional_setups.fieldlist () + return [[ + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Fieldlists % +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\def\startRSTfieldlist{% + \bgroup% + \unexpanded\def\RSTfieldname##1{\bTR\bTC ##1\eTC} + \unexpanded\def\RSTfieldbody##1{\bTC ##1\eTC\eTR} +% + \setupTABLE[c][first] [background=color, backgroundcolor=grey, style=\bf] + \setupTABLE[c][2] [align=right] + \setupTABLE[c][each] [frame=off] + \setupTABLE[r][each] [frame=off] + \bTABLE[split=yes,option=stretch] + \bTABLEhead + \bTR + \bTH Field \eTH + \bTH Body \eTH + \eTR + \eTABLEhead + \bTABLEbody +} + +\def\stopRSTfieldlist{% + %\eTABLEbody % doesn't work, temporarily moved to rst_context.field_list() + \eTABLE + \egroup% +} +]] +end + +function optional_setups.dbend () + -- There's just no reason for not providing this. + optional_setups.dbend_done = true + return [[ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Dangerous bend % +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\loadmapfile [manfnt.map] +\definefontsynonym [bends] [manfnt] + +\def\GetSym#1{\getglyph{bends}{\char#1}} + +\startsymbolset [Dangerous Bends] + \definesymbol [dbend] [\GetSym{127}] + \definesymbol [lhdbend] [\GetSym{126}] + \definesymbol [lhdbend] [\GetSym{0}] +\stopsymbolset + +\setupsymbolset [Dangerous Bends] + +]] +end + +function optional_setups.caution () + local result = "" + --if not optional_setups.dbend_done then + --result = result .. optional_setups.dbend() + --end + return result .. [[ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Caution directive % +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\usemodule[lettrine] + +\setbox0=\hbox{\symbol[dbend]} +\newskip\RSTbendskip +\RSTbendskip=\wd0 +\advance\RSTbendskip by 1em % These two lines should add +\advance\RSTbendskip by 1pt % 13.4pt in mkiv and 13.14983pt in mkii + % to make the indent equal to the indent + % of the “danger” directive. + % (2*(width)dbend + (kern)1pt + 1em + +\def\startRSTcaution{% +\startparagraph +\dontleavehmode\lettrine[Lines=2,Raise=.6,Findent=\RSTbendskip,Nindent=0pt]{\symbol[dbend]}{}% +} + +\let\stopRSTcaution\stopparagraph + +]] + +end + +function optional_setups.danger () + local result = "" + --if not optional_setups.dbend_done then + --result = result .. optional_setups.dbend() + --end + return result .. [[ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Danger directive % +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\usemodule[lettrine] + +\def\startRSTdanger{% +\startparagraph +\lettrine[Lines=2,Raise=.6,Findent=1em,Nindent=0pt]{\symbol[dbend]\kern 1pt\symbol[dbend]}{}% +} + +\let\stopRSTdanger\stopparagraph + +]] + +end + +return optional_setups + -- cgit v1.2.3