4

The psfrag package has the capability to intercept certain instructions in eps files, and replace them with new instructions. In this way, it is possible to replace fonts in an image with the fonts used elsewhere in a document. I would like to implement something more general, but simpler: when an eps file is included, string A is to be replaced (verbatim) by string B. For example, suppose the following masterpiece is to be included in a document:

%!PS-Adobe-2.0 EPSF-2.0
%%Title: pumpkin.eps
%%BoundingBox: 0 0 200 200
/tri {newpath 0 0 moveto 10 0 lineto 0 20 lineto -10 0 lineto closepath fill} bind def
1.0 0.6 0.25 setrgbcolor
1 setlinewidth
100 100 100 0 360 arc gsave stroke grestore fill
0 0 0 setrgbcolor
100 90 60 190 350 arc stroke
100 100 translate tri
-50 40 translate tri
100 0 translate tri
showpage
%EOF

However, the author decides that the line thickness should be 2, rather than 1. That is, 1 setlinewidth should be replaced by 2 setlinewidth. How can this be achieved from within a LaTeX document?

The actual application I have in mind involves thickening the frames on certain types of plot generated by Matlab. There is no option to do this within Matlab itself, and my current methods (manual postscript editing, and using system calls to sed to change the files after exporting them) are rather awkward.

5

For psfrag, tex doesn't access the file at all (except optionally looks to find a %%BoundingBox comment. It works by loading a PostScript header that redefines (within the scope of the EPS) the postscript show (and related operators) so that instead of simply typesetting the supplied string they look up the string and show a latex-typeset alternative.

So the analogue in your case would be to redefine setlinewidth so that if its argument is 1 then it does a real setlinewidth of 2, however in this case you probably only want to adjust specific instances of the command which might be tricky (or not, depending on how readable the postscript is, to see what commands to redefine, and how to test for the "right" instance.)

perhaps an alternative would be to put the original eps in a modified filecontents environment and then write it out with the replacement being defined and use the new/modified name in \includegraphics.

enter image description here

\documentclass{article}

\usepackage{graphicx}

\begin{document}


aaa

\includegraphics{zz.eps}

bbb

\special{ps: save  /zz {setlinewidth} bind def /setlinewidth { 10 mul zz} bind def}
\includegraphics{zz.eps}
\special{ps: restore}

ccc

\end{document}
  • To start with, I'll be happy with a method that replaces all instances. Let's say the file contains 1 LW (and /LW/setlinewidth load def). Then I would want to overwrite the definition with something like /LW{ 1 add setlinewidth} bind def. However, I have no idea how to load a header that affects an included eps file. – Ian Thompson Nov 21 '18 at 21:14
  • @IanThompson something added to my answer... – David Carlisle Nov 21 '18 at 21:17
  • @IanThompson actually my PS is rusty, I guess the bind means that you don't need the tex-style indirection through a saved original zz definition. I leave the details to you:-) – David Carlisle Nov 21 '18 at 21:20
  • @IanThompson I can still just about remember how psfrag works:-) – David Carlisle Nov 21 '18 at 21:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.