summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Master/texmf-dist/doc/latex/ocgx2/ChangeLog6
-rw-r--r--Master/texmf-dist/doc/latex/ocgx2/README.txt97
-rw-r--r--Master/texmf-dist/tex/latex/ocgx2/ocgbase.sty30
-rw-r--r--Master/texmf-dist/tex/latex/ocgx2/ocgx2.sty347
4 files changed, 396 insertions, 84 deletions
diff --git a/Master/texmf-dist/doc/latex/ocgx2/ChangeLog b/Master/texmf-dist/doc/latex/ocgx2/ChangeLog
index 9fe8420a144..db7e8bbe97d 100644
--- a/Master/texmf-dist/doc/latex/ocgx2/ChangeLog
+++ b/Master/texmf-dist/doc/latex/ocgx2/ChangeLog
@@ -1,3 +1,9 @@
+2019-05-24
+ * v0.41: ocgx2.sty
+ * v0.15: ocgbase.sty
+ * new: `ocmd' environment (PDF Optional content membership dictionary)
+ * fix: passing driver options to expl3
+
2019-01-02
* v0.40: ocgx2.sty
* fix: merge request incorporated (latex3 end-of-2018 deprecations)
diff --git a/Master/texmf-dist/doc/latex/ocgx2/README.txt b/Master/texmf-dist/doc/latex/ocgx2/README.txt
index e1788656734..87ef4e555ef 100644
--- a/Master/texmf-dist/doc/latex/ocgx2/README.txt
+++ b/Master/texmf-dist/doc/latex/ocgx2/README.txt
@@ -24,15 +24,17 @@ packages and adds support for all known engines and back-ends including
To enable dvipdfmx support, pass `dvipdfmx' globally as a class option.
Also, it adds some minor improvements and bug fixes, such as package
-options, remembering option settings of re-opened ocgs, correct behaviour
+options, remembering option settings of re-opened OCGs, correct behaviour
of layer switching links that were themselves placed on layers, correct
-listing of (nested) ocgs in the layers tab of PDF viewers, compatibility
+listing of (nested) OCGs in the layers tab of PDF viewers, compatibility
with the `animate' and `media9' packages.
* New features:
+ PDF layers extending over page breaks
- + grouping PDF layers into Radio Button Groups
+ + OCMDs (Optional Content Membership Dictionaries) for creating layers
+ with complex visibility dependency
+ + grouping OCGs into Radio Button Groups
+ additional keys for the TikZ interface of package `ocgx'
+ re-implementing `hyperref's `ocgcolorlinks' option for creating
OCG coloured links, which are printed on paper in the default
@@ -43,11 +45,17 @@ with the `animate' and `media9' packages.
2. Usage
========
-\usepackage[<options>]{ocgx2}
+ \usepackage[<options>]{ocgx2}
-\begin{ocg}[<options>]{<layer name>}{<layer id>}{<initial visibility>}
- ... material to be put on a PDF layer ...
-\end{ocg}
+ \begin{ocg}[<options>]{<layer name>}{<OCG id>}{<initial visibility>}
+ ... material to be put on a PDF layer ...
+ \end{ocg}
+
+ \begin{ocmd}[<OCMD id>]{[<visibility policy>][,<visibility expression>]}
+ ... material to be put on a PDF layer ...
+ visibility calculated by <visibility expression> (Boolean expression) from
+ other OCGs visibility, or according to <visibility policy>
+ \end{ocmd}
With <initial visibility> = ( on | true | 1 ) | ( off | false | 0 )
@@ -73,19 +81,72 @@ of the PDF viewer, automatically hides the previously visible layer.
Option `radiobtngrp' can be used repeatedly for the same OCG in order
to add the layer to more than one Radio Button Group.
-`ocg' environments can be nested and span multiple pages.
+`ocg' as well as `ocmd' environments can be nested and span multiple pages.
See the `ocg-p' manual about the environment usage and the meaning of
the remaining options:
texdoc ocg-p
-Clickable links for switching PDF layer visibility are created with:
- \switchocg[<trigger>]{<layer IDs to toggle, space separated>}{<link text>}
- \showocg[<trigger>]{<layer IDs to switch ON, space separated>}{<link text>}
- \hideocg[<trigger>]{<layer IDs to switch OFF, space separated>}{<link text>}
- \actionsocg[<trigger>]{<IDs to toggle>}{<IDs to switch ON>}{<IDs to switch OFF>}{<link text>}
+3. The `ocmd' environment (Optional Content Membership Dictionary)
+==================================================================
+
+ \begin{ocmd}[<OCMD id>]{[<visibility policy>][,<visibility expression>]}
+ ... material to be put on a PDF layer ...
+ \end{ocmd}
+
+This environment creates a PDF layer whose visibility is determined by the
+current visibilities of other OCGs in the document according to at most one
+visibility policy plus at most one visibility expression. If both are given
+(with a comma in between) `<visibility expression>' takes precedence over
+`<visibility policy>', but the latter may serve as a fallback in older PDF
+viewers.
+
+`<OCMD id>' is an optional identifier which can be used to re-open the same
+layer with the same visibility setting at another place further down in the
+document.
+
+A `<visibility policy>' can be _one_ of
+
+ \AllOn{<OCG id 1>, <OCG id 2>, ...}
+ \AnyOn{<OCG id 1>, <OCG id 2>, ...}
+ \AnyOff{<OCG id 1>, <OCG id 2>, ...}
+ \AllOff{<OCG id 1>, <OCG id 2>, ...}
+
+All four directives take a list of OCG ids from wich the OCMD visibility is
+calculated. If the condition represented by the policy is met, the content
+associated with the OCMD is shown. The listed OCGs can be defined anywhere in
+the document. These directives can neither be combined nor nested in order to
+define the policy. Thus, a visibility policy has limited capabilities.
+
+A `<visibility expression>' is much more flexible than a policy. Arbitrarily
+complex visibility relationships can be formulated, based on the Boolean
+functions
+
+ \And{<item a>, <item b>, ...}
+ \Or{<item i>, <item j>, ...}
+ \Not{<item n>}
+
+In the argument list, items represent OCG ids and nested Boolean
+functions. As nesting of the three functions is possible, any thinkable
+visibility relationship can be defined. Note that `\Not{...}' accepts only one
+item, either an OCG id or a nested function. Also note that Boolean functions
+and policy directives cannot be intermixed.
+
+As a trivial example, the visibility expression equivalent of the policy
+directive `\AllOff{...}' is written as `\Not{ \Or{ ... } }'.
+
+
+4. Clickable links for switching PDF layer visibility
+=====================================================
+
+The available commands are
+
+ \switchocg[<trigger>]{<OCG ids to toggle, space separated>}{<link text>}
+ \showocg[<trigger>]{<OCG ids to switch ON, space separated>}{<link text>}
+ \hideocg[<trigger>]{<OCG ids to switch OFF, space separated>}{<link text>}
+ \actionsocg[<trigger>]{<ids to toggle>}{<ids to switch ON>}{<ids to switch OFF>}{<link text>}
For details about their usage, read the `ocgx' package manual:
@@ -98,16 +159,16 @@ the commands listed above. Choose one of
onmousenter, onmouseexit, onmousedown, onmouseup, onmouseall
for <trigger>. In order to listen to more than one mouse event, use
-`onmouseall'. Layer IDs in the mandatory argument(s) must then be grouped with
+`onmouseall'. Layer ids in the mandatory argument(s) must then be grouped with
commas as follows:
<mouse-enter group>, <mouse-exit group>, <mouse-down group>, <mouse-up group>
Any of these groups may be left empty in order to configure only some
-mouse triggers. Inside the groups, layer IDs are separated by space.
+mouse triggers. Inside the groups, OCG ids are separated by space.
-3. Package option `ocgcolorlinks'
+5. Package option `ocgcolorlinks'
=================================
Is a re-implementation of the same `hyperref' option for creating OCG-
@@ -133,7 +194,7 @@ For example:
\ocglinkprotect{\includegraphics{ctan-lion}}!}
-4. Usage with TikZ
+5. Usage with TikZ
==================
`ocgx2' uses code from file `tikzlibraryocgx.code.tex' by P. Gaborit to
@@ -157,7 +218,7 @@ their usage:
The key `/tikz/ocg/opts' was added to the list in section
`How to add TikZ scopes into OCGs' in the `ocgx' manual:
- /tikz/ocg/opts={<ocg options>}
+ /tikz/ocg/opts={<OCG options>}
It allows passing `ocg'-environment options (`viewocg', `printocg', `exportocg',
`showingui', `radiobtngrp') to the TikZ scope.
diff --git a/Master/texmf-dist/tex/latex/ocgx2/ocgbase.sty b/Master/texmf-dist/tex/latex/ocgx2/ocgbase.sty
index b0113bf270a..d30786435dd 100644
--- a/Master/texmf-dist/tex/latex/ocgx2/ocgbase.sty
+++ b/Master/texmf-dist/tex/latex/ocgx2/ocgbase.sty
@@ -92,11 +92,19 @@
%
% The Current Maintainer of this work is A. Grahn.
-\RequirePackage{expl3}
+%process non-detectable dvipdfmx driver for passing to expl3
+\RequirePackage{xkeyval}
+\DeclareOptionX{dvipdfmx}{%
+ \PassOptionsToPackage{driver=dvipdfmx}{expl3}
+ \PassOptionsToPackage{dvipdfmx}{pdfbase}
+}
+\DeclareOptionX*{}\ProcessOptionsX*\relax %allow anything as an option
+
\RequirePackage{pdfbase}
+\RequirePackage{expl3}
-\def\g@ocgbase@date@tl{2018/06/07}
-\def\g@ocgbase@version@tl{0.14}
+\def\g@ocgbase@date@tl{2019/05/24}
+\def\g@ocgbase@version@tl{0.15}
\ProvidesExplPackage{ocgbase}{\g@ocgbase@date@tl}{\g@ocgbase@version@tl}
{support package for ocgx2.sty}
@@ -141,7 +149,7 @@
%generate RBGroups entry (radio button groups)
\tl_new:N\l_ocgbase_rbtn_groups_tl
\seq_map_inline:Nn\g_ocgbase_rbtn_groups_seq{
- \int_compare:nT{\seq_count:c{g_ocgbase_rbtn_group_#1_seq}>\c_one}{
+ \int_compare:nT{\seq_count:c{g_ocgbase_rbtn_group_#1_seq}>\c_one_int}{
\tl_put_right:Nx\l_ocgbase_rbtn_groups_tl{
~[\seq_use:cn{g_ocgbase_rbtn_group_#1_seq}{~}]
}
@@ -174,14 +182,14 @@
%macro for inserting new OCG object
\cs_new_protected_nopar:Nn\ocgbase_new_ocg:nnn{
\pbs_pdfobj:nnn{}{dict}{
- /Type/OCG/Name~(#1)~\str_if_eq_x:nnF{#2}{}{/Usage<<#2>>}
+ /Type/OCG/Name~(#1)~\str_if_eq:eeF{#2}{}{/Usage<<#2>>}
}
\tl_gput_right:Nx\g_ocgbase_ocgs_tl{~\pbs_pdflastobj:}
\bool_if:nT{
- \str_if_eq_x_p:nn{#3}{0} ||
- \str_if_eq_x_p:nn{#3}{off} ||
- \str_if_eq_x_p:nn{#3}{false} ||
- \str_if_eq_x_p:nn{#3}{invisible}
+ \str_if_eq_p:ee{#3}{0} ||
+ \str_if_eq_p:ee{#3}{off} ||
+ \str_if_eq_p:ee{#3}{false} ||
+ \str_if_eq_p:ee{#3}{invisible}
}{
\ocgbase_add_to_off_list:n{\pbs_pdflastobj:}
}
@@ -236,7 +244,7 @@
\cs_new_protected:Nn\ocgbase_tree_node_end:{
\seq_get:NN\g_ocgbase_tree_nd_stack_seq\l_tempa_tl
\seq_get:NN\g_ocgbase_tree_ocg_stack_seq\l_tempb_tl
- \str_if_eq_x:nnT{
+ \str_if_eq:eeT{
\cs_if_exist_use:c{g_ocgbase_nd_\l_tempa_tl _ocg_tl}
}{
\l_tempb_tl
@@ -252,7 +260,7 @@
% the node id of the sibling found is returned in arg #1
\cs_new:Nn\ocgbase_traverse_siblings:NN{
% #1: current node (in/out), #2: OCG obj (in/out)
- \str_if_eq_x:nnF{#2}{\tl_use:c{g_ocgbase_nd_#1_ocg_tl}}{
+ \str_if_eq:eeF{#2}{\tl_use:c{g_ocgbase_nd_#1_ocg_tl}}{
\tl_if_exist:cTF{g_ocgbase_nd_#1_sbl_tl}{
\tl_set:Nv#1{g_ocgbase_nd_#1_sbl_tl}
\ocgbase_traverse_siblings:NN#1#2
diff --git a/Master/texmf-dist/tex/latex/ocgx2/ocgx2.sty b/Master/texmf-dist/tex/latex/ocgx2/ocgx2.sty
index 72b51ce1940..404d849b962 100644
--- a/Master/texmf-dist/tex/latex/ocgx2/ocgx2.sty
+++ b/Master/texmf-dist/tex/latex/ocgx2/ocgx2.sty
@@ -15,7 +15,9 @@
%
% With ocgx2, PDF layers may extend across page breaks.
%
-% Adds some minor improvements, such as package options, remembering option
+% ocgx2 implements OCMDs (optional content membership dictionaries)
+%
+% Adds some minor improvements, such as package options, remembering option.
% settings of reopened ocgs, correct behaviour of ocg switching links that were
% themselves placed on layers, compatibility with the animate and media9
% packages.
@@ -38,8 +40,8 @@
\RequirePackage{xparse}
\RequirePackage{l3keys2e}
-\def\g@ocgxii@date@tl{2019/01/02}
-\def\g@ocgxii@version@tl{0.40}
+\def\g@ocgxii@date@tl{2019/05/24}
+\def\g@ocgxii@version@tl{0.41}
\ProvidesExplPackage{ocgx2}{\g@ocgxii@date@tl}{\g@ocgxii@version@tl}
{ports `ocgx' functionality to dvips+ps2pdf, xelatex and dvipdfmx}
@@ -60,6 +62,8 @@
}
}
+\msg_set:nnn{ocgx2}{generic~msg}{#1\\#2}
+
\msg_set:nnn{ocgx2}{missing~package}{
Package~`#1'~must~be~loaded~before~ocgx2.\\\\
Put\\\\
@@ -122,8 +126,8 @@
showingui .choices:nn = {true,false,always,never,iffirstuse}{
\bool_if:nTF{
- \str_if_eq_x_p:nn{#1}{false} ||
- \str_if_eq_x_p:nn{#1}{never}
+ \str_if_eq_p:ee{#1}{false} ||
+ \str_if_eq_p:ee{#1}{never}
}{
\bool_gset_false:N\g_ocgxii_showingui_bool
}{
@@ -159,42 +163,43 @@
%re-implement ocg-p's `ocg' environment
\DeclareDocumentEnvironment{ocg}{O{}mmm}{
- \ocgxii_beginocg:nnnn{#1}{#2}{#3}{#4}
+ \ocgxii_begin_ocg:nnnn{#1}{#2}{#3}{#4}
}{
- \ocgxii_endocg:
+ \ocgxii_end_ocg:
}
-\cs_new_protected_nopar:Nn\ocgxii_beginocg:nnnn{
+\cs_new_protected_nopar:Nn\ocgxii_begin_ocg:nnnn{
\group_begin:
\ocgxii_reset_cmd_opts: % ... to the user-set package options
- \tl_if_exist:cTF{ocgxii@#3}{ %re-open existing layer
- \tl_set:Nx\l_tempa_tl{\tl_use:c{ocgxii@#3.opts},#1}
- \tl_gset:cx{ocgxii@#3.opts}{\l_tempa_tl} %new options appended
- \keys_set:nV{ocgx2/user}\l_tempa_tl
+ \tl_set:Nx\l_ocgxii_argiv_tl{\tl_trim_spaces:n{#4}}
+ \tl_if_exist:cTF{ocgxii_ocg_#3}{ %re-open existing layer
+ \tl_set:Nx\l_tempa_tl{\tl_use:c{ocgxii_ocg_#3.opts},#1}
+ \tl_gset:cx{ocgxii_ocg_#3.opts}{\l_tempa_tl} %new options appended
+ \keys_set:nV{ocgx2/ocgenv}\l_tempa_tl
\bool_if:nTF{ %initial visibility
- \str_if_eq_x_p:nn{#4}{1} ||
- \str_if_eq_x_p:nn{#4}{on} ||
- \str_if_eq_x_p:nn{#4}{true}
+ \str_if_eq_p:ee{l_ocgxii_argiv_tl}{1} ||
+ \str_if_eq_p:ee{l_ocgxii_argiv_tl}{on} ||
+ \str_if_eq_p:ee{l_ocgxii_argiv_tl}{true}
}{
- \ocgbase_del_from_off_list:n{\tl_use:c{ocgxii@#3}}
+ \ocgbase_del_from_off_list:n{\tl_use:c{ocgxii_ocg_#3}}
}{
- \ocgbase_add_to_off_list:n{\tl_use:c{ocgxii@#3}}
+ \ocgbase_add_to_off_list:n{\tl_use:c{ocgxii_ocg_#3}}
}
}{
\tl_set:Nx\l_tempa_tl{#1}
- \tl_gset:cx{ocgxii@#3.opts}{\l_tempa_tl}
- \keys_set:nV{ocgx2/user}\l_tempa_tl
+ \tl_gset:cx{ocgxii_ocg_#3.opts}{\l_tempa_tl}
+ \keys_set:nV{ocgx2/ocgenv}\l_tempa_tl
\ocgbase_new_ocg:nnn{#2}{
\l_ocgxii_view_tl\l_ocgxii_print_tl\l_ocgxii_export_tl
- }{#4}
- \tl_gset:cx{ocgxii@#3}{\ocgbase_last_ocg:}
+ }{\l_ocgxii_argiv_tl}
+ \tl_gset:cx{ocgxii_ocg_#3}{\ocgbase_last_ocg:}
\iow_now:Nx\@mainaux{
\token_to_str:N\ocgxii@newkey{ocgx2.ocg.#3}{\ocgbase_last_ocg:}
}
}
\bool_if:nT{
!\cs_if_exist:cTF{ocgx2.ocg.#3}{
- \str_if_eq_x_p:nn{\tl_use:c{ocgx2.ocg.#3}}{\tl_use:c{ocgxii@#3}}
+ \str_if_eq_p:ee{\tl_use:c{ocgx2.ocg.#3}}{\tl_use:c{ocgxii_ocg_#3}}
}{
\c_false_bool
}
@@ -204,22 +209,22 @@
\AtEndDocument{\msg_warning:nn{ocgx2}{rerun}}
}
}
- \tl_gset:cx{ocgx2.ocg.#3}{\tl_use:c{ocgxii@#3}}
+ \tl_gset:cx{ocgx2.ocg.#3}{\tl_use:c{ocgxii_ocg_#3}}
\seq_map_inline:Nn\l_ocgxii_rbgrps_seq{% process list of radio btn groups
- \ocgbase_add_ocg_to_radiobtn_grp:nn{##1}{\tl_use:c{ocgxii@#3}}
+ \ocgbase_add_ocg_to_radiobtn_grp:nn{##1}{\tl_use:c{ocgxii_ocg_#3}}
}
- \ocgbase_open_stack_push:n{\tl_use:c{ocgxii@#3}}
+ \ocgbase_open_stack_push:n{\tl_use:c{ocgxii_ocg_#3}}
\ocgxii_stack_shipout:NN\ocgxii@ocg@stack@on@page\g_ocgbase_open_stack_seq
% insert OCG into Order tree
\bool_if:NT\l_ocgxii_showingui_bool{
- \ocgbase_tree_node_begin:n{\tl_use:c{ocgxii@#3}}
+ \ocgbase_tree_node_begin:n{\tl_use:c{ocgxii_ocg_#3}}
}
\group_end:
- \ocgbase_oc_bdc:n{\tl_use:c{ocgxii@#3}}
+ \ocgbase_oc_bdc:n{\tl_use:c{ocgxii_ocg_#3}}
\ignorespaces
}
-\cs_new_protected_nopar:Nn\ocgxii_endocg:{
+\cs_new_protected_nopar:Nn\ocgxii_end_ocg:{
\unskip
\ocgbase_oc_emc:
\ocgbase_tree_node_end:
@@ -227,6 +232,235 @@
\ocgxii_stack_shipout:NN\ocgxii@ocg@stack@on@page\g_ocgbase_open_stack_seq
}
+% OCMD implementation
+\DeclareDocumentEnvironment{ocmd}{O{}m}{
+ \ocgxii_begin_ocmd:nn{#1}{#2}
+}{
+ \ocgxii_end_ocmd:
+}
+
+\cs_new_protected_nopar:Nn\ocgxii_begin_ocmd:nn{ % #1: id,
+ \group_begin: % #2: visib. expression or policy
+ \bool_if:nF{ %do nothing if we re-open existing ocmd
+ \tl_if_blank:oTF{#1}{
+ \c_false_bool
+ }{
+ \tl_if_exist_p:c{ocgxii_ocmd_#1}
+ }
+ }{ %new ocmd
+ \ocgxii_read_ocmd_visbility:nN{#2}\l_ocgxii_ocmd_visibility_tl
+ \pbs_pdfobj:nnn{}{dict}{
+ /Type/OCMD\l_ocgxii_ocmd_visibility_tl
+ }
+ \tl_gset:cx{ocgxii_ocmd_#1}{\pbs_pdflastobj:}
+ }
+ \ocgbase_open_stack_push:n{\tl_use:c{ocgxii_ocmd_#1}}
+ \ocgxii_stack_shipout:NN\ocgxii@ocg@stack@on@page\g_ocgbase_open_stack_seq
+ \group_end:
+ \ocgbase_oc_bdc:n{\tl_use:c{ocgxii_ocmd_#1}}
+ \ignorespaces
+}
+\cs_new_protected_nopar:Nn\ocgxii_end_ocmd:{
+ \unskip
+ \ocgbase_oc_emc:
+ \ocgbase_open_stack_pop:N\l_trash_tl
+ \ocgxii_stack_shipout:NN\ocgxii@ocg@stack@on@page\g_ocgbase_open_stack_seq
+}
+
+%visibility expressions
+\cs_new_protected_nopar:Nn\ocgxii_read_ocmd_visbility:nN{
+ \int_zero:N\l_ocgxii_ve_cnt_int
+ \int_zero:N\l_ocgxii_vp_cnt_int
+ \tl_clear_new:N#2
+ \clist_map_inline:nn{#1}{\ocgxii_omcd_visib_map_func:nN{##1}#2}
+}
+\cs_new_protected_nopar:Nn\ocgxii_omcd_visib_map_func:nN{
+ \cs_set_eq:NN\Not\ocgxii_ve_check:n
+ \cs_set_eq:NN\And\ocgxii_ve_check:n
+ \cs_set_eq:NN\Or \ocgxii_ve_check:n
+ \cs_set_eq:NN\AllOn \ocgxii_vp_check:n
+ \cs_set_eq:NN\AnyOn \ocgxii_vp_check:n
+ \cs_set_eq:NN\AnyOff\ocgxii_vp_check:n
+ \cs_set_eq:NN\AllOff\ocgxii_vp_check:n
+ \tl_if_exist:cTF{ocgx2.ocg.#1}{
+ \msg_error:nnxx{ocgx2}{generic~msg}{
+ OCG~ids~cannot~be~directly~used~in~the~visibility~argument~of~an~
+ `ocmd'~environment.
+ }{\g_ocgxii_help_msg_tl}
+ }{
+ \tl_if_exist:cTF{ocgxii_#1}{
+ \str_case_e:nn{\tl_use:c{ocgxii_#1}}{
+ {VisExpr}{
+ \int_incr:N\l_ocgxii_ve_cnt_int
+ \int_compare:nNnTF{\l_ocgxii_ve_cnt_int}>{1}{
+ \msg_error:nnnn{ocgx2}{generic~msg}{
+ More~than~one~visibility~expression~passed~to~the~`ocmd'~
+ environment.
+ }{
+ At~most~one~visibility~expression~is~allowed.~A~visibility~
+ expression~is~a~boolean~expression~built~by~nesting~any~number~of~
+ \And{...},~\Or{...},~\Not{...}~commands.
+ }
+ }{
+ \ocgxii_ve_start:nN{#1}#2
+ }
+ }
+ {VisPol}{
+ \int_incr:N\l_ocgxii_vp_cnt_int
+ \int_compare:nNnTF{\l_ocgxii_vp_cnt_int}>{1}{
+ \msg_error:nnnn{ocgx2}{generic~msg}{
+ More~than~one~visibility~policy~passed~to~the~`ocmd'~environment.
+ }{
+ At~most~one~visibility~policy~out~of~\AllOn{...},~\AnyOn{...},~
+ \AnyOff{...},~\AllOff{...}~is~allowed.~Any~number~of~OCG~IDs,~
+ separated~by~commas,~may~be~passed~as~arguments~to~these~
+ commands,~but~commands~may~not~be~nested.~For~complex~visibilty~
+ relations,~consider~using~a~visibility~expression.
+ }
+ }{
+ \ocgxii_vp_start:nN{#1}#2
+ }
+ }
+ }
+ }{
+ \msg_error:nnxx{ocgx2}{generic~msg}{
+ The~visibility~argument~of~the~`ocmd'~environment~cannot~be~parsed.
+ }{\g_ocgxii_help_msg_tl}
+ }
+ }
+}
+\tl_set:Nn\g_ocgxii_help_msg_tl{
+ At~most~one~visibility~policy~and,~separated~by~a~comma,~at~most~one~
+ visibility~expression~may~be~passed~to~the~visibility~argument.~A~visibility~
+ policy~is~defined~by~one~of~\AllOn{...},~\AnyOn{...},~\AnyOff{...},~
+ \AllOff{...}.~A~visibility~expression~is~a~boolean~expression~built~by~
+ nesting~any~number~of~\And{...},~\Or{...},~\Not{...}~commands.~If~both~are~
+ provided,~the~visibility~expression~takes~precedence~over~the~policy,~but~the~
+ latter~may~be~used~as~fallback~by~non-conforming~PDF~viewers.
+}
+\int_new:N\l_ocgxii_vp_cnt_int %number of visib. policies
+\int_new:N\l_ocgxii_ve_cnt_int %number of visib. expressions
+\cs_new_protected_nopar:Nn\ocgxii_vp_start:nN{
+ \cs_set_eq:NN\AllOn \ocgxii_vp_allon:nN
+ \cs_set_eq:NN\AnyOn \ocgxii_vp_anyon:nN
+ \cs_set_eq:NN\AnyOff\ocgxii_vp_anyoff:nN
+ \cs_set_eq:NN\AllOff\ocgxii_vp_alloff:nN
+ #1#2
+}
+\cs_new_protected_nopar:Nn\ocgxii_vp_allon:nN{
+ \tl_put_right:Nx#2{/P/AllOn/OCGs~\g_ocgxii_left_bracket_tl}
+ \clist_map_inline:nn{#1}{\ocgxii_vp_map_func:nN{##1}#2}
+ \tl_put_right:Nx#2{\g_ocgxii_right_bracket_tl}
+}
+\cs_new_protected_nopar:Nn\ocgxii_vp_anyon:nN{
+ \tl_gput_right:Nx#2{/P/AnyOn/OCGs~\g_ocgxii_left_bracket_tl}
+ \clist_map_inline:nn{#1}{\ocgxii_vp_map_func:nN{##1}#2}
+ \tl_gput_right:Nx#2{\g_ocgxii_right_bracket_tl}
+}
+\cs_new_protected_nopar:Nn\ocgxii_vp_anyoff:nN{
+ \tl_gput_right:Nx#2{/P/AnyOff/OCGs~\g_ocgxii_left_bracket_tl}
+ \clist_map_inline:nn{#1}{\ocgxii_vp_map_func:nN{##1}#2}
+ \tl_gput_right:Nx#2{\g_ocgxii_right_bracket_tl}
+}
+\cs_new_protected_nopar:Nn\ocgxii_vp_alloff:nN{
+ \tl_gput_right:Nx#2{/P/AllOff/OCGs~\g_ocgxii_left_bracket_tl}
+ \clist_map_inline:nn{#1}{\ocgxii_vp_map_func:nN{##1}#2}
+ \tl_gput_right:Nx#2{\g_ocgxii_right_bracket_tl}
+}
+\cs_new_protected_nopar:Nn\ocgxii_vp_map_func:nN{
+ \cs_set_eq:NN\AllOn \ocgxii_vp_check:n
+ \cs_set_eq:NN\AnyOn \ocgxii_vp_check:n
+ \cs_set_eq:NN\AnyOff\ocgxii_vp_check:n
+ \cs_set_eq:NN\AllOff\ocgxii_vp_check:n
+ \tl_if_exist:cTF{ocgx2.ocg.#1}{
+ \tl_put_right:Nx#2{~\tl_use:c{ocgx2.ocg.#1}}
+ }{
+ \tl_if_exist:cTF{ocgxii_#1}{
+ \str_if_eq:eeTF{\tl_use:c{ocgxii_#1}}{VisPol}{
+ \msg_error:nnxx{ocgx2}{generic~msg}{
+ Visibility~policy~commands~cannot~be~nested.~For~more~complex~
+ visibilty~relations,~consider~using~a~visibility~expression.
+ }{\g_ocgxii_help_msg_tl}
+ }{
+ \msg_error:nnxx{ocgx2}{generic~msg}{
+ Visibility~policy~and~expression~commands~cannot~be~mixed.
+ }{\g_ocgxii_help_msg_tl}
+ }
+ }{
+ \msg_warning:nnx{ocgx2}{undefined~OCG}{#1}
+ \tl_if_exist:NF\g_ocgxii_refundefwarned_tl{
+ \tl_new:N\g_ocgxii_refundefwarned_tl
+ \AtEndDocument{\msg_warning:nn{ocgx2}{undefined~OCGs}}
+ }
+ }
+ }
+}
+\cs_new_protected_nopar:Nn\ocgxii_ve_start:nN{
+ \tl_put_right:Nx#2{/VE~}
+ \cs_set_eq:NN\Not\ocgxii_ve_not:nN
+ \cs_set_eq:NN\And\ocgxii_ve_and:nN
+ \cs_set_eq:NN\Or \ocgxii_ve_or:nN
+ #1#2
+}
+\cs_new_protected_nopar:Nn\ocgxii_ve_and:nN{
+ \tl_put_right:Nx#2{\g_ocgxii_left_bracket_tl/And}
+ \clist_map_inline:nn{#1}{\ocgxii_ve_map_func:nN{##1}#2}
+ \tl_put_right:Nx#2{\g_ocgxii_right_bracket_tl}
+}
+\cs_new_protected_nopar:Nn\ocgxii_ve_or:nN{
+ \tl_put_right:Nx#2{\g_ocgxii_left_bracket_tl/Or}
+ \clist_map_inline:nn{#1}{\ocgxii_ve_map_func:nN{##1}#2}
+ \tl_put_right:Nx#2{\g_ocgxii_right_bracket_tl}
+}
+\cs_new_protected_nopar:Nn\ocgxii_ve_not:nN{
+ % only one item allowed in \Not{...} argument
+ \int_compare:nNnT{\clist_count:n{#1}}>{\c_one_int}{
+ \msg_error:nnnn{ocgx2}{generic~msg}{
+ More~than~one~item~passed~to~\Not{...}.
+ }{
+ Only~one~item~is~allowed.
+ }
+ }
+ \int_compare:nNnT{\clist_count:n{#1}}={\c_one_int}{
+ \tl_put_right:Nx#2{\g_ocgxii_left_bracket_tl/Not}
+ \clist_map_inline:nn{#1}{\ocgxii_ve_map_func:nN{##1}#2}
+ \tl_put_right:Nx#2{\g_ocgxii_right_bracket_tl}
+ }
+}
+\cs_new_protected_nopar:Nn\ocgxii_ve_map_func:nN{
+ \cs_set_eq:NN\Not\ocgxii_ve_check:n
+ \cs_set_eq:NN\And\ocgxii_ve_check:n
+ \cs_set_eq:NN\Or \ocgxii_ve_check:n
+ \tl_if_exist:cTF{ocgx2.ocg.#1}{%ocg reference
+ \tl_put_right:Nx#2{~\tl_use:c{ocgx2.ocg.#1}}
+ }{
+ \tl_if_exist:cTF{ocgxii_#1}{
+ \str_if_eq:eeTF{\tl_use:c{ocgxii_#1}}{VisExpr}{
+ \cs_set_eq:NN\Not\ocgxii_ve_not:nN
+ \cs_set_eq:NN\And\ocgxii_ve_and:nN
+ \cs_set_eq:NN\Or \ocgxii_ve_or:nN
+ #1#2
+ }{
+ \msg_error:nnxx{ocgx2}{generic~msg}{
+ Visibility~policy~and~expression~commands~cannot~be~mixed.
+ }{\g_ocgxii_help_msg_tl}
+ }
+ }{
+ \msg_warning:nnx{ocgx2}{undefined~OCG}{#1}
+ \tl_if_exist:NF\g_ocgxii_refundefwarned_tl{
+ \tl_new:N\g_ocgxii_refundefwarned_tl
+ \AtEndDocument{\msg_warning:nn{ocgx2}{undefined~OCGs}}
+ }
+ }
+ }
+}
+\cs_new_protected_nopar:Nn\ocgxii_ve_check:n{VisExpr}
+\tl_set:cn{ocgxii_VisExpr}{VisExpr}
+\cs_new_protected_nopar:Nn\ocgxii_vp_check:n{VisPol}
+\tl_set:cn{ocgxii_VisPol}{VisPol}
+\tl_set:Nx\g_ocgxii_left_bracket_tl{\tl_to_str:N[}
+\tl_set:Nx\g_ocgxii_right_bracket_tl{\tl_to_str:N]}
+
\cs_new_protected_nopar:Nn\ocgxii_stack_shipout:NN{
\iow_shipout_x:Nx\@mainaux{
\token_to_str:N#1{
@@ -268,7 +502,7 @@
}
\bool_if:nT{
!\cs_if_exist:cTF{ocgx2.oldlnkcol.\int_use:N\g_ocgxii_page_int}{
- \str_if_eq_x_p:nn{
+ \str_if_eq_p:ee{
\tl_use:c{ocgx2.oldlnkcol.\int_use:N\g_ocgxii_page_int}
}{
\seq_use:cn{g_pending_lnkcols_on_\int_use:c{g_ocgxii_page_int}_seq}{,}
@@ -296,7 +530,7 @@
}
\bool_if:nT{
!\cs_if_exist:cTF{ocgx2.oldstack.\int_use:N\g_ocgxii_page_int}{
- \str_if_eq_x_p:nn{
+ \str_if_eq_p:ee{
\tl_use:c{ocgx2.oldstack.\int_use:N\g_ocgxii_page_int}
}{
\seq_use:cn{g_pending_ocgs_on_\int_use:c{g_ocgxii_page_int}_seq}{,}
@@ -338,7 +572,7 @@
\seq_gset_eq:cc{
g_pending_ocgs_on_\int_use:c{g_ocgxii_page_int}_seq
}{
- g_pending_ocgs_on_\int_eval:n{\g_ocgxii_page_int-\c_one}_seq
+ g_pending_ocgs_on_\int_eval:n{\g_ocgxii_page_int-\c_one_int}_seq
}
}
%the same for link colour stack
@@ -346,7 +580,7 @@
\seq_gset_eq:cc{
g_pending_lnkcols_on_\int_use:c{g_ocgxii_page_int}_seq
}{
- g_pending_lnkcols_on_\int_eval:n{\g_ocgxii_page_int-\c_one}_seq
+ g_pending_lnkcols_on_\int_eval:n{\g_ocgxii_page_int-\c_one_int}_seq
}
}
}
@@ -378,7 +612,7 @@
\cs_new_protected_nopar:Nn\ocgxii_ocglist_process_idlist:nn{
\ocgxii_ocglist_reset:
\tl_set:Nx\l_ocgxii_opt_tl{#1}\tl_remove_all:Nn\l_ocgxii_opt_tl{~}
- \str_case_x:nnF{\l_ocgxii_opt_tl}{
+ \str_case_e:nnF{\l_ocgxii_opt_tl}{
{onmouseup}{
\ocgxii_ocglist_build:Nn\l_ocgxii_u_list_tl{#2}
}
@@ -467,7 +701,7 @@
\tl_set_eq:NN\l_ocgxii_tohide_d_tl\l_ocgxii_d_list_tl
\tl_set_eq:NN\l_ocgxii_tohide_u_tl\l_ocgxii_u_list_tl
%any triggers apart from mouse-up?
- \str_if_eq_x:nnF{
+ \str_if_eq:eeF{
\l_ocgxii_toswitch_e_tl\l_ocgxii_toswitch_x_tl\l_ocgxii_toswitch_d_tl
\l_ocgxii_toshow_e_tl\l_ocgxii_toshow_x_tl\l_ocgxii_toshow_d_tl
\l_ocgxii_tohide_e_tl\l_ocgxii_tohide_x_tl\l_ocgxii_tohide_d_tl
@@ -488,7 +722,7 @@
/Subtype/Widget/Ff~65536/FT/Btn/BS<</W~0>>
/T~(ocgx2@\int_use:N\g_ocgxii_widcount_int)
%treat mouse-up as mouse-click --> handle through /A dictionary
- \str_if_eq_x:nnF{}{
+ \str_if_eq:eeF{}{
\l_ocgxii_toswitch_u_tl\l_ocgxii_toshow_u_tl\l_ocgxii_tohide_u_tl
}{
/A <</S/SetOCGState/State [
@@ -504,7 +738,7 @@
]>>
}
/AA <<
- %\str_if_eq_x:nnF{}{
+ %\str_if_eq:eeF{}{
% \l_ocgxii_toswitch_u_tl\l_ocgxii_toshow_u_tl\l_ocgxii_tohide_u_tl
%}{
% /U <</S/SetOCGState/State [
@@ -519,7 +753,7 @@
% }
% ]>>
%}
- \str_if_eq_x:nnF{}{ % mouse-down
+ \str_if_eq:eeF{}{ % mouse-down
\l_ocgxii_toswitch_d_tl\l_ocgxii_toshow_d_tl\l_ocgxii_tohide_d_tl
}{
/D <</S/SetOCGState/State [
@@ -534,7 +768,7 @@
}
]>>
}
- \str_if_eq_x:nnF{}{ % mouse-enter
+ \str_if_eq:eeF{}{ % mouse-enter
\l_ocgxii_toswitch_e_tl\l_ocgxii_toshow_e_tl\l_ocgxii_tohide_e_tl
}{
/E <</S/SetOCGState/State [
@@ -549,7 +783,7 @@
}
]>>
}
- \str_if_eq_x:nnF{}{ % mouse-exit
+ \str_if_eq:eeF{}{ % mouse-exit
\l_ocgxii_toswitch_x_tl\l_ocgxii_toshow_x_tl\l_ocgxii_tohide_x_tl
}{
/X <</S/SetOCGState/State [
@@ -620,7 +854,7 @@
triggerocg .choices:nn = {
onmouseenter, onmouseexit, onmousedown, onmouseup, allactions
}{
- \str_if_eq_x:nnTF{\l_keys_choice_tl}{allactions}{
+ \str_if_eq:eeTF{\l_keys_choice_tl}{allactions}{
\tl_set:Nn\l_ocgxii_trigger_tl{onmouseall}
}{
\tl_set_eq:NN\l_ocgxii_trigger_tl\l_keys_choice_tl
@@ -650,7 +884,7 @@
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\cs_new_protected:Nn\ocgxii_process_ocgref:NN{
- \str_if_eq_x:nnF{#2}{}{
+ \str_if_eq:eeF{#2}{}{
\tl_if_exist:cTF{ocgx2.ocg.#2}{
\tl_put_right:Nx#1{~\tl_use:c{ocgx2.ocg.#2}}
}{
@@ -663,8 +897,8 @@
}
}
-%command opts
-\keys_define:nn{ocgx2/user}{
+%ocg environment opts
+\keys_define:nn{ocgx2/ocgenv}{
viewocg .choice:,
viewocg / always .code:n={
\tl_set:Nn\l_ocgxii_view_tl{/View<</ViewState/ON>>}},
@@ -693,8 +927,8 @@
showingui .choices:nn = {true,false,always,never,iffirstuse}{
\bool_if:nTF{
- \str_if_eq_x_p:nn{#1}{false} ||
- \str_if_eq_x_p:nn{#1}{never}
+ \str_if_eq_p:ee{#1}{false} ||
+ \str_if_eq_p:ee{#1}{never}
}{
\bool_set_false:N\l_ocgxii_showingui_bool
}{
@@ -759,10 +993,10 @@
\cs_new_protected_nopar:Nn\ocgxii_colourlink_nobreak_end:{
\color@endgroup\hbox_set_end:
\mbox{
- \ocgbase_oc_bdc:n{\ocgxii@OCPrint}
+ \ocgbase_oc_bdc:n{\tl_use:c{ocgxii_ocg_OCPrint}}
\hbox_to_zero:n{\box_use:N\l_tmpa_box\hss}
\ocgbase_oc_emc:
- \ocgbase_oc_bdc:n{\ocgxii@OCView}
+ \ocgbase_oc_bdc:n{\tl_use:c{ocgxii_ocg_OCView}}
\group_begin:
\exp_after:wN\HyColor@UseColor\l_ocgxii_lnkcol_tl
\box_use_drop:N\l_tmpa_box
@@ -845,10 +1079,10 @@
%a tiny space char should keep empty link annots from flooding the page
% with link colour
\hbox_overlap_left:n{\ocgxii_tiny_space_char:}
- \ocgbase_oc_bdc:n{\ocgxii@OCPrint}
+ \ocgbase_oc_bdc:n{\tl_use:c{ocgxii_ocg_OCPrint}}
\pbs_literal:nn{page}{-88888~-88888~99999~99999~re~f}
\ocgbase_oc_emc:
- \ocgbase_oc_bdc:n{\ocgxii@OCView}
+ \ocgbase_oc_bdc:n{\tl_use:c{ocgxii_ocg_OCView}}
\group_begin:
\exp_after:wN\HyColor@UseColor\g_ocgxii_lnkcol_tl
\pbs_literal:nn{page}{-88888~-88888~99999~99999~re~f}
@@ -911,22 +1145,25 @@
/Print<</PrintState/OFF>>
/Export<</ExportState/OFF>>
}{on}
- \tl_gset:Nx\ocgxii@OCView{\ocgbase_last_ocg:}
- \tl_gset:cx{ocgxii@OCView.opts}{
+ \tl_gset:cx{ocgxii_ocg_OCView}{\ocgbase_last_ocg:}
+ %in case somebody wants to reopen with \begin{ocg}...
+ \tl_gset:cx{ocgxii_ocg_OCView.opts}{
showingui=never,printocg=never,exportocg=never}
\ocgbase_new_ocg:nnn{OCPrint}{
/Print<</PrintState/ON>>
/Export<</ExportState/ON>>
}{off}
- \tl_gset:Nx\ocgxii@OCPrint{\ocgbase_last_ocg:}
- \tl_gset:cx{ocgxii@OCPrint.opts}{
+ \tl_gset:cx{ocgxii_ocg_OCPrint}{\ocgbase_last_ocg:}
+ \tl_gset:cx{ocgxii_ocg_OCPrint.opts}{
showingui=never,printocg=always,exportocg=always}
\ocgxii_enable_ocglinks:
\iow_now:Nx\@mainaux{
- \token_to_str:N\ocgxii@newkey{ocgx2.ocg.OCView}{\ocgxii@OCView}
+ \token_to_str:N\ocgxii@newkey{ocgx2.ocg.OCView}{
+ \tl_use:c{ocgxii_ocg_OCView}}
}
\iow_now:Nx\@mainaux{
- \token_to_str:N\ocgxii@newkey{ocgx2.ocg.OCPrint}{\ocgxii@OCPrint}
+ \token_to_str:N\ocgxii@newkey{ocgx2.ocg.OCPrint}{
+ \tl_use:c{ocgxii_ocg_OCPrint}}
}
}
}{