Last active
January 8, 2016 13:37
-
-
Save dohyunkim/ff37e969def2a6fa85f7 to your computer and use it in GitHub Desktop.
read csv and print latex tabular
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| readcsv = readcsv or {} | |
| local readcsv = readcsv | |
| local function readcsvlines (s, sep) | |
| sep = sep or ',' | |
| s = s .. "\n" | |
| s = s:gsub("[\r\n]+", "\n") -- unix newline | |
| local curr, t = 1, {{}} | |
| while true do | |
| local tt, i, a, c = t[#t], curr | |
| if s:find('^"', curr) then -- starts with doublequote | |
| repeat | |
| a, i, c = s:find('"(.)', i+1) -- "" or ", or "\n | |
| until c ~= '"' | |
| tt[#tt+1] = s:sub(curr+1, a-1):gsub('""', '"') -- restore double doublequotes | |
| else | |
| a, i, c = s:find("(["..sep.."\n])", curr) | |
| tt[#tt+1] = s:sub(curr, a-1) | |
| end | |
| curr = i + 1 | |
| if curr > s:len() then break end | |
| if c == "\n" then t[#t+1] = {} end -- prepare another line | |
| end | |
| return t | |
| end | |
| -- http://www.lua.org/pil/20.4.html | |
| -- https://tools.ietf.org/html/rfc4180#section-2 | |
| local function readcsvfile (f, sep) | |
| local fh = io.open(kpse.find_file(f), "r") | |
| local t = readcsvlines(fh:read("*all"), sep) | |
| fh:close() | |
| return t | |
| end | |
| local function parse_option (opt, s, length) | |
| s = s .. "," | |
| local curr = 1 | |
| while true do | |
| local k, v, i | |
| _, i, k = s:find("%s*([^,]-)%s*=%s*", curr) | |
| if not i then break end | |
| curr = i + 1 | |
| _, i, v = s:find("^(%b{})%s*,+", curr) | |
| if i then | |
| v = v:gsub("^{(.-)}$", "%1") | |
| else | |
| _, i, v = s:find("(.-)%s*,+", curr) | |
| end | |
| curr = i + 1 | |
| if k and v and k ~= "" then | |
| local row = k:match("^afterrow(.+)") | |
| if row == "*" then | |
| for l=0, length do | |
| opt.afterrow[l] = v | |
| end | |
| elseif row then | |
| opt.afterrow[tonumber(row)] = v | |
| else | |
| opt[k] = v | |
| end | |
| end | |
| end | |
| return opt | |
| end | |
| local function select_cols (t, cols) | |
| if not cols or cols == "" then return t end | |
| cols = cols:explode(",+") | |
| for i, v in ipairs(cols) do | |
| cols[i] = tonumber(v) | |
| end | |
| local tt = {} | |
| for i, v in ipairs(t) do | |
| tt[i] = {} | |
| for _, c in ipairs(cols) do | |
| tt[i][#tt[i]+1] = t[i][c] | |
| end | |
| end | |
| return tt | |
| end | |
| local function skip_rows (rows) | |
| local t = {} | |
| if not rows or rows == "" then return t end | |
| rows = rows:explode(",+") | |
| for _, v in ipairs(rows) do | |
| t[tonumber(v)] = true | |
| end | |
| return t | |
| end | |
| local catreg = { string = -2, latex = -1, } | |
| local function csv2tabular(f, sep, op) | |
| local t = readcsvfile(f, sep) | |
| local opt = { | |
| header = "\\begin{tabular}{"..string.rep("r", #t[1]).."}", | |
| footer = "\\end{tabular}", | |
| afterrow = { [0] = "\\hline", [1] = "\\hline", [#t] ="\\hline" }, | |
| catcode = "string", -- string or latex | |
| crlf = " ", | |
| newline = "\\\\", | |
| } | |
| opt = parse_option(opt, op, #t) | |
| t = select_cols(t, opt.columns) | |
| local skiprows = skip_rows(opt.skiprows) | |
| -- now print tablular | |
| tex.sprint(opt.header) | |
| if opt.afterrow[0] then tex.sprint(opt.afterrow[0]) end | |
| for i, v in ipairs(t) do | |
| if not skiprows[i] then | |
| for ii, vv in ipairs(v) do | |
| tex.tprint({catreg[opt.catcode], (vv:gsub("\n", opt.crlf))}, | |
| {ii < #v and "&" or opt.newline}) | |
| end | |
| if opt.afterrow[i] then tex.sprint(opt.afterrow[i]) end | |
| end | |
| end | |
| tex.sprint(opt.footer) | |
| end | |
| readcsv.tabular = csv2tabular |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| \ProvidesPackage{readcsv}[2016/01/01 v0.0 CSV to tabular] | |
| \directlua{require "readcsv"} | |
| \protected\def\csvtabular{\def\csv@separator{,}\futurelet\next\csv@tabular} | |
| \protected\def\tsvtabular{\def\csv@separator{\string\t}\futurelet\next\csv@tabular} | |
| \def\csv@tabular{% | |
| \ifx[\next | |
| \expandafter\csv@@tabular | |
| \else | |
| \expandafter\csv@@tabular\expandafter[\expandafter]% | |
| \fi | |
| } | |
| \def\csv@@tabular[#1]#2{\directlua{% | |
| readcsv.tabular("#2", "\csv@separator", "\luaescapestring\expandafter{\detokenize{#1}}") | |
| }} | |
| \endinput | |
| % csvtabular[options]{file} | |
| % tsvtabular[options]{file} | |
| % | |
| % option examples: | |
| % | |
| % header=\begin{tabular}{rrr}, | |
| % footer=\end{tabular}, | |
| % | |
| % columns={1,4,5}, select columns to print. default: all columns. | |
| % | |
| % afterrow0=\hline, tex code inserted before first line. | |
| % afterrow1=\hline, tex code inserted after first line. | |
| % afterrow2=, tex code inserted after second line. | |
| % afterrow*=\hline, tex code inserted after each and every line. | |
| % | |
| % newline=\\, tabular new line. | |
| % | |
| % crlf={ }, endline char in csv data will be converted to space. | |
| % | |
| % catcode=string, latex: allow tex commands. string: prints verbatim. |
Author
dohyunkim
commented
Dec 5, 2015
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment