%
% This is file `chemobabel.sty',
% for generating chemical structural formulas
% using Open Babel and Inkscape.
%
% Copyright 2014-2022 Acetaminophen (Hironobu YAMASHITA)
%   Email   :  h.y.acetaminophen[a t]gmail.com
%   GitHub  :  https://github.com/aminophen
%   Blog    :  http://acetaminophen.hatenablog.com/
%   Twitter :  @aminophen
%
% This work is based on a lot of resources published online.
%  - Noel O'Boyle http://baoilleach.blogspot.jp/
%  - Jakob Lykke Andersen http://imada.sdu.dk/~jlandersen/
%  - TeX Forum http://oku.edu.mie-u.ac.jp/tex/
%

\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{chemobabel}
  [2022/09/19 v0.9j Chemical structures with Open Babel]

%% Start of package main code
%% Thanks: http://imada.sdu.dk/~jlandersen/latex/graphvizObabel.sty

\RequirePackage{verbatim}
\RequirePackage{graphicx}

%% ----- External command execution -----
\ifx\directlua\@undefined
  \def\chemob@bel@exec#1{\immediate\write18{#1}}
  \ifx\pdfshellescape\@undefined
    \ifx\shellescape\@undefined
      \chardef\chemob@bel@shellescape \@ne % fallback no warning
    \else
      % xelatex, hilatex
      \chardef\chemob@bel@shellescape \shellescape
    \fi
  \else
      % (pdf)latex, platex, uplatex
      \chardef\chemob@bel@shellescape \pdfshellescape
  \fi
\else
  \def\chemob@bel@exec#1{\directlua{os.execute[[#1]]}}
  \chardef\chemob@bel@shellescape =\directlua{tex.sprint(status.shell_escape)}
\fi

%% ----- Make a directory for images -----
\newcommand\chemobabelimgdir{chemobabelimgdir}
\chemob@bel@exec{mkdir \chemobabelimgdir}

%% ----- Definition of external commands -----
\def\smilesob@bel@obabelcmd#1#2{obabel -:"#1" -O \smilesob@belGetName.svg #2}
\def\chemob@bel@obabelcmd#1#2{obabel "#1" -O \chemob@belGetName.svg #2}
%
% inkscape 0.92 or earlier
\def\chemob@bel@inkscapeoldcmd#1#2{inkscape -f #1.svg --export-#2=#1.#2}
% inkscape major version 1.0
\def\chemob@bel@inkscapecmd#1#2{inkscape #1.svg --export-type=#2}
%
% librsvg
\def\chemob@bel@librsvgcmd#1#2{rsvg-convert -f #2 -o #1.#2 #1.svg}
%
% crop PDF
\def\chemob@bel@pdfcropcmd#1{pdfcrop #1.pdf}% -> #1-crop.pdf
% crop EPS
\def\chemob@bel@epscropcmd#1{ps2eps -f #1.eps}% -> #1.eps.eps

%% ----- Common part of \smilesobabel and \chemobabel -----
\def\chemob@bel@common@maybeimg#1#2#3{%
  \def\chemob@belImgName{#2\chemob@bel@maybecrop.\chemob@belimgExt}%
  \IfFileExists{\chemob@belImgName}{% the image exists: include it
    #1{\chemob@belImgName}%
  }{% the image was not created - show a warning and a hint
    \PackageWarning{chemobabel}{Processing of #3\space failed}%
    \fbox{\begin{minipage}{0.9\textwidth}
      Warning in chemobabel: #3\space was not processed.
    \ifnum\chemob@bel@shellescape=\@ne
      Please make sure that \texttt{obabel},
      \ifx\chemob@bel@svgtoimgcmd\chemob@bel@librsvgcmd
        \texttt{rsvg-convert}
      \else
        \texttt{inkscape}
      \fi
      \ifx\chemob@bel@cropcmd\chemob@bel@pdfcropcmd
        and \texttt{pdfcrop}
      \else\ifx\chemob@bel@cropcmd\chemob@bel@epscropcmd
        and \texttt{ps2eps}
      \fi\fi
      are installed.\\
    \else
      Remember to run \texttt{latex} (\texttt{pdflatex}, \texttt{platex}, etc.)
      with the \texttt{-shell-escape} option.\\
    \fi
      \IfFileExists{#2.log}{%
        obabel log (might be empty):
        \verbatiminput{#2.log}%
      }{%
        No log file.%
      }%
    \end{minipage}}%
  }%
}
%% ----- Common part of \smilesobabel and \chemobabel end -----

%% ----- Definition of \smilesobabel -----
\newcounter{smilesob@belCounter}
\setcounter{smilesob@belCounter}{1}
\newcommand\smilesob@belPrefix{\chemobabelimgdir/smilesobabelimg}
\newcommand\smilesob@belGetName{\smilesob@belPrefix\arabic{smilesob@belCounter}}

% 1: (optional) options for includegraphics
% 2: SMILES notation
% 3: options for obabel
\newcommand\smilesobabel[1][scale=1]{%
  \def\smilesobabel@next{\includegraphics[#1]}%
  \begingroup
    \let\do\@makeother \dospecials \catcode`\{=1 \catcode`\}=2
    \@smilesobabel
}
\newcommand\@smilesobabel[2]{%
  \endgroup
  \chemob@bel@exec{%
    \smilesob@bel@obabelcmd{#1}{#2} 2>\smilesob@belGetName.log
    && \chemob@bel@svgtoimgcmd{\smilesob@belGetName}{\chemob@belimgExt} 2>>\smilesob@belGetName.log
    || rm -f \smilesob@belGetName.\chemob@belimgExt}%
  \chemob@bel@exec{\chemob@bel@cropcmd{\smilesob@belGetName}}%
  \chemob@bel@common@maybeimg{\smilesobabel@next}{\smilesob@belGetName}{SMILES string}%
  \addtocounter{smilesob@belCounter}{1}% select next name
}
%% ----- Definition of \smilesobabel end -----

%% ----- Definition of \chemobabel -----
\newcounter{chemob@belCounter}
\setcounter{chemob@belCounter}{1}
\newcommand\chemob@belPrefix{\chemobabelimgdir/chemobabelimg}
\newcommand\chemob@belGetName{\chemob@belPrefix\arabic{chemob@belCounter}}

% 1: (optional) options for includegraphics
% 2: original files (.mol, .cdx, etc.)
% 3: options for obabel
\newcommand\chemobabel[1][scale=1]{%
  \def\chemobabel@next{\includegraphics[#1]}%
  \begingroup
    \let\do\@makeother \dospecials \catcode`\{=1 \catcode`\}=2
    \@chemobabel
}
\newcommand\@chemobabel[2]{%
  \endgroup
  \IfFileExists{"#1"}{%
    % the file exists: start processing
    % (``#1'' can contain spaces, so ``"'' required)
    \chemob@bel@exec{%
      \chemob@bel@obabelcmd{#1}{#2} 2>\chemob@belGetName.log
      && \chemob@bel@svgtoimgcmd{\chemob@belGetName}{\chemob@belimgExt} 2>>\chemob@belGetName.log
      || rm -f \chemob@belGetName.\chemob@belimgExt}%
    \chemob@bel@exec{\chemob@bel@cropcmd{\chemob@belGetName}}%
    \chemob@bel@common@maybeimg{\chemobabel@next}{\chemob@belGetName}{file ``#1''}%
  }{%
    % the file does not exist: show a std error
    \PackageError{chemobabel}{File ``#1'' not found}{}%
    \fbox{\begin{minipage}{0.9\textwidth}
      Error in chemobabel: the file ``#1'' does not exist.
    \end{minipage}}%
  }%
  \addtocounter{chemob@belCounter}{1}% select next name
}
%% ----- Definition of \chemobabel end -----

%% ----- Check if no chemical structures -----
\def\chemob@bel@ifnochem{%
  \let\chemob@bel@nochem\relax
  \ifnum\value{smilesob@belCounter}=\@ne
  \ifnum\value{chemob@belCounter}=\@ne
    \let\chemob@bel@nochem\@empty
  \fi\fi
  \ifx\chemob@bel@nochem\@empty
    \expandafter\@firstoftwo
  \else
    \expandafter\@secondoftwo
  \fi
}

%% ----- Declaration of options -----
% load macros for extracting \chemobabel and \smilesobabel commands
\let\chemob@bel@extract\relax
\DeclareOption{extract}{\let\chemob@bel@extract\@empty}
% define the image extension
\DeclareOption{pdf}{%
  \def\chemob@belimgExt{pdf}%
  \let\chemob@bel@cropcmd\chemob@bel@pdfcropcmd
  \def\chemob@bel@maybecrop{-crop}}
\DeclareOption{eps}{%
  \def\chemob@belimgExt{eps}%
  \let\chemob@bel@cropcmd\chemob@bel@epscropcmd
  \def\chemob@bel@maybecrop{.eps}}
% determine image conversion command
\DeclareOption{inkscape-old}%
  {\let\chemob@bel@svgtoimgcmd\chemob@bel@inkscapeoldcmd}
\DeclareOption{inkscape}%
  {\let\chemob@bel@svgtoimgcmd\chemob@bel@inkscapecmd}
\DeclareOption{librsvg}%
  {\let\chemob@bel@svgtoimgcmd\chemob@bel@librsvgcmd}
% crop image or not
\DeclareOption{nocrop}{%
  \let\chemob@bel@cropcmd\@gobble
  \let\chemob@bel@maybecrop\@empty}
% default settings
\ExecuteOptions{pdf,inkscape}
\ProcessOptions\relax
%% ----- Declaration of options end -----

%% ----- Exit this package now, if [extract] is not specified -----
\ifx\chemob@bel@extract\relax \endinput \fi

%% Extracting all codes of Open Babel figures
%% Thanks: http://oku.edu.mie-u.ac.jp/tex/mod/forum/discuss.php?d=1411

\PackageWarningNoLine{chemobabel}{%
  You are using [extract] option.\MessageBreak
  No chemical structures will be printed}

%% ----- Define intermediate output file and load packages -----
\newwrite\ChemFigFile
\immediate\openout\ChemFigFile=ChemFigFile.tex\relax
\immediate\write\ChemFigFile{\string\documentclass{article}}
\immediate\write\ChemFigFile{\string\usepackage{graphicx}}
\immediate\write\ChemFigFile{\string\usepackage{chemobabel}}

%% ----- Read and write -----
\immediate\write\ChemFigFile{\string\begin{document}}
\AtEndDocument{%
  \immediate\write\ChemFigFile{\string\end{document}}%
  \immediate\closeout\ChemFigFile
  \chemob@bel@ifnochem{}{%
    \PackageWarningNoLine{chemobabel}{%
      Some chemical structures are extracted.\MessageBreak
      Run 'pdflatex -shell-escape ChemFigFile.tex'}}%
}
\renewcommand\smilesobabel{%
  \begingroup
  \let\do\@makeother
  \dospecials
  \catcode`\{=1
  \catcode`\}=2
  \@@smilesobabel
}
\newcommand\@@smilesobabel[3][scale=1]{%
  \endgroup
  \immediate\write\ChemFigFile{%
    \string\smilesobabel[#1]{#2}{#3}%
    \string\newpage}%
  [\smilesob@belGetName.\chemob@belimgExt]%
  \addtocounter{smilesob@belCounter}{1}}
\renewcommand\chemobabel{%
  \begingroup
  \let\do\@makeother
  \dospecials
  \catcode`\{=1
  \catcode`\}=2
  \@@chemobabel
}
\newcommand\@@chemobabel[3][scale=1]{%
  \endgroup
  \immediate\write\ChemFigFile{%
    \string\chemobabel[#1]{#2}{#3}%
    \string\newpage}%
  [\chemob@belGetName.\chemob@belimgExt]%
  \addtocounter{chemob@belCounter}{1}}
%% ----- Read and write end -----

\endinput

%%
%% End of file `chemobabel.sty'.
