%D \module %D [ file=t-inifile, %D version=2008.02.25, %D title=\CONTEXT\ User Module, %D subtitle=Formatting of ini-files, %D author=Peter Münster, %D date=\currentdate, %D copyright={Peter Münster}] %C This module is copyrighted by Peter Münster. %C Please send any comments to pmrb at free.fr. \writestatus{loading}{Formatting of ini-files} \unprotect \startluacode -- namespace inifile = {} -- just for debugging: print the table to stdout local function print_table() for i = 1,#inifile.t do print("") print(i, inifile.t[i].key) for k, v in pairs(inifile.t[i]) do print("", k, v) end print("") end end -- sort the table -- s1: primary key -- s2: secondary key local function sort_table(s1, s2) local function cmp(a, b) if s2 ~= "" and a[s1] == b[s1] then return a[s2] < b[s2] else return a[s1] < b[s1] end end if s1 ~= "" then table.sort(inifile.t, cmp) end end -- write default values to table entry -- d: the default values separated by commas -- i: the index of the entry local function write_defaults(d, i) for k, v in string.gmatch(d, "[,%s]*(.-)=([^,]*)") do inifile.t[i][k] = v end end -- generate table from ini-file -- d: default values for all entries -- s1: primary sort-key -- s1: secondary sort-key function inifile.make_table(d, s1, s2) inifile.t = {} local i = 0 while true do local l = io.read() if not l then break end while true do -- check for new entry: key = string.match(l, "^%[(.+)%]$") if key then i = i + 1 inifile.t[i] = {} inifile.t[i]["key"] = key write_defaults(d, i) break -- continue ! end -- treat continued lines: while string.match(l, "\\$") do local c = io.read() l = string.match(l, "^(.*)\\$") .. c end -- get a new key value pair: key, val = string.match(l, "^([%w_]+)%s*=%s(.*)$") if key then inifile.t[i][key] = val end break end end sort_table(s1, s2) print_table() end -- let ConTeXt print the sorted table with user defined formatting -- c: the user supplied command to print one entry function inifile.print(c) for i = 1,#inifile.t do tex.print(string.format("%s\\def\\IF@index{%d}%s\\%s", "\\unprotect", i, "\\protect", c)) end end -- initialise the new entry, in general to be called in the beginning -- of the user supplied formatting command -- i: the index of the new entry function inifile.newentry(i) for k, v in pairs(inifile.t[i]) do tex.print(string.format("\\def\\IF%s{%s}", k, v)) end end -- filter applied to values of a key -- k: the key -- s: the search pattern -- r: the replace string function inifile.filter(k, s, r) for i = 1,#inifile.t do inifile.t[i][k] = string.gsub(inifile.t[i][k], s, r) end end \stopluacode \def\setupIniFile[#1]{ \getparameters[IF@][defaults=,sortA=,sortB=,#1] \ctxlua{io.input("\IF@file")} \ctxlua{inifile.make_table("\IF@defaults", "\IF@sortA", "\IF@sortB")} } \def\IniFilePrint{\ctxlua{inifile.print("\IF@command")}} \def\IniFileNewEntry{\ctxlua{inifile.newentry(\IF@index)}} \def\IniFileFilter[#1][#2][#3]{\ctxlua{inifile.filter("#1", "#2", "#3")}} \protect \doifnotmode{demo}{\endinput} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %D Usage example: \usemodule[inifile] \setupIniFile[defaults={birthyear=1944,comment=}, sortA=birthyear,sortB=key,command=FormatMember,file=thewho.txt] \IniFileFilter[comment][\%\% ][\\letterpercent\\space ] \IniFileFilter[comment][\%\%][\\letterpercent ] \setupTABLE[frame=off,width=0.5\textwidth] \nonknuthmode \def\IFbirthyear{} \def\FormatMember{ \edef\LastBirthyear{\IFbirthyear} \IniFileNewEntry \doifnot\IFbirthyear\LastBirthyear{\section{\IFbirthyear}} \subsection{\WORD{\IFkey}} \bTABLE\bTR \bTD Given name: \IFgivenname\eTD\bTD Surname: \IFsurname\eTD \eTR\eTABLE \doifsomething\IFcomment{Comment to show the treatment of the percent sign: \IFcomment}} \starttext \title{The Who} \IniFilePrint \stoptext %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Put this into the file thewho.txt for the usage example: [p_t] givenname = Peter surname = Townshend birthyear = 1945 comment = 100 % with nobreakspace [r_d] givenname = Roger surname = Daltrey comment = 100 % with thinspace [j_e] givenname = John surname = Entwistle [k_m] givenname = Keith surname = Moon birthyear = 1946 [k_j] givenname = Kenney surname = Jones birthyear = 1948 %%% Local Variables: %%% default-tab-width: 4 %%% End: