summaryrefslogtreecommitdiff
path: root/graphics/chemobabel/chemobabel.sty
diff options
context:
space:
mode:
Diffstat (limited to 'graphics/chemobabel/chemobabel.sty')
-rw-r--r--graphics/chemobabel/chemobabel.sty274
1 files changed, 274 insertions, 0 deletions
diff --git a/graphics/chemobabel/chemobabel.sty b/graphics/chemobabel/chemobabel.sty
new file mode 100644
index 0000000000..4f3122bb37
--- /dev/null
+++ b/graphics/chemobabel/chemobabel.sty
@@ -0,0 +1,274 @@
+%
+% 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'.