Commits

Anonymous committed 8c3cb5b

new job processor

  • Participants
  • Parent commits a535e3b

Comments (0)

Files changed (1)

File tex/context/third/bstellen/bibelstellen.lua

 local lpeg    = require "lpeg"
 local unicode = require "unicode"
 
-local verbose = false
+local verbose = true
 
 local     P,      R,      S,      V
    = lpeg.P, lpeg.R, lpeg.S, lpeg.V
 end
 
 ------------------------------------------------------------------------
--- strings
+-- directives, for postprocessing
 ------------------------------------------------------------------------
 
-local localized_strings = { -- all except “keys” have a long alternative
-    ["keys"]       = "schlüssel",
-    ["abbrev"]     = "sigle",
-    ["location"]   = "stelle",
-    ["text"]       = "text",
-}
-
-local localize = function (str)
-    return localized_strings[str] or str
+local postprocess_entry
+do
+    local h_keywords = function (key, raw)
+        local tdsk    = td.stellen.keywords
+        local keys    = stringexplode(raw, ",")
+        local newkeys = { }
+        for i=1, #keys do
+            local keyword = stringstrip(keys[i])
+            newkeys[keyword] = true
+            tdsk[keyword]    = true
+        end
+        return key, newkeys
+    end
+    local h_opt_long = function (key, raw)
+        local value = stringstrip(raw)
+        local long  = stringfind(key, "-l$") and true or false
+        if long then key = stringmatch(key, "(.+)-l$") end
+        return key, { value = value, long = long }
+    end
+    local localized_strings = { -- all except “keys” have a long alternative
+        ["abbrev-l"]   = "sigle-l",
+        ["abbrev"]     = "sigle",
+        ["key"]        = "schlüssel",
+        ["keys"]       = "schlüssel",
+        ["location-l"] = "stelle-l",
+        ["location"]   = "stelle",
+        ["text"]       = "text",
+    }
+    local handlers = {
+        ["schlüssel"]  = h_keywords,
+        ["sigle"]      = h_opt_long,
+        ["sigle-l"]    = h_opt_long,
+        ["stelle"]     = h_opt_long,
+        ["stelle-l"]   = h_opt_long,
+        ["text"]       = h_opt_long,
+        ["text-l"]     = h_opt_long,
+    }
+    postprocess_entry = function (entry)
+        local new = { }
+        for k, v in next, entry do
+            k = localized_strings[k] or k
+            --print(k,v)
+            k, v = handlers[k](k, v)
+            new[k] = v
+        end
+        return new
+    end
 end
-
-------------------------------------------------------------------------
--- directives, for use with parser
-------------------------------------------------------------------------
-
-local add_entry = function (...)
-    local all = { ... }
-    local new = { }
-    local id, keywords
-
-    local n = 1
-    while n <= #all do
-        local this = all[n]
-        local long = false
-        local key, value = utflower(this[1]), stringstrip(this[2])
-
-        if stringfind(key, "%-l$") then
-            long = true
-            key = stringmatch(key, "^(.*)-l$")
-        end
-
-        key = localize(key)
-
-        if key == "sigle" or key == "stelle" then
-            id = value
-        end
-
-        if key == "schlüssel" then
-            keywords = stringexplode(value, ",")
-        end
-
-        --new[key] = value
-        new[key] = { value = value, long = long }
-        n = n + 1
-    end
-    warn("adding entry:", id)
-
-    local tdsk = td.stellen.keywords
-    for _, key in next, keywords do
-        key = stringstrip(key)
-        -- this *does* look awful
-        local tdskk = tdsk[key] or {}
-        tdskk[#tdskk+1] = id
-        tdsk[key]       = tdskk
-    end
-    td.stellen.data[id] = new
-end
-
-------------------------------------------------------------------------
--- old input parser
-------------------------------------------------------------------------
-local b_parser = P{
-    [1] = "file",
-    file             = V"block" * (V"separator"^1 * V"block")^0,
-
-    dash             = P"-",
-    colon            = P":",
-    comment_char     = P";",
-    eol              = P"\n\r" + P"\r\n" + P"\r" + P"\n", -- you never know
-    eof              = -P(1),
-    space            = P" ",
-    tabs             = S"\t\v",
-    whitespace       = (V"space" + V"tabs"),
-    blank_line       = V"whitespace"^0 * V"eol",
-    rest_of_line     = (1 - V"eol")^0  * V"eol",
-    blank_or_comment = V"blank_line" + V"comment_line",
-    comment_line     = V"comment_char"^1 * V"rest_of_line",    -- ignored
-
-    separator        = V"blank_or_comment"^0
-                     * V"dash"^1
-                     * V"eol"
-                     * V"blank_or_comment"^0
-                     ,
-    block            = V"blank_or_comment"^0  * V"line"
-                     * (V"blank_or_comment"^1 * V"line")^0
-                     * (V"blank_or_comment"^0 + V"whitespace"^0 * V"eof")
-                     / add_entry
-                     ,
-    line             = V"comment_line" + V"entry",
-    entry            = Ct(C(V"key") * V"colon" * C(V"value")),
-    key              = V"schluessel"
-                     + ((V"stelle" + V"sigle" + V"text")
-                     * V"longsuffix"^-1)
-                     ,
-    stelle           = V"stelle_en"     + V"stelle_de",
-    sigle            = V"sigle_en"      + V"sigle_de",
-    text             = V"text_en"       + V"text_de",
-    schluessel       = V"schluessel_en" + V"schluessel_de",
-
-    --- TODO make strings configurable
-    stelle_en        = P"LOCATION"  + P"Location" + P"location",
-    sigle_en         = P"ABBREV"    + P"Abbrev"   + P"abbrev",
-    text_en          = P"TEXT"      + P"Text"     + P"text",
-    schluessel_en    = P"KEYS"      + P"Keys"     + P"keys",
-
-    stelle_de        = P"STELLE"    + P"Stelle"    + P"stelle",
-    sigle_de         = P"SIGLE"     + P"Sigle"     + P"sigle",
-    text_de          = P"TEXT"      + P"Text"      + P"text",
-    schluessel_de    = P"SCHLÜSSEL" + P"Schlüssel" + P"schlüssel",
-
-    longsuffix       = V"dash" * P"l",
-    --value            = (1 - (V"blank_or_comment"
-    --                       * (V"key" + V"separator")))^1,
-    value_illegal    = V"eol" * V"blank_or_comment",
-    value            = (1 - V"value_illegal")^1,
-}
-
-------------------------------------------------------------------------
--- input file processing
-------------------------------------------------------------------------
-
-local get_data = function (filename)
-    local files
-    if stringmatch(filename, ",") then
-        -- multiple files
-        files = stringexplode(filename, ",+")
-    else
-        files = { filename }
-    end
-
-    for _,file in next, files do
-        warn("Processing file " .. file)
-        local raw = string_of_file(file)
-        if raw then
-            lpegmatch(b_parser, raw)
-        end
-    end
-
-    return 0
-end
-
 ------------------------------------------------------------------------
 --                           refined parser
 ------------------------------------------------------------------------
     local dash             = P"-"
     local colon            = P":"
     local semicolon        = P";"
-    local eol              = P"\n\r" + P"\r\n" + P"\r" + P"\n" / " " -- you never know
+    local eol              = P"\n\r" + P"\r\n" + P"\r" + P"\n" -- you never know
+    local nuke_eol         = eol / " "
     local eof              = -P(1)
     local space            = P" "
     local tabs             = S"\t\v"
                            * whitespace^0 * dash^1 * whitespace^0
                            * eol
                            * blank_or_comment^0
-    local non_blank_line   = -#blank_or_comment * rest_of_line
-    local dbg = function (...)
-        local args = { ... }
-        io.write"=>"
-        io.write(args[1])
-        if args[2] then
-            for i=2, #args do
-                io.write(" <> ")
-                io.write(args[i])
-            end
-        end
-        io.write"\n"
-        return ...
-    end
+    local non_blank_line   = -#blank_or_comment * (1 - eol)^1 * nuke_eol
+    --local dbg = function (...)
+    --    local args = { ... }
+    --    io.write"=>"
+    --    io.write(args[1])
+    --    if args[2] then
+    --        for i=2, #args do
+    --            io.write(" <> ")
+    --            io.write(args[i])
+    --        end
+    --    end
+    --    io.write"\n"
+    --    return ...
+    --end
     --- grammar
     local stellen_parser = P{
         "blocks",
                     ,
         value       = Cs(non_blank_line^1), -- substitutes eols with spaces
     }
+    local add_stellen = function (s)
+        local data = td.stellen.data or { }
+        for i=1, #s do
+            data[#data+1] = postprocess_entry(s[i])
+        end
+        td.stellen.data = data
+    end
     get_data = function (filename)
         local files
         if stringmatch(filename, ",") then
         for _,file in next, files do
             warn("Processing file " .. file)
             local raw = string_of_file(file)
-            print">>>>>>>>>>>>>>>>>>>>>>>>>>>"
             if raw then
                 local data = lpegmatch(stellen_parser, raw)
-                table.print(data)
-                td.stellen.data = data
+                add_stellen(data)
             end
         end
         return 0
 -- typesetting routines
 ------------------------------------------------------------------------
 
-local do_do_one = function (entry)
-    local tdsp = td.stellen.parameters
-
-    local thishead = entry[tdsp.head]["value"]
-    local thisheadstyle = entry[tdsp.head]["long"] and tdsp.longheadstyle or tdsp.headstyle
-
+local do_do_one = function (parms, entry)
+    local thishead = entry[parms.head].value
+    local thisheadstyle = entry[parms.head].long and parms.longheadstyle or parms.headstyle
     local thisbody = entry.text.value
-    local thisbodystyle = entry.text.long and tdsp.longbodystyle or tdsp.bodystyle
+    local thisbodystyle = entry.text.long and parms.longbodystyle or parms.bodystyle
 
     contextbgroup()
         context(thisheadstyle)
         context(thishead)
     contextegroup()
     contextendgraf()
-    context(tdsp.inbetween)
+    context(parms.inbetween)
     contextbgroup()
         context(thisbodystyle)
         context(thisbody)
     contextegroup()
     contextendgraf()
-    return ""
 end
 
 local do_one = function (entry)
             roffset      = tdsp.foffset,
         }, 
         function ()
-                do_do_one(entry)
+                do_do_one(tdsp, entry)
             return ""
         end
     )
     return 0
 end
 
+local by_category = function (cat)
+    local cats   = { }
+    local result = { }
+    local data   = td.stellen.data
+    for _, cat in next,stringexplode(cat, ",") do
+        cats[#cats+1] = stringstrip(cat)
+    end
+    local ncats = #cats
+    for i=1, #data do
+        local entry = data[i]
+        local keys  = entry["schlüssel"]
+        for i=1, ncats do
+            if keys[cats[i]] == true then
+                --table.print(entry)
+                result[#result+1] = entry
+                break
+            end
+        end
+    end
+    return result
+end
+
 td.stellen.typeset = function (filename, categories)
     get_data(filename)
     warn("done processing file:", filename)
 
     local done = { }
-    local cnt  = 1
     local tdsk = td.stellen.keywords
     local tdsd = td.stellen.data
     local tdsp = td.stellen.parameters
+    local job  = by_category(categories)
     --table.print(tdsd)
+    --table.print(tdsk)
+    --table.print(tdsp)
+    --table.print(job)
+    warn("processing categories:", categories)
+    warn("total entries selected:", #job)
     contextstartcolumns({
         n        = tdsp.columns,
         distance = "0mm"
     })
     context.offinterlineskip()
-    for _,category in next,stringexplode(categories, ",") do
-        category = stringstrip(category)
-        if tdsk[category] then
-            local keys = tdsk[category]
-            for _,key in next,keys do
-                warn("typesetting entry", key, "of category", category )
-                if not done[key] then
-                    if cnt > 1 and cnt % (tdsp.columns * tdsp.rows) == 1 then
-                        warn("starting new page at entry nr.", cnt)
-                        contextpage()
-                    elseif cnt > 1 and cnt % 6 == tdsp.rows then
-                        contextpar()
-                    end
-                    do_one(tdsd[key])
-                    done[key] = true
-                    cnt       = cnt + 1
-                end
-            end
+    local cnt  = 1
+    for i=1, #job do
+        local entry = job[i]
+        if cnt > 1 and cnt % (tdsp.columns * tdsp.rows) == 1 then
+            warn("starting new page at entry nr.", cnt)
+            contextpage()
+        elseif cnt > 1 and cnt % 6 == tdsp.rows then
+            contextpar()
         end
+        do_one(entry)
+        cnt       = cnt + 1
     end
     contextstopcolumns()
     return 0