Eu sei que podemos usar parshape
o shapepar
pacote para ter formas de parágrafo customizadas, mas me pergunto se é possível ler um arquivo SVG e usá-lo como layout de página?
Uma solução possível seria usar luaxml
e ler arquivos SVG para reconhecer caixas ou caminhos fechados, por alguma ordem, e então usar parshape. No entanto, eu me pergunto como as caixas podem ser conectadas umas às outras para permitir o fluxo de texto entre elas, e como as caixas podem ser usadas repetidamente até que todo o texto seja consumido e digitado, especialmente em várias páginas. O tcolorbox
pacote com magazine
biblioteca possui alguns recursos semelhantes, mas não tenho certeza se pode ser usado dessa forma.
Existe alguma solução (ou algo semelhante) disponível? A intenção principal não é ter formatos de parágrafo estranhos, mas usar ferramentas de edição SVG para facilitar a edição do layout da página.
Responder1
Aqui está uma prova de conceito usando LuaXML para análise SVG e Flowfram para quadros de fluxo.
Eu criei um pacote svgflowfram.sty
:
\ProvidesPackage{svgflowfram}
\RequirePackage{flowfram}
\RequirePackage{xparse}
\RequirePackage{luacode}
\begin{luacode*}
local load_frames = require "svgframes"
function print_frame(x,y, width, height)
tex.print(string.format("\\newflowframe{%isp}{%isp}{%isp}{%isp}", width, height, x, y))
end
\end{luacode*}
\NewDocumentCommand\svgframes{o m o}{%
\IfNoValueTF{#1}{\def\svgflowfram@pages{}}{\def\svgflowfram@pages{#1}}
\IfNoValueTF{#3}{\def\svgflowfram@name{}}{\def\svgflowfram@name{#3}}
\directlua{
local frames = load_frames("\luatexluaescapestring{#2}")
for _, frame in ipairs(frames) do
print_frame(frame.x, frame.y, frame.width, frame.height)
end
}
}
\endinput
Ele fornece um comando \svgframes
. Pode consumir três parâmetros, um é obrigatório e outros opcionais. Os argumentos opcionais devem adicionar suporte para a especificação da página usada pelo Flowframe e nome opcional para os frames. Esses recursos ainda não foram implementados, então você pode apenas usar o argumento obrigatório, que é o nome do arquivo SVG.
A análise de quadros SVG é implementada na svgframes.lua
biblioteca:
local domobj = require "luaxml-domobject"
-- just assume we use milimeters at the moment
local function get_dimen(el, dimen_attr)
return tex.sp(el:get_attribute(dimen_attr) .. "mm")
end
function load_frames(svgfile, name)
local f=io.open(svgfile, "r")
if not f then return nil, "Cannot open file " .. svgfile end
local content = f:read("*all")
f:close()
local dom = domobj.parse(content)
local frames = {}
for _, r in ipairs(dom:query_selector("rect")) do
local x, y, width, height = get_dimen(r, "x"), get_dimen(r, "y"), get_dimen(r, "width"), get_dimen(r, "height")
y = tex.pageheight - (y + height)
frames[#frames+1] = {x=x, y=y, width=width, height=height}
end
return frames
end
return load_frames
Ele fornece uma função load_frames
que carrega o arquivo SVG usando funções LuaXML DOM, faz um loop sobre todos <rect>
os elementos. As dimensões são convertidas para milímetros e depois para sp
. A y
dimensão precisa ser calculada em relação à altura da página.
Pode ser usado desta forma:
\documentclass{article}
\usepackage{svgflowfram}
\usepackage{lipsum}
\usepackage[margin=0pt]{geometry}
\svgframes{frames.svg}
\begin{document}
\lipsum[1-10]
\end{document}
Exemplo de arquivo SVG:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="210mm"
height="297mm"
viewBox="0 0 210 297"
version="1.1"
id="svg8"
inkscape:version="0.92.4 (unknown)"
sodipodi:docname="frames.svg">
<defs
id="defs2" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="0.41"
inkscape:cx="-316.1324"
inkscape:cy="554.28571"
inkscape:document-units="mm"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="1920"
inkscape:window-height="1016"
inkscape:window-x="0"
inkscape:window-y="27"
inkscape:window-maximized="1" />
<metadata
id="metadata5">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Vrstva 1"
inkscape:groupmode="layer"
id="layer1">
<rect
style="fill:#ffffff;stroke:#000000;stroke-width:0.27966458;stroke-miterlimit:0.30000001;stroke-dasharray:none;stroke-dashoffset:0"
id="rect815"
width="58.724594"
height="40.655487"
x="17.42378"
y="33.061993" />
<rect
style="fill:#ffffff;stroke:#000000;stroke-width:0.27966458;stroke-miterlimit:0.30000001;stroke-dasharray:none;stroke-dashoffset:0"
id="rect817"
width="82.601608"
height="36.783535"
x="90.990852"
y="91.141266" />
<rect
style="fill:#ffffff;stroke:#000000;stroke-width:0.27966458;stroke-miterlimit:0.30000001;stroke-dasharray:none;stroke-dashoffset:0;image-rendering:auto"
id="rect819"
width="80.020325"
height="41.94614"
x="20.005081"
y="143.4126">
<title
id="title842">logo</title>
</rect>
<rect
style="fill:#ffffff;stroke:#000000;stroke-width:0.27966458;stroke-miterlimit:0.30000001;stroke-dasharray:none;stroke-dashoffset:0"
id="rect821"
width="108.41463"
height="43.236786"
x="70.985771"
y="203.42784" />
</g>
</svg>
Renderizado no Inkscape
E o PDF:
Um problema é que as larguras dos parágrafos divididos em dois quadros estão erradas. Não tenho certeza de como consertar isso.