parshape
Ich weiß , dass wir das Paket nutzen können, shapepar
um Absatzformen anzupassen, aber ich frage mich, ob es möglich ist, eine SVG-Datei zu lesen und sie als Seitenlayout zu verwenden?
Eine mögliche Lösung könnte darin bestehen, SVG-Dateien zu verwenden luaxml
und zu lesen, um Boxen oder geschlossene Pfade in einer bestimmten Reihenfolge zu erkennen und dann Parshape zu verwenden. Ich frage mich jedoch, wie Boxen miteinander verbunden werden können, um den Textfluss zwischen ihnen zu ermöglichen, und wie Boxen wiederholt verwendet werden können, bis der gesamte Text verbraucht und gesetzt ist, insbesondere über mehrere Seiten hinweg. Das tcolorbox
Paket mit magazine
der Bibliothek hat einige ähnliche Funktionen, aber ich bin nicht sicher, ob es auf diese Weise verwendet werden kann.
Gibt es eine Lösung (oder etwas Ähnliches)? Die Hauptabsicht besteht nicht darin, seltsame Absatzformen zu haben, sondern SVG-Bearbeitungstools für eine einfache Bearbeitung des Seitenlayouts zu verwenden.
Antwort1
Hier ist ein Proof of Concept mit LuaXML zur SVG-Analyse und Flowfram für Flow-Frames.
Ich habe ein Paket erstellt 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
Es stellt einen Befehl bereit \svgframes
. Er kann drei Parameter verwenden, einer ist obligatorisch, die anderen optional. Die optionalen Argumente sollten Unterstützung für die von Flowframe verwendete Seitenspezifikation und optionale Namen für die Frames hinzufügen. Diese Funktionen sind noch nicht implementiert, daher können Sie einfach das obligatorische Argument verwenden, also den SVG-Dateinamen.
Die SVG-Frame-Analyse ist in der svgframes.lua
Bibliothek implementiert:
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
Es bietet eine Funktion load_frames
, die die SVG-Datei mithilfe von LuaXML-DOM-Funktionen lädt und alle Elemente durchläuft <rect>
. Die Abmessungen werden in Millimeter und dann in umgerechnet sp
. Die y
Abmessungen müssen relativ zur Seitenhöhe berechnet werden.
Es kann folgendermaßen verwendet werden:
\documentclass{article}
\usepackage{svgflowfram}
\usepackage{lipsum}
\usepackage[margin=0pt]{geometry}
\svgframes{frames.svg}
\begin{document}
\lipsum[1-10]
\end{document}
Beispiel einer SVG-Datei:
<?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>
Mit Inkscape gerendert
Und das PDF:
Ein Problem besteht darin, dass die Breiten für Absätze, die auf zwei Rahmen verteilt sind, falsch sind. Ich bin nicht sicher, wie ich das beheben kann.