% Copyright (C) 2012 by Werner Moshammer % Parts of this code are Copyright (C) 2007 by Michael Ritzert % REPLACEMENT FOR THE OLD OCG.STY % FOR PDFLATEX AND XELATEX (the old ocg.sys works only with pdflatex) % This file may be distributed and/or modified under the LaTeX Project Public License \NeedsTeXFormat{LaTeX2e} \def\ocgpversion{0.4} \ProvidesPackage{ocg-p}[2013/01/10 v\ocgpversion\space Optional Content Group in a PDF document] % v0.1: 2012/11/01; v0.2: 2012/11/23; v0.3: 2012/12/01; v0.4: 2013/01/10 \RequirePackage{eso-pic} \RequirePackage{ifpdf} \RequirePackage{ifxetex} \RequirePackage{xkeyval} \newif\ifocgtabular \DeclareOptionX[ocgp]{ocgtabular}{\ocgtabulartrue} \DeclareOptionX*{\PackageWarning{ocg-p}{Option unknown: \CurrentOption}} \ProcessOptionsX[ocgp]\relax \ifocgtabular \RequirePackage{datatool} \RequirePackage{tikz} \RequirePackage{listings} \fi \newif\if@ocgp@ifps \ifpdf \ifnum\pdftexversion<120 \PackageError{ocg-p}{% pdfeTeX, version >= 1.20, required% }{% Install a newer version!% }% \fi \else \ifxetex %already ok \else % dvips \@ocgp@ifpstrue \PackageWarningNoLine{ocg-p}{% Only XeLaTeX and pdfLaTeX are supported% }% \fi \fi \def\@ocgp@ocgHandle{\@auxout} \newif\if@ocgp@iffirstrun\@ocgp@iffirstruntrue \newif\if@ocgp@isnestedB\@ocgp@isnestedBfalse % nested OCG begin \newif\if@ocgp@isnestedE\@ocgp@isnestedEfalse % nested OCG end \def\@ocgp@nestedB{% \xdef\@ocgp@ocgorderlist{\@ocgp@ocgorderlist\space[} } \def\@ocgp@nestedE{% \xdef\@ocgp@ocgorderlist{\@ocgp@ocgorderlist\space]} } \providecommand\ocg[3]{} % if running with ocgtools \renewenvironment{ocg}[4][]{% \if@ocgp@isnestedB% begin of nested ocg detected \immediate\write\@ocgp@ocgHandle{% \string\@ocgp@nestedB{}% } \fi \global\@ocgp@isnestedBtrue % ocg begin \global\@ocgp@isnestedEfalse % ocg end \if@filesw% \immediate\write\@ocgp@ocgHandle{% \string\@ocgp@newocg{#2}{#3}{#4}{#1}% }% \fi \gdef\@ocgp@curnum{#3}% \ifpdf \pdfliteral{/OC /OC\@ocgp@curnum\space BDC}% \else \if@ocgp@ifps % soon (not implemented yet) POSTSCRIPT \special{ps: mark /_objdef {psocgobj\@ocgp@curnum} /type/stream /OBJ pdfmark} \special{ps: mark {psocgobj\@ocgp@curnum} (/OC /OC\@ocgp@curnum\space BDC) /PUT pdfmark} %\special{ps: mark /OC /OC\@ocgp@curnum\space /BDC pdfmark}% \else \special{pdf: content /OC /OC\@ocgp@curnum\space BDC}% \fi \fi \message{/OC\@ocgp@curnum}% \ignorespaces }{% \ifpdf \pdfliteral{EMC}% \else \if@ocgp@ifps % soon (not implemented yet) POSTSCRIPT %\special{ps: mark /EMC pdfmark}% \special{ps: mark {psocgobj\@ocgp@curnum} (EMC) /PUT pdfmark} \else \special{pdf: content EMC}% \fi \fi \if@ocgp@isnestedE% end of nested ocg detected \immediate\write\@ocgp@ocgHandle{% \string\@ocgp@nestedE{}% } \fi \global\@ocgp@isnestedEtrue % ocg end \global\@ocgp@isnestedBfalse % ocg begin \ignorespacesafterend } \def\@ocgp@ocglist{} \def\@ocgp@ocgofflist{} \def\@ocgp@ocgviewlist{} % to switch ocg off in layer toolbar of the viewer \gdef\@ocgp@ocgmaplist{} \def\@ocgp@ocgorderlist{} % ocgs in first-defined order + hierarchy \define@choicekey*[ocgp]{ocg}{printocg}[\@ocgp@printbin\@ocgp@printno]{always,never,ifvisible}[ifvisible]{% \ifcase\@ocgp@printno\relax \def\@ocgp@print{/Print<>}% \or% \def\@ocgp@print{/Print<>}% \or% \def\@ocgp@print{}% \fi% } \define@choicekey*[ocgp]{ocg}{exportocg}[\@ocgp@exportbin\@ocgp@exportno]{always,never,ifvisible}[ifvisible]{% \ifcase\@ocgp@exportno\relax \def\@ocgp@export{/Export<>}% \or% \def\@ocgp@export{/Export<>}% \or% \def\@ocgp@export{}% \fi% } \define@choicekey*[ocgp]{ocg}{listintoolbar}[\@ocgp@listbin\@ocgp@listno]{always,never,iffirstuse}[iffirstuse]{} \define@choicekey*[ocgp]{ocgaction}{triggerocg}[\@ocgp@actionbin\@ocgp@actionno]{onareaenter,onareaexit,onmousedown,onmouseup,allactions}[onmouseup]{% \ifcase\@ocgp@actionno\relax \def\@ocgp@trigger{/E}% \or% \def\@ocgp@trigger{/X}% \or% \def\@ocgp@trigger{/D}% \or% \def\@ocgp@trigger{/U}% \or% \def\@ocgp@trigger{}% \fi% } \presetkeys[ocgp]{ocg}{printocg=ifvisible,exportocg=ifvisible,listintoolbar=iffirstuse}{} \presetkeys[ocgp]{ocgaction}{triggerocg=onmouseup}{} \newcount\@ocgp@num\@ocgp@num=0 \newcount\@ocgp@tonum\@ocgp@tonum=0 \newcount\@ocgp@sonum\@ocgp@sonum=0 \def\@ocgp@newocg#1#2#3#4{% #1: OCG name, #2: OC id num, #3: visiblity on/off \if@ocgp@iffirstrun \expandafter\ifx\csname OCG#2\endcsname\relax \expandafter\gdef\csname OCG#2\endcsname{#1}% \global\advance\@ocgp@num by 1 \begingroup \setkeys[ocgp]{ocg}{#4} \ifpdf% PDFLATEX \immediate\pdfobj{<< /Type /OCG /Name (#1) /Usage <<% \@ocgp@print% %/View<> % \@ocgp@export% >> >>}% new ocg \xdef\@ocgp@curocg{\the\pdflastobj\space 0 R}% reference to current ocg id \else \if@ocgp@ifps % soon (not implemented yet) POSTSCRIPT \xdef\@ocgp@curocg{{@ocg\the\@ocgp@num}}% reference to current ocg id \special{ps: mark /_objdef \@ocgp@curocg /type/dict /OBJ pdfmark} \special{ps: mark \@ocgp@curocg << /Type /OCG /Name (#1) >> /PUT pdfmark}% new ocg \else % XELATEX \xdef\@ocgp@curocg{@ocg\the\@ocgp@num}% reference to current ocg id \special{pdf:obj \@ocgp@curocg\space <> % \@ocgp@export% >> >>}% new ocg \fi \fi \expandafter\xdef\csname OCGpdfobj#2\endcsname{\@ocgp@curocg} % for ogcx-package \xdef\@ocgp@ocglist{\@ocgp@ocglist\space\@ocgp@curocg}% list of all OCGs in "first defined" order \ifnum\@ocgp@listno=1\else \xdef\@ocgp@ocgorderlist{\@ocgp@ocgorderlist\space\@ocgp@curocg} % all OCGs in "first defined" order + hierarchy \fi \endgroup \xdef\@ocgp@ocgmaplist{\@ocgp@ocgmaplist\space/OC#2\space\@ocgp@curocg\space ^^J} % name-to-id mapping \ifnum#3=1 %on % no list of all default-on OCGs needed, because of basestate on \else% \xdef\@ocgp@ocgofflist{\@ocgp@ocgofflist\space\@ocgp@curocg}% list of all default-off OCGs \fi% \else \message{OCG#2 reopened}% layer reopened \begingroup \setkeys[ocgp]{ocg}{#4} \ifnum\@ocgp@listno=0 \xdef\@ocgp@ocgobjlist{}% \@ocgp@parseSpaceSeperatedList{#2}% \xdef\@ocgp@ocgorderlist{\@ocgp@ocgorderlist\space\@ocgp@ocgobjlist} \fi \endgroup \fi \fi } \AtBeginDocument{% AtEndDocument{% changed because of xetex problem in beamer class \@ocgp@iffirstrunfalse %\message{... \@ocgp@ocgorderlist ...} \ifpdf % PDFLATEX \pdfcatalog{% /OCProperties << /OCGs [\@ocgp@ocglist] /D <>% <>% <>% ]>>% >>% } \else \if@ocgp@ifps % soon (not implemented yet) POSTSCRIPT \special{ps: mark {Catalog} << /OCProperties << /OCGs [\@ocgp@ocglist] /D <> >> >> /PUT pdfmark}% \else % XELATEX \special{pdf:put @catalog << /OCProperties << /OCGs [\@ocgp@ocglist] /D <>% <>% <>% ]>>% >>% >>}% \fi \fi } \AtBeginDocument{% \ifpdf % PDFLATEX \immediate\pdfobj{<<\@ocgp@ocgmaplist\space>>}% \xdef\@ocgp@namesobj{\the\pdflastobj\space 0 R}% % append to pageresources \begingroup \edef\x{\endgroup \pdfpageresources{% \the\pdfpageresources /Properties \@ocgp@namesobj% }% }% \x \else \if@ocgp@ifps % soon (not implemented yet) POSTSCRIPT \AddToShipoutPicture{ \special{ps: mark /_objdef {Resources} /type/stream /OBJ pdfmark} \special{ps: mark {Resources} << % it is something wrong here % /Resources << /Properties << ^^J% \@ocgp@ocgmaplist %>> >> >> /PUT pdfmark}}% \else % XELATEX \AddToShipoutPicture{ \special{pdf: put @resources << /Properties << ^^J% \@ocgp@ocgmaplist >> >>}}% \fi \fi } % parsing a space-delimited ocgid-list to a space-delimited list of ocg-objects \def\@ocgp@parseSpaceSeperatedList#1{\@ocgp@doparseSpaceSeperatedList#1 \relax} \def\@ocgp@doparseSpaceSeperatedList#1 #2{% \ifcsname OCGpdfobj#1\endcsname% \xdef\@ocgp@ocgobjlist{\@ocgp@ocgobjlist\space\csname OCGpdfobj#1\endcsname}% \fi \ifx#2\relax %\@ocgp@ocgobjlist % only for debugging reasons \else \expandafter\@ocgp@doparseSpaceSeperatedList \fi #2% } %get the n-th element from a comma separated list \newcommand\@ocg@selectElementN[2]{% \newcount\@ocgp@inum\@ocgp@inum=0% \def\@ocgp@tempN{}% \@for\@ocg@i:=#1\do{% \advance\@ocgp@inum by 1\relax \ifnum\@ocgp@inum=#2\relax \edef\@ocgp@tempN{\@ocg@i}% \fi }% } % link to toggle layers in a document without using the layer toolbar of the viewer \newcommand\toggleocgs[3][]{% \setocgs[#1]{#2}{}{}{#3}% } % link to show layers in a document without using the layer toolbar of the viewer \newcommand\showocgs[3][]{% \setocgs[#1]{}{#2}{}{#3}% } % link to hide layers in a document without using the layer toolbar of the viewer \newcommand\hideocgs[3][]{% \setocgs[#1]{}{}{#2}{#3}% } % link to set layers in a document without using the layer toolbar of the viewer \newcommand\setocgs[5][]{% \begingroup \setkeys[ocgp]{ocgaction}{#1}% \newcount\@ocgp@aanum\@ocgp@aanum=0 \def\@ocgp@actionlist{}% \loop\ifnum\@ocgp@aanum<4 \xdef\@ocgp@ocgobjlist{}% \advance\@ocgp@aanum by 1\relax \ifx\\#2\else% \expandafter\@ocg@selectElementN\expandafter{#2}{\@ocgp@aanum}% \ifx\@ocgp@tempN\@empty\else \xdef\@ocgp@ocgobjlist{/Toggle }% \expandafter\@ocgp@parseSpaceSeperatedList\expandafter{\@ocgp@tempN}% \fi \fi \ifx\\#3\else% \expandafter\@ocg@selectElementN\expandafter{#3}{\@ocgp@aanum}% \ifx\@ocgp@tempN\@empty\else \xdef\@ocgp@ocgobjlist{\@ocgp@ocgobjlist /ON }% \expandafter\@ocgp@parseSpaceSeperatedList\expandafter{\@ocgp@tempN}% \fi \fi \ifx\\#4\else% \expandafter\@ocg@selectElementN\expandafter{#4}{\@ocgp@aanum}% \ifx\@ocgp@tempN\@empty\else \xdef\@ocgp@ocgobjlist{\@ocgp@ocgobjlist /OFF }% \expandafter\@ocgp@parseSpaceSeperatedList\expandafter{\@ocgp@tempN}% \fi \fi \ifnum\@ocgp@actionno<4\relax% only one action \def\@ocgp@actionlist{\@ocgp@trigger << /S /SetOCGState /State [\@ocgp@ocgobjlist]>>}% \advance\@ocgp@aanum by 10\relax \else% allactions \ifcase\@ocgp@aanum\relax\or% \def\@ocgp@trigger{/E}% \or% \def\@ocgp@trigger{/X}% \or% \def\@ocgp@trigger{/D}% \or% \def\@ocgp@trigger{/U}% \fi \ifx\@ocgp@ocgobjlist\@empty\else \edef\@ocgp@actionlist{\@ocgp@actionlist\space\@ocgp@trigger << /S /SetOCGState /State [\@ocgp@ocgobjlist]>> }% \fi \fi \repeat \global\advance\@ocgp@sonum by 1\relax \leavevmode% \ifpdf% \pdfstartlink user {% %/Subtype /Link /Subtype /Widget /FT/Btn /Ff 65536 /T(setocg\the\@ocgp@sonum) /H/N %Highlightning Mode: N=No;I=Invert;O=Outline;P=Push %/A <> /AA << \@ocgp@actionlist >> %/Border [0 0 0]% no border }% #5\pdfendlink% \else% \if@ocgp@ifps % soon (not implemented yet) POSTSCRIPT \special{ps: bann << /Type /Annot %/Subtype /Link /Subtype /Widget /FT/Btn/Ff 65536 /T(setocg\the\@ocgp@sonum) /H/N %/Border [0 0 0]% no border %/A <>% /AA << \@ocgp@actionlist >> >>}#5% \special{ps:eann}% \else% XELATEX \special{pdf: bann << /Type /Annot %/Subtype /Link /Subtype /Widget /FT/Btn/Ff 65536 /T(setocg\the\@ocgp@sonum) /H/N %/Border [0 0 0]% no border %/A <>% /AA << \@ocgp@actionlist >> >>}#5% \special{pdf:eann}% \fi% \fi% \endgroup } % environment for a table which can be sorted by clicking on the header % IMPLEMENTATION NOT FINISHED (last argument for options) \ifocgtabular \lst@RequireAspects{writefile} \lstnewenvironment{ocgtabular}[4][]{ \lstset{aboveskip=0pt,belowskip=0pt} \global\advance\@ocgp@tonum by 1\relax \newcommand\setocgtabularheader[2]{% \newcount\@ocgp@thnum\@ocgp@thnum=0% \xdef\@ocgp@ocgobjtlist{}% %\newcount\@ocgp@colindex% \DTLgetcolumnindex{\@ocgp@colindex}{#3}{##1}% \loop\ifnum\@ocgp@thnum<\DTLcolumncount{#3}% \advance\@ocgp@thnum by 1\relax \ifnum\@ocgp@thnum=\@ocgp@colindex\relax\else% \edef\@ocgp@ocgobjtlist{\@ocgp@ocgobjtlist\space ocgtabular\the\@ocgp@tonum o\the\@ocgp@thnum}% \fi% \repeat% \setocgs{}{ocgtabular\the\@ocgp@tonum o\@ocgp@colindex}{\@ocgp@ocgobjtlist}{##2}% } \newcount\@ocgp@tcnum\@ocgp@tcnum=0% \setbox\@tempboxa\hbox\bgroup \lst@BeginWriteFile{\jobname.oct}% }{ \lst@EndWriteFile% closes output file \egroup %\vspace{-\baselineskip}%remove line from write-op \begin{tikzpicture} \loop\ifnum\@ocgp@tcnum<\DTLcolumncount{#3} \advance\@ocgp@tcnum by 1\relax \DTLgetkeyforcolumn{\@ocgp@theader}{#3}{\the\@ocgp@tcnum} \message{+++ocgtabular\the\@ocgp@tonum o\the\@ocgp@tcnum +++} \begin{ocg}[listintoolbar=never]{ocgtabular\the\@ocgp@tcnum}{ocgtabular\the\@ocgp@tonum o\the\@ocgp@tcnum}{\ifnum\@ocgp@tcnum=1 1\else 0\fi} \node[] (ocgnode\the\@ocgp@tcnum) { \DTLsort*{\@ocgp@theader}{#3}% \begin{tabular}[#1]{#2} \@@input\jobname.oct% %\input{\jobname.oct}%problems with some commands \end{tabular} }; \end{ocg} \repeat \end{tikzpicture} } \fi