3

I use a \special command to drive some diagonal lines as a part of a macro for drawing puzzles. While these work fine when compiling with XeTeX, they seem to corrupt the resulting PDF document when using pdftex instead. Here is a minimal reproducable example:

\special{pdf: content q 0 G 0.4 w
 0   8 m  2  10 l
 0   6 m  4  10 l
 0   4 m  6  10 l
 0   2 m  8  10 l
 0   0 m 10  10 l
 0  -2 m 12  10 l
 0  -4 m 14  10 l
 0  -6 m 16  10 l
 0  -8 m 18  10 l
 0 -10 m 20  10 l
 2 -10 m 20   8 l
 4 -10 m 20   6 l
 6 -10 m 20   4 l
 8 -10 m 20   2 l
10 -10 m 20   0 l
12 -10 m 20  -2 l
14 -10 m 20  -4 l
16 -10 m 20  -6 l
18 -10 m 20  -8 l
S Q}
\bye

When I open the resulting document in Adobe Acrobat or with Ghostscript, it'll complain about a defective page. E.g. for pdf2ps we have:

$ pdf2ps test.pdf
   **** Error: File did not complete the page properly and may be damaged.
               Output may be incorrect.

What could the problem be? How can I change the \special command to fix this issue?

4
  • Just replace \special{pdf: content with \pdfliteral{
    – AlexG
    Dec 1, 2020 at 15:26
  • @AlexG Doesn't seem to work with XeTeX though. Is there a solution that works for both (aside from writing a compatibility shim)?
    – FUZxxl
    Dec 1, 2020 at 15:30
  • @AlexG Thanks. I found that \special{pdf: ...} (without the content clause) also works. Would you mind writing up an answer?
    – FUZxxl
    Dec 1, 2020 at 15:40
  • \special{pdf: ...} doesn't work for me with xetex. The page is empty.
    – AlexG
    Dec 1, 2020 at 15:50

2 Answers 2

2

I would go with a conditional to abstract the backend differences

\ifdefined\XeTeXversion
  \protected\def\myspecial#1{\special{pdf:content q #1 Q}}
\else
  \protected\def\myspecial#1{\pdfliteral{q #1 Q}}
\fi
\myspecial{%
0 G 0.4 w
 0   8 m  2  10 l
 0   6 m  4  10 l
 0   4 m  6  10 l
 0   2 m  8  10 l
 0   0 m 10  10 l
 0  -2 m 12  10 l
 0  -4 m 14  10 l
 0  -6 m 16  10 l
 0  -8 m 18  10 l
 0 -10 m 20  10 l
 2 -10 m 20   8 l
 4 -10 m 20   6 l
 6 -10 m 20   4 l
 8 -10 m 20   2 l
10 -10 m 20   0 l
12 -10 m 20  -2 l
14 -10 m 20  -4 l
16 -10 m 20  -6 l
18 -10 m 20  -8 l
S}
\bye

(This could be extended for DVI mode, LuaTeX, etc.)

If you want to have everything inside a macro, one could go with

\protected\def\myspecial#1{%
  \special{%
    \ifdefined\XeTeXversion
      pdf:content q #1 Q
    \else
      pdf:q #1 Q
    \fi
  }%
}
\myspecial{%
0 G 0.4 w
 0   8 m  2  10 l
 0   6 m  4  10 l
 0   4 m  6  10 l
 0   2 m  8  10 l
 0   0 m 10  10 l
 0  -2 m 12  10 l
 0  -4 m 14  10 l
 0  -6 m 16  10 l
 0  -8 m 18  10 l
 0 -10 m 20  10 l
 2 -10 m 20   8 l
 4 -10 m 20   6 l
 6 -10 m 20   4 l
 8 -10 m 20   2 l
10 -10 m 20   0 l
12 -10 m 20  -2 l
14 -10 m 20  -4 l
16 -10 m 20  -6 l
18 -10 m 20  -8 l
S}
\bye
2
  • It's actually something OP wanted to avoid (engine detecting shim).
    – AlexG
    Dec 1, 2020 at 16:48
  • @AlexG Feel free to edit: I didn't double-check the q/Q situation. My reading of the question is it doesn't rule out the approach I've suggested. Although as \special does expansion, one could put it inside the literal.
    – Joseph Wright
    Dec 1, 2020 at 17:13
0

I ended up using

\special{pdf:content ...}

(note the lack of space between pdf: and content). This seems to work fine with both pdfTeX and XeTeX.

4
  • It doesn't (pdftex). Check with pdf2ps, Ghostscript complains. The string content is put verbatim into the page stream which is an error because there is no PDF operator named like this.
    – AlexG
    Dec 10, 2020 at 14:01
  • @AlexG Indeed, how strange. It did work when I tried it a few days ago and I had accepted an answer already (which has since been deleted).
    – FUZxxl
    Dec 10, 2020 at 14:15
  • Yes, the deleted answer was mine. I flagged it for deletion after I discovered that there is no common special for both xetex and pdftex. You may need to use @Joseph's solution which queries the TeX engine in use.
    – AlexG
    Dec 10, 2020 at 14:19
  • @AlexG How unfortunate.
    – FUZxxl
    Dec 10, 2020 at 15:13

You must log in to answer this question.

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