diff options
Diffstat (limited to 'Master/texmf-dist/source/latex/l3experimental/l3graphics/l3graphics.dtx')
-rw-r--r-- | Master/texmf-dist/source/latex/l3experimental/l3graphics/l3graphics.dtx | 546 |
1 files changed, 296 insertions, 250 deletions
diff --git a/Master/texmf-dist/source/latex/l3experimental/l3graphics/l3graphics.dtx b/Master/texmf-dist/source/latex/l3experimental/l3graphics/l3graphics.dtx index 8b97a562ed3..cf4a70983d2 100644 --- a/Master/texmf-dist/source/latex/l3experimental/l3graphics/l3graphics.dtx +++ b/Master/texmf-dist/source/latex/l3experimental/l3graphics/l3graphics.dtx @@ -46,7 +46,7 @@ % }^^A % } % -% \date{Released 2022-02-05} +% \date{Released 2022-04-10} % % \maketitle % @@ -54,140 +54,60 @@ % % \section{\pkg{l3graphics} documentation} % -% \subsection{Driver functions} +% \subsection{Graphics keys} % % Inclusion of graphic files requires a range of low-level data be passed to -% the driver layer. These functions are primarily aimed at supporting this -% work. +% the backend. This is set up using a small number of key--value settings, +% which are stored in the |graphics| tree. % -% \begin{variable}{\l_graphics_decodearray_tl} +% \begin{variable}{decodearray} % Array to decode color in bitmap graphic: when non-empty, this should % be in the form of one, two or three pairs of real numbers in the range % $[0,1]$, separated by spaces. % \end{variable} % -% \begin{variable}{\l_graphics_interpolate_bool} -% Indicates whether interpolation should be applied to bitmap graphic files. +% \begin{variable}{draft} +% Switch to enable draft mode: graphics are read but not included when this is +% true. +% \end{variable} +% +% \begin{variable}{interpolate} +% Switch which indicates whether interpolation should be applied to bitmap +% graphic files. % \end{variable} % -% \begin{variable}{\l_graphics_page_int} +% \begin{variable}{page} % The page to extract from a multi-page graphic file: used for |.pdf| files % which may contain multiple pages. % \end{variable} % -% \begin{variable}{\l_graphics_pagebox_tl} +% \begin{variable}{pagebox} % The nature of the page box setting used to determine the bounding box of % material: used for |.pdf| files which feature multiple page box -% specifications. +% specifications. A choice from |art|, |bleed|, |crop|, |media|, |trim|. +% The standard setting is |crop|. % \end{variable} % -% \begin{variable}{\l_graphics_draft_bool} +% \begin{variable}{draft} % Switch to enable draft mode: graphics are read but not included when this is % true. % \end{variable} % -% \begin{variable} -% {\l_graphics_llx_dim, \l_graphics_lly_dim, \l_graphics_urx_dim, \l_graphics_ury_dim} -% Dimensions which return the points $(\meta{llx},\meta{lly})$ and -% $(\meta{urx},\meta{ury})$ for the graphic. For many graphics only the resulting -% height and width are significant, but this is driver-dependent. -% \end{variable} -% -% \begin{variable}{\l_graphics_name_bool} -% The name of a graphics file being loaded: usually the same as the -% input file name, but may be altered by some drivers. +% \begin{variable}{type} +% The type of graphic file beign included: if this key is not set, the +% \emph{type} is determined from the file extension. % \end{variable} % -% \begin{function} -% { -% \graphics_bb_save:n, \graphics_bb_save:x, -% \graphics_bb_restore:nF, \graphics_bb_restore:xF -% } -% \begin{syntax} -% \cs{graphics_bb_save:n} \Arg{graphic} -% \cs{graphics_bb_restore:nF} \Arg{graphic} \Arg{false code} -% \end{syntax} -% This pair of functions are used to cache the bounding box of an \meta{graphic} -% so that extraction/reading is only required once. The \texttt{save} -% function stores the values from \cs{l_graphics_llx_dim}, -% \cs{l_graphics_lly_dim}, \cs{l_graphics_urx_dim} and -% \cs{l_graphics_ury_dim} as constants. The \texttt{restore} function will then -% look up values for the bounding box of an \meta{graphic} and set the four -% dimensions appropriately. For any one \meta{graphic} the bounding box will -% be constant, so the \texttt{save} function should only be called once. Thus -% a typical use case is -% \begin{verbatim} -% \graphics_bb_restore:nF { <name> } -% { -% % Code to read the bb -% \graphics_bb_save:n { <name> } -% } -% \end{verbatim} -% \emph{i.e.}~every use of a bounding box will attempt to restore saved data, -% and saving will only take place where that is not possible. -% -% Note that the \meta{graphic} may not be a simple file name: a multi-page PDF, -% for example, will need to have the bounding box cached for each page used. -% \end{function} +% \subsection{Including graphics} % -% \begin{function}{\graphics_extract_bb:n} +% \begin{function}{\graphics_include:nn, \graphics_include:nV} % \begin{syntax} -% \cs{graphics_extract_bb:n} \Arg{file} +% \cs{graphics_include:nn} \Arg{keys} \Arg{file} % \end{syntax} -% Extracts bounding box data for the graphic \meta{file} using the |extractbb| -% utility, and stores the bounding box of the graphic file in -% \cs{l_graphics_llx_dim}, \cs{l_graphics_lly_dim}, \cs{l_graphics_urx_dim} and -% \cs{l_graphics_ury_dim}. -% -% The \meta{file} name should be fully-qualified and sanitized: no search -% or other manipulation is carried out at this level. No check is made on -% the file \emph{type} at this stage: it is assumed that the driver code -% using this function has made such a check. File types such as |.pdf| and -% |.jpg| are appropriate for parsing using this function. -% -% When \cs{l_graphics_page_int} is positive the appropriate page will be -% queried from the graphic file. -% -% Note that this function requires pipe shell calls to be enabled: this is -% generally true but may require the option |--enable-pipes| to be enabled -% when running the \TeX{} job. -% \end{function} -% -% \begin{function}{\graphics_read_bb:n} -% \begin{syntax} -% \cs{graphics_read_bb:n} \Arg{file} -% \end{syntax} -% Parses the graphic \meta{file} to find a PostScript-style bounding box -% line of the form -% \begin{verbatim} -% %%BoundingBox: llx lly urx urx -% \end{verbatim} -% where \meta{llx}, \meta{lly}, \meta{urx} and \meta{ury} are the corners -% of the bounding box expressed in PostScript (\enquote{big}) points. The -% values are stored in \cs{l_graphics_llx_dim}, \cs{l_graphics_lly_dim}, -% \cs{l_graphics_urx_dim} and \cs{l_graphics_ury_dim}. -% -% The \meta{file} name should be fully-qualified and sanitized: no search -% or other manipulation is carried out at this level. No check is made on -% the file \emph{type} at this stage: it is assumed that the driver code -% using this function has made such a check. File types such as |.eps| and -% |.bb|/|.xbb| are appropriate for parsing using this function. -% \end{function} -% -% \begin{function}{\graphics_include:n, \graphics_include:nn} -% \begin{syntax} -% \cs{graphics_include:n} \Arg{file} -% \cs{graphics_include:nn} \Arg{file} \Arg{type} -% \end{syntax} -% Horizontal-mode commands which include the \meta{file} as an graphic -% at the current location. The file \meta{type} is given explicitly in -% the two-argument version, or is inferred from the file extension extracted -% in the single-argument form. The exact graphic types supported depend upon -% the driver in use. -% -% Where the \meta{file} is not found and the \meta{type} is \emph{not} -% given, a search for possible graphic files is undertaken using the extensions -% stored in \cs{l_graphics_search_ext_seq}. +% Horizontal-mode command which includes the \meta{file} as an graphic +% at the current location. The file \meta{type} may be given as one of the +% \meta{keys}, or will otherwise be determined from file extension. The +% \meta{keys} is used to pass settings as detailed above. % \end{function} % % \begin{variable}{\l_graphics_ext_type_prop} @@ -200,11 +120,6 @@ % \end{verbatim} % \end{variable} % -% \begin{variable}{\l_graphics_search_ext_seq} -% Extensions to use for graphic searching when the given \meta{file} name is not -% found by \cs{graphics_include:n}. -% \end{variable} -% % \begin{variable}{\l_graphics_search_path_seq} % Each entry is the path to a directory which should be searched when % seeking an graphic file. Each path can be relative or absolute, and should @@ -213,6 +128,36 @@ % variable content. Spaces need not be quoted. % \end{variable} % +% \subsection{Utility functions} +% +% \begin{function}[noTF]{\graphics_get_full_name:nN} +% \begin{syntax} +% \cs{graphics_get_full_name:nN} \Arg{file} \meta{tl~var} +% \cs{graphics_get_full_name:nNTF} \Arg{file} \meta{tl~var} \Arg{true code} \Arg{false code} +% \end{syntax} +% Searches for \meta{file} first as given and then using the extensions +% listed in \cs{l_graphics_search_ext_seq}. The search path used will be +% the entries of \cs{l_graphics_search_path_seq}. If found, the full file +% name including any path and extension will be returned in the +% \meta{tl~var}. In the non-branching version, the \meta{tl var} will be +% set to \cs{q_no_value} in the case that the graphics is not found. +% \end{function} +% +% \begin{variable}{\l_graphics_search_ext_seq} +% Extensions to use for graphic searching when the given \meta{file} name is not +% found by \cs{graphics_get_full_name:nN}. +% \end{variable} +% +% \begin{function}{\graphics_get_pagecount:nN} +% \begin{syntax} +% \cs{graphics_get_pagecount:nn} \Arg{file} \meta{tl~var} +% \end{syntax} +% Reads the graphics \meta{file} and extracts the number of pages, which +% are stored in the \meta{tl~var}. +% \end{function} +% +% \subsection{Showing and logging included graphics} +% % \begin{function}{\graphics_show_list:, \graphics_log_list:} % \begin{syntax} % \cs{graphics_show_list:} @@ -240,15 +185,15 @@ % \end{macrocode} % % \begin{macrocode} -\ProvidesExplPackage{l3graphics}{2022-02-05}{} +\ProvidesExplPackage{l3graphics}{2022-04-10}{} {L3 Experimental graphics inclusion support} % \end{macrocode} % -% \begin{variable}{\l_@@_tmp_ior, \l_@@_tmp_tl} +% \begin{variable}{\l_@@_internal_ior, \l_@@_internal_tl} % Scratch space. % \begin{macrocode} -\ior_new:N \l_@@_tmp_ior -\tl_new:N \l_@@_tmp_tl +\ior_new:N \l_@@_internal_ior +\tl_new:N \l_@@_internal_tl % \end{macrocode} % \end{variable} % @@ -259,24 +204,47 @@ % \end{macrocode} % \end{variable} % -% \subsection{Image feature support} +% \subsection{Graphics keys} % % \begin{macro} % { -% \l_graphics_decodearray_tl , -% \l_graphics_interpolate_bool, -% \l_graphics_page_int , -% \l_graphics_pagebox_tl +% \l_@@_decodearray_str , +% \l__@@_draft_bool , +% \l_@@_interpolate_bool , +% \l_@@_page_int , +% \l_@@_pagebox_tl , +% \l_@@_type_str % } % Keys which control features of graphics. The standard value of |pagebox| -% set up here should match the default for the drivers themselves: in -% the absence of any other setting the |cropbox| should be used. +% set up here should match the default for the backends themselves: in +% the absence of any other setting the |crop| should be used. Note that +% the variable \cs{l_@@_pagebox_str} can be empty internally, as backends +% which do not support |pagebox| are set up to clear it entirely. The +% store for |pagebox| is a |tl| as that makes extracting the data +% easier for some backends. % \begin{macrocode} -\tl_new:N \l_graphics_decodearray_tl -\tl_new:N \l_graphics_pagebox_tl -\bool_new:N \l_graphics_interpolate_bool -\tl_set:Nn \l_graphics_pagebox_tl { cropbox } -\int_new:N \l_graphics_page_int +\tl_new:N \l_@@_pagebox_tl +\keys_define:nn { graphics } + { + decodearray .str_set:N = + \l_@@_decodearray_str , + draft .bool_set:N = + \l_@@_draft_bool , + interpolate .bool_set:N = + \l_@@_interpolate_bool , + pagebox .choices:nn = + { art , bleed , crop , media , trim } + { + \tl_set:Nx \l_@@_pagebox_tl + { \tl_use:N \l_keys_choice_tl box } + } , + pagebox .initial:n = + crop , + page .int_set:N = + \l_@@_page_int , + type . str_set:N = + \l_@@_type_str + } % \end{macrocode} % \end{macro} % @@ -284,60 +252,60 @@ % % \begin{variable} % { -% \l_graphics_llx_dim , \l_graphics_lly_dim, -% \l_graphics_urx_dim , \l_graphics_ury_dim +% \l_@@_llx_dim , \l_@@_lly_dim, +% \l_@@_urx_dim , \l_@@_ury_dim % } % Storage for the return of bounding box. % \begin{macrocode} -\dim_new:N \l_graphics_llx_dim -\dim_new:N \l_graphics_lly_dim -\dim_new:N \l_graphics_urx_dim -\dim_new:N \l_graphics_ury_dim +\dim_new:N \l_@@_llx_dim +\dim_new:N \l_@@_lly_dim +\dim_new:N \l_@@_urx_dim +\dim_new:N \l_@@_ury_dim % \end{macrocode} % \end{variable} % -% \begin{macro}{\graphics_bb_save:n, \graphics_bb_save:x} -% \begin{macro}{\graphics_bb_restore:nF, \graphics_bb_restore:xF} +% \begin{macro}{\@@_bb_save:n, \@@_bb_save:x} +% \begin{macro}{\@@_bb_restore:nF, \@@_bb_restore:xF} % Caching graphic bounding boxes is sensible, and these functions are needed both % here and for drive-specific work. So they are made available as documented % functions. To save on registers, the \enquote{origin} is only saved if it is % not at zero. % \begin{macrocode} -\cs_new_protected:Npn \graphics_bb_save:n #1 +\cs_new_protected:Npn \@@_bb_save:n #1 { \dim_if_exist:cTF { c_@@_ #1 _urx_dim } { \msg_error:nnn { graphic } { bb-already-cached } {#1} } { - \dim_compare:nNnF \l_graphics_llx_dim = { 0pt } - { \dim_const:cn { c_@@_ #1 _llx_dim } { \l_graphics_llx_dim } } - \dim_compare:nNnF \l_graphics_lly_dim = { 0pt } - { \dim_const:cn { c_@@_ #1 _lly_dim } { \l_graphics_lly_dim } } - \dim_const:cn { c_@@_ #1 _urx_dim } { \l_graphics_urx_dim } - \dim_const:cn { c_@@_ #1 _ury_dim } { \l_graphics_ury_dim } + \dim_compare:nNnF \l_@@_llx_dim = { 0pt } + { \dim_const:cn { c_@@_ #1 _llx_dim } { \l_@@_llx_dim } } + \dim_compare:nNnF \l_@@_lly_dim = { 0pt } + { \dim_const:cn { c_@@_ #1 _lly_dim } { \l_@@_lly_dim } } + \dim_const:cn { c_@@_ #1 _urx_dim } { \l_@@_urx_dim } + \dim_const:cn { c_@@_ #1 _ury_dim } { \l_@@_ury_dim } } } -\cs_generate_variant:Nn \graphics_bb_save:n { x } -\cs_new_protected:Npn \graphics_bb_restore:nF #1#2 +\cs_generate_variant:Nn \@@_bb_save:n { x } +\cs_new_protected:Npn \@@_bb_restore:nF #1#2 { \dim_if_exist:cTF { c_@@_ #1 _urx_dim } { - \dim_set_eq:Nc \l_graphics_urx_dim { c_@@_ #1 _urx_dim } - \dim_set_eq:Nc \l_graphics_ury_dim { c_@@_ #1 _ury_dim } + \dim_set_eq:Nc \l_@@_urx_dim { c_@@_ #1 _urx_dim } + \dim_set_eq:Nc \l_@@_ury_dim { c_@@_ #1 _ury_dim } \dim_if_exist:cTF { c_@@_ #1 _llx_dim } - { \dim_set_eq:Nc \l_graphics_llx_dim { c_@@_ #1 _llx_dim } } - { \dim_zero:N \l_graphics_llx_dim } + { \dim_set_eq:Nc \l_@@_llx_dim { c_@@_ #1 _llx_dim } } + { \dim_zero:N \l_@@_llx_dim } \dim_if_exist:cTF { c_@@_ #1 _lly_dim } - { \dim_set_eq:Nc \l_graphics_lly_dim { c_@@_ #1 _lly_dim } } - { \dim_zero:N \l_graphics_lly_dim } + { \dim_set_eq:Nc \l_@@_lly_dim { c_@@_ #1 _lly_dim } } + { \dim_zero:N \l_@@_lly_dim } } {#2} } -\cs_generate_variant:Nn \graphics_bb_restore:nF { x } +\cs_generate_variant:Nn \@@_bb_restore:nF { x } % \end{macrocode} % \end{macro} % \end{macro} % -% \begin{macro}{\graphics_extract_bb:n, \graphics_read_bb:n} +% \begin{macro}{\@@_extract_bb:n, \@@_read_bb:n} % \begin{macro}{\@@_extract_bb_auix:nn, \@@_extract_bb_auix:Vn} % \begin{macro}{\@@_extract_bb_auxii:nnn} % \begin{macro}{\@@_extract_bb_auxiii:nnnn, \@@_extract_bb_auxiii:Vnnn} @@ -357,10 +325,10 @@ % box has to be calculated by |extractbb|, with just the initial phase % different. % \begin{macrocode} -\cs_new_protected:Npn \graphics_extract_bb:n #1 +\cs_new_protected:Npn \@@_extract_bb:n #1 { - \int_compare:nNnTF \l_graphics_page_int > 0 - { \@@_extract_bb_auxi:Vn \l_graphics_page_int {#1} } + \int_compare:nNnTF \l_@@_page_int > 0 + { \@@_extract_bb_auxi:Vn \l_@@_page_int {#1} } { \@@_extract_bb_auxii:nnn {#1} { } { } } } \cs_new_protected:Npn \@@_extract_bb_auxi:nn #1#2 @@ -368,9 +336,9 @@ \cs_generate_variant:Nn \@@_extract_bb_auxi:nn { Vn } \cs_new_protected:Npn \@@_extract_bb_auxii:nnn #1#2#3 { - \tl_if_empty:NTF \l_graphics_pagebox_tl + \tl_if_empty:NTF \l_@@_pagebox_tl { \@@_extract_bb_auxiv:nnn } - { \@@_extract_bb_auxiii:Vnnn \l_graphics_pagebox_tl } + { \@@_extract_bb_auxiii:Vnnn \l_@@_pagebox_tl } {#1} {#2} {#3} } \cs_new_protected:Npn \@@_extract_bb_auxiii:nnnn #1#2#3#4 @@ -379,13 +347,13 @@ \cs_new_protected:Npn \@@_extract_bb_auxiv:nnn #1#2#3 { \@@_read_bb_auxi:nnnn {#1} {#2} - { \ior_shell_open:Nn \l_@@_tmp_ior { extractbb~#3-O~#1 } } + { \ior_shell_open:Nn \l_@@_internal_ior { extractbb~#3-O~#1 } } { pipe-failed } } -\cs_new_protected:Npn \graphics_read_bb:n #1 +\cs_new_protected:Npn \@@_read_bb:n #1 { \@@_read_bb_auxi:nnnn {#1} { } - { \ior_open:Nn \l_@@_tmp_ior {#1} } + { \ior_open:Nn \l_@@_internal_ior {#1} } { graphic-not-found } } % \end{macrocode} @@ -401,31 +369,23 @@ % \begin{macrocode} \cs_new_protected:Npn \@@_read_bb_auxi:nnnn #1#2#3#4 { - \graphics_bb_restore:nF {#1#2} + \@@_bb_restore:nF {#1#2} { \@@_read_bb_auxii:nnnn {#3} {#4} {#1} {#2} } } \cs_new_protected:Npx \@@_read_bb_auxii:nnnn #1#2#3#4 { #1 - \exp_not:N \ior_if_eof:NTF \exp_not:N \l_@@_tmp_ior + \exp_not:N \ior_if_eof:NTF \exp_not:N \l_@@_internal_ior { \msg_error:nnn { graphics } {#2} {#3} } { - \ior_str_map_inline:Nn \exp_not:N \l_@@_tmp_ior + \ior_str_map_inline:Nn \exp_not:N \l_@@_internal_ior { \exp_not:N \@@_read_bb_auxiii:w ##1 ~ \c_colon_str \s_@@_stop } + \@@_bb_save:n {#3#4} } - \exp_not:n - { - \ior_close:N \l_@@_tmp_ior - \dim_compare:nNnF \l_graphics_llx_dim = { 0pt } - { \dim_const:cn { c_@@_ #3#4 _llx_dim } { \l_graphics_llx_dim } } - \dim_compare:nNnF \l_graphics_lly_dim = { 0pt } - { \dim_const:cn { c_@@_ #3#4 _lly_dim } { \l_graphics_lly_dim } } - \dim_const:cn { c_@@_ #3#4 _urx_dim } { \l_graphics_urx_dim } - \dim_const:cn { c_@@_ #3#4 _ury_dim } { \l_graphics_ury_dim } - } + \ior_close:N \exp_not:N \l_@@_internal_ior } \use:x { @@ -450,13 +410,13 @@ { \str_if_eq:nnF {#2} { atend } { - \tl_set_rescan:Nnx \l_@@_tmp_tl + \tl_set_rescan:Nnx \l_@@_internal_tl { \char_set_catcode_space:n { 9 } \char_set_catcode_space:n { 32 } } { \use:n #1 } - \exp_after:wN \@@_read_bb_auxv:w \l_@@_tmp_tl \s_@@_stop + \exp_after:wN \@@_read_bb_auxv:w \l_@@_internal_tl \s_@@_stop } } % \end{macrocode} @@ -465,10 +425,10 @@ % \begin{macrocode} \cs_new_protected:Npn \@@_read_bb_auxv:w #1~#2~#3~#4~#5 \s_@@_stop { - \dim_set:Nn \l_graphics_llx_dim { #1 bp } - \dim_set:Nn \l_graphics_lly_dim { #2 bp } - \dim_set:Nn \l_graphics_urx_dim { #3 bp } - \dim_set:Nn \l_graphics_ury_dim { #4 bp } + \dim_set:Nn \l_@@_llx_dim { #1 bp } + \dim_set:Nn \l_@@_lly_dim { #2 bp } + \dim_set:Nn \l_@@_urx_dim { #3 bp } + \dim_set:Nn \l_@@_ury_dim { #4 bp } \ior_map_break: } % \end{macrocode} @@ -480,17 +440,13 @@ % \end{macro} % \end{macro} % -% \begin{variable}{\l_graphics_draft_bool} -% Relevant to including graphics but not to reading them. -% \begin{macrocode} -\bool_new:N \l_graphics_draft_bool -% \end{macrocode} -% \end{variable} -% -% \begin{variable}{\l_graphics_name_tl, \l_@@_name_tl} +% \begin{variable}{\l_@@_final_name_str, \l_@@_full_name_str} +% The full name is as you'd expect the name including path and extension. +% The final name here reflects any conversions carried out by the backend, +% for example if an |.eps| is converted to |.pdf|. % \begin{macrocode} -\tl_new:N \l_graphics_name_tl -\tl_new:N \l_@@_name_tl +\str_new:N \l_@@_final_name_str +\str_new:N \l_@@_full_name_str % \end{macrocode} % \end{variable} % @@ -515,7 +471,7 @@ % \end{variable} % % \begin{variable}{\l_graphics_search_ext_seq} -% Used to specify fall-back extensions: actually set on a per-driver basis. +% Used to specify fall-back extensions: actually set on a per-backend basis. % \begin{macrocode} \seq_new:N \l_graphics_search_ext_seq % \end{macrocode} @@ -536,66 +492,49 @@ % \end{macrocode} % \end{variable} % -% \begin{macro}{\graphics_include:n} +% \begin{macro}{\graphics_include:nn, \graphics_include:nV} % \begin{macro}{\@@_include_search:n} % \begin{macro}{\@@_include:} -% \begin{macro}{\graphics_include:nn} % \begin{macro} % { -% \@@_include_auxi:n, \@@_include_auxii:n, +% \@@_include_auxi:n, \@@_include_auxi:e, \@@_include_auxii:n, % \@@_include_auxiii:n, \@@_include_auxiv:n % } % Actually including an graphic is relatively straight-forward: most of the -% work is done by the driver. We only have to deal with making sure the +% work is done by the backend. We only have to deal with making sure the % box has no apparent depth. Where the first given name is not found, we % search based on extension only if the \meta{type} was not given. The one % wrinkle is that we may have found a \texttt{.tex} file matching the file % name stem: that's not what we want, so we have to filter out. % \begin{macrocode} -\cs_new_protected:Npn \graphics_include:n #1 +\cs_new_protected:Npn \graphics_include:nn #1#2 { \group_begin: + \keys_set:nn { graphics } {#1} \seq_set_eq:NN \l_file_search_path_seq \l_graphics_search_path_seq - \file_get_full_name:nNTF {#1} \l_@@_name_tl + \file_get_full_name:nNTF {#2} \l_@@_full_name_str { - \str_if_eq:eeTF { \l_@@_name_tl } { #1 .tex } - { \@@_include_search:n {#1} } + \str_if_eq:eeTF { \l_@@_full_name_str } { #2 .tex } + { \msg_error:nnn { graphics } { graphic-not-found } {#2} } { \@@_include: } } - { \@@_include_search:n {#1} } + { \msg_error:nnn { graphics } { graphic-not-found } {#2} } \group_end: } -\cs_new_protected:Npn \@@_include_search:n #1 - { - \seq_map_inline:Nn \l_graphics_search_ext_seq - { - \file_get_full_name:nNT { #1 . ##1 } \l_@@_name_tl - { \seq_map_break:n { \use_i:nnn \@@_include: } } - } - \use:n - { \msg_error:nnn { graphics } { graphic-not-found } {#1} } - } +\cs_generate_variant:Nn \graphics_include:nn { nV } \cs_new_protected:Npn \@@_include: { - \file_parse_full_name:VNNN \l_@@_name_tl - \l_@@_dir_str \l_@@_name_str \l_@@_ext_str - \exp_args:Ne \@@_include_auxi:n + \str_if_empty:NTF \l_@@_type_str { - \exp_args:Ne \str_tail:n - { \str_foldcase:V \l_@@_ext_str } - } - } -\cs_new_protected:Npn \graphics_include:nn #1#2 - { - \group_begin: - \seq_set_eq:NN \l_file_search_path_seq \l_graphics_search_path_seq - \file_get_full_name:nNTF {#1} \l_@@_name_tl - { - \exp_args:Ne \@@_include_auxi:n - { \str_foldcase:n {#1} } - } - { \msg_error:nnn { graphics } { graphic-not-found } {#1} } - \group_end: + \file_parse_full_name:VNNN \l_@@_full_name_str + \l_@@_dir_str \l_@@_name_str \l_@@_ext_str + \@@_include_auxi:e + { + \exp_args:Ne \str_tail:n + { \str_foldcase:V \l_@@_ext_str } + } + } + { \@@_include_auxi:e { \l_@@_type_str } } } \cs_new_protected:Npn \@@_include_auxi:n #1 { @@ -603,20 +542,21 @@ { \tl_set:Nn \l_@@_internal_tl {#1} } \exp_args:NV \@@_include_auxii:n \l_@@_internal_tl } +\cs_generate_variant:Nn \@@_include_auxi:n { e } \cs_new_protected:Npn \@@_include_auxii:n #1 { \mode_leave_vertical: \cs_if_exist:cTF { @@_backend_include_ #1 :n } { - \tl_set_eq:NN \l_graphics_name_tl \l_@@_name_tl + \tl_set_eq:NN \l_@@_final_name_str \l_@@_full_name_str + \str_set:Nx \l_@@_full_name_str + { \exp_args:NV \__kernel_file_name_quote:n \l_@@_full_name_str } \exp_args:NnV \use:c { @@_backend_getbb_ #1 :n } - \l_@@_name_tl - \seq_gput_right:NV \g_@@_record_seq \l_graphics_name_tl -%<*package> + \l_@@_full_name_str + \seq_gput_right:NV \g_@@_record_seq \l_@@_final_name_str \clist_if_exist:NT \@filelist - { \exp_args:NV \@addtofilelist \l_graphics_name_tl } -%</package> - \bool_if:NTF \l_graphics_draft_bool + { \exp_args:NV \@addtofilelist \l_@@_final_name_str } + \bool_if:NTF \l_@@_draft_bool { \@@_include_auxiii:n } { \@@_include_auxiv:n } {#1} @@ -625,23 +565,21 @@ } \cs_new_protected:Npn \@@_include_auxiii:n #1 { - \hbox_to_wd:nn { \l_graphics_urx_dim - \l_graphics_llx_dim } + \hbox_to_wd:nn { \l_@@_urx_dim - \l_@@_llx_dim } { \tex_vrule:D \tex_hss:D \vbox_to_ht:nn - { \l_graphics_ury_dim - \l_graphics_lly_dim } + { \l_@@_ury_dim - \l_@@_lly_dim } { \tex_hrule:D width - \dim_eval:n { \l_graphics_urx_dim - \l_graphics_llx_dim } + \dim_eval:n { \l_@@_urx_dim - \l_@@_llx_dim } \tex_vss:D \hbox_to_wd:nn - { \l_graphics_urx_dim - \l_graphics_llx_dim } + { \l_@@_urx_dim - \l_@@_llx_dim } { -%<*package> \ttfamily -%</package> - \tex_hss:D \l_@@_name_tl \tex_hss:D + \tex_hss:D \l_@@_full_name_str \tex_hss:D } \tex_vss:D \tex_hrule:D @@ -655,13 +593,13 @@ \hbox_set:Nn \l_@@_internal_box { \exp_args:NnV \use:c { @@_backend_include_ #1 :n } - \l_@@_name_tl + \l_@@_full_name_str } \box_set_dp:Nn \l_@@_internal_box { 0pt } \box_set_ht:Nn \l_@@_internal_box - { \l_graphics_ury_dim - \l_graphics_lly_dim } + { \l_@@_ury_dim - \l_@@_lly_dim } \box_set_wd:Nn \l_@@_internal_box - { \l_graphics_urx_dim - \l_graphics_llx_dim } + { \l_@@_urx_dim - \l_@@_llx_dim } \box_use_drop:N \l_@@_internal_box } % \end{macrocode} @@ -669,7 +607,6 @@ % \end{macro} % \end{macro} % \end{macro} -% \end{macro} % % \begin{macro}{\graphics_show_list:, \graphics_log_list:, \@@_list:N} % \begin{macro}[EXP]{\@@_list_aux:n} @@ -680,7 +617,7 @@ \cs_new_protected:Npn \@@_list:N #1 { \seq_remove_duplicates:N \g_@@_record_seq - #1 { LaTeX/kernel } { file-list } + #1 { kernel } { file-list } { \seq_map_function:NN \g_@@_record_seq \@@_list_aux:n } { } { } { } } @@ -689,14 +626,123 @@ % \end{macro} % \end{macro} % +% \subsection{Utility functions} +% +% \begin{macro}{\graphics_get_full_name:nN} +% \begin{macro}[TF]{\graphics_get_full_name:nN} +% \begin{macro}{\@@_get_full_name:n} +% A simple search. +% \begin{macrocode} +\cs_new_protected:Npn \graphics_get_full_name:nN #1#2 + { + \graphics_get_full_name:nNF {#1} #2 + { \tl_set:Nn #2 { \q_no_value } } + } +\prg_new_protected_conditional:Npnn \graphics_get_full_name:nN #1#2 + { T , F , TF } + { + \group_begin: + \seq_set_eq:NN \l_file_search_path_seq \l_graphics_search_path_seq + \file_get_full_name:nNTF {#1} \l_@@_full_name_str + { + \str_if_eq:eeT { \l_@@_full_name_str } { #1 .tex } + { \@@_get_full_name:n {#1} } + } + { \@@_get_full_name:n {#1} } + \exp_args:NNNV \group_end: + \tl_set:Nn #2 \l_@@_full_name_str + \tl_if_empty:NTF #2 + { \prg_return_false: } + { \prg_return_true: } + } +\cs_new_protected:Npn \@@_get_full_name:n #1 + { + \str_clear:N \l_@@_full_name_str + \seq_map_inline:Nn \l_graphics_search_ext_seq + { + \file_get_full_name:nNT { #1 ##1 } \l_@@_full_name_str + { \seq_map_break:n { \use_none:nn } } + } + \use:n + { \str_clear:N \l_@@_full_name_str } + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\graphics_get_pagecount:nN} +% \begin{macro}{\@@_get_pagecount:n} +% \begin{macro}{\@@_get_pagecount:nw} +% A generic function to read the number of pages in a graphic file. This is +% used by all of the backend where there is not a dedicated primitive. The +% plan is essentially the same as reading the bounding box. To avoid multiple +% calls, the value is cached either here or in the backend. +% \begin{macrocode} +\cs_new_protected:Npn \graphics_get_pagecount:nN #1#2 + { + \group_begin: + \seq_set_eq:NN \l_file_search_path_seq \l_graphics_search_path_seq + \file_get_full_name:nNTF {#1} \l_@@_full_name_str + { + \int_if_exist:cF { c_@@_ \l_@@_full_name_str _pages_int } + { + \exp_args:NV \@@_backend_get_pagecount:n + \l_@@_full_name_str + } + \tl_set:Nv #2 { c_@@_ \l_@@_full_name_str _pages_int } + } + { + \tl_set:Nn #2 { 0 } + \msg_error:nnn { graphics } { graphic-not-found } {#1} + } + \exp_args:NNNV \group_end: + \tl_set:Nn #2 #2 + } +\cs_new_protected:Npx \@@_get_pagecount:n #1 + { + \ior_shell_open:Nn \exp_not:N \l_@@_internal_ior + { extractbb~-O~#1 } + \exp_not:N \ior_if_eof:NTF \exp_not:N \l_@@_internal_ior + { \msg_error:nnn { graphics } { pipe-failed } } + { + \ior_str_map_inline:Nn \exp_not:N \l_@@_internal_ior + { + \exp_not:N \@@_get_pagecount:nw {#1} + ##1 ~ \c_colon_str \c_colon_str \s_@@_stop + } + \exp_not:N \int_if_exist:cF { c_@@_ #1 _pages_int } + { \int_const:cn { c_@@_ #1 _pages_int } { 1 } } + } + \ior_close:N \exp_not:N \l_@@_internal_ior + } +\use:x + { + \cs_new_protected:Npn \exp_not:N \@@_get_pagecount:nw + ##1##2 \c_colon_str ##3 \c_colon_str ##4 \s_@@_stop + { + \exp_not:N \str_if_eq:nnT + { \c_percent_str \c_percent_str Pages } + {##2} + { + \int_const:cn { c_@@_ ##1 _pages_int } {##3} + \exp_not:N \ior_map_break: + } + } + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% % \subsection{Messages} % % \begin{macrocode} \msg_new:nnnn { graphics } { graphic-not-found } { Image~file~'#1'~not~found. } { - LaTeX~tried~to~open~graphic~file~'#1', - ~but~the~file~could~not~be~read. + LaTeX~tried~to~open~graphic~file~'#1',~ + but~the~file~could~not~be~read. } \msg_new:nnnn { graphics } { pipe-failed } { Cannot~run~piped~system~commands. } |