%\iffalse % makeindex -s gglo.ist -o web.gls web.glo %<*copyright> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% aebxmp.sty package, 2016-05-29 %% %% Copyright (C) 2006--2016 D. P. Story %% %% dpstory@uakron.edu %% %% %% %% This program can redistributed and/or modified under %% %% the terms of the LaTeX Project Public License %% %% Distributed from CTAN archives in directory %% %% macros/latex/base/lppl.txt; either version 1.2 of %% %% the License, or (at your option) any later version. %% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % %\NeedsTeXFormat{LaTeX2e}[1997/12/01] %\ProvidesPackage{aebxmp} % [2017/02/17 v2.5a Populate advanced metadata (dps)] %<*driver> \documentclass{ltxdoc} \usepackage[colorlinks,hyperindex]{hyperref} \OnlyDescription % comment out for implementation details \EnableCrossrefs \CodelineIndex \RecordChanges \InputIfFileExists{aebdocfmt.def}{\PackageInfo{aebxmp}{Inputting aebdocfmt.def}} {\def\IndexOpt{\DescribeMacro}\def\IndexKey{\DescribeMacro}\let\setupFullwidth\relax \PackageInfo{aebxmp}{aebdocfmt.def cannot be found}} \begin{document} \def\CMD#1{\textbackslash#1} \GetFileInfo{aebxmp.sty} \title{AeBXMP: Updating XMP using E4X and {\LaTeX}} \author{D. P. Story\\ Email: \texttt{dpstory@uakron.edu}} \date{processed \today} \maketitle \tableofcontents \DocInput{aebxmp.dtx} \IfFileExists{\jobname.ind}{\newpage\setupFullwidth\par\PrintIndex}{\paragraph*{Index} The index goes here.\\Execute \texttt{makeindex -s gind.ist -o aebxmp.ind aebxmp.idx} on the command line and recompile \texttt{aebxmp.dtx}.} \IfFileExists{\jobname.gls}{\PrintChanges}{\paragraph*{Change History} The list of changes goes here.\\Execute \texttt{makeindex -s gglo.ist -o aebxmp.gls aebxmp.glo} on the command line and recompile \texttt{aebxmp.dtx}.} \end{document} % % \fi % \MakeShortVerb{|} % \InputIfFileExists{aebdonotindex.def}{\PackageInfo{aebxmp}{Inputting aebdonotindex.def}} % {\PackageInfo{aebxmp}{cannot find aebdonotindex.def}} % % \begin{macrocode} %<*package> % \end{macrocode} % \changes{v2.5}{2016/05/20}{Moved DJLS from \string\texttt{addScript} in \string\texttt{insDLJS} env.} % \changes{v2.3c}{2012/09/20}{Changed \cs{copyrightNotice} and a % added \cs{Title} and \cs{Subject}, and . These now accept multiple entries with a required % language specification.Also defined the JavaScript arrays \texttt{aTitle}, \texttt{aSubject} % \texttt{aRights}. Added \cs{sourceFile} to save the name of the source file in the % DC packet. Added \cs{metaLang}, also to the DC packet.} % \changes{v2.3a}{2012/01/12}{Set the \texttt{lang} attribute to a value of \texttt{x-default} % for \cs{copyrightNotice}. Added a choice key to \cs{copyrightStatus} to force an % acceptable argument.} % \changes{v2.3}{2012/01/09}{All XMP elements now is inserted by E4X.} % \changes{v2.2}{2012/01/04}{Added the \cs{Keywords} command for creating an array % of keywords that can be accessed individually using the JavaScript function % \texttt{aKeyWords}, also defined in this package.} % \changes{v2.1a}{2011/12/30}{More code efficiencies} % \changes{v2.1}{2011/12/30}{Cleaned up the code, fixed a bug.} % \changes{v2.0}{2011/12/30}{Defined commands to producing custom document properties, % defined the \cs{Authors} command.} % \changes{v1.0}{2011/12/29}{Made a proper DTX file for this package; added % \cs{authortitle} and \cs{descriptionwriter}; support for \texttt{xmp:CreateDate}.} % \changes{v0.2}{2007/03/13}{Added support for unicode escape sequences in the % \cs{copyrightNotice} and \cs{copyrightInfoURL} fields.} % \changes{v0.1}{2006/12/01}{Original distribution} % \begin{macrocode} \RequirePackage{xkeyval} \@ifpackageloaded{insdljs}{\let\execjs=y} % \end{macrocode} % (2017/02/17) Require 2016/07/31 for insdljs to make colon syntax available. % \changes{v2.5a}{2017/02/17}{Require 2016/07/31 for insdljs} % \begin{macrocode} {\RequirePackage[execJS]{insdljs}[2016/07/31]} % incls conv-xkv % \end{macrocode} % \section{Utility commands and switches} % \begin{macrocode} \newif\if@xmp@several \@xmp@severaltrue % \end{macrocode} % The following is a utility command used in \cs{copyrightStatus}, \cs{Title}, % and \cs{Subject}. % \begin{macrocode} \def\xmp@testBrace#1{\@ifnextchar\bgroup {\@xmp@severaltrue#1}{\@xmp@severalfalse#1}} % \end{macrocode} % \cs{xmpLangAndArg} is used by the same commands listed above. These are the ones % that have a language attribute. % \begin{macrocode} \newcommand{\xmpLangAndArg}[1][]{%x-default \edef\xmpLang{#1}\xmpGetNextArg} \def\xmpGetNextArg#1\@nil{\edef\xmpArg{#1}} % \end{macrocode} % A major utility command used by \cs{copyrightStatus}, \cs{Title}, % and \cs{Subject}. \texttt{\#1} is the arguments of the calling command, % and \texttt{\#2} is the ``array'' macro. % \begin{macrocode} \edef\xmp@dquoteCat{\the\catcode`\"} \catcode`\"=12\relax \def\xmp@ProcessArgs#1#2{% \if@xmp@several \@tfor\xmpArg:=#1\do{% \expandafter\xmpLangAndArg\xmpArg\@nil \ifnum\count0=0\relax \xdef#2{#2^^J% \xmp@insItem[\the\count0]="\xmpArg";^^J% \xmp@insItem[\the\count0].@xml::lang="x-default";}% \ifx\xmpLang\@empty\else \advance\count0by1\relax \xdef#2{#2^^J% \xmp@insItem[\the\count0]="\xmpArg";^^J% \xmp@insItem[\the\count0].@xml::lang="\xmpLang";}% \fi \else \xdef#2{#2^^J% \xmp@insItem[\the\count0]="\xmpArg";^^J% \xmp@insItem[\the\count0].@xml::lang="\xmpLang";}% \fi \advance\count0by1\relax }% \else \@tfor\xmpArg:={#1}\do{% \expandafter\xmpLangAndArg\xmpArg\@nil \xdef#2{#2^^J% \xmp@insItem[\the\count0]="\xmpArg";^^J% \xmp@insItem[\the\count0].@xml::lang="x-default";}% \ifx\xmpLang\@empty\else \advance\count0by1 \xdef#2{#2^^J% \xmp@insItem[\the\count0]="\xmpArg";^^J% \xmp@insItem[\the\count0].@xml::lang="\xmpLang";}% \fi \advance\count0by1\relax }% \fi } \bgroup\obeyspaces \gdef\tabiv{ }% \egroup % \end{macrocode} % % \section{Top-level Interface to Metadata} % Through this package, the author can specify certain ``Advanced Metadata'' % items: copyright notice; copyright notice; copyright url; author title; % and writer description. % % \subsection{Dublin Core Properties} % % \begin{macro}{\copyrightNotice} % The argument \texttt{\#1} is the text of the \textsf{Copyright Notice}, % multiple languages supported. The first copyright notice is also tagged % as the default, \texttt{x-default}. %\begin{verbatim} %\copyrightNotice{% % {[lang_1] Copyright notice} % {[lang_2] Copyright notice} % ... %} %\end{verbatim} % \begin{macrocode} \let\arrayOfRights\@empty \newcommand{\copyrightNotice}[1]{\def\xmpcopyrightNotice{#1}% \xmp@testBrace{\xmp@cont@CopyRightNotice}#1\@nil}% \let\xmpcopyrightNotice\@empty % \end{macrocode} % \cs{copyrightNotice} continues with \cs{xmp@cont@CopyRightNotice} % \begin{macrocode} \def\xmp@cont@CopyRightNotice#1\@nil{% \begingroup\let\u\relax\count0=0\relax \def\xmp@insItem{p.aebdc::rights.aebrdf::Alt.aebrdf::li}% \ifx\xmpcopyrightNotice\@empty\else \xmp@ProcessArgs{#1}{\arrayOfRights}% \fi \endgroup } % \end{macrocode} % \begin{macro}{\Authors} % Enter multiple authors using a token list %\begin{verbatim} %\Authors %{% % {D. P. Story} % {A. P. Story} % ... %} %\end{verbatim} % We use \cs{@tfor} to build an array of authors, and use the simple mechanism % of \texttt{this.info.Authors} to set the multiple authors. % \begin{macrocode} \let\arrayOfAuthors\@empty \let\xmpAuthors\@empty \newcommand{\Authors}[1]{\def\xmpAuthors{#1}% \begingroup\let\u\relax\count0=0\relax \def\insSeqItem{p.aebdc::creator.aebrdf::Seq.aebrdf::li}% \ifx\xmpAuthors\@empty\else \let\arrayOfAuthors\@gobble \@tfor\xmpAuthor:=#1\do{% \xdef\arrayOfAuthors{\arrayOfAuthors^^J% \insSeqItem[\the\count0]="\xmpAuthor";}% \advance\count0by1 }% \fi \endgroup } \def\insertAuthors{\ifx\arrayOfAuthors\@empty\else ^^J\arrayOfAuthors\fi} % \end{macrocode} % \end{macro} % \end{macro} % \begin{macro}{\Title} % Allow multiple Titles, with language specification; syntax %\begin{verbatim} %\Title{% % {[lang_1] Title} % {[lang_2] Title} % ... %} %\end{verbatim} % Begin \cs{Title} % \begin{macrocode} \let\arrayOfTitles\@empty \newcommand{\Title}[1]{\edef\xmpTitle{#1}% \xmp@testBrace{\xmp@cont@Title}#1\@nil} % \end{macrocode} % continuation of \cs{Title} % \begin{macrocode} \def\xmp@cont@Title#1\@nil{% \begingroup\let\u\relax\count0=0\relax \def\xmp@insItem{p.aebdc::title.aebrdf::Alt.aebrdf::li}% \ifx\xmpTitle\@empty\else \xmp@ProcessArgs{#1}{\arrayOfTitles}% \fi \endgroup } \def\insertTitles{\ifx\arrayOfTitles\@empty\else ^^J\arrayOfTitles\fi} % \end{macrocode} % \end{macro} % \begin{macro}{\Subject} % Allow multiple subjects, with language specification. % Begin \cs{Subject} % \begin{macrocode} \let\arrayOfSubjects\@empty \newcommand{\Subject}[1]{\edef\xmpSubject{#1}% \xmp@testBrace{\xmp@cont@Subject}#1\@nil}% % \end{macrocode} % Continue \cs{Subject} % \begin{macrocode} \def\xmp@cont@Subject#1\@nil{% \begingroup\let\u\relax\count0=0\relax \def\xmp@insItem{p.aebdc::description.aebrdf::Alt.aebrdf::li}% \ifx\xmpSubject\@empty\else \xmp@ProcessArgs{#1}{\arrayOfSubjects}% \fi \endgroup } \def\insertSubjects{\ifx\arrayOfSubjects\@empty\else ^^J\arrayOfSubjects\fi} % \end{macrocode} % \end{macro} % \begin{macro}{\metaLang} % A list of languages used in this document. % \begin{macrocode} \let\arrayOfLangs\@empty \newcommand{\metaLang}[1]{\def\xmplangOfDoc{#1}% \begingroup\let\u\relax\count0=0\relax \def\insBagItem{p.aebdc::language.aebrdf::Bag.aebrdf::li}% \ifx\xmpLangs\@empty\else \let\arrayOfLangs\@gobble \@for\xmpLang:=#1\do{% \xdef\arrayOfLangs{\arrayOfLangs^^J% \insBagItem[\the\count0]="\xmpLang";}% \advance\count0by1 }% \fi \endgroup } \def\insertLangs{\ifx\arrayOfLangs\@empty\else ^^J\arrayOfLangs\fi} % \end{macrocode} % \end{macro} % \DescribeMacro{\sourceFile} is used to insert the name of the source file % in to the Dublin Core. By default \cs{jobname.tex} is used. If this command % is not executed, \cs{jobname.tex} is used. If executed with % an empty argument, no \texttt{dc:source} is not inserted at all. If executed % with a nonempty argument, that argument is assumed to be a file name and is % inserted as the value of the \texttt{dc:source}. % \begin{macrocode} \newcommand{\sourceFile}[1]{\let\xmp@bSourcefile=1 \def\xmp@sourcefile{#1}} \let\xmp@bSourcefile=0 \let\xmp@sourcefile\@empty \def\insertSource{% \if\xmp@bSourcefile0 ^^Jp.aebdc::source="\jobname.tex"\else \ifx\xmp@sourcefile\@empty\else ^^Jp.aebdc::source="\xmp@sourcefile"\fi\fi} % \end{macrocode} % \begin{macro}{\Keywords} % We try to implement keywords in a manner similar to \cs{Authors}; that is, % we want to reference each key word. The individual keywords are listed in % \texttt{dc:subject}, in a \texttt{Bag}, an unordered array. % \begin{macrocode} \let\arrayOfKeywords\@empty \let\aKeywords\@empty \let\xmpKeywords\@empty \newcommand{\Keywords}[1]{\def\xmpKeywords{#1}% \begingroup\let\u\relax\count0=0\relax \def\insBagItem{% p.aebdc::subject.aebrdf::Bag.aebrdf::li}% \ifx\xmpKeywords\@empty\else \let\arrayOfKeywords\@gobble \let\aKeywords\@gobbletwo \@for\xmpKeyword:=#1\do{% \xdef\arrayOfKeywords{\arrayOfKeywords^^J% \insBagItem[\the\count0]="\xmpKeyword";}% \xdef\aKeywords{\aKeywords;\space\xmpKeyword}% \advance\count0by1 }% \xdef\aKeywords{"\aKeywords"}% \fi \endgroup } % \end{macrocode} % \cs{insertKeywords} does what the other ``insert'' commands do, insert the % code, we use the \texttt{dc:subject} tag, which corresponds to keywords. % Used in the disposable code below. % \begin{macrocode} \def\insertKeywords{\ifx\arrayOfKeywords\@empty\else ^^J\arrayOfKeywords\fi} % \end{macrocode} % \end{macro} % We set the keywords using the JavaScript property \texttt{Doc.info}, rather % than a pdfmark. We also optionally include document-level JS so the document % user can access individual keywords. \DescribeMacro{\xmpDoNotInsKWScript}\cs{xmpDoNotInsKWScript} % optionally turns off the insertion of the function \texttt{aKeywords()}. % \begin{macrocode} \let\xmpInsScript\@empty \newcommand{\xmpDoNotInsKWScript}{\let\xmpInsScript\null} % \end{macrocode} %\subsection{XMP Rights Management Properties} % \begin{macro}{\copyrightStatus} %If \texttt{\#1} is \texttt{True}, the \textsf{Copyright Status} is set to %\texttt{Copyrighted}; if \texttt{False}, \textsf{Copyright Status} is set %to \textsf{Public Domain}. If left empty, the status is set to %\textsf{Unknown}. % \begin{macrocode} \newcommand{\copyrightStatus}[1]{% \setkeys{aebxmp}{copyrightstatus=#1}} % \end{macrocode} % We offer choices of \texttt{true}, \texttt{false}, or \texttt{unknown} (case insensitive) % for the argument of \cs{copyrightStatus} % \begin{macrocode} \define@choicekey*+{aebxmp}{copyrightstatus}[\val\nr]% {true,false,unknown}[unknown]{% \ifcase\nr\relax \def\xmpcopyrightStatus{True}\or \def\xmpcopyrightStatus{False}\else \let\xmpcopyrightStatus\@empty\fi }{\PackageWarning{aebxmp}{% Bad choice for \string\copyrightStatus,\MessageBreak you entered '#1'.\MessageBreak Permissible values are true, false, or unknown\MessageBreak (or an empty argument). Setting status to 'unknown'.\MessageBreak Try again,}} \let\xmpcopyrightStatus\@empty % \end{macrocode} % \end{macro} % \cs{insertMarked} inserts the copyright status and is used in the % disposable code. It only if one has been declared. If none is declared, % the copyright notice will be \texttt{Unknown}. % \begin{macrocode} \def\insertMarked{\ifx\xmpcopyrightStatus\@empty \else^^Jp.aebxapRights::Marked="\xmpcopyrightStatus";\fi} % \end{macrocode} % \begin{macrocode} \def\insertCopyrightNotice{\ifx\arrayOfRights\@empty\else \arrayOfRights\fi} % \end{macrocode} % Insert copyright notice and specify the language attribute, which is % \texttt{x-default}. Used in the disposable code below. % \begin{macro}{\copyrightInfoURL} % The argument \texttt{\#1} is the \textsf{URL} to the copyright information % \begin{macrocode} \newcommand{\copyrightInfoURL}[1]{\def\xmpcopyrightInfoURL{#1}} \let\xmpcopyrightInfoURL\@empty % \end{macrocode} % Insert the web statement. Used in the disposable code below. % \begin{macrocode} \def\insertWebStatement{\ifx\xmpcopyrightInfoURL\@empty \else^^Jp.aebxapRights::WebStatement="\xmpcopyrightInfoURL";\fi} % \end{macrocode} % \end{macro} %\subsection{Acrobat Custom Properties} % \begin{macro}{\customProperties} %\begin{verbatim} %\customProperties %{ % {name=dps,value=5} % {name=jg,value=good} % ... %} %\end{verbatim} % \begin{macrocode} \let\insertCusProps\@empty \newcommand\customProperties[1]{\def\pdfx@cusProps{#1}% \begingroup\let\u\relax \@tfor\thisproperty:=#1\do{% \edef\tmp@exp{\noexpand % \end{macrocode} % (2017/02/17) Values of \texttt{customProperties} can use the colon notation % \changes{v2.5a}{2017/02/17}{Values of customProperties can use the colon notation} % \begin{macrocode} \cxkvsetkeys{pdfx@cusPropKV}{name,value,\thisproperty}}\tmp@exp \xdef\insertCusProps{\insertCusProps^^J% % \end{macrocode} % We permit the use of \cs{u} the the value of the custom property, % the name of the custom property should be a restricted XML name, basically % \texttt{A-Z},\texttt{a-z}, and \texttt{0-9}. % \begin{macrocode} p.aebpdfx::\pdfx@KName="\pdfx@VValue";} }% \endgroup } % \end{macrocode} % The \texttt{pdfx@cusPropKV} family has two keys, \texttt{name} and \texttt{value}. % These keys are used in the command \cs{customProperties} defined above. % \begin{macrocode} \define@key{pdfx@cusPropKV}{name}[]{\def\pdfx@KName{#1}} \define@key{pdfx@cusPropKV}{value}[]{\def\pdfx@VValue{#1}} % \end{macrocode} % \end{macro} % We define a simple tabbing command \cs{tabiv} to use within the JavaScript. % % \subsection{XMP Core Properties} % These are some helper macros that conditionally fill in metadata when it exists. % All these commands are used internally; the document author has no reason to use them. % \changes{v2.5}{2016/05/20}{Added the \string\texttt{ModifyDate} property} % \begin{macrocode} \def\insertCreateDate{^^Jp.@aebxap::CreateDate=createDateStr;% ^^Jp.@aebxap::ModifyDate=createDateStr;} \def\xmpnEOL{\string\n\string\^^J} % \end{macrocode} % \subsection{Adobe Photoshop Properties} % \begin{macro}{\authortitle} % The \texttt{} (argument \texttt{\#1}) appears in the % \textsf{Author Title} line on the \textsf{Advanced Metadata} dialog box. % This is a \textbf{Photoshop} property. (See the Advanced category in the left % panel.) % \begin{macrocode} \newcommand{\authortitle}[1]{\def\xmpauthortitle{#1}} % \end{macrocode} % \DescribeMacro{\authorTitle} is an alias for \cs{authortitle}. % \begin{macrocode} \let\authorTitle\authortitle \let\xmpauthortitle\@empty % \end{macrocode} % Insert the author title. Used in the disposable code below. % \begin{macrocode} \def\insertAuthorTitle{\ifx\xmpauthortitle\@empty \else^^Jp.aebphotoshop::AuthorsPosition="\xmpauthortitle";\fi} % \end{macrocode} % \end{macro} % \begin{macro}{\descriptionwriter} % The \texttt{} (argument \texttt{\#1}) appears in the %\textsf{Description Writer} line on the \textsf{Advanced Metadata} dialog box. %This is a \textbf{Photoshop} property. (See the Advanced category in the left %panel.) % \begin{macrocode} \newcommand{\descriptionwriter}[1]{\def\xmpdescriptionwriter{#1}} % \end{macrocode} % \DescribeMacro{\descriptionWriter} is an alias for \cs{descriptionwriter}. % \begin{macrocode} \let\descriptionWriter\descriptionwriter \let\xmpdescriptionwriter\@empty % \end{macrocode} % Insert the description writer. Used in the disposable code below. % \begin{macrocode} \def\insertDescriptionWriter{\ifx\xmpdescriptionwriter\@empty \else^^Jp.aebphotoshop::CaptionWriter="\xmpdescriptionwriter";\fi} % \end{macrocode} % \end{macro} % % \section{Disposable JavaScript} % Most of this package consists of a few new commands to populate the ``disposable'' % JavaScript that is input as an \textsf{FDF} when the PDF file is first opened after distilling. % This code does all the work. % \par\medskip\noindent % \cs{insertKWJS} expands to a JavaScript property assignment if there are \cs{aKeywords} % is nonempty. % \begin{macrocode} \def\insertKWJS{\ifx\aKeywords\@empty\else this.info.Keywords=\aKeywords;^^J\fi} % \end{macrocode} % When \textsf{pdflatex} is used (MiKTeX version), the package fails % when \texttt{p.@xmlns::pdfx} is included. This seems to because the % \textsf{pdflatex} version defines its own custom property. Haven't figured % how to detect the presence of a custom property yet. % \begin{macrocode} %\edef\insertPDFX{\ifpdf\else p.@xmlns::pdfx=aebpdfx.uri;^^J\fi} % \end{macrocode} % Some namespace definitions % \begin{macrocode} \def\xNNS{new Namespace} \def\xAdbNS{http://ns.adobe.com} \def\xWiiiNS{http://www.w3.org} \begin{execJS}{execXMP} % \end{macrocode} % Get the metadata from the current document. % \begin{macrocode} var meta=this.metadata; var aebXMPData=new XML(meta); % \end{macrocode} % Define the needed namespaces % \begin{macrocode} var aebx=\xNNS("x","adobe:ns:meta/"); var xmlns=\xNNS("xmlns","\xWiiiNS/2000/xmlns/"); var xml=\xNNS("xml", "\xWiiiNS/XML/1998/namespace"); var aebrdf=\xNNS("rdf","\xWiiiNS/1999/02/22-rdf-syntax-ns#"); var aebdc=\xNNS("dc","http://purl.org/dc/elements/1.1/"); var aebpdf=\xNNS("pdf","\xAdbNS/pdf/1.3/"); var aebxap=\xNNS("xmp","\xAdbNS/xap/1.0/"); var aebxapRights=\xNNS("xmpRights","\xAdbNS/xap/1.0/rights/"); var aebphotoshop=\xNNS("photoshop","\xAdbNS/photoshop/1.0/"); var aebpdfx=\xNNS("pdfx","\xAdbNS/pdfx/1.3/"); % \end{macrocode} % \begin{macrocode} var p=aebXMPData.aebrdf::RDF.aebrdf::Description; % \end{macrocode} % The MiKTeX version of \textsf{pdflatex} places a custom property at the creation % of the PDF. We detect whether any custom properties already exist, if they do, % don't emit \texttt{p.@xmlns::pdfx=aebpdfx.uri}, otherwise, an exception it thrown % when the metadata is updated at the end of this code. % \begin{macrocode} if ( p.@aebpdfx::*.toString() == "" ) p.@xmlns::pdfx=aebpdfx.uri; p.@xmlns::photoshop=aebphotoshop.uri; p.@xmlns::xmpRights=aebxapRights.uri; % \end{macrocode} % The creation date shall be the time this \textsf{FDF} is imported into the document. % \begin{macrocode} var d=new Date(); var createDateStr=util.printd("yyyy-mm-ddTHH:MM:ss",d); % \end{macrocode} % We delete the element, in case it already has a value (unlikely), the we % assign it our value. % \begin{macrocode} delete p.@aebdc::rights.aebrdf::Alt.aebrdf::li; % \end{macrocode} % \paragraph*{Dublin Core Properties % (\texttt{dc}, \begin{NoHyper}\url{http://purl.org/dc/elements/1.1/}\end{NoHyper})}\strut\\ % Core properties include \texttt{dc:format}, \texttt{dc:title}, % \texttt{dc:rights}, \texttt{dc:creator}, and \texttt{dc:subject} (aka, keywords). % Here, we set \texttt{dc:rights}, called \textsf{Copyright Notice} in the user interface. % \begin{macrocode} /* Dublin Core Properties */% \insertTitles% \insertAuthors% \insertSubjects% \insertKeywords% \insertLangs% \insertSource% \insertCopyrightNotice% % \end{macrocode} % We delete all old values of \texttt{xapRights:Marked} and \texttt{xap:WebStatement}, % and replace them with the new values. % \begin{macrocode} /* XMP Rights Management Properties */ delete p.@aebxapRights::Marked; delete p.@aebxapRights::WebStatement;% % \end{macrocode} % Now we insert additional properties, if there are any % \begin{macrocode} % \end{macrocode} % \paragraph*{XMP Rights Management}\strut\\(\texttt{xmpRights}, % \begin{NoHyper}\url{http://ns.adobe.com/xap/1.0/rights/}\end{NoHyper})\\ % These include \texttt{xmpRights:Marked} and \texttt{xmpRights:WebStatement}, both of which % are set. % \begin{macrocode} \insertMarked% \insertWebStatement% % \end{macrocode} % \paragraph*{Adobe Photoshop Properties}\strut\\(\texttt{photoshop}, % \begin{NoHyper}\url{http://ns.adobe.com/photoshop/1.0/}\end{NoHyper})\\ % These include \texttt{photoshop:AuthorsPosition} and \texttt{photoshop:CaptionWriter}, both of which % are set. % \begin{macrocode} delete p.@aebphotoshop::AuthorsPosition; delete p.@aebphotoshop::CaptionWriter; delete p.@aebxap::CreateDate; /* Adobe Photoshop Properties */% \insertAuthorTitle% \insertDescriptionWriter% % \end{macrocode} % \paragraph*{Acrobat Custom Properties} (\texttt{pdfx}, % \begin{NoHyper}\url{http://ns.adobe.com/pdfx/1.3/}\end{NoHyper})\\ % Adobe allows the creation of custom properties that are accessible % through the \texttt{Doc.info} object. % \begin{macrocode} /* Acrobat Custom Properties */% \insertCusProps% % \end{macrocode} % \paragraph*{XMP Core Properties} (\texttt{xmp}, % \begin{NoHyper}\url{http://ns.adobe.com/xap/1.0/}\end{NoHyper})\\ % These properties include \texttt{xmp:CreatorTool}, % \texttt{xmp:ModifyDate}, \texttt{xmp:CreateDate}, and \texttt{xmp:MetadataDate}. % Here we set only \texttt{CreateDate}. % \begin{macrocode} /* XMP Core Properties */% \insertCreateDate% % \end{macrocode} % Convert \texttt{aebXMPData} into a string % \begin{macrocode} /* Convert aebXMPData into an XML String and save is as this.metadata */ var aebNewXMPStr=aebXMPData.toXMLString(); % \end{macrocode} % and assign it to the document metadata % \begin{macrocode} try { this.metadata=aebNewXMPStr; } catch(e) {console.println(e.toString());} % \end{macrocode} % Insert a JavaScript assignment for keywords. % \begin{macrocode} \insertKWJS% \end{execJS} % \end{macrocode} % % \section{Document JavaScript} % % This definition environment defines four functions and four arrays. % The functions are used to build the arrays. The arrays are user accessible, % they are \texttt{aKeywords}, \texttt{aTitle}, \texttt{aSubject}, and \texttt{aRights}. % \begin{macrocode} \ifx\xmpInsScript\@empty \begin{insDLJS}{xmpjs}{Access to Title, Subject, and Keywords} function getKeywordsXMP(i) { var uriRdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"; var uriDc="http://purl.org/dc/elements/1.1/"; var meta=this.metadata; var aebXMPData=new XML(meta); var aebrdf=new Namespace(uriRdf); var aebdc=new Namespace(uriDc); var p=aebXMPData.aebrdf::RDF.aebrdf::Description; return p.aebdc::subject.aebrdf::Bag.aebrdf::li[i]; } var i=0; var aKeywords=new Array(); while ( typeof getKeywordsXMP(i)!="undefined" ) { aKeywords[i]=getKeywordsXMP(i).toString(); i++; } function getTitleXMP(i) { var uriRdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"; var uriDc="http://purl.org/dc/elements/1.1/"; var uriXML="http://www.w3.org/XML/1998/namespace"; var meta=this.metadata; var aebXMPData=new XML(meta); var aebrdf=new Namespace(uriRdf); var aebdc=new Namespace(uriDc); var xml=new Namespace("xml",uriXML); var p=aebXMPData.aebrdf::RDF.aebrdf::Description; var retnStr; try { retnStr="[" + p.aebdc::title.aebrdf::Alt.aebrdf::li[i].% @xml::lang.toString()+"]: " + p.aebdc::title.aebrdf::Alt.aebrdf::li[i].toString(); } catch(e) { retnStr="undefined" }; return retnStr; } var i=0; var aTitle=new Array(); while ( getTitleXMP(i)!="undefined" ) { aTitle[i]=getTitleXMP(i); i++; } function getSubjectXMP(i) { var uriRdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"; var uriDc="http://purl.org/dc/elements/1.1/"; var uriXML="http://www.w3.org/XML/1998/namespace"; var meta=this.metadata; var aebXMPData=new XML(meta); var aebrdf=new Namespace(uriRdf); var aebdc=new Namespace(uriDc); var xml=new Namespace("xml",uriXML); var p=aebXMPData.aebrdf::RDF.aebrdf::Description; var retnStr; try { retnStr="[" + p.aebdc::description.aebrdf::Alt.aebrdf::li[i].% @xml::lang.toString()+"]: " + p.aebdc::description.aebrdf::Alt.aebrdf::li[i].toString(); } catch(e) { retnStr="undefined" }; return retnStr; } var i=0; var aSubject=new Array(); while ( getSubjectXMP(i)!="undefined" ) { aSubject[i]=getSubjectXMP(i); i++; } function getRightsXMP(i) { var uriRdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"; var uriDc="http://purl.org/dc/elements/1.1/"; var uriXML="http://www.w3.org/XML/1998/namespace"; var meta=this.metadata; var aebXMPData=new XML(meta); var aebrdf=new Namespace(uriRdf); var aebdc=new Namespace(uriDc); var xml=new Namespace("xml",uriXML); var p=aebXMPData.aebrdf::RDF.aebrdf::Description; var retnStr; try { retnStr="["+ p.aebdc::rights.aebrdf::Alt.aebrdf::li[i]% .@xml::lang.toString()+"]: " + p.aebdc::rights.aebrdf::Alt.aebrdf::li[i].toString(); } catch(e) { retnStr="undefined" }; return retnStr; } var i=0; var aRights=new Array(); while ( getRightsXMP(i)!="undefined" ) { aRights[i]=getRightsXMP(i); i++; } function getCopyrightStatus() { var uriRdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"; var uriXAP="http://ns.adobe.com/xap/1.0/rights/"; var meta=this.metadata; var aebXMPData=new XML(meta); var xmlns=new Namespace("xmlns","http://www.w3.org/2000/xmlns/"); var aebrdf=new Namespace(uriRdf); var aebxapRights=new Namespace("xmpRights",uriXAP); var p=aebXMPData.aebrdf::RDF.aebrdf::Description; p.xmlns::xmpRights=aebxapRights.uri; var copyrightStatus = p.@aebxapRights::Marked; if ( copyrightStatus=="True" ) return "Copyrighted"; else if ( copyrightStatus=="False" ) return "Public Domain"; else return "Unknown"; } function getCopyrightInfoURL() { var uriRdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"; var uriXAP="http://ns.adobe.com/xap/1.0/rights/"; var meta=this.metadata; var aebXMPData=new XML(meta); var xmlns=new Namespace("xmlns","http://www.w3.org/2000/xmlns/"); var aebrdf=new Namespace(uriRdf); var aebxapRights=new Namespace("xmpRights",uriXAP); var p=aebXMPData.aebrdf::RDF.aebrdf::Description; p.xmlns::xmpRights=aebxapRights.uri; var copyrightInfoURL=(p.@aebxapRights::WebStatement.toString()!="")? (p.@aebxapRights::WebStatement):"Not provided"; return copyrightInfoURL; } function getAuthorTitle() { var uriRdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"; var uriPhotoshop="http://ns.adobe.com/photoshop/1.0/"; var meta=this.metadata; var aebXMPData=new XML(meta); var xmlns=new Namespace("xmlns","http://www.w3.org/2000/xmlns/"); var aebrdf=new Namespace(uriRdf); var aebPhotoshop=new Namespace("photoshop",uriPhotoshop); var p=aebXMPData.aebrdf::RDF.aebrdf::Description; p.xmlns::photoshop=aebPhotoshop.uri; var authorTitle=(p.@aebPhotoshop::AuthorsPosition.toString()!="")? (p.@aebPhotoshop::AuthorsPosition):"Not provided"; return authorTitle; } function getDescriptionWriter() { var uriRdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"; var uriPhotoshop="http://ns.adobe.com/photoshop/1.0/"; var meta=this.metadata; var aebXMPData=new XML(meta); var xmlns=new Namespace("xmlns","http://www.w3.org/2000/xmlns/"); var aebrdf=new Namespace(uriRdf); var aebPhotoshop=new Namespace("photoshop",uriPhotoshop); var p=aebXMPData.aebrdf::RDF.aebrdf::Description; p.xmlns::photoshop=aebPhotoshop.uri; var captionWriter=(p.@aebPhotoshop::CaptionWriter.toString()!="")? (p.@aebPhotoshop::CaptionWriter):"Not provided"; return captionWriter; } \end{insDLJS} \fi \catcode`\"=\xmp@dquoteCat % \end{macrocode} % \begin{macrocode} % % \end{macrocode} \endinput p.aebdc::description.aebrdf::Alt.aebrdf::li[0]="Euro \u20AC"; p.aebdc::description.aebrdf::Alt.aebrdf::li[0].@xml::lang="x-default";