Latex의 페이지 레이아웃으로서의 SVG

Latex의 페이지 레이아웃으로서의 SVG

parshape사용자 정의된 단락 모양을 갖는 패키지 를 사용할 수 있다는 것을 알고 있지만 shapeparSVG 파일을 읽고 페이지 레이아웃으로 사용할 수 있는지 궁금합니다.

가능한 해결책은 luaxmlSVG 파일을 사용하고 읽어서 상자나 닫힌 경로를 인식한 다음 parshape를 사용하는 것입니다. 그러나 상자 사이에 텍스트 흐름을 허용하기 위해 상자를 서로 연결하는 방법과 특히 여러 페이지에 걸쳐 전체 텍스트가 소비되고 조판될 때까지 상자를 반복적으로 사용할 수 있는 방법이 궁금합니다. 라이브러리 tcolorbox가 포함된 패키지에는 몇 magazine가지 유사한 기능이 있지만 그런 방식으로 사용할 수 있는지 확실하지 않습니다.

사용 가능한 솔루션(또는 유사한 것)이 있습니까? 이상한 문단 모양을 가지지 않고 SVG 편집 도구를 사용하여 페이지 레이아웃을 쉽게 편집할 수 있도록 하는 것이 주요 목적입니다.

답변1

다음은 SVG 구문 분석에 LuaXML을 사용하고 흐름 프레임에 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_framesLuaXML DOM 함수를 사용하여 SVG 파일을 로드하고 모든 요소를 ​​반복하는 기능을 제공합니다 <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:

여기에 이미지 설명을 입력하세요

한 가지 문제는 두 프레임에 걸쳐 분할된 단락의 너비가 잘못되었다는 것입니다. 문제를 해결하는 방법을 잘 모르겠습니다.

관련 정보