% \iffalse meta-comment % %% File: l3pdf.dtx % % Copyright(C) 2019,2020 The LaTeX3 Project % % It may be distributed and/or modified under the conditions of the % LaTeX Project Public License (LPPL), either version 1.3c of this % license or (at your option) any later version. The latest version % of this license is in the file % % http://www.latex-project.org/lppl.txt % % This file is part of the "l3experimental bundle" (The Work in LPPL) % and all files in that bundle must be distributed together. % % ----------------------------------------------------------------------- % % The development version of the bundle can be found at % % https://github.com/latex3/latex3 % % for those people who are interested. % %<*driver|package> \RequirePackage{expl3} % %<*driver> \documentclass[full]{l3doc} \begin{document} \DocInput{\jobname.dtx} \end{document} % % \fi % % \title{^^A % The \pkg{l3pdf} package\\ Core PDF support^^A % } % % \author{^^A % The \LaTeX3 Project\thanks % {^^A % E-mail: % \href{mailto:latex-team@latex-project.org} % {latex-team@latex-project.org}^^A % }^^A % } % % \date{Released 2020-05-18} % % \maketitle % % \begin{documentation} % % \section{\pkg{l3pdf} documentation} % % \subsection{Objects} % % \begin{function}[added = 2019-06-02]{\pdf_object_new:nn} % \begin{syntax} % \cs{pdf_object_new:nn} \Arg{object} \Arg{type} % \end{syntax} % Declares \meta{object} as a PDF object of \meta{type}, which should be % one of % \begin{itemize} % \item \texttt{array} % \item \texttt{dict} % \item \texttt{fstream} % \item \texttt{stream} % \end{itemize} % The object may be referenced from this point on, and written later % using \cs{pdf_object_write:nn}. % \end{function} % \begin{function}[EXP, pTF, added=2020-05-15]{\pdf_object_if_exist:n} % \begin{syntax} % \cs{pdf_object_if_exist_p:n} \Arg{object} % \cs{pdf_object_if_exist:nTF} \Arg{object} % \end{syntax} % Tests whether an object with name \Arg{object} has been defined. % \end{function} % \begin{function}[added = 2019-06-02] % {\pdf_object_write:nn, \pdf_object_write:nx} % \begin{syntax} % \cs{pdf_object_write:nn} \Arg{object} \Arg{content} % \end{syntax} % Writes the \meta{content} as content of the \meta{object}. Depending on the % \meta{type} declared for the object, the format required for the % \meta{data} will vary % \begin{itemize} % \item[\texttt{array}] A space-separated list of values % \item[\texttt{dict}] Key--value pairs in the form % \texttt{/\meta{key} \meta{value}} % \item[\texttt{fstream}] Two brace groups: \meta{file name} and % \meta{file content} % \item[\texttt{stream}] Two brace groups: \meta{attributes (dictionary)} % and \meta{stream contents} % \end{itemize} % \end{function} % % \begin{function}[EXP, added = 2019-06-02]{\pdf_object_ref:n} % \begin{syntax} % \cs{pdf_object_ref:n} \Arg{object} % \end{syntax} % Inserts the appropriate information to reference the \meta{object} % in for example page resource allocation % \end{function} % % \begin{function}[added = 2019-06-02] % {\pdf_object_now:nn, \pdf_object_now:nx} % \begin{syntax} % \cs{pdf_object_now:nn} \Arg{type} \Arg{content} % \end{syntax} % Writes the \meta{content} as content of an anonymous object. Depending on the % \meta{type}, the format required for the \meta{data} will vary % \begin{itemize} % \item[\texttt{array}] A space-separated list of values % \item[\texttt{dict}] Key--value pairs in the form % \texttt{/\meta{key} \meta{value}} % \item[\texttt{fstream}] Two brace groups: \meta{file name} and % \meta{file content} % \item[\texttt{stream}] Two brace groups: \meta{attributes (dictionary)} % and \meta{stream contents} % \end{itemize} % \end{function} % % \begin{function}[EXP, added = 2019-06-02]{\pdf_object_last:} % \begin{syntax} % \cs{pdf_object_last:} % \end{syntax} % Inserts the appropriate information to reference the last \meta{object} % created. This is particularly useful for anonymous objects. % \end{function} % % \subsection{Version} % % \begin{function}[pTF, EXP, added = 2019-06-02]{\pdf_version_compare:Nn} % \begin{syntax} % \cs{pdf_version_compare:NnTF} \meta{comparator} \Arg{version} \Arg{true code} \Arg{false code} % \end{syntax} % Compares the version of the PDF being created with the \meta{version} % string specified, using the \meta{comparator}. Either the \meta{true code} % or \meta{false code} will be left in the output stream. % \end{function} % % \begin{function}[added = 2019-06-02] % {\pdf_version_gset:n, \pdf_version_min_gset:n} % \begin{syntax} % \cs{pdf_version_gset:n} \Arg{version} % \end{syntax} % Sets the \meta{version} of the PDF being created. The |min| version will % not alter the output version unless it is currently lower than the % \meta{version} requested. % % This function may only be used up to the point where the PDF file is % initialised. % \end{function} % % \begin{function}[EXP, added = 2019-06-02] % {\pdf_version:, \pdf_version_major:, \pdf_version_minor:} % \begin{syntax} % \cs{pdf_version:} % \end{syntax} % Expands to the currently-active PDF version. % \end{function} % % \subsection{Compression} % % \begin{function}[added = 2019-06-02]{\pdf_uncompress:} % \begin{syntax} % \cs{pdf_uncompress:} % \end{syntax} % Disables any compression of the PDF, where possible. % % This function may only be used up to the point where the PDF file is % initialised. % \end{function} % % \end{documentation} % % \begin{implementation} % % \section{\pkg{l3pdf} implementation} % % \begin{macrocode} %<*initex|package> % \end{macrocode} % % \begin{macrocode} %<@@=pdf> % \end{macrocode} % % \begin{macrocode} %<*package> \ProvidesExplPackage{l3pdf}{2020-05-18}{} {L3 Experimental core PDF support} % % \end{macrocode} % % \begin{variable}{\s_@@_stop} % Internal scan marks. % \begin{macrocode} \scan_new:N \s_@@_stop % \end{macrocode} % \end{variable} % % \begin{variable}{\g_@@_init_bool} % A flag so we have some chance of avoiding setting things we are not % allowed to. % \begin{macrocode} \bool_new:N \g_@@_init_bool %<*package> \cs_if_exist:NT \documentclass { \AtBeginDocument { \bool_gset_true:N \g_@@_init_bool } } % % \end{macrocode} % \end{variable} % % \subsection{Compression} % % \begin{macro}{\pdf_uncompress:} % Simple to do. % \begin{macrocode} \cs_new_protected:Npn \pdf_uncompress: { \bool_if:NF \g_@@_init_bool { \@@_backend_compresslevel:n { 0 } \@@_backend_compress_objects:n { \c_false_bool } } } % \end{macrocode} % \end{macro} % % \subsection{Objects} % % \begin{macro}{\pdf_object_new:nn, \pdf_object_write:nn, \pdf_object_write:nx} % \begin{macro}[pTF]{\pdf_object_if_exist:n} % \begin{macro}{\pdf_object_ref:n} % \begin{macro}{\pdf_object_now:nn, \pdf_object_now:nx} % \begin{macro}{\pdf_object_last:} % Simple to do. % \begin{macrocode} \cs_new_protected:Npn \pdf_object_new:nn #1#2 { \@@_backend_object_new:nn {#1} {#2} } \prg_new_conditional:Npnn \pdf_object_if_exist:n #1 { p , T , F , TF } { \int_if_exist:cTF { c__pdf_backend_object_ \tl_to_str:n {#1} _int } { \prg_return_true: } { \prg_return_false:} } \cs_new_protected:Npn \pdf_object_write:nn #1#2 { \@@_backend_object_write:nn {#1} {#2} } \cs_generate_variant:Nn \pdf_object_write:nn { nx } \cs_new:Npn \pdf_object_ref:n #1 { \@@_backend_object_ref:n {#1} } \cs_new_protected:Npn \pdf_object_now:nn #1#2 { \@@_backend_object_now:nn {#1} {#2} } \cs_generate_variant:Nn \pdf_object_now:nn { nx } \cs_new:Npn \pdf_object_last: { \@@_backend_object_last: } % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % % \subsection{Version} % % \begin{macro}{\pdf_version_compare:Nn} % \begin{macro} % { % @@_version_compare_=:w , % @@_version_compare_<:w , % @@_version_compare_>:w % } % \begin{macrocode} % To compare version, we need to split the given value then deal with both % major and minor version \prg_new_conditional:Npnn \pdf_version_compare:Nn #1#2 { p , T , F , TF } { \use:c { @@_version_compare_ #1 :w } #2 . . \s_@@_stop } \cs_new:cpn { @@_version_compare_=:w } #1 . #2 . #3 \s_@@_stop { \bool_lazy_and:nnTF { \int_compare_p:nNn \@@_backend_version_major: = {#1} } { \int_compare_p:nNn \@@_backend_version_minor: = {#2} } { \prg_return_true: } { \prg_return_false: } } \cs_new:cpn { @@_version_compare_<:w } #1 . #2 . #3 \s_@@_stop { \bool_lazy_or:nnTF { \int_compare_p:nNn \@@_backend_version_major: < {#1} } { \bool_lazy_and_p:nn { \int_compare_p:nNn \@@_backend_version_major: = {#1} } { \int_compare_p:nNn \@@_backend_version_minor: < {#2} } } { \prg_return_true: } { \prg_return_false: } } \cs_new:cpn { @@_version_compare_>:w } #1 . #2 . #3 \s_@@_stop { \bool_lazy_or:nnTF { \int_compare_p:nNn \@@_backend_version_major: > {#1} } { \bool_lazy_and_p:nn { \int_compare_p:nNn \@@_backend_version_major: = {#1} } { \int_compare_p:nNn \@@_backend_version_minor: > {#2} } } { \prg_return_true: } { \prg_return_false: } } % \end{macrocode} % \end{macro} % \end{macro} % % \begin{macro}{\pdf_version_gset:n, \pdf_version_min_gset:n} % \begin{macro}{\@@_version_gset:w} % Split the version and set. % \begin{macrocode} \cs_new_protected:Npn \pdf_version_gset:n #1 { \@@_version_gset:w #1 . . \s_@@_stop } \cs_new_protected:Npn \pdf_version_min_gset:n #1 { \pdf_version_compare:NnT < {#1} { \@@_version_gset:w #1 . . \s_@@_stop } } \cs_new_protected:Npn \@@_version_gset:w #1 . #2 . #3\s_@@_stop { \bool_if:NF \g_@@_init_bool { \@@_backend_version_major_gset:n {#1} \@@_backend_version_minor_gset:n {#2} } } % \end{macrocode} % \end{macro} % \end{macro} % % \begin{macro}[EXP]{\pdf_version:, \pdf_version_major:, \pdf_version_minor:} % Wrappers. % \begin{macrocode} \cs_new:Npn \pdf_version: { \@@_backend_version_major: . \@@_backend_version_minor: } \cs_new:Npn \pdf_version_major: { \@@_backend_version_major: } \cs_new:Npn \pdf_version_minor: { \@@_backend_version_minor: } % \end{macrocode} % \end{macro} % % \begin{macrocode} % % \end{macrocode} % % \end{implementation} % % \PrintIndex