SVG как макет страницы в Latex

SVG как макет страницы в Latex

Я знаю, что мы можем использовать parshapeэтот shapeparпакет для создания настраиваемых форм абзацев, но мне интересно, можно ли прочитать файл SVG и использовать его в качестве макета страницы?

Возможным решением может быть использование luaxmlи чтение файлов SVG для распознавания блоков или замкнутых путей, в некотором порядке, а затем использование parshape. Однако мне интересно, как блоки могут быть связаны друг с другом, чтобы текст мог течь между ними, и как блоки могут использоваться повторно, пока весь текст не будет использован и набран, особенно на нескольких страницах. Пакет tcolorboxс magazineбиблиотекой имеет некоторые похожие функции, но не уверен, можно ли его использовать таким образом.

Есть ли какое-то решение (или что-то похожее)? Основная цель — не иметь странные формы абзацев, а использовать инструменты редактирования SVG для легкого редактирования макета страницы.

решение1

Ниже представлено доказательство концепции использования LuaXML для анализа SVG и Flowfram для потоковых кадров.

Я создал пакет 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

Он предоставляет команду \svgframes. Он может использовать три параметра, один обязательный, остальные необязательные. Необязательные аргументы должны добавить поддержку спецификации страницы, используемой Flowframe, и необязательного имени для фреймов. Эти функции пока не реализованы, поэтому вы можете просто использовать обязательный аргумент, которым является имя файла SVG.

В библиотеке реализован парсинг SVG-фрейма svgframes.lua:

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

Он предоставляет функцию load_frames, которая загружает файл SVG с помощью функций LuaXML DOM, проходит по всем <rect>элементам. Размеры преобразуются в миллиметры, а затем в sp. yРазмеры необходимо рассчитывать относительно высоты страницы.

Его можно использовать следующим образом:

\documentclass{article}
\usepackage{svgflowfram}
\usepackage{lipsum}
\usepackage[margin=0pt]{geometry}
\svgframes{frames.svg}
\begin{document}
\lipsum[1-10]
\end{document}

Пример файла 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>

Рендеринг в Inkscape

введите описание изображения здесь

И PDF-файл:

введите описание изображения здесь

Одна из проблем заключается в том, что ширина абзацев, разделенных на два фрейма, неправильная. Я не уверен, как это исправить.

Связанный контент