summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhilipp Gesang <pgesang@ix.urz.uni-heidelberg.de>2010-09-17 09:53:31 +0200
committerPhilipp Gesang <pgesang@ix.urz.uni-heidelberg.de>2010-09-17 09:53:31 +0200
commitecf071dcc4f2447eee93c76d3c6e4201c97b3589 (patch)
treeae7e6247d62c0919d5ec9f8ef56d0ee5a53c3e10
parent279c04787d18e186c6c1c6bed2eb9002f8f0ec92 (diff)
downloadcontext-rst-ecf071dcc4f2447eee93c76d3c6e4201c97b3589.tar.gz
sectioning redone
-rw-r--r--rst_context.lua11
-rw-r--r--rst_parser.lua67
2 files changed, 66 insertions, 12 deletions
diff --git a/rst_context.lua b/rst_context.lua
index 6ace513..05ed14f 100644
--- a/rst_context.lua
+++ b/rst_context.lua
@@ -501,15 +501,16 @@ function rst_context.section (...) -- TODO general cleanup; move validity
local tab = { ... } -- checking to parser.
local section, str = true, ""
local adornchar
+ local ulen = unicode.utf8.len
if #tab == 3 then -- TODO use unicode length with ConTeXt
adornchar = tab[1]:sub(1,1)
- section = tab[1] == tab[3] and #tab[1] >= #tab[2]
- section = get_line_pattern(adornchar):match(tab[1]) ~= nil and section
+ section = ulen(tab[1]) >= ulen(tab[2])
+ --section = get_line_pattern(adornchar):match(tab[1]) ~= nil and section
str = string.strip(tab[2])
else -- no overline
adornchar = tab[2]:sub(1,1)
- section = #tab[1] <= #tab[2]
- section = get_line_pattern(adornchar):match(tab[2]) ~= nil and section
+ section = ulen(tab[1]) <= ulen(tab[2])
+ --section = get_line_pattern(adornchar):match(tab[2]) ~= nil and section
str = tab[1]
end
@@ -527,6 +528,8 @@ function rst_context.section (...) -- TODO general cleanup; move validity
ref = get_context_reference (str)
str = string.format("\n\\\\%s[%s]{%s}\n", sectionlevels[level], ref, str)
+ else
+ return [[{\\bf fix your sectioning!}\\endgraf}]]
end
return section and str or ""
diff --git a/rst_parser.lua b/rst_parser.lua
index 0901de4..a83209a 100644
--- a/rst_parser.lua
+++ b/rst_parser.lua
@@ -57,6 +57,7 @@ state.currentindent = "" -- used in definition lists and elsewhere
state.previousindent = "" -- for literal blocks included in paragraphs to restore the paragraph indent
state.currentwidth = 0 -- table layout
state.currentlayout = {} -- table layout
+state.previousadorn = nil -- section underlining and overlining
state.footnotes = {}
state.footnotes.autonumber = 0
@@ -67,6 +68,32 @@ state.footnotes.symbol = {}
state.addme = {}
+do
+ local first_adornment = ""
+ local valid_adornment = P{
+ [1] = "adorncheck",
+ adorncheck = V"check_first" * V"check_other"^1 * -P(1),
+
+ -- check_first = Cg(V"adornment_char", "first"), -- This *should* work but but due to some heavenly
+ -- intervention the governing rules of the universe
+ -- have been altered so as to annoy everybody
+ -- trying to deploy it.
+
+ check_first = Cmt(V"adornment_char", function(_,_, first)
+ first_adornment = first
+ return true
+ end)
+ ,
+ check_other = Cmt(V"adornment_char", function(_,_, char)
+ local prev = first_adornment
+ return char == prev
+ end)
+ ,
+ adornment_char = S[[!"#$%&'()*+,-./:;<=>?@[]^_`{|}~]] + P[[\\]],
+ }
+ state.valid_adornment = valid_adornment
+end
+
local enclosed_mapping = {
["'"] = "'",
['"'] = '"',
@@ -910,17 +937,41 @@ local parser = P{
-- Sectioning
--------------------------------------------------------------------------------
- section_adorn = C(V"adornment_char"^1) * V"space"^0 * V"eol",
+ section_adorn = V"adornment_char"^1,
+
+ section = V"section_before"^-1
+ * V"section_text"
+ * V"section_after"
+ * (V"eol" + V"end_block")
+ / rst.section
+ ,
-- The whitespace handling after the overline is necessary because headings
-- without overline aren't allowed to be indented.
- section = (V"section_adorn" * V"whitespace"^0)^-1
- * C((1 - V"whitespace") * (1 - V"eol")^1)
- * V"eol"
- * V"section_adorn"
- * V"eol"^-1
- / rst.section, -- validity checking done by the formatter. Now, if
- -- this ain't lazy then I don't know …
+ section_before = C(Cmt(V"section_adorn", function(s,i, adorn)
+ state.previousadorn = adorn
+ warn ("sec-f", state.valid_adornment:match(adorn), adorn:sub(1,2) .. "...", "", i)
+ return state.valid_adornment:match(adorn)
+ end))
+ * V"whitespace"^0
+ * V"eol"
+ * V"whitespace"^0
+ ,
+
+ section_text = C((1 - V"space" - V"eol")^1) * V"eol",
+
+ section_after = C(Cmt(V"section_adorn", function(s,i, adorn)
+ local tests = false
+ tests = state.valid_adornment:match(adorn) and true
+ if state.previousadorn then
+ tests = tests and adorn == state.previousadorn
+ end
+ warn ("sec-o", tests, adorn:sub(1,2) .. "…", "", i)
+ state.previousadorn = nil
+ return tests
+ end))
+ * V"whitespace"^0
+ ,
--------------------------------------------------------------------------------
-- Target Blocks