summaryrefslogtreecommitdiff
path: root/macros/luatex/latex/odsfile
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2022-12-14 03:01:10 +0000
committerNorbert Preining <norbert@preining.info>2022-12-14 03:01:10 +0000
commit4a68164a544897aa6fc54b5eb61b23135e44d4df (patch)
tree73f3a85754eb5c5bea7e0ea5986b135a8d5236bf /macros/luatex/latex/odsfile
parent7b8bd496c62a5a8e18fb7a038217d4118c02b1e2 (diff)
CTAN sync 202212140301
Diffstat (limited to 'macros/luatex/latex/odsfile')
-rw-r--r--macros/luatex/latex/odsfile/README2
-rw-r--r--macros/luatex/latex/odsfile/odsfile.lua68
-rw-r--r--macros/luatex/latex/odsfile/odsfile.pdfbin253761 -> 94940 bytes
-rw-r--r--macros/luatex/latex/odsfile/odsfile.sty50
-rw-r--r--macros/luatex/latex/odsfile/odsfile.tex42
-rw-r--r--macros/luatex/latex/odsfile/pokus.odsbin15481 -> 11019 bytes
6 files changed, 132 insertions, 30 deletions
diff --git a/macros/luatex/latex/odsfile/README b/macros/luatex/latex/odsfile/README
index 50ba5f3333..981cf49210 100644
--- a/macros/luatex/latex/odsfile/README
+++ b/macros/luatex/latex/odsfile/README
@@ -34,7 +34,7 @@ Basic usage
...
-\includespread[\begin{tabular}{l l}
+\begin{tabular}{l l}
\includespread[file=pokus.ods]
\end{tabular}
diff --git a/macros/luatex/latex/odsfile/odsfile.lua b/macros/luatex/latex/odsfile/odsfile.lua
index 5017b7bc16..e7112a939d 100644
--- a/macros/luatex/latex/odsfile/odsfile.lua
+++ b/macros/luatex/latex/odsfile/odsfile.lua
@@ -1,16 +1,25 @@
-module(...,package.seeall)
-require "zip"
+-- Package odsfile. Author Michal Hoftich <michal.h21@gmail.com>
+-- This package is subject of LPPL license, version 1.3c
+-- module(...,package.seeall)
+
+local M = {}
+local zip = require "zip"
local xmlparser = require ("luaxml-mod-xml")
local handler = require("luaxml-mod-handler")
local namedRanges = {}
function load(filename)
+ -- add support for -reader command line option
+ -- we must open the file and close it immediatelly
+ local f = io.open(filename, "r")
+ f:close()
local p = {
file = zip.open(filename),
content_file_name = "content.xml",
loadContent = function(self,filename)
local treehandler = handler.simpleTreeHandler()
+ -- treehandler.options.noReduce = {["table:table-cell"]=true, ["text:p"]=true}
local filename = filename or self.content_file_name
local xmlfile = self.file:open(filename)
local text = xmlfile:read("*a")
@@ -29,6 +38,7 @@ function getTable(x,table_name)
for key, val in pairs(t) do
if key == "table:table-row" then
local rows = {}
+ if #val == 0 then val = {val} end
for i = 1, #val do
local r = val[i]
@@ -111,7 +121,7 @@ function loadNameRanges(root, tblname)
local a = r["_attr"] or {}
local range = a["table:cell-range-address"] or ""
local name = a["table:name"]
- if name and range:match("^"..tblname) then
+ if name and range:match("^$?"..tblname) then
range = range:gsub("^[^%.]*",""):gsub("[%$%.]","")
print("named range", name, range)
t[name] = range
@@ -152,6 +162,7 @@ function tableValues(tbl,x1,y1,x2,y2)
end
function getRange(range)
+ if range == nil then return {nil,nil,nil,nil} end
local range = namedRanges[range] or range
local r = range:lower()
local function getNumber(s)
@@ -164,7 +175,7 @@ function getRange(range)
return f
end
for x1,y1,x2,y2 in r:gmatch("(%a*)(%d*):*(%a*)(%d*)") do
- return getNumber(x1),tonumber(y1),getNumber(x2),tonumber(y2)
+ return {getNumber(x1),tonumber(y1),getNumber(x2),tonumber(y2)}
--print(string.format("%s, %s, %s, %s",getNumber(x1),y1,getNumber(x2),y2))
end
end
@@ -202,15 +213,28 @@ function interp(s, tab)
)
end
+function escape(s)
+ return string.gsub(s, "([%\\]?)([#%%%$&_%{%}%\\|])", function(a,b)
+ if a=="" then
+ if b == "\\" then
+ return "\\textbackslash"
+ elseif b == "|" then
+ return "\\textbar"
+ else
+ return "\\"..b
+ end
+ elseif a=="\\" and b=="\\" then
+ return "\\textbackslash\\textbackslash"
+ end
+ end)
+end
+
get_link = function(val)
local k = val["text:a"][1]
local href = val["text:a"]["_attr"]["xlink:href"]
- return "\\odslink{"..href.."}{"..k.."}"
+ return "\\odslink{"..href.."}{".. escape(k).."}"
end
-function escape(s)
- return string.gsub(s, "([#%%$&])", "\\%1")
-end
function get_cell(val, delim)
local val = val or ""
@@ -224,7 +248,7 @@ function get_cell(val, delim)
return get_cell(val["text:span"], delim)
elseif val["text:s"] then
-- return get_cell(val["text:s"], delim)
- return table.concat(val, " ")
+ return escape(table.concat(val, " "))
else
local t = {}
for _,v in ipairs(val) do
@@ -298,3 +322,29 @@ function updateZip(zipfile, updatefile)
local command = string.format("zip %s %s",zipfile, updatefile)
print ("Updating an ods file.\n" ..command .."\n Return code: ", os.execute(command))
end
+
+M.load= load
+M.loadContent = loadContent
+M.getTable= getTable
+M.getTable0= getTable0
+M.getColumnCount= getColumnCount
+M.loadNameRanges= loadNameRanges
+M.tableValues= tableValues
+M.getRange= getRange
+M.getNumber= getNumber
+M.table_slice = table_slice
+M.interp= interp
+M.get_link =get_link
+M.escape= escape
+M.get_cell= get_cell
+M.newRow= newRow
+ -- Generic for inserting cell
+M.addCell = addCell
+M.addString = addString
+M.addFloat = addFloat
+M.findLastRow = findLastRow
+M.insert = insert
+-- for updateing the archive. Depends on external zip utility
+M.updateZip= updateZip
+
+return M
diff --git a/macros/luatex/latex/odsfile/odsfile.pdf b/macros/luatex/latex/odsfile/odsfile.pdf
index 3aaee3587b..7ea30cb63f 100644
--- a/macros/luatex/latex/odsfile/odsfile.pdf
+++ b/macros/luatex/latex/odsfile/odsfile.pdf
Binary files differ
diff --git a/macros/luatex/latex/odsfile/odsfile.sty b/macros/luatex/latex/odsfile/odsfile.sty
index 97f9e0d9c6..0e4085ded0 100644
--- a/macros/luatex/latex/odsfile/odsfile.sty
+++ b/macros/luatex/latex/odsfile/odsfile.sty
@@ -1,18 +1,22 @@
-\ProvidesPackage{odsfile}
-\RequirePackage{luacode,xkeyval}
+% Package odsfile. Author Michal Hoftich <michal.h21@gmail.com>
+% This package is subject of LPPL license, version 1.3c
+\ProvidesPackage{odsfile}[2022/12/13 v0.7 odsfile package to select cells from ODS sheets and
+ typeset them as LaTeX tables]
+\RequirePackage{luacode,xkeyval,xparse}
%keyval keys
\define@key{includespread}{file}{\loadodsfile{#1}}%
\define@key{includespread}{sheet}{\luaexec{sheetname = "\luatexluaescapestring{#1}"}}%
-\define@key{includespread}{range}{\luaexec{%
-local x1,y1,x2,y2 = odsreader.getRange("\luatexluaescapestring{#1}")%
-range = {x1,y1,x2,y2}%
-}}
+\define@key{includespread}{range}{\luaexec{range="\luatexluaescapestring{#1}"}}%
\define@key{includespread}{template}{\luaexec{currenttemplate="\luatexluaescapestring{#1}"}}%
-\define@key{includespread}{rowtemplate}{\luaexec{rowtemplate="\luatexluaescapestring{\unexpanded{#1}}"}}%
+\define@key{includespread}{rowtemplate}{\luaexec{rowtemplate="\luatexluaescapestring{\detokenize{#1}}"}}%
+\define@key{includespread}{celltemplate}{\luaexec{celltpl="\luatexluaescapestring{\detokenize{#1}}"}}%
\define@key{includespread}{multicoltemplate}{\luaexec{multicoltpl="\luatexluaescapestring{\unexpanded{#1}}"}}%
+\newcommand\OdsNl{\\}
+\newcommand\OdsLastNl{\\}
+
\define@choicekey*+{includespread}{rowseparator}[\val\nr]{tableline,hline,newline}[tableline]%
{%
\ifcase\nr\relax%
@@ -66,6 +70,7 @@ body = nil
odsfilename = ""
currenttemplate = nil
rowtemplate = nil
+celltpl = "-{value}"
multicoltpl = "\\multicolumn{-{count}}{l}{-{value}}"
\end{luacode*}
@@ -84,20 +89,35 @@ multicoltpl = "\\multicolumn{-{count}}{l}{-{value}}"
}
}
-\newcommand\includespread[1][]{%
+\NewDocumentCommand\includespread{s o}{%
+ \IfBooleanTF#1%
+ {\ods@includespread@star{#2}}%
+ {\ods@includespread@unstar{#2}}%
+}
+
+\newcommand\ods@includespread@star[1]{%
+ \let\ods@tmp@lastNL\OdsLastNl%
+ \renewcommand\OdsLastNl{}%
+ \ods@includespread@unstar{#1}%
+ \let\OdsLastNl\ods@tmp@lastNL%
+}
+
+\newcommand\ods@includespread@unstar[1]{%
\luaexec{%
- range = {nil,nil,nil,nil}
+ range = nil
rowseparator = ""
columns=nil
currenttemplate = nil
rowtemplate = nil
+ celltpl = "-{value}"
columnbreak = "\\linebreak{}"
coltypes = nil
}%
\setkeys{includespread}{#1}%
\luaexec{%
body = odsreader.getTable(odsfile,sheetname)
- local values = odsreader.tableValues(body,range[1],range[2],range[3],range[4])
+ local real_range = odsreader.getRange(range)
+ local values = odsreader.tableValues(body,real_range[1],real_range[2],real_range[3],real_range[4])
%-- Conversion of odsfile table values to LaTeX tabular
local concatParagraphs = function(column)
% -- second returned value signalize whether cell contain paragraph, or not
@@ -119,6 +139,8 @@ multicoltpl = "\\multicolumn{-{count}}{l}{-{value}}"
x = tonumber(x)
if x > 1 then
value = odsreader.interp(multicoltpl, {value = value, count = x})
+ else
+ value = odsreader.interp(celltpl, {value = value})
end
table.insert(t,value)
headings[i] = br
@@ -163,10 +185,10 @@ multicoltpl = "\\multicolumn{-{count}}{l}{-{value}}"
columns = rowValues(values[1])
content = odsreader.table_slice(content,2,nil)
elseif type(columns) == "number" and columns == 2 then
- local t = odsreader.tableValues(body,range[1],1,range[3],2)
+ local t = odsreader.tableValues(body,real_range[1],1,real_range[3],2)
columns = rowValues(t[1])
end
- if type(columns) == "table" then colheading = table.concat(columns," & ") .. "\\\\" end
+ if type(columns) == "table" then colheading = table.concat(columns," & ") .. "\\OdsNl " end
% coltypes = ""
if type(content)== "table" then
% coltypes= string.rep("l",\#content[1])
@@ -174,7 +196,7 @@ multicoltpl = "\\multicolumn{-{count}}{l}{-{value}}"
coltypes = makeColtypes(headings)
end
end
- content = table.concat(content, "\\\\ "..rowseparator) .. "\\\\"
+ content = table.concat(content, "\\OdsNl "..rowseparator) .. "\\OdsLastNl"
local result = odsreader.interp(templates[currenttemplate],{content=content,coltypes=coltypes,colheading=colheading,rowsep=rowseparator})
print(result)
tex.print(result)
@@ -202,7 +224,7 @@ multicoltpl = "\\multicolumn{-{count}}{l}{-{value}}"
-{colheading}
\midrule
-{content}
-\\ \bottomrule
+\bottomrule
\end{tabular}
}
diff --git a/macros/luatex/latex/odsfile/odsfile.tex b/macros/luatex/latex/odsfile/odsfile.tex
index cf2d141f6a..9aefc2a890 100644
--- a/macros/luatex/latex/odsfile/odsfile.tex
+++ b/macros/luatex/latex/odsfile/odsfile.tex
@@ -1,11 +1,14 @@
\documentclass{ltxdoc}
-\usepackage[utf8]{luainputenc}
-\usepackage[T1]{fontenc}
-\usepackage{odsfile,tgschola,metalogo,hyperref,xspace,microtype,showexpl,booktabs,url}
+\usepackage{fontspec}
+\setmainfont{TeX Gyre Schola}
+% \usepackage[utf8]{luainputenc}
+% \usepackage[T1]{fontenc}
+% \usepackage{odsfile,tgschola,metalogo,hyperref,xspace,showexpl,booktabs,url}
+\usepackage{odsfile,metalogo,hyperref,xspace,microtype,showexpl,booktabs,url}
\author{Michal Hoftich (\url{michal.h21@gmail.com})}
\title{The \textsf{odsfile} package:\\
accessing of the \textsf{opendocument spreadsheet} from \LaTeX{}
-documents\thanks{Version 0.6, last revisited 2015-09-20.}
+documents\thanks{Version 0.7, last revisited 2022-12-13.}
}
\usepackage[english]{babel}
\lstloadlanguages{[LaTeX]Tex}
@@ -50,13 +53,17 @@ You can load |odsfile| classically with
There are macros:
\begin{itemize}
\item \cmd{\includespread}
+\item \cmd{\includespread*}
+\item \cmd{\OdsNl}
+\item \cmd{\OdsLastNl}
\item \cmd{\tabletemplate}
\item \cmd{\loadodsfile}
\item \cmd{\savespreadsheet}
\item |AddRow| environment
\end{itemize}
-\noindent Main command is\marginpar{\cmd{\includespread}} \cmd{\includespread}. It's syntax is:\\
+\noindent Main command is\marginpar{\cmd{\includespread}} \cmd{\includespread}
+and it's starred variant \cmd{\includespread*}. It's syntax is:\\
\cmd{\includespread}\oarg{key-value list}
Options are:
@@ -102,6 +109,13 @@ You can omit some or both of the numbers:
\includespread[range=b2:c]
\end{tabular}
\end{LTXexample}
+
+\begin{LTXexample}
+\begin{tabular}{lll}
+\includespread[range=newrangetest]
+\end{tabular}
+\end{LTXexample}
+
\item[columns] Column heading specification. It can be either |head|, |top|, or comma separated list of values.
\begin{description}
\item[top] Use as headers first line from the table.
@@ -172,6 +186,14 @@ number is the position of the cell from beginning of the selection.
\includespread[range=a2:b,rowseparator={,\ },rowtemplate={\textit{-{1}}:-{2}}]
\end{LTXexample}
+\item[celltemplate] This template is applied to every cell in the included table.
+ \begin{LTXexample}
+ \begin{tabular}{lll}
+ \includespread[range=a1:c1,celltemplate={\textit{-{value}}}]
+ \includespread[range=a2:c]
+ \end{tabular}
+ \end{LTXexample}
+
\item[multicoltemplate]
supports merged cells. Default template uses left aligned \verb|\multicolumn|
command
@@ -216,7 +238,7 @@ The |p| column specifier is used for each column, where cell with manual line br
-{colheading}
\midrule
-{content}
-\\ \bottomrule
+\bottomrule
\end{tabular}
}
\end{verbatim}
@@ -359,6 +381,14 @@ CC & 5 & 7
\section{Changes}
\begin{description}
+ \item[v0.7]
+ \begin{itemize}
+ \item Fixed character escaping. Unescaped ``\%,\#,\$, \_ and \&'' characters will be escaped to prevent compilation errors.
+ Characters that are already escaped in the ODS file will be left untouched.\footnote{Thanks to Wybo Dekker}
+ \item Added support for LuaTeX -recorder command line option
+ \item Added \texttt{celltemplate} option
+ \item Fixed named range handling\footnote{Thanks to Angelforest}
+ \end{itemize}
\item[v0.6]
\begin{itemize}
diff --git a/macros/luatex/latex/odsfile/pokus.ods b/macros/luatex/latex/odsfile/pokus.ods
index e59b876215..52bdbf4cc3 100644
--- a/macros/luatex/latex/odsfile/pokus.ods
+++ b/macros/luatex/latex/odsfile/pokus.ods
Binary files differ