6

I found a strange issue when experimenting with dvisvgm trying to create SVG files from DVI files.

I found that if I append a box (or a coffin) to a drawing created with the l3draw package and this box (or coffin) is inside a scope, the DVI created via a run of latex cannot be converted to an SVG via dvisvgm. But if this box (of coffin) is not inside a scope, it works.

Consider the following MWE:

\documentclass[border=10pt]{standalone}
\usepackage{l3draw}

\begin{document}
    
    \ExplSyntaxOn
    \draw_begin:
    
        \draw_path_circle:nn { 0cm , 0cm } { 1cm }
        \draw_path_use_clear:n { stroke }
        
        \draw_scope_begin:
        \hbox_set:Nn \l_tmpa_box {foo}
        \draw_box_use:N \l_tmpa_box
        \draw_scope_end:
    
    \draw_end:
    \ExplSyntaxOff
    
\end{document}

I run latex and then dvisvgm and the error PostScript error: stackunderflow in restore will occur. If I comment out the scope, the file is converted without problems and the circle and the text in the box show up in resulting SVG.

I am unsure where to locate the problem: With the l3draw package or with dvisvgm (or somewhere else altogether).

3
  • This is probably really a bug in dvisvgm. I tried latex > dvips > ps2pdf and everyhing is fine. Commented Mar 9 at 17:18
  • 3
    Nope. It's a bug in the PostScript code embedded in the DVI file. When you convert the file with dvips and call Ghostscript on the generated PS file, you get the same error.
    – Martin
    Commented Mar 9 at 18:08
  • 1
    Issue filed with GitHub. Commented Mar 11 at 17:26

2 Answers 2

6

This seems to be a bug in the dvips backend of l3draw.

\draw_scope_begin: and \draw_scope_end: create PS code that looks like this:

@beginspecial
...
save
@endspecial
...
@beginspecial
restore
@endspecial

The PS operator save puts a save object on the operand stack that holds information about the current state of the PS interpreter. restore, on the other hand, expects a save object on the stack to restore the corresponding memory state.

However, @endspecial which is a PS procedure defined by dvips, removes the save object created by save. Therefore, there's nothing left on the stack when restore is executed and that's why the PS interpreter stops with stackunderflow in restore.

2
  • Nice catch! In fact, this might be a bit of a special case, but considering the fact that the l3draw package provides distinct commands to place boxes and coffins, I think this should be fixed and an issue should probably be filed at GitHub. I think, PGF does things a bit differently and does not use @endspecial. Commented Mar 10 at 17:47
  • Issue is github.com/latex3/latex3/issues/1504 - I think most sensible to discuss reasons, etc., there
    – Joseph Wright
    Commented Mar 11 at 21:35
2

You are using the dvips back end, with the dvisvgm back end you get no error

\documentclass[border=10pt]{standalone}
\ExplSyntaxOn
\sys_load_backend:n {dvisvgm}
\ExplSyntaxOff
\usepackage{l3draw}

\begin{document}
    
    \ExplSyntaxOn
    \draw_begin:
    
        \draw_path_circle:nn { 0cm , 0cm } { 1cm }
        \draw_path_use_clear:n { stroke }
        
        \draw_scope_begin:
        \hbox_set:Nn \l_tmpa_box {foo}
        \draw_box_use:N \l_tmpa_box
        \draw_scope_end:
    
    \draw_end:
    \ExplSyntaxOff
    
\end{document}

although I just get the text

enter image description here

5
  • But how does this answer that without scoping the above also runs fine (even including the circle) without explicitly stating the backend? Commented Mar 9 at 20:34
  • 1
    @JasperHabicht It only addresses half the problem, if you use the wrong backend then anything that works only works by accident depending on how similar the dvips and dvisvgm \specials are. So I answered that bit. It looks like l3draw is generating something wrong even if the right driver is used but I didn't adress that while driving my car this morning probably not legal:-) Commented Mar 9 at 23:35
  • @DavidCarlisle dvisvgm actually supports all dvips specials as well and should convert Jasper's example correctly even with the dvips backend driver.
    – Martin
    Commented Mar 10 at 8:52
  • @Martin I know it supports a lot (although hadn't checked it did these) but it can't support all specials. It can support literal postscript inserted at one place by converting that ps to svg, but things like psfrag that redefine the postscript show commands that dvips generates from normal tex text can't really work. But I wanted to highlight the driver option as people are so used to pdftex/luatex/xetex being auto-detected that the need to specify the back end in use for dvi is a bit of a lost art. Commented Mar 10 at 9:21
  • @DavidCarlisle Ok, that's right. It supports all specials but not all PS code embedded with them. If the code redefines PS operators, like show that dvisvgm also redefines, then this may not work correctly in most cases. Fortunately, these code twists are not so common -- at least I haven't come across many of them yet.
    – Martin
    Commented Mar 10 at 9:41

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .