summaryrefslogtreecommitdiff
path: root/mod/tex/context/third/rst/rst_context.lua
diff options
context:
space:
mode:
authorPhilipp Gesang <phg@phi-gamma.net>2014-03-01 22:47:25 +0100
committerPhilipp Gesang <phg@phi-gamma.net>2014-03-01 22:47:25 +0100
commit7d1114cd66025cc18535f3cdab3105e66bbda48d (patch)
treeeca33193cdbb0d7923527b0c0bfb58cd893036b6 /mod/tex/context/third/rst/rst_context.lua
parent7652729ada000906e5e6b2b4d0c5dea01c73c29d (diff)
downloadcontext-rst-7d1114cd66025cc18535f3cdab3105e66bbda48d.tar.gz
adopt more conventional directory structure
Diffstat (limited to 'mod/tex/context/third/rst/rst_context.lua')
-rw-r--r--mod/tex/context/third/rst/rst_context.lua1316
1 files changed, 0 insertions, 1316 deletions
diff --git a/mod/tex/context/third/rst/rst_context.lua b/mod/tex/context/third/rst/rst_context.lua
deleted file mode 100644
index c7e21fe..0000000
--- a/mod/tex/context/third/rst/rst_context.lua
+++ /dev/null
@@ -1,1316 +0,0 @@
-#!/usr/bin/env texlua
---------------------------------------------------------------------------------
--- FILE: rst_context.lua
--- USAGE: called by rst_parser.lua
--- DESCRIPTION: Complement to the reStructuredText parser
--- AUTHOR: Philipp Gesang (Phg), <phg42.2a@gmail.com>
--- CHANGED: 2013-03-26 22:46:17+0100
---------------------------------------------------------------------------------
---
---- TODO
---- Find an appropriate way to handle generic tables irrespective of the grid
---- settings. The problem is:
---- http://archive.contextgarden.net/message/20100912.112605.8a1aaf13.en.html
---- Seems we'll have to choose either the grid or split tables as default. Not
---- good.
-
-
-local helpers = helpers or thirddata and thirddata.rst_helpers
-local rst_directives = rst_directives or thirddata and thirddata.rst_directives
-
-local utf = unicode.utf8
-local utflen = utf.len
-local utflower = utf.lower
-local utfupper = utf.upper
-local iowrite = io.write
-local tableconcat = table.concat
-
-local stringmatch = string.match
-local stringgmatch = string.gmatch
-local stringgsub = string.gsub
-
-local dbg_write = helpers.dbg_writef
-
-local C, Cb, Cc, Cg, Cmt, Cp,
- Cs, Ct, P, R, S, V, lpegmatch
- = lpeg.C, lpeg.Cb, lpeg.Cc, lpeg.Cg, lpeg.Cmt, lpeg.Cp,
- lpeg.Cs, lpeg.Ct, lpeg.P, lpeg.R, lpeg.S, lpeg.V, lpeg.match
-
--- This one should ignore escaped spaces.
-do
- local stripper = P{
- [1] = "stripper",
- stripper = V"space"^0 * C((V"space"^0 * (V"escaped" + V"nospace")^1)^0),
- space = S(" \t\v\n"),
- nospace = 1 - V"space",
- escaped = P"\\" * V"space"
- }
- function string.strip(str)
- return lpegmatch(stripper, str) or ""
- end
-end
-local stringstrip = string.strip
-local stringformat = string.format
-
-local err = function(str)
- if str then
- iowrite("\n*[rstctx] Error: " .. str .. "\n\n")
- end
-end
-
-local rst_context = thirddata.rst
-
-rst_context.collected_adornments = {}
-rst_context.last_section_level = 0
-rst_context.anonymous_targets = 0
-rst_context.anonymous_links = {}
-
-rst_context.collected_references = {}
-rst_context.context_references = {}
-rst_context.structure_references = {}
-rst_context.anonymous_set = {}
-
-rst_context.substitutions = {}
-rst_context.lastitemnumber = 0 -- enumerations in RST allow arbitrary skips
-
-rst_context.current_footnote_number = 0
-rst_context.current_symbolnote_number = 0
-
-function rst_context.addsetups(item)
- local state = rst_context.state
- state.addme[item] = state.addme[item] or true
- return 0
-end
-
-function rst_context.footnote_reference (label)
- local tf = rst_context.state.footnotes
- if stringmatch(label, "^%d+$") then -- all digits
- local c = tonumber(label)
- return [[\\footnote{\\getbuffer[__footnote_number_]].. c .."]}"
- elseif label == "#" then --autonumber
- local rc = rst_context.current_footnote_number
- rc = rc + 1
- rst_context.current_footnote_number = rc
- return [[\\footnote{\\getbuffer[__footnote_number_]].. rc .."]}"
- elseif stringmatch(label, "^#.+$") then
- local thelabel = stringmatch(label, "^#(.+)$")
- return [[\\footnote{\\getbuffer[__footnote_label_]].. thelabel .."]}"
- elseif label == "*" then
- local rc = rst_context.current_symbolnote_number
- rc = rc + 1
- rst_context.current_symbolnote_number = rc
- return [[\\symbolnote{\\getbuffer[__footnote_symbol_]].. rc .."]}"
- else -- “citation reference” for now treating them like footnotes
- rst_context.addsetups("citations")
- return [[\\cite{]] .. label .. [[}]]
- end
-end
-
-do
- local w = S" \v\t\n" / "_"
- local wp = Cs((w + 1)^1)
- function rst_context.whitespace_to_underscore(str)
- return str and lpegmatch(wp, str) or ""
- end
-end
-
---- So we can use crefs[n][2] to refer to the place where the reference was
---- created.
-local function get_context_reference (str)
- local crefs = rst_context.context_references
- local srefs = rst_context.structure_references
- srefs[str] = true
- refstring = "__target_" .. rst_context.whitespace_to_underscore(str)
- crefs[#crefs + 1] = { refstring, str }
- return refstring
-end
-
-function rst_context.emphasis (str)
- return [[{\\em ]] .. str .. [[}]]
-end
-
-function rst_context.strong_emphasis (str)
- return [[{\\sc ]] .. str .. [[}]]
-end
-
-function rst_context.literal (str)
- return [[\\type{]] .. str .. [[}]]
-end
-
---- ROLES for interpreted text
-
-rst_context.roles = {}
-rst_context.roles.emphasis = rst_context.emphasis
-rst_context.roles.strong_emphasis = rst_context.strong_emphasis
-rst_context.roles.literal = rst_context.literal
-rst_context.roles.bold = function(str)
- return [[{\\bold ]] .. str .. [[}]]
-end
-rst_context.roles.bf = rst_context.roles.bold
-
-rst_context.roles.italic = function(str)
- return [[{\\italic ]] .. str .. [[}]]
-end
-rst_context.roles.it = rst_context.roles.italic
-
-rst_context.roles.sans = function(str)
- return [[{\\ss ]] .. str .. [[}]]
-end
-rst_context.roles.sans_serif = rst_context.roles.sans
-rst_context.roles.ss = rst_context.roles.sans
-
-rst_context.roles.uppercase = function(str)
- return utfupper(str)
-end
-
-rst_context.roles.lowercase = function(str)
- return utflower(str)
-end
-
-rst_context.roles.color = function(color, str)
- local p = helpers.patterns
- local definition = stringmatch(color, "^color_(.+)$")
- if stringmatch(definition, "^rgb_") then -- assume rgb
- local rgb = lpegmatch(p.rgbvalues, definition)
- definition = stringformat([[r=%s,g=%s,b=%s]], rgb[1], rgb[2], rgb[3])
- end
- return stringformat([[\\colored[%s]{%s}]], definition, str)
-end
-
---------------------------------------------------------------------------------
---- Inofficial text roles for my private bib
---------------------------------------------------------------------------------
-
--- Afterthought:
--- Different citation commands are essentially typographical instructions:
--- they are concerned with the final representation of the data with respect to
--- a concrete implementation. Not the thing at all that would make reST
--- portable. But then its support for Python-style string escaping &c. ain’t at
--- all portable either. The problem is the same with XML written to be
--- processed with ConTeXt -- when processing the text directly in MkIV you’ll
--- always find yourself adding setups that allow fine-grained control of the
--- typeset output. At the same time those instructions directly contradict the
--- main reason for XML: to provide an application-independent data markup.
--- Typesetting XML (and now reST) with TeX, you will always end up writing TeX
--- code disguised in XML brackets. (Btw. the docutils reST specification has
--- the same kind of inclination to HTML -- some of its components don’t even
--- have a meaning save in HTML peculiarities.) If you strive to avoid this
--- *and* would like to have decent typesetting, you should use the
--- automatically generated TeX code as a starting point for the actual
--- typesetting job. Wish it was possible to have both -- the data in a
--- universal form and the output in the Optimal Typesetting System -- but
--- that’s a dream for now. If you really read these musings, then prove me
--- wrong if you can! Or go tell those digital publishers and their willing
--- subordinates, the authors, who think they can save a few pennys,
--- substituting the typesetter and editor by some fancy software. Keep in mind
--- that zapf.tex is not just random dummy text. </rant>
-
-function rst_context.roles.ctsh(str) -- shorthand
- rst_context.addsetups("citator")
- return [[\\ctsh{]] .. str .. [[}]]
-end
-
-function rst_context.roles.ctas(str) -- short cite
- rst_context.addsetups("citator")
- return [[\\ctas{]] .. str .. [[}]]
-end
-
-function rst_context.roles.ctau(str) -- author only
- rst_context.addsetups("citator")
- return [[\\ctau{]] .. str .. [[}]]
-end
-
-function rst_context.roles.cttt(str) -- title only
- rst_context.addsetups("citator")
- return [[\\cttt{]] .. str .. [[}]]
-end
-
-function rst_context.roles.ctay(str) -- author year
- rst_context.addsetups("citator")
- return [[\\ctay{]] .. str .. [[}]]
-end
-
-function rst_context.roles.ctfu(str) -- full cite
- rst_context.addsetups("citator")
- return [[\\ctfu{]] .. str .. [[}]]
-end
-
-function rst_context.roles.nocite(str) -- nocite
- rst_context.addsetups("citator")
- return [[\\nocite[]] .. str .. [=[]]=]
-end
-
---------------------------------------------------------------------------------
---- End citator roles
---------------------------------------------------------------------------------
-
---------------------------------------------------------------------------------
---- Experimental roles.
---------------------------------------------------------------------------------
-
---- Feature request by Philipp A.
-function rst_context.roles.math(str)
- return [[\\mathematics{]] .. str .. [[}]]
-end
-
---------------------------------------------------------------------------------
---- End roles
---------------------------------------------------------------------------------
-
-function rst_context.interpreted_text (...)
- local tab = { ... }
- local role, str
- role = stringmatch(tab[1], "^:(.*):$") or stringmatch(tab[3], "^:(.*):$")
- str = tab[2]
-
- if not role then -- implicit role
- role = "emphasis"
- end
-
- if stringmatch(role, "^color_") then
- return rst_context.roles.color(role, str)
- end
-
- return rst_context.roles[role](str)
-end
-
-function rst_context.link_standalone (str)
- return "\n"
- .. [[\\goto{\\hyphenatedurl{]] .. str .. [[}}[url(]] .. str .. [=[)]]=]
-end
-
-function rst_context.reference (str)
- rst_context.addsetups("references")
- str = stringmatch(str, "^`?([^`]+)`?_$")
- return [[\\RSTchoosegoto{__target_]] .. rst_context.whitespace_to_underscore(str) .. "}{"
- .. str .. "}"
-end
-
-function rst_context.anon_reference (str)
- rst_context.addsetups("references")
- str = stringmatch(str, "^`?([^`]+)`?__$")
- rst_context.anonymous_links[#rst_context.anonymous_links+1] = str
- link = "__target_anon_" .. #rst_context.anonymous_links
- return stringformat([[\\RSTchoosegoto{%s}{%s}]], link, str)
-end
-
-local whitespace = S" \n\t\v"
-local nowhitespace = 1 - whitespace
-local removewhitespace = Cs((nowhitespace^1 + Cs(whitespace / ""))^0)
-
-function rst_context.target (tab)
- rst_context.addsetups("references")
- --local tab = { ... }
- local refs = rst_context.collected_references
- local arefs = rst_context.anonymous_set
- local target = tab[#tab] -- Ct + C could be clearer but who cares
- tab[#tab] = nil
-
- local function create_anonymous ()
- rst_context.anonymous_targets = rst_context.anonymous_targets + 1
- return { "anon_" .. rst_context.anonymous_targets, rst_context.anonymous_targets }
- end
-
- local insert = ""
-
- if target == "" then -- links here
- for _, id in next, tab do
- insert = insert .. "\n\\reference[__target_" .. id .. "]{}"
- end
- else
- for i=1,#tab do
- local id = tab[i]
- if id == "" then -- anonymous
- local anon = create_anonymous()
- id, arefs[anon[1]] = anon[1], anon[2]
- else
- local tmp = tab[i]
- tmp = stringgsub(tmp, "\\:",":")
- tmp = stringmatch(tmp, "`?([^`]+)`?")
- id = tmp
- --id = tab[i]:gsub("\\:",":"):match("`?([^`]+)`?") -- deescaping
- end
- if id then
- refs[id] = refs[id] or target
- end
- end
- end
-
- return insert
-end
-
-function rst_context.inline_internal_target (str)
- return "\\\\reference[__target_" .. rst_context.whitespace_to_underscore(str) .."]{}"
-end
-
-function rst_context.substitution_reference (str, underscores)
- local sub = ""
- rst_context.addsetups "substitutions"
- if underscores == "_" then -- normal reference
- sub = sub .. [[\\reference[__target_]] .. rst_context.whitespace_to_underscore(stringstrip(str)) .. "]{}"
- elseif underscores == "__" then -- normal reference
- rst_context.anonymous_targets = rst_context.anonymous_targets + 1
- sub = sub .. [[\\reference[__target_anon_]] .. rst_context.anonymous_targets .. "]{}"
- end
- return sub .. [[{\\RSTsubstitution]] .. stringgsub(str, "%s", "") .. "}"
-end
-
-do
- -- see catc-sym.tex
- local escape_me = {
- ["&"] = [[\letterampersand ]],
- ["$"] = [[\letterdollar ]],
- ["#"] = [[\letterhash ]],
- ["^"] = [[\letterhat ]],
- ["_"] = [[\letterunderscore ]],
- }
-
- local chars
- for chr, repl in next, escape_me do
- chars = chars and chars + (P(chr) / repl) or P(chr) / repl
- end
-
- local p_escape = P{
- [1] = Cs((V"skip"
- --+ V"literal" -- achieved via gsub later
- + chars
- + 1)^1),
- skip1 = P"\\starttyping" * (1 - P"\\stoptyping")^1,
- balanced = P"{" * (V"balanced" + (1 - P"}"))^0 * P"}",
- skip2 = P"\\type" * V"balanced",
- skip3 = P"\\mathematics" * V"balanced",
- skip = V"skip1" + V"skip2" + V"skip3",
- --literal = Cs(P"\\" / "") * 1
- }
-
- function rst_context.escape (str)
- str = stringgsub(str, "\\(.)", "%1")
- return lpegmatch(p_escape, str)
- end
-end
-
-function rst_context.joinindented (tab)
- return tableconcat (tab, "")
-end
-
-local corresponding = {
- ['"'] = '"',
- ["'"] = "'",
- ["{"] = "}",
- ["("] = ")",
- ["["] = "]",
- ["<"] = ">",
-}
-
-local inline_parser = P{
- [1] = "block",
-
- block = Cs(V"inline_as_first"^-1 * (V"except" + V"inline_element" + V"normal_char")^0),
-
- inline_element = V"precede_inline"
- * Cs(V"inline_do_elements")
- * #V"succede_inline"
- + V"footnote_reference"
- ,
-
- -- Ugly but needed in case the first element of a paragraph is inline
- -- formatted.
- inline_as_first = V"inline_do_elements" * #V"succede_inline",
-
- except = P"\\starttyping" * (1 - P"\\stoptyping")^1 * P"\\stoptyping"
- + V"enclosed"
- ,
-
- inline_do_elements = V"strong_emphasis"
- + V"substitution_reference"
- + V"anon_reference"
- + V"inline_literal"
- + V"reference"
- + V"emphasis"
- + V"interpreted_text"
- + V"inline_internal_target"
- + V"link_standalone"
- ,
-
- precede_inline = V"spacing"
- + V"eol"
- + -P(1)
- + S[['"([{<-/:]]
- + P"‘" + P"“" + P"’" + P"«" + P"¡" + P"¿"
- + V"inline_delimiter"
- + P"„", -- not in standard Murkin reST
-
- succede_inline = V"spacing"
- + V"eol"
- + S[['")]}>-/:.,;!?\]]
- + P"’" + P"”" + P"»"
- + V"inline_delimiter"
- + -P(1)
- + P"“" -- non-standard again but who cares
- ,
-
- enclosed = V"precede_inline"^-1
- * Cg(V"quote_single" + V"quote_double" + V"leftpar", "lastgroup")
- * V"inline_delimiter"
- * Cmt(C(V"quote_single" + V"quote_double" + V"rightpar") * Cb("lastgroup"), function(s, i, char, oldchar)
- return corresponding[oldchar] == char
- end)
- * V"succede_inline"^-1
- * -V"underscore"
- ,
-
- space = P" ",
- whitespace = (P" " + Cs(P"\t") / " " + Cs(S"\v") / " "),
- spacing = V"whitespace"^1,
-
- eol = P"\n",
- --inline_delimiters = P"‐" + P"‑" + P"‒" + P"–" + V"emdash" + V"space", -- inline markup
- inline_delimiter = P"‐" + P"‑" + P"‒" + P"–" + V"emdash" + V"space"
- + V"bareia"
- + V"asterisk"
- + V"bar"
- + V"lbrack" + V"rbrack"
- , -- inline markup
- asterisk = P"*",
- quote_single = P"'",
- quote_double = P'"',
- double_asterisk = V"asterisk" * V"asterisk",
- bareia = P"`",
- backslash = P"\\",
- bar = P"|",
- double_bareia = V"bareia" * V"bareia",
- escaped_bareia = (Cs(V"backslash") / "" * V"bareia") + 1,
- colon = P":",
- escaped_colon = (Cs(V"backslash") / "" * V"colon") + 1,
- semicolon = P";",
- underscore = P"_",
- double_underscore = V"underscore" * V"underscore",
- dot = P".",
- interpunct = P"·",
- comma = P",",
- dash = P"-",
- emdash = P"—",
- ellipsis = P"…" + P"...",
- exclamationmark = P"!",
- questionmark = P"?",
- interrobang = P"‽",
- double_dash = V"dash" * V"dash",
- triple_dash = V"double_dash" * V"dash",
- hyphen = P"‐",
- dashes = V"dash" + P"‒" + P"–" + V"emdash" + P"―",
-
- lparenthesis = P"(",
- rparenthesis = P")",
- lbrack = P"[",
- rbrack = P"]",
- lbrace = P"{" / [[{\\letterleftbrace}]],
- rbrace = P"}" / [[{\\letterrightbrace}]],
- less = P"<",
- greater = P">",
- leftpar = V"lparenthesis" + V"lbrack" + V"lbrace" + V"less",
- rightpar = V"rparenthesis" + V"rbrack" + V"rbrace" + V"greater",
-
- normal_char = V"lbrace" + V"rbrace" + V"lbrack" + V"rbrack" -- escape those if in input
- + 1
- ,
-
- --groupchars = S"()[]{}",
- groupchars = V"leftpar" + V"rightpar",
- apostrophe = P"’" + P"'",
-
- guillemets = P"«" + P"»",
- quotationmarks= P"‘" + P"’" + P"“" + P"”",
- solidus= P"⁄",
- slash = P"/",
-
- gartenzaun = P"#",
- digit = R"09",
- letter = R"az" + R"AZ",
-
- punctuation = V"apostrophe"
- + V"colon"
- + V"comma"
- + V"dashes"
- + V"dot"
- + V"ellipsis"
- + V"exclamationmark"
- + V"guillemets"
- + V"hyphen"
- + V"interpunct"
- + V"interrobang"
- + V"questionmark"
- + V"quotationmarks"
- + V"semicolon"
- + V"slash"
- + V"solidus"
- + V"underscore"
- ,
-
- emphasis = (V"asterisk" - V"double_asterisk")
- * Cs((V"normal_char" - V"spacing" - V"eol" - V"asterisk")
- * ((V"normal_char" - (V"normal_char" * V"asterisk"))^0
- * (V"normal_char" - V"spacing" - V"eol" - V"asterisk"))^-1)
- * V"asterisk"
- / rst_context.emphasis,
-
- strong_emphasis = V"double_asterisk"
- * Cs((V"normal_char" - V"spacing" - V"eol" - V"asterisk")
- * ((V"normal_char" - (V"normal_char" * V"double_asterisk"))^0
- * (V"normal_char" - V"spacing" - V"eol" - V"asterisk"))^-1)
- * V"double_asterisk"
- / rst_context.strong_emphasis,
-
- inline_literal = V"double_bareia"
- * C ((V"escaped_bareia" - V"spacing" - V"eol" - V"bareia")
- * ((V"escaped_bareia" - (V"normal_char" * V"double_bareia"))^0
- * (V"escaped_bareia" - V"spacing" - V"eol" - V"bareia"))^-1)
- * V"double_bareia"
- / rst_context.literal,
-
- interpreted_single_char = (V"normal_char" - V"spacing" - V"eol" - V"bareia") * #V"bareia",
- interpreted_multi_char = (V"normal_char" - V"spacing" - V"eol" - V"bareia") * (V"normal_char" - (1 * V"bareia"))^0 * (1 - V"spacing" - V"eol" - V"bareia"),
-
- interpreted_text = C(V"role_marker"^-1)
- * (V"bareia" - V"double_bareia")
- * C(V"interpreted_single_char" + V"interpreted_multi_char")
- * V"bareia"
- * C(V"role_marker"^-1)
- / rst_context.interpreted_text,
-
- role_marker = V"colon" * (V"backslash" * V"colon" + V"letter" + V"digit" + V"dash" + V"underscore" + V"dot")^1 * V"colon",
-
- link_standalone = C(V"uri")
- / rst_context.link_standalone,
-
- anon_reference = Cs(V"anon_phrase_reference" + V"anon_normal_reference")
- / rst_context.anon_reference,
-
- anon_normal_reference = C((1 - V"underscore" - V"spacing" - V"eol" - V"punctuation" - V"groupchars")^1) * V"double_underscore",
-
- anon_phrase_reference = (V"bareia" - V"double_bareia")
- * C((1 - V"bareia")^1)
- * V"bareia" * V"double_underscore"
- ,
-
- reference = Cs(V"normal_reference" + V"phrase_reference")
- / rst_context.reference,
-
- normal_reference = (1 - V"underscore" - V"spacing" - V"eol" - V"punctuation" - V"groupchars")^1 * V"underscore",
-
- phrase_reference = (V"bareia" - V"double_bareia")
- * C((1 - V"bareia")^1)
- * V"bareia" * V"underscore"
- ,
-
- footnote_reference = V"lbrack"
- * Cs(V"footnote_label" + V"citation_reference_label")
- * V"rbrack"
- * V"underscore"
- / rst_context.footnote_reference
- ,
-
- footnote_label = V"digit"^1
- + V"gartenzaun" * V"letter"^1
- + V"gartenzaun"
- + V"asterisk"
- ,
-
- citation_reference_label = V"letter" * (1 - V"rbrack")^1,
-
- inline_internal_target = V"underscore"
- * V"bareia"
- * Cs((1 - V"bareia")^1)
- * V"bareia"
- / rst_context.inline_internal_target
- ,
-
- substitution_reference = V"bar"
- * C((1 - V"bar")^1)
- * V"bar"
- * C((V"double_underscore" + V"underscore")^-1)
- / rst_context.substitution_reference
- ,
-
---------------------------------------------------------------------------------
--- Urls
---------------------------------------------------------------------------------
- uri = V"url_protocol" * V"url_domain" * V"url_path_char"^0,
-
- url_protocol = (P"http" + P"ftp" + P"shttp" + P"sftp") * P"://",
- url_domain_char = 1 - V"dot" - V"spacing" - V"eol" - V"punctuation",
- url_domain = V"url_domain_char"^1 * (V"dot" * V"url_domain_char"^1)^0,
- url_path_char = R("az", "AZ", "09") + S[[-_.!~*'()/]],
-}
-
-rst_context.inline_parser = inline_parser
-
-function rst_context.paragraph (data)
- local str
- if not data then
- return ""
- elseif type(data) == "table" then
--- str = #data > 1 and helpers.string.wrapat(lpegmatch(inline_parser, tableconcat(data, " ")), 65)
--- or inline_parser:match(data[1])
- if #data > 1 then
- str = helpers.string.wrapat(
- lpegmatch(inline_parser, tableconcat(data, " "))
- , 65)
- else
- str = lpegmatch(inline_parser, data[1])
- end
- else
- str = data
- end
- return stringformat([[
-
-\\startparagraph
-%s
-\\stopparagraph
-]], str)
-end
-
-local sectionlevels = {
- [1] = "chapter",
- [2] = "section",
- [3] = "subsection",
- [4] = "subsubsection",
- [5] = "subsubsubsection",
-}
-
-local function get_line_pattern (chr)
- return P(chr)^1 * (-P(1))
-end
-
-function rst_context.section (...) -- TODO general cleanup; move validity
- local tab = { ... } -- checking to parser.
- local section, str = true, ""
- local adornchar
- local ulen = utflen
- if #tab == 3 then -- TODO use unicode length with ConTeXt
- adornchar = tab[1]:sub(1,1)
- section = ulen(tab[1]) >= ulen(tab[2])
- str = stringstrip(tab[2])
- else -- no overline
- adornchar = tab[2]:sub(1,1)
- section = ulen(tab[1]) <= ulen(tab[2])
- str = tab[1]
- end
-
- if section then -- determine level
- local level = rst_context.last_section_level
- local rca = rst_context.collected_adornments
- if rca[adornchar] then
- level = rca[adornchar]
- else
- level = level + 1
- rca[adornchar] = level
- rst_context.last_section_level = level
- end
-
- ref = get_context_reference (str)
-
- str = stringformat("\n\\\\%s[%s]{%s}\n", sectionlevels[level], ref, str)
- else
- return [[{\\bf fix your sectioning!}\\endgraf}]]
- end
-
- return section and str or ""
-end
-
--- Prime time for the fancybreak module.
-function rst_context.transition (str)
- rst_context.addsetups("breaks")
- --return "\\fancybreak\n"
- return "\\fancybreak{$* * *$}\n"
-end
-
-function rst_context.bullet_marker(str)
- return "marker"
-end
-
--- This one should ignore escaped spaces.
-do
- local stripper = P{
- [1] = "stripper",
- stripper = V"space"^0 * C((V"space"^0 * V"nospace"^1)^0),
- space = S(" \t\v\n"),
- escaped = P"\\" * V"space",
- nospace = V"escaped" + (1 - V"space"),
- }
- function stringstrip(str)
- return lpegmatch(stripper, str) or ""
- end
-end
-
-local enumeration_types = {
- ["*"] = "*", -- unordered bulleted
- ["+"] = "*",
- ["-"] = "*",
- ["•"] = "*",
- ["‣"] = "*",
- ["⁃"] = "*",
-
- ["#"] = "n", -- numbered lists and conversion
- ["A"] = "A",
- ["a"] = "a",
- ["I"] = "R",
- ["i"] = "r",
-}
-
--- \setupitemize[left=(, right=), margin=4em, stopper=]
-
-local stripme = S"()."
-local dontstrip = 1 - stripme
-local itemstripper = stripme^0 * C(dontstrip^1) * stripme^0
-
-local function parse_itemstring(str)
- local offset = nil
- local setup = ",fit][itemalign=flushright,"
- if stringmatch(str, "^%(") then
- setup = setup .. [[left=(,]]
- end
- if stringmatch(str, "%)$") then
- setup = setup .. [[right=)]]
- end
- if stringmatch(str, "%.$") then
- setup = setup .. [[stopper={.\\space}]]
- end
- local num = stringmatch(str, "^%d")
- if num then
- -- http://thread.gmane.org/gmane.comp.tex.context/61728/focus=61729
- setup = setup .. ",start=" .. num
- str = "n"
- end
-
- str = lpegmatch(itemstripper, str)
- str = enumeration_types[str] or str
- return { setup = setup, str = str }
-end
-
-function rst_context.startitemize(str)
- local setup = ""
- local result = ""
- str = stringstrip(str)
-
- local listtype = enumeration_types[str] or parse_itemstring(str)
-
- if type(listtype) == "table" then
- setup = listtype.setup
- listtype = listtype.str
- end
-
- result = [[
-\\startitemize[]] .. listtype .. setup .. [[]
-]]
- return result
-end
-
-local last_item = {} -- stack
-local current_itemdepth = 0
-function rst_context.stopitemize(str)
- last_item[current_itemdepth] = nil
- current_itemdepth = current_itemdepth - 1
- return str .. [[
-\\stopitemize
-]]
-end
-
-function rst_context.bullet_item (tab)
- local li = last_item
- -- The capture of the first item has the \startitemize as
- -- *second* element in the array.
- local content = #tab == 2 and tab[2] or tab[3]
- local startstr = #tab == 3 and tab[2] or nil
- local itemtype = tab[1]
- local result = startstr or ""
- if startstr then
- current_itemdepth = current_itemdepth + 1
- li[current_itemdepth] = itemtype
- elseif li[current_itemdepth] then
- if helpers.list.successor(itemtype, li[current_itemdepth]) then
- -- just leave it alone
- elseif helpers.list.greater(itemtype, li[current_itemdepth]) then
- local itemnum = tonumber(stringstrip(itemtype)) or helpers.list.get_decimal(itemtype)
- result = result .. stringformat([[
-\\setnumber[itemgroup:itemize]{%s}
-]], itemnum)
- end
- li[current_itemdepth] = itemtype
- end
-
- return result .. [[
-
-\\item ]] .. lpegmatch(inline_parser, content) .. [[
-
-]]
-end
-
---------------------------------------------------------------------------------
--- Definition lists
---------------------------------------------------------------------------------
--- TODO define proper setups (probably bnf-like and some narrower for def-paragraphs)
-
-function rst_context.deflist (list)
- rst_context.addsetups("deflist")
-
- local deflist = [[
-\\startRSTdefinitionlist
-]]
- for nd=1, #list do
- local item = list[nd]
- local term = item[1]
- local nc = 2
- local tmp = [[
-
- \\RSTdeflistterm{]] .. stringstrip(term) .. "}"
- if #item > 2 then
- while nc < #item do
- tmp = tmp .. [[
-
- \\RSTdeflistclassifier{]] .. stringstrip(item[nc]) .. "}"
- nc = nc + 1
- end
- end
- tmp = tmp .. [[
-
- \\RSTdeflistdefinition{%
-]]
- local final = item[#item]
- for np=1, #final do
- local par = final[np]
- tmp = tmp .. [[
- \\RSTdeflistparagraph{%
-]] .. lpegmatch(inline_parser, par) .. "}\n"
- end
- tmp = tmp .. " }"
- deflist = deflist .. tmp
- end
- return deflist .. [[
-
-\\stopRSTdefinitionlist
-]]
-end
-
---------------------------------------------------------------------------------
--- Field lists
---------------------------------------------------------------------------------
-
--- TODO Do something useful with field lists. For now I'm not sure what as the
--- bibliography directives from the reST specification seem to make sense only
--- when using docinfo and, after all, we have .bib files that are portable.
-
-function rst_context.field_list (str)
- rst_context.addsetups("fieldlist")
- return [[
-
-\\startRSTfieldlist]] .. str .. [[\\eTABLEbody\\stopRSTfieldlist
-]]
-end
-
-function rst_context.field_name (str)
- return [[\\fieldname{]] .. str .. [[}]]
-end
-
-function rst_context.field_body (str)
- return [[\\fieldbody{]] .. lpegmatch(inline_parser, str) .. [[}]]
-end
-
-function rst_context.field (tab)
- local name, body = tab[1], tab[2]
- return stringformat([[
-
- \\RSTfieldname{%s}
- \\RSTfieldbody{%s}
-]], name, lpegmatch(inline_parser, body))
-end
-
-function rst_context.line_comment (str)
- return "% " .. str
-end
-
-function rst_context.block_comment (str)
- return stringformat([[
-
-\iffalse %% start block comment
-%s\fi %% stop block comment
-]], str)
-end
-
-function rst_context.option_list (str)
- return [[
-\\setupTABLE[c][first] [background=color, backgroundcolor=grey, style=\tt]
-\\setupTABLE[c][each] [frame=off]
-\\setupTABLE[r][each] [frame=off]
-\\bTABLE[split=yes,option=stretch]
-\\bTABLEhead
-\\bTR
- \\bTH Option \\eTH
- \\bTH Description \\eTH
-\\eTR
-\\eTABLEhead
-\\bTABLEbody
-]] .. lpegmatch(inline_parser, str) .. [[
-
-\\eTABLEbody
-\\eTABLE
-]]
-end
-
-function rst_context.option_item (tab)
- return stringformat([[\\bTR\\bTC %s \\eTC\\bTC %s \\eTC\\eTR
-]], tab[1], tab[2])
-end
-
-function rst_context.test(str)
- return ":"
-end
-
-function rst_context.literal_block (str, included)
- local indent = P" "^1
- local stripme = #str
- for line in stringgmatch(str, "[^\n]+") do
- -- setting to the lowest indend of all lines
- local idt = lpegmatch(indent, line)
- if line and idt then
- stripme = idt < stripme and idt or stripme
- end
- end
-
- local strip = P{
- [1] = "strip",
- strip = Cs(V"line"^1),
- eol = P"\n",
- restofline = (1 - V"eol")^0,
- stop = Cs(V"eol" * P" "^0) * -P(1) / "", -- remove trailing blank lines
- line = Cs(V"restofline" * (V"stop" + V"eol")) / function (line)
- return #line > stripme and line:sub(stripme) or line
- end,
- }
-
- str = lpegmatch(strip, str)
- str = [[
-
-\starttyping[lines=hyphenated]
-]] .. str .. [[
-
-\stoptyping
-]]
- if included then -- escaping can ruin your day
- str = str:gsub("\\", "\\\\")
- end
- return str
-end
-
-function rst_context.included_literal_block (str)
- return rst_context.literal_block(str, true)
-end
-
-function rst_context.line_block (str)
- rst_context.addsetups("lines")
- return [[
-
-\\startlines
-]] .. lpegmatch(inline_parser, str) .. [[\\stoplines
-]]
-end
-
-function rst_context.line_block_line(str)
- str = str:gsub("\n", " ")
- return str .. "\n"
-end
-
-function rst_context.line_block_empty()
- return "\n"
-end
-
-function rst_context.block_quote (tab)
- rst_context.addsetups("blockquote")
- local str = [[
-\\startlinecorrection
-\\blank[small]
-\\startblockquote
-]] .. lpegmatch(inline_parser, tab[1]) .. [[
-
-\\stopblockquote
-]]
-
- return tab[2] and str .. [[
-\\blank[small]
-\\startattribution
-]] .. lpegmatch(inline_parser, tab[2]) .. [[
-\\stopattribution
-\\blank[small]
-\\stoplinecorrection
-]] or str .. [[
-\\blank[small]
-\\stoplinecorrection
-]]
-end
-
---function rst_context.table (str)
- --return [[
---\\startlinecorrection
---]] .. str .. [[
-
---\\stoplinecorrection
---]]
---end
-
-function rst_context.grid_table (tab)
- local body = ""
- local nr = 1
- local head
- if tab.has_head then
- head = [[
-\\setupTABLE[c][each] [frame=off]
-\\setupTABLE[r][each] [frame=off]
-%\\startlinecorrection
-\\bTABLE[split=repeat,option=stretch]
-\\bTABLEhead
-]]
- while nr <= tab.head_end do
- local r = tab.rows[nr]
- local isempty = true
- for n=1, #r do
- local cell = r[n]
- if cell.variant == "normal" then
- isempty = false
- break
- end
- end
-
- if not isempty then
- local row = [[\\bTR]]
- for n=1, #r do
- local c = r[n]
- if not (c.parent or
- c.variant == "separator") then
- local celltext = lpegmatch(inline_parser, c.stripped)
- if c.span.x or c.span.y then
- local span_exp = "["
- if c.span.x then
- span_exp = span_exp .. "nc=" .. c.span.x .. ","
- end
- if c.span.y then
- span_exp = span_exp .. "nr=" .. c.span.y
- end
- celltext = span_exp .. "] " .. celltext
-
- end
-
- row = row .. "\n " .. [[\\bTH ]] .. celltext .. [[\\eTH]]
- end
- end
- head = head .. row .. "\n" .. [[\\eTR]] .. "\n"
- end
- nr = nr + 1
- end
- head = head .. [[
-\\eTABLEhead
-\\bTABLEbody
-]]
- else
- head = [[
-\\setupTABLE[c][each] [frame=off]
-\\setupTABLE[r][each] [frame=off]
-%\\startlinecorrection
-\\bTABLE[split=repeat,option=stretch]
-\\bTABLEbody
-]]
- end
- while nr <= #tab.rows do
- local r = tab.rows[nr]
- local isempty = true
- for n=1, #r do
- local cell = r[n]
- if cell.variant == "normal" then
- isempty = false
- break
- end
- end
-
- if not isempty then
- local row = [[\\bTR]]
- for n=1, #r do
- local c = r[n]
- if not (c.parent or
- c.variant == "separator") then
- local celltext = lpegmatch(inline_parser, c.stripped)
- if c.span.x or c.span.y then
- local span_exp = "["
- if c.span.x then
- span_exp = span_exp .. "nc=" .. c.span.x .. ","
- end
- if c.span.y then
- span_exp = span_exp .. "nr=" .. c.span.y
- end
- celltext = span_exp .. "] " .. celltext
-
- end
-
- row = row .. "\n " .. [[\\bTC ]] .. celltext .. [[\\eTC]]
- end
- end
- body = body .. row .. "\n" .. [[\\eTR]] .. "\n"
- end
- nr = nr + 1
- end
- local tail = [[
-\\eTABLEbody
-\\eTABLE
-%\\stoplinecorrection
-]]
- return head .. body .. tail
-end
-
-
-function rst_context.simple_table(tab)
- local head
- local nr = 1
- if tab.head_end then
- head = [[
-\\setupTABLE[c][each] [frame=off]
-\\setupTABLE[r][each] [frame=off]
-%\\startlinecorrection
-\\bTABLE[split=yes,option=stretch]
-\\bTABLEhead
-]]
- while nr <= tab.head_end do
- local row = tab[nr]
- if not row.ignore then
- dbg_write(">hr>" .. #row)
- head = head .. [[\\bTR]]
- for nc=1, #row do
- local cell = row[nc]
- dbg_write("%7s | ", cell.content)
- local celltext = lpegmatch(inline_parser, cell.content)
- if cell.span then
- head = head .. stringformat([=[\\bTH[nc=%s]%s\\eTH]=], cell.span.x, celltext or "")
- else
- head = head .. [[\\bTH ]] .. celltext .. [[\\eTH]]
- end
- end
- dbg_write("\n")
- head = head .. "\\\\eTR\n"
- end
- nr = nr + 1
- end
-
- head = head .. [[
-\\eTABLEhead
-\\bTABLEbody
-]]
- else
- head = [[
-\\setupTABLE[c][each] [frame=off]
-\\setupTABLE[r][each] [frame=off]
-%\\startlinecorrection
-\\bTABLE[split=yes,option=stretch]
-\\bTABLEbody
-]]
- end
- local tail = [[
-\\eTABLEbody
-\\eTABLE
-%\\stoplinecorrection
-]]
- local body = ""
- while nr <= #tab do
- local row = tab[nr]
- if not row.ignore then
- dbg_write(">tr>" .. #row)
- body = body .. [[\\bTR]]
- for nc=1, #row do
- local cell = row[nc]
- dbg_write("%7s | ", cell.content)
- local celltext = lpegmatch(inline_parser, cell.content)
- if cell.span then
- body = body .. stringformat([=[\\bTC[nc=%s]%s\\eTC]=], cell.span.x, celltext or "")
- else
- body = body .. [[\\bTC ]] .. celltext .. [[\\eTC]]
- end
- end
- dbg_write("\n")
- body = body .. "\\\\eTR\n"
- end
- nr = nr + 1
- end
- return head .. body .. tail
-end
-
-function rst_context.footnote (label, content)
- local tf = rst_context.state.footnotes
- rst_context.addsetups("footnotes")
- if stringmatch(label, "^%d+$") then -- all digits
- tf.numbered[tonumber(label)] =
- rst_context.escape(lpegmatch(inline_parser, content))
- elseif label == "#" then --autonumber
- repeat -- until next unrequested number
- tf.autonumber = tf.autonumber + 1
- until tf.numbered[tf.autonumber] == nil
- tf.numbered[tf.autonumber] =
- rst_context.escape(lpegmatch(inline_parser, content))
- elseif stringmatch(label, "^#.+$") then
- local thelabel = stringmatch(label, "^#(.+)$")
- tf.autolabel[thelabel] =
- rst_context.escape(lpegmatch(inline_parser, content))
- elseif label == "*" then
- rst_context.addsetups("footnote_symbol")
- tf.symbol[#tf.symbol+1] =
- rst_context.escape(lpegmatch(inline_parser, content))
- else -- “citation reference” treated like ordinary footnote
- repeat -- until next unrequested number
- tf.autonumber = tf.autonumber + 1
- until tf.numbered[tf.autonumber] == nil
- tf.numbered[tf.autonumber] =
- rst_context.escape(lpegmatch(inline_parser, content))
- end
- return ""
-end
-
---- hack to differentiate inline images
-local special_substitutions = {
- image = "inline_image",
-}
-
-function rst_context.substitution_definition (subtext, directive, data)
- local special = special_substitutions[directive]
- if special then
- --- override; pass data directly
- directive = special
- else
- local tmp
- if data.first ~= "" then
- tmp = { data.first }
- else
- tmp = { }
- end
- data.first = nil
- for i=1, #data do -- paragraphs
- local current = tableconcat(data[i], "\n")
- --current = lpegmatch(inline_parser, current)
- --current = rst_context.escape(current)
- tmp[#tmp+1] = current
- end
- data = tableconcat(tmp, "\n\n")
- data = stringstrip(data)
- end
- subtext = stringgsub(subtext, "%s", "")
- rst_context.substitutions[subtext] = { directive = directive,
- data = data }
- return ""
-end
-
--- not to be confused with the directive definition table rst_directives
-function rst_context.directive(directive, data)
- local fun = rst_directives[directive]
- if fun then
- rst_context.addsetups("directive")
- local result = ""
- result = fun(data)
- return result
- end
- return ""
-end
-
--- vim:ft=lua:sw=4:ts=4:expandtab