%% This is file `novel-pdfx.sty', part of `novel' document class.
%% Copyright (c) 2017-2024 Robert Allgeyer.
%%
%% This file may be distributed and/or modified under the
%% conditions of the LaTeX Project Public License, version 1.3c.
%% License URL:  https://www.latex-project.org/lppl/lppl-1-3c/
%% 
%% ----------------------------------------------------------------------------
%%
%% File `novel-pdfx.sty' uses code, directly copied or modified,
%%   from file `pdfx.sty', part of LaTeX package `pdfx': Copyright (c) 2015,
%%   CV Radhakrishnan, Han The Thanh, Ross Moore, Peter Selinger.
%%   Licensed LPPL 1.2+ -> 1.3c.
%% 
%% ----------------------------------------------------------------------------
%%
\NeedsTeXFormat{LaTeX2e}
\ProvidesFile{novel-pdfx.sty}%
[2024/02/17 v2.1 LaTeX file (PDF/X support for novel class)]
% This package supports, and is part of, class `novel'.
% No support for anything but LuaLaTeX.

% DO NOT ATTEMPT TO USE OUTSIDE `NOVEL' DOCUMENT CLASS.
% Reason: Other files in this class define stuff that is used here.

%%
%% This file is loaded \AtEndPreamble.
%%


%% Preliminary tests for cases forbidding PDF/X:
\ifdraftdoc
  \global\@pdfxISofftrue
\fi
\if@sandbox
  \global\@pdfxISofftrue
\fi
%
\gdef\@AlertNoPDFX{% called by `novel.cls' AtBeginDocument
  \if@pdfxSEToff\else
    \ifdraftdoc
      \typeout{^^JClass `novel' Alert: No PDF/X in draft mode. ^^J%
       Your document was processed with \string\SetPDFX{off}. ^^J}%
    \fi
    \if@sandbox
      \typeout{^^JClass `novel' Alert: No PDF/X with sandbox option. ^^J%
       Your document was processed with \string\SetPDFX{off}. ^^J}%
    \fi
  \fi
} % end @AlertNoPDFX
%%


% Hyperref options for PDF/X with LuaLaTeX:
\def\pdfx@pdfX@opts@luatex{%
  draft,pdfpagemode=UseNone,bookmarks=false,hyperfootnotes=false,%
  hyperindex=false,implicit=false,pdfversion=1.\the\pdfminorversion,%
  pdfpagelabels=true,pageanchor=false,pdfstartview=}
%
\RequirePackage[\pdfx@pdfX@opts@luatex]{hyperref}
%
\hypersetup{pdfencoding=auto}
\expandafter\ifx\csname KV@Hyp@psdextra\endcsname\relax\else
 \hypersetup{psdextra}
\fi
\Hy@bookmarksfalse
%
\ifthenelse{\equal{\@title}{} \OR \equal{\@title}{ }}{%
  \global\@HasTitlefalse}{\global\@HasTitletrue%
}
\ifthenelse{\equal{\@title}{IMPORTANT: Provide Book Title}}{%
  \ClassWarning{novel}{^^JDid not provide title using \string\SetTitle. ^^J%
   Default used: `IMPORTANT: Provide Book Title'. Be sure to change it! ^^J}%
}{}%
%
% Sanity check: If title is missing at this step, then compliance must be off:
\if@pdfxISoff\else
  \if@HasTitle\else
    \ClassError{novel}{PDF/X requires non-empty \string\SetTitle\space}%
     {Unless \string\SetPDFX\space is off, must use \string\SetTitle\space ^^J%
      with non-empty title. Blank space counts as empty.}%
  \fi
\fi
%
\if@HasTitle\else
  \ClassWarning{novel}{^^JYour file has been compiled without standard ^^J%
    PDF internal metadata, such as the title. This is allowable, and in ^^J%
    some cases desirable. But in most cases it is not what you intended. ^^J%
    If you want title and other metadata to be in PDF internal metadata, ^^J%
    then you must place them prior to the \string\SetPDFX. ^^J}
\fi
%
\expandafter\ifx\csname pdfresetpageorigin\endcsname\relax\else
 \pdfresetpageorigin=0
\fi
\edef\pdfcreationdate{\pdfcreationdate}%
\let\pdfx@mdfivesum\pdf@mdfivesum
%



%% CALCULATE AND SPECIFY CROPBOX AND TRIMBOX
%% ----------------------------------------------------------------------------
%%
% The MediaBox is automatically provided, so there is no need to write
%   MediaBox in /pdfInfo (because it would be a duplicate).
% TrimBox is always necessary for PDF/X.
% Although CropBox is not necessary, it seems that it is often written
%   by professional PDF software. For that reason, and for proper centering
%   of TrimBox when MediaBox is larger, CropBox is created (= MediaBox).
%
\newcommand\@myMWN{\strip@pt\paperwidth}
\FPmul{\@myMWN}{\@myMWN}{0.99626401}
\FPround{\@myMWN}{\@myMWN}{3}
\FPclip{\@myMWN}{\@myMWN}
\newcommand\@myMHN{\strip@pt\paperheight}
\FPmul{\@myMHN}{\@myMHN}{0.99626401}
\FPround{\@myMHN}{\@myMHN}{3}
\FPclip{\@myMHN}{\@myMHN}
\newcommand\@myTWN{\strip@pt\@TrimWidth}
\FPmul{\@myTWN}{\@myTWN}{0.99626401}
\FPround{\@myTWN}{\@myTWN}{3}
\newcommand\@myTHN{\strip@pt\@TrimHeight}
\FPmul{\@myTHN}{\@myTHN}{0.99626401}
\FPround{\@myTHN}{\@myTHN}{3}
%
\FPsub{\@myTWorigin}{\@myMWN}{\@myTWN}
\FPmul{\@myTWorigin}{\@myTWorigin}{0.5}
\FPround{\@myTWorigin}{\@myTWorigin}{3}
\FPadd{\@myTWcorner}{\@myTWorigin}{\@myTWN}
\FPround{\@myTWcorner}{\@myTWcorner}{3}
\FPsub{\@myTHorigin}{\@myMHN}{\@myTHN}
\FPmul{\@myTHorigin}{\@myTHorigin}{0.5}
\FPround{\@myTHorigin}{\@myTHorigin}{3}
\FPadd{\@myTHcorner}{\@myTHorigin}{\@myTHN}
\FPround{\@myTHcorner}{\@myTHcorner}{3}
%
\FPclip{\@myTWorigin}{\@myTWorigin}
\FPclip{\@myTWcorner}{\@myTWcorner}
\FPclip{\@myTHorigin}{\@myTHorigin}
\FPclip{\@myTHcorner}{\@myTHcorner}
%
\newcommand\novel@CropBox{%
 \if@cropview%
  /CropBox[\@myTWorigin\space\@myTHorigin\space\@myTWcorner\space\@myTHcorner]%
 \else%
  /CropBox[0\space0\space\@myMWN\space\@myMHN]%
 \fi%
}
%
\newcommand\novel@TrimBox{%
  /TrimBox[\@myTWorigin\space\@myTHorigin\space\@myTWcorner\space\@myTHcorner]%
}
%
% BleedBox, only for cover art. Same size as MediaBox.
\newcommand\novel@BleedBox{%
  \if@coverart%
    /BleedBox[0\space0\space\@myMWN\space\@myMHN]%
  \fi%
}
%
\begingroup\edef\next{%
\endgroup\pdfpageattr{\novel@CropBox^^J\novel@BleedBox^^J\novel@TrimBox}}\next
%
%% End calculate and specify TrimBox.



%% GENERAL PDF INTERNAL METADATA PREPARATION
%% ----------------------------------------------------------------------------
%
% Create hashes that will be used for uuid data. Does not need to be fancy:
\def\tweak@temp@s{
  \lowercase\expandafter{% Per 'egreg' tex.stackexchange.com q.351065.
    \expandafter\def\expandafter\temp@s\expandafter{\temp@s}%
  }
  \StrLeft{\temp@s}{8}[\temp@n]
  \StrRight{\temp@s}{24}[\temp@d]
  \edef\temp@s{\temp@n-\temp@d}
  \StrLeft{\temp@s}{13}[\temp@n]
  \StrRight{\temp@s}{19}[\temp@d] % Omit character, becomes 4.
  \edef\temp@s{\temp@n-4\temp@d}
  \StrLeft{\temp@s}{18}[\temp@n]
  \StrRight{\temp@s}{15}[\temp@d] % Omit character, becomes 8.
  \edef\temp@s{\temp@n-8\temp@d}
  \StrLeft{\temp@s}{23}[\temp@n]
  \StrRight{\temp@s}{12}[\temp@d]
  \edef\temp@s{\temp@n-\temp@d}
}
\edef\temp@s{\pdf@mdfivesum{\jobname\@title\@author novel}}
\tweak@temp@s
\edef\@documentID{uuid:\temp@s}
\edef\temp@s{\pdf@mdfivesum{\pdffeedback creationdate}}
\tweak@temp@s
\edef\@instanceID{uuid:\temp@s}
%%



%
%% End general PDF in internal metadata preparation.



%% PREPARATION OF XMP METADATA
%% ----------------------------------------------------------------------------
%% Data prepared here, will later be inserted into the XMP packet template,
%%   then the processed template will be incuded in the PDF.
%% XMP metadata is in utf-8 encoding.
%
% Make the XMP look pretty:
\def\pad@ii{\space\space}
\def\pad@iv{\pad@ii\pad@ii}
\def\pad@vi{\pad@iv\pad@ii}
\def\pad@viii{\pad@vi\pad@ii}
\def\pad@x{\pad@viii\pad@ii}
\def\pad@xii{\pad@x\pad@ii}
\def\pad@xiv{\pad@xii\pad@ii}
\def\pad@xvi{\pad@xiv\pad@ii}
\def\pad@xviii{\pad@xvi\pad@ii}
\def\pad@xx{\pad@xviii\pad@ii}
\def\pad@xxxii{\pad@xvi\pad@xvi}
\def\pad@lxiv{\pad@xxxii\pad@xxxii}
\def\pad@cxxviii{\pad@lxiv\pad@lxiv}
\def\pad@cclvi{\pad@cxxviii\pad@cxxviii}
\def\pad@dxii{\pad@cclvi\pad@cclvi}
%
% Frankly, I am not sure if all this rigamarole is necessary, but it works!
% Here, portions of XMP code are prepared. Later, they will be inserted
%  into the XMP packet template.
\gdef\@titleString{
  \pad@vi<dc:title>^^J
  \pad@viii<rdf:Alt>^^J
  \pad@x<rdf:li xml:lang="x-default">\@title</rdf:li>^^J
  \pad@viii</rdf:Alt>^^J
  \pad@vi</dc:title>^^J
}
%
\ifthenelse{\equal{\@author}{}}{
  \gdef\@authorString{}
}{
  \gdef\@authorString{
    \pad@vi<dc:creator>^^J
    \pad@viii<rdf:Bag>^^J
    \pad@x<rdf:li>\@author</rdf:li>^^J
    \pad@viii</rdf:Bag>^^J
    \pad@vi</dc:creator>^^J
  }
}
%

%
\def\@pdfVersion{1.\the\pdfminorversion}
%
\if@pdfxISoff
  \gdef\@verconfString{}%
\else
  \gdef\@verconfString{
    \pad@vi<pdfx:GTS_PDFXVersion>\@PDFXversion</pdfx:GTS_PDFXVersion>^^J
    \if@HasConformance
      \pad@vi<pdfx:GTS_PDFXConformance>%
        \@PDFXconformance</pdfx:GTS_PDFXConformance>^^J
    \fi
  }
\fi
%
\if@pdfxISoff
  \gdef\@pdfidString{}%
\else
  \gdef\@pdfidString{
    \pad@vi<pdfxid:GTS_PDFXVersion>\@PDFXversion</pdfxid:GTS_PDFXVersion>^^J
  }
\fi
%
\ifthenelse{\equal{\@novelApplication}{} \OR \equal{\@novelApplication}{ }}{
  \gdef\@applicationString{}%
}{
  \gdef\@applicationString{\pad@vi<xmp:CreatorTool>%
    \@novelApplication</xmp:CreatorTool>^^J}%
}
%
\ifthenelse{\equal{\@novelProducer}{} \OR \equal{\@novelProducer}{ }}{
  \gdef\@producerString{}%
}{
  \gdef\@producerString{\pad@vi<pdf:Producer>%
    \@novelProducer</pdf:Producer>^^J}%
}
%
% Calculation of Dates and Times, which must be in a specific format.
% Each time you process to PDF, the current date/time is used,
%   for all of the several metadata date/time strings.
\def\xmp@cDate{\pdfx@getYear}
{\catcode`\D=12 \catcode`\:=12
 \gdef\pdfx@getYear D:#1#2#3#4{\edef\pdfx@xYear{#1#2#3#4}\pdfx@getMonth}
}
\def\pdfx@getMonth#1#2{\edef\pdfx@xMonth{#1#2}\pdfx@getDay}
\def\pdfx@getDay#1#2{\edef\pdfx@xDay{#1#2}\pdfx@getHour}
\def\pdfx@getHour#1#2{\edef\pdfx@xHour{#1#2}\pdfx@getMin}
\def\pdfx@getMin#1#2{\edef\pdfx@xMin{#1#2}\pdfx@getSec}
\def\pdfx@getSec#1#2{\edef\pdfx@xSec{#1#2}\pdfx@getTZh}
\def\pdfx@getTZh{\futurelet\pdfx@next\pdfx@getTzh@branches}
%
{\catcode`\@=11 \catcode`\Z=12 \catcode`\+=12 \catcode`\-=12 % ends below
\gdef\pdfx@getTzh@branches{%
 \ifx\pdfx@next Z\let\pdfx@getTzbranch\pdfx@getTznozone
 \else\ifx\pdfx@next +\let\pdfx@getTzbranch\pdfx@getTzplus
 \else\ifx\pdfx@next -\let\pdfx@getTzbranch\pdfx@getTzminus
 \else\let\pdfx@getTzbranch\pdfx@getTzerror
 \fi\fi\fi \pdfx@getTzbranch }
%
\catcode`\0=12
\gdef\pdfx@getTznozone Z#1\pdfx@getTzend{%
 \edef\pdfx@xTzh{+00}\edef\pdfx@xTzm{00}}
\gdef\pdfx@getTzplus +#1'#2'#3\pdfx@getTzend{%
 \edef\pdfx@xTzh{+#1}\edef\pdfx@xTzm{#2}%
 \ifx\relax#2\relax\def\pdfx@xTzm{00}\fi}
\gdef\pdfx@getTzminus -#1'#2'#3\pdfx@getTzend{%
 \edef\pdfx@xTzh{-#1}\edef\pdfx@xTzm{#2}%
 \ifx\relax#2\relax\def\pdfx@xTzm{00}\fi}
%
\expandafter\ifx\csname pdfcreationdate\endcsname\relax
\else
 \expandafter\expandafter\expandafter\xmp@cDate\pdfcreationdate''\pdfx@getTzend
 \xdef\pdfx@convDate{\pdfx@xYear\pdfx@xMonth\pdfx@xDay\pdfx@xHour
  \pdfx@xMin\pdfx@xSec\pdfx@xTzh'\pdfx@xTzm'}%
 \xdef\xmp@cDate{\pdfx@xYear-\pdfx@xMonth-\pdfx@xDay
  T\pdfx@xHour:\pdfx@xMin:\pdfx@xSec\pdfx@xTzh:\pdfx@xTzm}%
\fi
}% End of \catcode`\@=11 etc.
\let\@modifyDate\xmp@cDate
\let\@createDate\xmp@cDate
\let\@metadataDate\xmp@cDate
% End dates and times.
%
%% End Prepare XMP metadata.



%% WRITE THE XMP METADATA, UNLESS PDF/X IS OFF OR NO TITLE
%%-----------------------------------------------------------------------------
%% Inserts the prepared XMP metadata into XMP packet template, then writes
%% the result at the start of the PDF, right now, before the document.
%
\if@pdfxISoff\else
 \if@HasTitle
   \begingroup
     \makeatletter
     \input{novel-xmppacket.sty}
     \global\let\@xmpData\@xmpPacket % from the above file
     \begingroup
      \pdfcompresslevel=0
      \immediate\pdfobj stream attr {/Type /Metadata /Subtype /XML} {\@xmpData}
      \pdfcatalog{/Metadata \the\pdflastobj\space 0 R}
     \endgroup
   \endgroup
   % Creates external xml file, if requested:
   \if@wantXMPasXML
     \newwrite\file
     \immediate\openout\file=\jobname-XMPasXML.xml
     \immediate\write\file{<?xml version="1.0" encoding="UTF-8" %
       standalone="yes" ?>^^J}
     \immediate\write\file{<!-- Ignore any message about not having style %
       information. That is normal. -->^^J}
     \immediate\write\file{<!-- Your viewer's font must be able to display %
       any characters used in the XMP. -->^^J}
     \immediate\write\file{<!-- For example, if your XMP has Cyrillic, %
       then you need a Cyrillic-capable font. -->^^J}
     \immediate\write\file{<!-- Any decorations (such as dashes in front of %
       lines) are added by the viewer. Not in XMP. -->^^J}
     \immediate\write\file{<!-- Note: xpacket begin="" contains the invisible %
       3-byte utf-8 BOM within its quotes. -->^^J}
     \immediate\write\file{<!-- The above xml declaration, and these %
       comments, are not part of the XMP packet. -->^^J}
     \immediate\write\file{\@xmpData^^J}
     \closeout\file
   \fi
 \fi
\fi
%
%
%% End write the XMP metadata.



%% PREPARE PDF /INFO METADATA
%% ----------------------------------------------------------------------------
%% PDF /Info is another form of metadata, older than XMP but still used.
%% It is NOT in utf-8 encoding. Depending on content, one of two encodings
%%   will be automatically used: PDFDoc encoding if metadata uses only
%%   characters within Latin-1, or utf-16 if metadata is not within Latin-1.
%% Either way, the input was utf-8 before processing.
%% In principle, PDF /Info is obsolete whenever PDF/X is used, because
%%   XMP metadata is supposed to prevail through the printing workflow.
%% In practice, things don't always work that way. So, unless your PDF
%%   has no metadata, essential items are re-encoded and copied to PDF /Info.
%% Other than encoding, XMP metadata and PDF /Info must be exactly the same.
%% All of those issues are handled automatically here.
%% The result is written at the end of the PDF, after the document.
%
% Macro for massaging encodings:
\def\@infotopdfstring#1#2{%
  \ifx#2\@empty
    \global\let#1\empty
  \else
    \begingroup
      \hypersetup{pdfencoding=auto}%
      \pdfstringdef#1{#2}%
    \endgroup
  \fi
}
% Now, massage the metadata:
\@infotopdfstring{\@infotitle}{\@title}
\@infotopdfstring{\@infoauthor}{\@author}
\@infotopdfstring{\@infoapplication}{\@novelApplication}
\@infotopdfstring{\@infoproducer}{\@novelProducer}
%
%% End prepare PDF /Info.



%% WRITE THE OUTPUT INTENT, UNLESS PDFX IS OFF.
%% ----------------------------------------------------------------------------
% Data for CGATS TR 001, FOGRA39, and JC200103 are in file novel-FileData.sty.
\if@pdfxISoff\else
  \begingroup
    \edef\@pctchar{\expandafter\@gobble\string\%} % Escaped in TeX, not PDF.
    \edef\@bchar{\expandafter\@gobble\string\\} % For use as escape, below.
    \edef\0{\string\0} % Not sure why, but it works.
    \edef\({\string\(} % PDF Catalog requires escaped parentheses.
    \edef\){\string\)} % PDF Catalog requires escaped parentheses.
    \catcode`\_ 12 % The icc file name might contain underscores.
    %
    \if@EmbedICC
      \IfFileExists{\@OIprofile}{%
        \immediate\pdfobj stream attr{/N 4} file{\@OIprofile}%
        \edef\OBJ@OI{\the\pdflastobj\space 0 R}%
      }{%
        \ClassError{novel}{Requested icc color profile not found}%
         {You used the starred \string\SetPDFX*\space which embeds the ^^J%
          associated icc color profile. But the file could not be located. ^^J%
          If necessary, put it in the same folder as your *.tex document. ^^J%
          Incidentally: Do you really need to embed the profile?}%
      }
    \fi
    \ifthenelse{\equal{\@OIcondition}{}}{
      \edef\@OIconditionString{}%
    }{
      \edef\@OIconditionString{/OutputCondition (\@OIcondition)}%
    }
    \ifthenelse{\equal{\@OIidentifier}{}}{
      \edef\@OIidentifierString{}%
    }{
      \edef\@OIidentifierString{/OutputConditionIdentifier (\@OIidentifier)}%
    }
    \ifthenelse{\equal{\@OIinfo}{}}{
      \edef\@OIinfoString{}%
    }{
      \edef\@OIinfoString{/Info (\@OIinfo)}%
    }
    \ifthenelse{\equal{\@OIregistry}{}}{
      \edef\@OIregistryString{}%
    }{
      \edef\@OIregistryString{/RegistryName (\@OIregistry)}%
    }
    \pdfcatalog{%
      /OutputIntents [ <<%
      /Type/OutputIntent%
      /S/GTS_PDFX%
      \@OIconditionString%
      \@OIidentifierString%
      \@OIinfoString%
      \@OIregistryString%
      \if@EmbedICC/DestOutputProfile \OBJ@OI\fi%
      >> ]%
    }%
  \endgroup
\fi
%
%% End write the output intent.



%% DISABLE HYPERREF OPTIONS
%%-----------------------------------------------------------------------------
%% Prevents changes that will cause an incompatibility.
%
\Hy@DisableOption{pdfauthor}%
\Hy@DisableOption{pdftitle}%
\Hy@DisableOption{pdfsubject}%
\Hy@DisableOption{pdfcreator}%
\Hy@DisableOption{pdfcreationdate}%
\Hy@DisableOption{pdfmoddate}%
\Hy@DisableOption{pdfproducer}%
\Hy@DisableOption{pdfkeywords}%
%
%% End disable hyperref options.



%% PREPARE PDF/Info
%% ----------------------------------------------------------------------------
\gdef\@ActivatePDFInfo{% called by `novel.cls' \AtBeginDocument
  \if@HasTitle
    \pdfinfo{
      \ifx\@infotitle\@empty\else /Title(\@infotitle)\fi
      \ifx\@infoauthor\@empty\else /Author(\@infoauthor)\fi
      \ifx\@infoapplication\@empty\else /Creator(\@infoapplication)\fi
      \ifx\@pdfcreationdate\@empty
        /CreationDate(D:\pdfx@convDate)%
      \else
        /CreationDate(\@pdfcreationdate)%
      \fi
      \ifx\@pdfmoddate\@empty
        /ModDate(D:\pdfx@convDate)%
      \else
        /ModDate(\@pdfmoddate)%
      \fi
      \ifx\@infoproducer\@empty\else /Producer(\@infoproducer)\fi%
      /Trapped/False%
      \if@pdfxISoff\else
        /GTS_PDFXVersion(\@PDFXversion)%
        \if@HasConformance /GTS_PDFXConformance(\@PDFXconformance)\fi%
      \fi
    }
  \fi
}%
%% End \@ActivatePDFInfo.



%%
\endinput
%%
%% End of file `novel-pdfx.sty'.


