.\" Define the PDFPIC macro. .\" .\" When used with output devices other than `pdf`, convert image to .\" encapsulated PostScript and process it with PSPIC. .\" .\" Usage: .\" .\" .PDFPIC [-L|-R|-C|-I ] [ []] .\" .\" Requires the poppler-utils package (for pdfinfo(1) and pdftops(1)). .\" Requires running troff(1) in unsafe mode. . .do if d PDFPIC .nx . .do nr *groff_pdfpic_tmac_C \n[.cp] .cp 0 . .\" Locate a directory to house temporary files. Check each argument .\" in turn, confirming its existence, writability, and searchability. .\" .\" `pdfpic*temporary-directory` contains its name if one is found, and .\" is empty otherwise. .de pdfpic@get-temporary-directory . ds pdfpic*temporary-directory \" empty . while !'\\$1'' \{\ . sy test -d \\$1 && test -w \\$1 && test -x \\$1 . if \\n[systat]=0 .ds pdfpic*temporary-directory \\$1 . ie '\\*[pdfpic*temporary-directory]'' .shift . el .break . \} .. . .\" A user may wish to append an 'ab' to this macro using 'am'. That .\" is why we don't 'return X' from here to return from two scopes. .de pdfpic@error . tm pdfpic.tmac:\\n[.F]:\\n[.c]: error: \\$* .. . .de pdfpic@cleanup . rm pdfpic*pspic-args . rm pdfpic*file-extension . rm pdfpic*file-name-base . rm pdfpic*temporary-directory . rm pdfpic*temporary-file . rr pdfpic*do-conversion . rr pdfpic*offset-mode . rr pdfpic*indentation . rr pdfpic*width . rr pdfpic*height . rr pdfpic*did-pdfinfo-work . rr pdfpic*desired-width . rr pdfpic*desired-height .. . .de PDFPIC . if !\\n[.U] \{\ . pdfpic@error use of \\$0 requires GNU troff's unsafe mode \ (-U option) . return . \} . . \" Dispose of junk from any previous early return. . pdfpic@cleanup . . nr pdfpic*do-conversion 0 . if !'\\*[.T]'pdf' .nr pdfpic*do-conversion 1 . . nr pdfpic*offset-mode 0 . . \" Preserve the trailing space in definitions of pdfpic*pspic-args. . . \" left-aligned? . ie '\\$1'-L' \{\ . nr pdfpic*offset-mode 1 . if \\n[pdfpic*do-conversion] .ds pdfpic*pspic-args \\$1 \" . shift . \} . el \{\ . \" right-aligned? . ie '\\$1'-R' \{\ . nr pdfpic*offset-mode 2 . if \\n[pdfpic*do-conversion] .ds pdfpic*pspic-args \\$1 \" . shift . \} . el \{\ . \" indented? . ie '\\$1'-I' \{\ . nr pdfpic*offset-mode 3 . nr pdfpic*indentation (m;\\$2) . if \\n[pdfpic*do-conversion] .ds pdfpic*pspic-args \\$1 \\$2 \" . shift 2 . \} . el \{\ . \" centered is the default . ie '\\$1'-C' \{\ . if \\n[pdfpic*do-conversion] .ds pdfpic*pspic-args \\$1 \" . shift . \} . el .nr pdfpic*offset-mode 0 . \} . \} . \} . br . . ds pdfpic*file-extension \\$1\" . substring pdfpic*file-extension -4 . stringdown pdfpic*file-extension . if !'\\*[pdfpic*file-extension]'.pdf' \{\ . pdfpic@error '\\$1' lacks a '.pdf' extension; skipping . return . \} . . \" Ensure the file exists and is readable. . \" . \" This test is subject to a time-of-check-to-time-of-use (TOCTTOU) . \" attack (or a simple race with a concurrent `rm` command, for . \" instance). . sy test -r \\$1 . if \\n[systat]!=0 \{\ . pdfpic@error '\\$1' does not exist or is not readable; skipping . return . \} . . \" if driver is not gropdf, convert image to .eps . if \\n[pdfpic*do-conversion] \{\ . ds pdfpic*file-name-base \\$1 . substring pdfpic*file-name-base 0 -5 . . sy pdftops -eps \\$1 . shift . . as pdfpic*pspic-args \\*[pdfpic*file-name-base].eps \\$* . . PSPIC \\*[pdfpic*pspic-args] . return . \} . . pdfpic@get-temporary-directory \\V[GROFF_TMPDIR] \\V[TMPDIR] . . if 'pdfpic*temporary-directory'' \{\ . \" Figure out if we're on a Windows system (with a Unix shell). . nr pdfpic*is-on-windows 0 . . sy expr $(uname -s) : "CYGWIN.*" > /dev/null . if \\n[systat]=0 .nr pdfpic*is-on-windows 1 . sy expr $(uname -s) : "MINGW.*" > /dev/null . if \\n[systat]=0 .nr pdfpic*is-on-windows 1 . . if \\n[pdfpic*is-on-windows] \ . pdfpic@get-temporary-directory \\V[TEMP] \\V[TMP] . . rr pdfpic*is-on-windows . \} . . if '\\*[pdfpic*temporary-directory]'' \ . pdfpic@get-temporary-directory /tmp . . if '\\*[pdfpic*temporary-directory]'' \{\ . pdfpic@error cannot locate a usable temporary directory; \ skipping '\\$1' . return . \} . ds pdfpic*temporary-file \\*[pdfpic*temporary-directory]/pdfpic\n[$$] . . \" Get image dimensions. The `tr` command to strip null bytes is . \" distasteful, but its necessity is imposed on us. See . \" . . ec @ . sy pdfinfo @$1 | \ tr -d '\000' | \ grep "Page *size" | \ sed -e 's/Page *size: *\\([[:digit:].]*\\) *x *\\([[:digit:].]*\\).*$/\ .nr pdfpic*width (p;\\1)\\n\ .nr pdfpic*height (p;\\2)/' \ > @*[pdfpic*temporary-file] . ec . if \\n[systat] \{\ . pdfpic@error retrieval of '\\$1' image dimensions failed with \ exit status \\n[systat]; skipping . return . \} . so \\*[pdfpic*temporary-file] . sy rm \\*[pdfpic*temporary-file] . . nr pdfpic*did-pdfinfo-work 1 . if !r pdfpic*width .nr pdfpic*did-pdfinfo-work 0 . if !r pdfpic*height .nr pdfpic*did-pdfinfo-work 0 . if !\\n[pdfpic*did-pdfinfo-work] \{\ . pdfpic@error retrieval of '\\$1' image dimensions failed; skipping . return . \} . rr pdfpic*did-pdfinfo-work . . \" reject nonsense dimensions <= 0 (and avoid zero divide later) . if !\\n[pdfpic*width] \{\ . pdfpic@error '\\$1' reports image width of \\n[pdfpic*width]u; \ skipping . return . \} . if !\\n[pdfpic*height] \{\ . pdfpic@error '\\$1' reports image height of \\n[pdfpic*height]u; \ skipping . return . \} . . \" if we have a parameter, use it as the final . \" image width; otherwise we use the image's natural width . \" or the current line length, whatever is smaller . ie (\\n[.$] >= 2) \{\ . nr pdfpic*desired-width (i;\\$2) . if !\\n[pdfpic*desired-width] \{\ . pdfpic@error rejecting desired image width of \ \\n[pdfpic*desired-width]u; skipping '\\$1' . return . \} . \} . el \ . nr pdfpic*desired-width ((\\n[.l] - \\n[.i]) = 3) \{\ . nr pdfpic*desired-height (i;\\$3) . if !\\n[pdfpic*desired-height] \{\ . pdfpic@error rejecting desired image height of \ \\n[pdfpic*desired-height]u; skipping '\\$1' . return . \} . \} . \" We have no else clause; pdfpic*desired-height will get clobbered . \" anyway. . . \" compute the final image height (with proper rounding), . \" based on the image's aspect ratio . nr pdfpic*desired-height (\\n[pdfpic*desired-width] * 1000 \ + (\\n[pdfpic*width] / 2) \ / \\n[pdfpic*width] * \\n[pdfpic*height] \ + 500 / 1000) . . \" if we have a parameter, use it as the final . \" image height in case it is smaller than the height . \" value we have just computed . if ((\\n[.$] >= 3) & (\\n[pdfpic*desired-height] > (i;0\\$3))) \{\ . nr pdfpic*desired-height (i;\\$3) . \" recompute the final image width since we always . \" keep the correct image aspect . nr pdfpic*desired-width (\\n[pdfpic*desired-height] * 1000 \ + (\\n[pdfpic*height] / 2) \ / \\n[pdfpic*height] * \\n[pdfpic*width] \ + 500 / 1000) . \} . . \" reserve vertical space for image . ne (\\n[pdfpic*desired-height]u + 1v) . . \" compute image offset w.r.t. the current left margin . if (\\n[pdfpic*offset-mode] == 0) \ . nr pdfpic*indentation \ (\\n[.l] - \\n[.i] - \\n[pdfpic*desired-width] / 2) . if (\\n[pdfpic*offset-mode] == 1) \ . nr pdfpic*indentation 0 . if (\\n[pdfpic*offset-mode] == 2) \ . nr pdfpic*indentation \ (\\n[.l] - \\n[.i] - \\n[pdfpic*desired-width]) . \h'\\n[pdfpic*indentation]u'\ \X'pdf: pdfpic \\$1 -L \\n[pdfpic*desired-width]z \ \\n[pdfpic*desired-height]z' . if !r PDFPIC_NOSPACE \{\ . nr PDFPIC_NOSPACE 0 . if \B'\\V[GROFF_PDFPIC_NOSPACE]' \ . nr PDFPIC_NOSPACE \\V[GROFF_PDFPIC_NOSPACE] . \} . if \\n[PDFPIC_NOSPACE]=0 \{\ . br . sp \\n[pdfpic*desired-height]u . \} . . pdfpic@cleanup .. . .cp \n[*groff_pdfpic_tmac_C] .do rr *groff_pdfpic_tmac_C . .\" Local Variables: .\" mode: nroff .\" fill-column: 72 .\" End: .\" vim: set expandtab filetype=groff tabstop=2 textwidth=72: