273 lines
8.8 KiB
Nix
273 lines
8.8 KiB
Nix
# TODO: Remove LaTeX-Code, replace with renderer-methods
|
|
{ chunks, core, evaluator, renderer, ... }:
|
|
let
|
|
inherit(core) debug error indentation list string type;
|
|
inherit(evaluator) evaluate;
|
|
inherit(renderer) toBody toCaption toDescription putCaption render;
|
|
|
|
# { ... } -> [ string ]:
|
|
mapChemeToken
|
|
= token:
|
|
let
|
|
phantom
|
|
= text:
|
|
if token.phantom or false
|
|
then
|
|
"\\phantom{${text}}"
|
|
else
|
|
text;
|
|
in
|
|
if token ? plus
|
|
then
|
|
[ "\\+" ]
|
|
else if token ? arrow
|
|
then
|
|
let
|
|
optionals
|
|
= list.map
|
|
(
|
|
argument:
|
|
type.matchPrimitiveOrPanic argument
|
|
{
|
|
bool = error.throw "Bool in mapChemeToken?";
|
|
null = "[]";
|
|
int = "[${string argument}]";
|
|
float = "[${string argument}]";
|
|
string = "[\\tiny{${argument}}]";
|
|
set
|
|
= if argument ? text
|
|
then let
|
|
pos
|
|
= if argument ? pos
|
|
then
|
|
".${argument.pos}"
|
|
else
|
|
"";
|
|
in
|
|
"[*{0${pos}}\\tiny{${argument.text}}]"
|
|
else
|
|
debug.panic "mapChemeToken" "Argument does not has a text.";
|
|
}
|
|
)
|
|
token.arguments;
|
|
from = token.config.from or "";
|
|
till = token.config.till or "";
|
|
fromTo
|
|
= if from != ""
|
|
|| till != ""
|
|
then
|
|
"(${string from}--${string till})"
|
|
else
|
|
"";
|
|
angle = token.config.angle or "";
|
|
length = token.config.length or "";
|
|
config
|
|
= if angle != "" || length != ""
|
|
then
|
|
"[${string angle},${string length}]"
|
|
else
|
|
"";
|
|
in
|
|
[ (phantom "\\arrow${fromTo}{${token.arrow}${string.concat optionals}}${config}") ]
|
|
else let
|
|
yield = token.config.yield or null;
|
|
withYield = if yield != null then "Yield{${string yield}}" else "";
|
|
in if token ? substance
|
|
then
|
|
if token.number or false
|
|
&& token.code or false
|
|
then
|
|
[ (phantom "\\directlua{substances.printMoleculeWithNumberCode([[${token.substance}]])}") ]
|
|
else if token.number or false
|
|
then
|
|
[ (phantom "\\directlua{substances.printMoleculeWithNumber([[${token.substance}]])}") ]
|
|
else if token.code or false
|
|
then
|
|
[ (phantom "\\directlua{substances.printMoleculeWithCode([[${token.substance}]])}") ]
|
|
else if token.text or null != null
|
|
then
|
|
[ (phantom "\\chemname{\\directlua{substances.printMolecule([[${token.substance}]])}}{\\tiny ${token.text}}") ]
|
|
else
|
|
[ (phantom "\\directlua{substances.printMolecule([[${token.substance}]])}") ]
|
|
else let
|
|
movPart
|
|
= type.matchPrimitiveOrPanic token.movPart
|
|
{
|
|
list = string.concat token.movPart;
|
|
string = token.movPart;
|
|
};
|
|
movPart'
|
|
= if token ? movPart
|
|
then
|
|
[ "\\chemmove{${movPart}}" ]
|
|
else
|
|
[];
|
|
figPart
|
|
= type.matchPrimitiveOrPanic token.figPart
|
|
{
|
|
list = string.concat token.figPart;
|
|
string = token.figPart;
|
|
};
|
|
in if token ? name
|
|
then
|
|
[
|
|
(phantom "\\chemname{\\chemfig{${figPart}}}{\\tiny{${token.name}}}")
|
|
] ++ movPart'
|
|
else
|
|
[ (phantom "\\chemfig{${figPart}}") ] ++ movPart';
|
|
|
|
|
|
# [ { ... } ] -> [ string ]:
|
|
mapChemeLine
|
|
= line:
|
|
list.concatMap
|
|
(
|
|
{ scale ? 1.5, scheme, skip ? null, only ? null, uncover ? null, ... } @ line:
|
|
(
|
|
if only != null
|
|
then
|
|
[ "\\only<${only}>{%" ]
|
|
else if uncover != null
|
|
then
|
|
[ "\\uncover<${uncover}>{%" ]
|
|
else
|
|
[]
|
|
)
|
|
++ [
|
|
"\\scalebox{${string scale}}%"
|
|
"{%" indentation.more
|
|
]
|
|
++ [ "\\schemestart%" ]
|
|
++ ( list.concatMap mapChemeToken scheme )
|
|
++ [ "\\schemestop%" ]
|
|
++ (
|
|
if line ? movPart
|
|
then
|
|
[ "\\chemmove{%" indentation.more ]
|
|
++ line.movPart
|
|
++ [ indentation.less "}%" ]
|
|
else
|
|
[]
|
|
)
|
|
++ [ indentation.less "}%" ]
|
|
++ (
|
|
let
|
|
skip'
|
|
= if skip != null
|
|
then
|
|
"[${string skip}\\normalbaselineskip]"
|
|
else
|
|
"";
|
|
|
|
in
|
|
[ "\\chemnameinit{}\\\\${skip'}%" ]
|
|
)
|
|
++ (
|
|
if only != null || uncover != null
|
|
then
|
|
[ "}%" ]
|
|
else
|
|
[]
|
|
)
|
|
)
|
|
line;
|
|
|
|
evaluateCheme
|
|
= { ... } @ document:
|
|
{ ... } @ state:
|
|
{ dependencies, ... } @ scheme:
|
|
let
|
|
state' = state;
|
|
in
|
|
state
|
|
// {
|
|
dependencies = state'.dependencies ++ dependencies;
|
|
schemes
|
|
= state'.schemes
|
|
// {
|
|
counter = state'.schemes.counter + 1;
|
|
};
|
|
};
|
|
|
|
# { ... } -> Document::Chunk::Cheme -> [ indentation | string ]:
|
|
renderCheme
|
|
= _:
|
|
{ numbers, body, label ? null, ... } @ scheme:
|
|
output:
|
|
if output == "LaTeX"
|
|
then
|
|
[
|
|
"\\begin{scheme}[H]" indentation.more
|
|
]
|
|
++ (
|
|
if numbers
|
|
then
|
|
[ "\\numAtoms" ]
|
|
else
|
|
[]
|
|
)
|
|
++ [
|
|
"\\centering{%" indentation.more
|
|
]
|
|
++ ( mapChemeLine body )
|
|
++ [ indentation.less "}%" ]
|
|
++ ( putCaption scheme )
|
|
++ (
|
|
if label != null
|
|
then
|
|
[ "\\labelScheme{${label}}%" ]
|
|
else
|
|
[ ]
|
|
)
|
|
++ [ indentation.less "\\end{scheme}" ]
|
|
else if output == "Markdown"
|
|
then
|
|
[]
|
|
else
|
|
debug.panic "render" "Unknown output ${output}";
|
|
in
|
|
{
|
|
# string | set -> [ T ] -> Document::Chunk::Cheme:
|
|
Cheme
|
|
= {
|
|
Arrow
|
|
= arrow:
|
|
config:
|
|
arguments:
|
|
{ inherit arrow config arguments; };
|
|
Plus = { plus = null; };
|
|
__functor
|
|
= self:
|
|
config:
|
|
body:
|
|
chunks.Chunk "Cheme"
|
|
{
|
|
render = renderCheme;
|
|
evaluate = evaluateCheme;
|
|
}
|
|
(
|
|
type.matchPrimitiveOrPanic config
|
|
{
|
|
string
|
|
= {
|
|
caption = toCaption config;
|
|
description = toDescription config;
|
|
label = null;
|
|
numbers = false;
|
|
dependencies = [];
|
|
};
|
|
set
|
|
= {
|
|
caption = toCaption ( config.caption or config.description or "" );
|
|
description = toDescription ( config.description or config.caption or "" );
|
|
label = config.label or null;
|
|
numbers = config.numbers or false;
|
|
dependencies = config.dependencies or [];
|
|
};
|
|
}
|
|
// {
|
|
body = list.expect body;
|
|
}
|
|
);
|
|
};
|
|
} |