%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% fixocgx.sty
%
% Copyright 2015--\today, Alexander Grahn
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% This package extends the usability of `ocgx' to all known engines including
% latex+dvips+ps2pdf, xelatex and latex+dvipdfmx.
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% This work may be distributed and/or modified under the
% conditions of the LaTeX Project Public License, either version 1.3
% of this license or (at your option) any later version.
% The latest version of this license is in
%
http://mirrors.ctan.org/help/Catalogue/licenses.lppl.html
% and version 1.3 or later is part of all distributions of LaTeX
% version 2005/12/01 or later.
%
% This work has the LPPL maintenance status `maintained'.
%
% The Current Maintainer of this work is A. Grahn.
\RequirePackage{xparse}
\RequirePackage{atenddvi}
\RequirePackage{ifpdf}
%prevent ocg-p from inserting PS specials in dvipdfmx mode
\ifpdf\else
\DeclareOption{dvipdfmx}{\@ocgp@ifpsfalse}
\ProcessOptions\relax
\fi
\@ifpackageloaded{ocgx}{}{
\PackageError{fixocgx}{%
Package `fixocgx' must be loaded /after/ one of\MessageBreak
\space\space\string\usepackage{ocgx}\MessageBreak
or\MessageBreak
\space\space\string\usetikzlibrary{ocgx}
}{}%
}
\AtBeginDocument{
\@ifpackageloaded{media9}{}{\RequirePackage{media9}}
\@ifpackagelater{media9}{2015/01/21}{}{
\PackageError{fixocgx}{%
Requires package `media9' v0.49 [2015/01/21] or\MessageBreak
newer, but only v\g@mix@version@tl\space[\g@mix@date@tl] is available
}{}%
}
}
\ProvidesExplPackage{fixocgx}{2015/06/15}{0.5}
{ports `ocgx' functionality to dvips+ps2pdf, xelatex and dvipdfmx}
%re-implement ocg-p's `ocg' environment
\DeclareDocumentEnvironment{ocg}{O{}mmm}{
\bool_if:NT\g_fxocg_nestedB_bool{\tl_gput_right:Nx\@ocgbase@ocgorder{~[}}
\bool_gset_true:N\g_fxocg_nestedB_bool
\bool_gset_false:N\g_fxocg_nestedE_bool
\group_begin:
\tl_if_exist:cTF{fxocg@#3}{ %re-open existing layer
\tl_set:Nx\l_tempa_tl{[ocgp]{ocg}{\use:c{fxocg@#3.opts},#1}}
\exp_after:wN\setkeys\l_tempa_tl
\int_compare:nT{\@ocgp@listno=\c_zero}{
\tl_gput_right:Nx\@ocgbase@ocgorder{~\use:c{fxocg@#3}}
}
}{
\tl_gset:cn{fxocg@#3.opts}{#1}
\setkeys[ocgp]{ocg}{#1}
\mix_pdfobj:nnn{}{dict}{
/Type/OCG/Name~(#2)/Usage<<\l_fxocg_view_tl\@ocgp@print\@ocgp@export>>
}
\tl_gput_right:Nx\@ocgbase@ocgs{\space\g_mix_pdflastobj_tl}
\int_compare:nT{#4==\c_zero}{
\tl_gput_right:Nx\@ocgbase@offocgs{\space\g_mix_pdflastobj_tl}
}
\tl_gset:cx{fxocg@#3}{\g_mix_pdflastobj_tl}
\int_compare:nF{\@ocgp@listno=\c_one}{
\tl_gput_right:Nx\@ocgbase@ocgorder{~\g_mix_pdflastobj_tl}
}
\iow_now:Nx\@auxout{
\token_to_str:N\expandafter\xdef\token_to_str:N\csname
\space OCGpdfobj#3\endcsname{\g_mix_pdflastobj_tl}
}
}
\bool_if:nT{
!\cs_if_exist_p:c{OCGpdfobj#3} ||
!\str_if_eq_x_p:nn{\use:c{OCGpdfobj#3}}{\use:c{fxocg@#3}}
}{
\cs_if_exist:NF\g_fxocg_rerunwarned_tl{
\tl_new:N\g_fxocg_rerunwarned_tl
\AtEndDocument{\msg_warning:nn{fixocgx}{rerun}}
}
}
\tl_gset:cx{OCGpdfobj#3}{\use:c{fxocg@#3}}
\seq_gput_left:Nx\g_fixocg_ocgstack_seq{\use:c{fxocg@#3}}
\group_end:
\mix_pdfbdc:nn{/OC}{\use:c{fxocg@#3}}
\ignorespaces
}{
\unskip
\mix_pdfemc:
\seq_gpop_left:NN\g_fixocg_ocgstack_seq\l_tempa_tl
\bool_if:NT\g_fxocg_nestedE_bool{\tl_gput_right:Nx\@ocgbase@ocgorder{~]}}
\bool_gset_true:N\g_fxocg_nestedE_bool
\bool_gset_false:N\g_fxocg_nestedB_bool
}
\bool_new:N\g_fxocg_nestedB_bool % nested OCG begin
\bool_new:N\g_fxocg_nestedE_bool % nested OCG end
%stack of PDF obj references of currently open OCGs
\seq_new:N\g_fixocg_ocgstack_seq
%macro that inserts /OC <<OCMD with currently open OCGs>> entry;
%for use within annotation dicts
\tl_set:Nn\fxocg@insert@OC{
\seq_if_empty:NF\g_fixocg_ocgstack_seq{
/OC~<</Type/OCMD/OCGs~[\seq_use:Nn\g_fixocg_ocgstack_seq{~}]/P/AllOn>>
}
}
%workaround for ocg buttons (from tikzlibraryocgx.code.tex)
%with dvipdfmx and xelatex
\cs_set:Nn\fxocg_pdflink:nn{
\bool_if:nTF{
\g_mix_dvipdfmx_bool && \cs_if_exist_p:N\pgfpictureid
}{
\hbox_set:Nn\l_tmpa_box{#2}
\mix_pdfannot:nnnn{
\dim_use:N\box_wd:N\l_tmpa_box}{
\dim_use:N\box_ht:N\l_tmpa_box}{
\dim_use:N\box_dp:N\l_tmpa_box
}{#1}
\box_use_clear:N\l_tmpa_box
}{
\mix_pdflink:nn{#1}{#2}
}
}
%re-implement commands from ocgx.sty (all engines including ps2pdf [gs>=9.15])
\DeclareDocumentCommand\switchocg{mm}{
\tl_set:Nn\l_fxocg_ocglist_tl{}
\tl_set:Nx\l_ocglistarg_tl{#1}\tl_trim_spaces:N\l_ocglistarg_tl
\seq_set_split:NnV\l_fxocg_ocglistarg_seq{~}\l_ocglistarg_tl
\seq_map_variable:NNn\l_fxocg_ocglistarg_seq\l_tempa_tl{
\fxocg_process_ocgref:NN\l_fxocg_ocglist_tl\l_tempa_tl
}
\leavevmode
\fxocg_pdflink:nn{
/Subtype/Link\fxocg@insert@OC
/A <</S/SetOCGState/State [
\str_if_eq:VnF{\l_fxocg_ocglist_tl}{}{/Toggle~\l_fxocg_ocglist_tl}]>>
/Border [0~0~0]
}{#2}
}
\DeclareDocumentCommand\showocg{mm}{
\tl_set:Nn\l_fxocg_ocglist_tl{}
\tl_set:Nx\l_ocglistarg_tl{#1}\tl_trim_spaces:N\l_ocglistarg_tl
\seq_set_split:NnV\l_fxocg_ocglistarg_seq{~}\l_ocglistarg_tl
\seq_map_variable:NNn\l_fxocg_ocglistarg_seq\l_tempa_tl{
\fxocg_process_ocgref:NN\l_fxocg_ocglist_tl\l_tempa_tl
}
\leavevmode
\fxocg_pdflink:nn{
/Subtype/Link\fxocg@insert@OC
/A <</S/SetOCGState/State [
\str_if_eq:VnF{\l_fxocg_ocglist_tl}{}{/ON~\l_fxocg_ocglist_tl}]>>
/Border [0~0~0]
}{#2}
}
\DeclareDocumentCommand\hideocg{mm}{
\tl_set:Nn\l_fxocg_ocglist_tl{}
\tl_set:Nx\l_ocglistarg_tl{#1}\tl_trim_spaces:N\l_ocglistarg_tl
\seq_set_split:NnV\l_fxocg_ocglistarg_seq{~}\l_ocglistarg_tl
\seq_map_variable:NNn\l_fxocg_ocglistarg_seq\l_tempa_tl{
\fxocg_process_ocgref:NN\l_fxocg_ocglist_tl\l_tempa_tl
}
\leavevmode
\fxocg_pdflink:nn{
/Subtype/Link\fxocg@insert@OC
/A <</S/SetOCGState/State [
\str_if_eq:VnF{\l_fxocg_ocglist_tl}{}{/OFF~\l_fxocg_ocglist_tl}]>>
/Border [0~0~0]
}{#2}
}
\DeclareDocumentCommand\actionsocg{mmmm}{
\tl_set:Nx\l_ocglistarg_tl{#1}\tl_trim_spaces:N\l_ocglistarg_tl
\tl_set:Nn\l_fxocg_toswitch_tl{}
\seq_set_split:NnV\l_fxocg_ocglistarg_seq{~}\l_ocglistarg_tl
\seq_map_variable:NNn\l_fxocg_ocglistarg_seq\l_tempa_tl{
\fxocg_process_ocgref:NN\l_fxocg_toswitch_tl\l_tempa_tl
}
\tl_set:Nx\l_ocglistarg_tl{#2}\tl_trim_spaces:N\l_ocglistarg_tl
\tl_set:Nn\l_fxocg_toshow_tl{}
\seq_set_split:NnV\l_fxocg_ocglistarg_seq{~}\l_ocglistarg_tl
\seq_map_variable:NNn\l_fxocg_ocglistarg_seq\l_tempa_tl{
\fxocg_process_ocgref:NN\l_fxocg_toshow_tl\l_tempa_tl
}
\tl_set:Nx\l_ocglistarg_tl{#3}\tl_trim_spaces:N\l_ocglistarg_tl
\tl_set:Nn\l_fxocg_tohide_tl{}
\seq_set_split:NnV\l_fxocg_ocglistarg_seq{~}\l_ocglistarg_tl
\seq_map_variable:NNn\l_fxocg_ocglistarg_seq\l_tempa_tl{
\fxocg_process_ocgref:NN\l_fxocg_tohide_tl\l_tempa_tl
}
\leavevmode
\fxocg_pdflink:nn{
/Subtype/Link\fxocg@insert@OC
/A <</S/SetOCGState
/State [
\str_if_eq:VnF{\l_fxocg_toswitch_tl}{}{/Toggle~\l_fxocg_toswitch_tl}~
\str_if_eq:VnF{\l_fxocg_toshow_tl}{}{/ON~\l_fxocg_toshow_tl}~
\str_if_eq:VnF{\l_fxocg_tohide_tl}{}{/OFF~\l_fxocg_tohide_tl}
]
>>
/Border [0~0~0]
}{#4}
}
\cs_new:Nn\fxocg_process_ocgref:NN{
\str_if_eq_x:nnF{#2}{}{
\tl_if_exist:cTF{OCGpdfobj#2}{\tl_put_right:Nx#1{~\use:c{OCGpdfobj#2}}}{
\msg_warning:nnx{fixocgx}{undefined~OCG}{#2}
\cs_if_exist:NF\g_fxocg_refundefwarned_tl{
\tl_new:N\g_fxocg_refundefwarned_tl
\AtEndDocument{\msg_warning:nn{fixocgx}{undefined~OCGs}}
}
}
}
}
\define@choicekey*[ocgp]{ocg}{viewocg}[\l_fxocg_viewbin_tl\l_fxocg_viewno_tl]{always,never,ifvisible}[ifvisible]{%
\if_case:w\l_fxocg_viewno_tl
\def\l_fxocg_view_tl{/View<</ViewState/ON>>}
\or:%
\def\l_fxocg_view_tl{/View<</ViewState/OFF>>}
\or:
\def\l_fxocg_view_tl{}
\fi:
}
\presetkeys[ocgp]{ocg}{viewocg=ifvisible,printocg=ifvisible,exportocg=ifvisible,listintoolbar=iffirstuse}{}
\group_begin:
\char_set_catcode_active:N\+\let+\space
\tl_gset:Nx\g_fxocg_gsoldwarning_tl{
{product~(Ghostscript)~search~{pop~pop~pop~true}{pop~false}ifelse~
revision~915~lt~and~{
(\token_to_str:N\n
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\token_to_str:N\n
@@++++++++++++Warning:+Ghostscript+too+old!++++++++++++++++@@\token_to_str:N\n
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\token_to_str:N\n
@@+++++++++++++++++++++++++++++++++++++++++++++++++++++++++@@\token_to_str:N\n
@@+Package+`fixocgx'+requires+Ghostscript+version+>=+9.15.+@@\token_to_str:N\n
@@+Otherwise,+PDF+layers+will+not+work.++++++++++++++++++++@@\token_to_str:N\n
@@+++++++++++++++++++++++++++++++++++++++++++++++++++++++++@@\token_to_str:N\n
@@+Get+current+version+from++++++++++++++++++++++++++++++++@@\token_to_str:N\n
@@+
http://www.ghostscript.com/download+++++++++++++++++++++@@\token_to_str:N\n
@@+++++++++++++++++++++++++++++++++++++++++++++++++++++++++@@\token_to_str:N\n
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\token_to_str:N\n)
print}~if}~?pdfmark
}
\group_end:
\AtBeginDocument{
\ifpdf\else
\bool_if:NF\g_mix_dvipdfmx_bool{
\AtEndDvi{\special{ps::[nobreak]\g_fxocg_gsoldwarning_tl}}
}
\fi
}
\msg_set:nnn{fixocgx}{rerun}{Rerun~to~get~OCG~references~right!}
\msg_set:nnn{fixocgx}{undefined~OCG}{
Line~\msg_line_number: :~OCG~`#1'~is~not~defined.
}
\msg_set:nnn{fixocgx}{undefined~OCGs}{There~were~undefined~OCGs!}