% % graphicp.tex -- a graphics.sty replacement for LaTeX and laemu.sty % by pts@fazekas.hu at Fri Jan 24 13:26:22 CET 2003 % % GraphicP is a system that provides an easy, fast and reliable method for % including external images into LaTeX and plain TeX documents. The % \includegraphics macro of GraphicP is a drop-in replacement of the same % command of LaTeX graphics.sty and graphicx.sty, but with many enhancements. % Input images are ususally in EPS or PDF format. Drivers for xdvi, dvips, % pdftex and dvipdfm are included. Perl scripts are provided for % faster bounding box manipulations. % % This is version 0.12. % % Features over LaTeX `\usepackage{graphicx}': % % -- both plain TeX and LaTeX support % -- specified width=... and height=... are strictly enforced, without rounding % -- image scaling calculations are much more accurate % -- works with `dvips -E' bounding-box calculations, even with buggy dvips % 5.86e % -- doesn't have to open the .eps file for reading the bbox % -- xdvi doesn't forcibly crop (clip) the image to the bbox % -- Below feature: allows the image descend below the baseline % (supports depth, not only width and height) % -- drop dependency on Perl, parse Adobe DSC comments in EPS files % -- non-standard, quick, DSC-like parsing for special PDF files % -- an enhanced `epstopdf' utility % -- the `img_bbox.pl' utility % -- the `pdfboxes.pl' utility % -- voluntary clipping (cropping) % -- all 8 mirror and rotate transformation (must be a multipe of 90 degrees) % -- does not rely on the filename to determine the FileFormat % -- embeds each image file only once with pdfTeX and dvipdfm % -- imtrix: unified PSTricks/PSFrag support for EPS and PDF % % Q1. Can I use the Below feaure with dvipdfm+EPS? % ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ % Use the epstopdf untility shipped with graphicP instead of the default one % shipped with teTeX. % To do it, please update /etc/texmf/dvipdfm/config first with the line: % % D "zcat -f %i | ./epstopdf --below --hires --outfile=%o -" % % Substitute the `./epstopdf' with the real, absolute path to our epstopdf. % % Don't forget to specify \includegraphics[...,below]{...} % % Which characters can I have in the filename? % ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ % For dvips, xdvi and dvipdfm: % -- You must avoid the double quote ("), because it is the filename terminator % of the PSFile \special. % For pdftex: % -- You must also avoid the dollar sign % ($), because kpsewhich interprets it as a variable substitution, and % pdftex calls KPSE to look up image file names. % For old pdftex 0.12 shipped with Debian Slink (pdftex >=0.14 is OK): % -- You must avoid space, because stupid \pdfimage cannot parse it. % For xdvi and dvipdfm: % -- You must also avoid the % backslash (\), because xdvi removes it from the filename (dvips doesn't). % % All other characters can be used, but you have to quote some of them to % avoid wrong category codes and/or expansion: % % All characters [\000-\037\177-\377] should be input as hex: \expandafter\@secondoftwo\string\^^HL % All characters [\040-\176] can be written as-is, except for: % $ is OK % & is OK % _ is OK % a space should be input as '\iftrue\space\fi '; # won't collapse two spaces into one % \ { } % # ^ ~ ` " should be input as \expandafter\@secondoftwo\string\\ etc. % % Note that `\noexpand"' is not good enough for `"', because `\noexpand"e' % would expand to an accented letter if expanded twice under % \usepackage[german]{babel}. % % I've verified these characters on the file name % % ugly_"$&_ \}%#^^aáéb{%#^~` % % which was input as % % ugly_"$&_\iftrue\space\fi \iftrue\space\fi \iftrue\space\fi \expandafter\@secondoftwo\string\\\expandafter\@secondoftwo\string\}\expandafter\@secondoftwo\string\%\expandafter\@secondoftwo\string\#\expandafter\@secondoftwo\string\^\expandafter\@secondoftwo\string\^a\expandafter\@secondoftwo\string\^^e1\expandafter\@secondoftwo\string\^^e9b\expandafter\@secondoftwo\string\{\expandafter\@secondoftwo\string\%\expandafter\@secondoftwo\string\#\expandafter\@secondoftwo\string\^\expandafter\@secondoftwo\string\~\expandafter\@secondoftwo\string\` % % Can I embed MetaPost output? % ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ % Yes, \includegraphics{ajobname.1} works fine with all drivers. (ajobname.1 % is the output file of MetaPost when ajobname.mp contains `beginfig(1)'.) % % How do I specify an output filename for MetaPost? % ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ % Basicly you invoke MetaPost as `mpost ajobname.mp', where ajobname.mp is % the MetaPost source file. MetaPost writes the log file ajobname.log. If % you say `beginfig(42)' in ajobname.mp, the output EPS file `ajobname.42' % will be created. If you say `beginfig(-1)' (or any negative number), % `ajobname.ps' will be created. You cannot force any other filename -- % these are hard-wired to the MetaPost executable. % % How do I make MetaPost emit a HiResBoundingBox? % ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ % Just add % % extra_endfig := extra_endfig % & "special (" % & ditto & "%%HiResBoundingBox: " & ditto % & "&decimal xpart llcorner currentpicture &" & ditto & " " & ditto % & "&decimal ypart llcorner currentpicture &" & ditto & " " & ditto % & "&decimal xpart urcorner currentpicture &" & ditto & " " & ditto % & "&decimal ypart urcorner currentpicture );"; % % to the beginning of ajobname.mp. context/mp-tool.mp does this already. % You cannot force it before %%EndProlog or %%Page:. This is an inherent % limitation of the MetaPost executable. % % --- % % Dat: dvipdfm crops EPS images below y==0; it doesn't crop PDF images. See % FAQ answer Q1 to overcome it. % Dat: works with `dvips', `dvipdfm', `xdvi' and `pdftex' % Dat: works with pdftex 3.14159-0.12r (Slink), 0.14 (Potato), 1.00a (Woody) % OK : use bbox cache by img_bbox.pl % OK : verify slink -- potato -- woody % OK : sam2p Below feature % OK : verify and document various filename chars % OK : bbox read directly from image % OK : respect best of BoundingBox, HiResBoundingBox and ExactBoundingBox % OK : pdfboxes.pl: Perl script to inject PDF bbox near beginning % OK : guess extension if unspecified, automatic filename.ext % OK : pts_bbox.sty handles PDF, EPS, MPS % OK : pts_bbox.sty handles TIFF, JPEG and PNG -- only with pdfTeX % OK : pts_img.sty handles JPEG and PNG for pdfTeX and dvipdfm, TIFF for pdfTeX % OK : MetaPost EPS is recognised properly by the pdftex driver (dvipdfm already did it right) % OK : warning if FileFormat not supported by driver % OK : \usepackage[nopdftexmpost]{graphicp} disables loading of ConTeXt supp-pdf.tex % OK : \usepackage[forceunknown]{graphicp}. If an unknown FileFormat is not % forced, an \errmessage is displayed, and the reference point is moved % without drawing the image. % OK : \includegraphics[raise=20]{...} or lower=-20 specifies raising in image % dimensions (pixels) % OK : \includegraphics[lower=0] disables autobelow % OK : needed sam2p "Q endstream", because we say \pdfliteral{ Q}, so % the embedding bug pdfTeX Version 3.14159-0.12r won't manifest. % In sam2p-0.42 /Length+=1 on the content stream fixed the problem. % OK : dvipdfm usexobj % OK : sam2p 0.43 pre-/MediaBox feature (object reordering) % OK : move reference point for \convertMPtoPDF in Debian Slink % OK : below option is not default since Sun Feb 9 22:27:23 CET 2003 % OK : proven not to work: PDF XObject on old pdftexs (Potato, Slink) % OK : frame, namedframe, invisible and blackbox drivers, only show the bboxes and the filename % Imp: documentation .tex % Imp: use pdfTeX to read the bounding box (non-negative below feature) % Imp: better \usepackage{graphicx} compatibility: clip=, bb=, totalheight=, % keepaspectratio=, type=, ext=, read=, viewport=, clip=, `gunzip % Imp: allow user select from BoundingBox, HiResBoundingBox and ExactBoundingBox % Imp: add clipping support % Imp: add rotation + mirroring support % Imp: advanced \textascii for driver=namedframe % Imp: imtrix ? \expandafter\ifx\csname ifLaTeX\endcsname\relax\input laemu.sty\relax\fi% \NeedsTeXFormat{LaTeX2e} \ProvidesPackage{graphicp}[2003/01/24 v0.0 graphics.sty replacement] \RequirePackage{keyvalx} \RequirePackage{pts_bbox} %\errmessage{O(\csname opt@graphicp.sty\endcsname)}% %\errmessage{D(\@declaredoptions)}% %\errmessage{C(\@curroptions)}% %\errmessage{C(\@unprocessedoptions)}% %\expandafter\def\csname opt@graphicp.sty\endcsname{}% %\def\@declaredoptions{}% %\expandafter\let\csname ds@alma\endcsname\relax% %\show\@unprocessedoptions %\let\@unprocessedoptions\relax %\AtEndOfPackage{\def\@unprocessedoptions{}}% %** \def's #1 to 1 if #2 contains a true boolean value; 0 otherwise. A true %** value is a value beginning with `t', `y' or `1'. \def\@@gp@boolpon#1#2{% \expandafter\@@gp@boolpon@low#2f\\#1% %\message{ponated(#1)}% }% \def\@@gp@boolpon@low#1#2\\#3{% \edef#3{% \if\noexpand#1t1% true \else\if\noexpand#1y1% yes \else\if\noexpand#111% 1 \else0\fi\fi\fi% }% }% %** Similar to \@@gp@boolpon, but inverts the condition \def\@@gp@boolneg#1#2{% \@@gp@boolpon{#1}{#2}% \edef#1{\if#101\else0\fi}% }% %\LaemuProcessOptions\errmessage \define@key{graphicp}{driver}{\edef\@@gp@driver{#1}}% \define@key{graphicp}{pdftex}{\edef\@@gp@driver{pdftex}}% \define@key{graphicp}{dvi}{\edef\@@gp@driver{dvi}}% \define@key{graphicp}{dvips}{\edef\@@gp@driver{dvips}}% \define@key{graphicp}{dvipdfm}{\edef\@@gp@driver{dvipdfm}}% \define@key{graphicp}{pdftexmpost}[true]{\@@gp@boolpon\@@gp@pdftexmpost{#1}}% \define@key{graphicp}{nopdftexmpost}[true]{\@@gp@boolneg\@@gp@pdftexmpost{#1}}% %\define@key{graphicp}{forceunknown}[true]{\@@gp@boolpon\@@gp@forceunknown{#1}}% \define@key{graphicp}{forceunknown}[2]{\def\@@gp@forceunknown{#1}}% \define@key{graphicp}{forceunknown}[true]{\@@gp@boolneg\@@gp@forceunknown{#1}}% \def\@@gp@pdftexmpost{1}% \def\@@gp@driver{}% \def\@@gp@forceunknown{0}% \LaemuProcessOptions{\setkeys{graphicp}}% \if0\@@gp@pdftexmpost \def\graphicPnopdftexmpost{}\fi% \if1\@@gp@forceunknown \def\@@img@forceunknown{1}\fi% \let\@@gp@pdftexmpost\relax% \RequirePackage{pts_img}% uses \graphicPnopdftexmpost \@@img@setdriver{\@@gp@driver}% \let\@@gp@driver\relax% %\let\@@gp@forceunknown\relax% % --- Mon Feb 3 18:12:46 CET 2003 %** Expands to the filename extension of #1, e.g 'ePs' for `a.b/cd.ePs' \def\@@gp@getext#1{% \@@gp@getexta#1/\@empty% }% \def\@@gp@getexta#1/#2{% \ifx#2\@empty% \@empty itself or a macro with empty expansion \@@gp@getextb#1.\@empty% %\expandafter\@gobble% needed unless \@empty is the delimiter \else% \expandafter\@@gp@getexta \fi% #2% }% \def\@@gp@getextb#1.#2{% \ifx#2\@empty% % Extension not found, expand to nothing %\expandafter\@gobble% needed unless \@empty is the delimiter \else% %:#2%\@@gp@getextc#2\\% \expandafter\@@gp@getextc% \fi% #2% }% \def\@@gp@getextc#1.#2{% \ifx#2\@empty% #1% found extension %\expandafter\@gobble% needed unless \@empty is the delimiter \else% \expandafter\@@gp@getextc \fi% #2% }% %** Adds extension #1 to filename #2, unless #2 already has an extension. %** Example: `\@@gp@addext{eps}{my.document/myfigure}' expands to %** `my.document/myfigure.eps' \def\@@gp@addext#1#2{% #2\if.\@@gp@getext{#2}..#1\fi% % ^^^ we use the fact that the first unexpandable token of the expansion of % \@@gp@getext is either nonexistent, or it is a char other than `.' } % --- %** Doesn't work if the 1st token of #1 is expandable or it is a control %** sequence. %\def\@@gp@isempty#1{% % \if\noexpand\noexpand\noexpand#1\noexpand% % empty% % \else% % not% % \fi% %}% %** Expands #1 iff #2 is empty. %** @param #2 may not contain an extra (unbalanced) \else \def\@@gp@isempty#1#2{% \@@gp@isemptyi{#1}#2\else\fi% }% %** Same as \@@gp@isempty{#2}{#1} \def\@@gp@isemptyr#1#2{% \message{(\noexpand#1:#2)}% \@@gp@isemptyi{#2}#1\else\fi% }% \def\@@gp@isemptyi#1#2{\iffalse#2#1}% % Regression test: %\message{g(\@@gp@getext{hello})} %%\tracingmacros=1 %\message{g(\@@gp@getext{hel.lo/barna})} %\message{g(\@@gp@getext{hel.lo/you/barna.ePs})} %\message{g(\@@gp@getext{hel.lo/you/barna.ePs.gz})} %\message{e(\@@gp@isempty{empty}{})}% %\message{e(\@@gp@isempty{empty}{foo})}% %\message{e(\@@gp@isempty{empty}{,alma})}% %\message{e(\@@gp@isempty{empty}{\relax,korte})}% %\message{e(\@@gp@isempty{empty}{\iftrue\else\fi})}% %\message{a(\@@gp@addext{alma}{kor.te})} %\message{a(\@@gp@addext{alma}{korte})} %\message{a(\@@gp@addext{eps}{my.document/myfigure})} %\@@gp@addext{alma}{korte} % --- GraphicP implementation begins \def\@@gp@setbbox#1#2#3#4{% %\message{bb:(#1)(#2)(#3)(#4).}% \def\@@gp@llx{#1}% \def\@@gp@lly{#2}% \def\@@gp@urx{#3}% \def\@@gp@ury{#4}% }% \def\@@gp@question{?}% \def\@@gp@PDF{PDF}% \def\@@gp@setfbbox#1#2#3#4#5{% %\message{(ff=#1)(#2)(#3)(#4)(#5).}% \def\@@gp@format{#2}% assign temporarily \ifx\@@gp@format\@@gp@question\else % ^^^ assign only other than `?', so \@@GetBBox can override @@gp@format \def\@@gp@llx{#2}% \def\@@gp@lly{#3}% \def\@@gp@urx{#4}% \def\@@gp@ury{#5}% \fi% \edef\@@gp@format{#1}% FileFormat }% %** Must be bbox={{0bp}{0bp}{72bp}{72bp}} \define@key{incgP}{bbox}{\@@gp@setbbox#1}% %** Must be fbbox={{TIFF}{0bp}{0bp}{72bp}{72bp}} \define@key{incgP}{fbbox}{\@@gp@setfbbox#1}% \define@key{incgP}{format}{\def\@@gp@format{#1}}% \define@key{incgP}{width}{\def\@@gp@width{#1}}% \define@key{incgP}{height}{\def\@@gp@height{#1}}% \define@key{incgP}{raise}{\def\@@gp@raise{#1}}% \define@key{incgP}{lower}{\def\@@gp@raise{-#1}}% \define@key{incgP}{below}[]{\def\@@gp@raise{-#1}}% \define@key{incgP}{clip}[true]{\csname if#1\endcsname\let\@@dp@clip1\else\let\@@dp@clip0\fi}% \define@key{incgP}{noclip}[true]{\csname if#1\endcsname\let\@@dp@clip0\else\let\@@dp@clip1\fi}% \define@key{incgP}{forceunknown}[2]{\def\@@gp@forceunknown{#1}}% \def\@@gp@checkbbox{% \edef\@@gp@havebbox{% \ifx\@@gp@llx\@@gp@question\else% \ifx\@@gp@lly\@@gp@question\else% \ifx\@@gp@urx\@@gp@question\else% \ifx\@@gp@ury\@@gp@question\else% 1\fi\fi\fi\fi% }% }% \def\@@gp@runpdfboxes{\MessageBreak Run pdfboxes.pl to fix the file.}% \def\includegraphicP{\@ifnextchar[\@@gp@includegraphics{\@@gp@includegraphics[]}}% \let\includegraphics\includegraphicP \def\@@gp@includegraphics[#1]#2{% % Imp: change space tokens to `\space' in the filename \begingroup %\def\@@gp@bbox{{invalid}{}{}{}}% %\def\@@gp@raise{}% dimension to raise above the baseline -- or empty \def\@@gp@raise{0bp}% \usepackage{graphicx} compatibility \def\@@gp@llx{?}% source image bbox and size \def\@@gp@lly{?}% \def\@@gp@urx{?}% \def\@@gp@ury{?}% \def\@@gp@format{?}% \def\@@gp@width{0pt}% \def\@@gp@height{0pt}% desired target width+height \def\@@gp@clip{0}% %\def\space{\noexpand\space}%expandafter\string\csname space \endcsname}% \chardef\space0 % \space will expand to `\space ' \edef\@@gp@filename{\@@gp@addext{\@@img@defext}{#2}}% add default extension %\message{fn(\@@gp@filename)}% \def\space{ }% change it back \setkeys{incgP}{#1}% \@@gp@checkbbox% \ifx\@@gp@havebbox\@empty% bbox not specified as arg \@@GetBBox\@@gp@setfbbox{\@@gp@filename}% load bbox from file %\errmessage{z}% \else% \ifx\@@gp@format\@@gp@question% \@@GetBBox\@@gp@setfbbox{\@@gp@filename}% determine FileFormat from file, possibly override with real bbox \fi% \fi% \@@gp@checkbbox% %\message{fn=(#2) havebbox=(\@@gp@havebbox) bbox=(\@@gp@llx)}% \ifx\@@gp@havebbox\@empty% failed to determine bbox \ifx\@@gp@format\@@gp@PDF \let\@@gp@err\@@gp@runpdfboxes \else \let\@@gp@err\@empty\fi \PackageError{graphicP}{Cannot get BoundingBox of image file `#2'\@@gp@err}\@ehc% \@@gp@setbbox{0}{0}{72bp}{72bp}% fallback if the user continues \fi% %\expandafter\@@PutImage\@@gp@bbox% \chardef\space0 % \space will expand to `\space ' \edef\@tempa{\noexpand\@@PutImage% {\@@gp@raise}{\@@gp@forceunknown}.% {{\@@gp@llx}{\@@gp@lly}{\@@gp@urx}{\@@gp@ury}}% {\@@gp@width}{\@@gp@height}{\@@gp@clip}{\@@gp@filename}{\@@gp@format}}% \def\space{ }% change it back \expandafter\endgroup\@tempa % so \@@PutImage can change global variables }% %\zzzzzzzz