mirror of
https://github.com/ankitects/anki.git
synced 2026-01-13 22:13:58 -05:00
Align LaTeX with surrounding text
So far, LaTeX images were just rendered and included as pictures. However, the bounding box of the image might not necessarily coincide with the actual baseline of the equation. By using preview.sty (which is hopefully not that big of an additional dependency), we can however access the "depth" -- the offset from the baseline -- of the generated image and correct for that.
This commit is contained in:
parent
16c5eaf00a
commit
f081001201
4 changed files with 35 additions and 3 deletions
|
|
@ -230,6 +230,7 @@ KolbyML <https://github.com/KolbyML>
|
|||
Adnane Taghi <dev@soleuniverse.me>
|
||||
Spiritual Father <https://github.com/spiritualfather>
|
||||
Emmanuel Ferdman <https://github.com/emmanuel-ferdman>
|
||||
Tony Zorman <mail@tony-zorman.com>
|
||||
|
||||
********************
|
||||
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ from __future__ import annotations
|
|||
|
||||
import html
|
||||
import os
|
||||
import re
|
||||
from dataclasses import dataclass
|
||||
|
||||
import anki
|
||||
|
|
@ -25,6 +26,7 @@ pngCommands = [
|
|||
"200",
|
||||
"-T",
|
||||
"tight",
|
||||
"--depth",
|
||||
"tmp.dvi",
|
||||
"-o",
|
||||
"tmp.png",
|
||||
|
|
@ -84,6 +86,25 @@ def render_latex(
|
|||
return html
|
||||
|
||||
|
||||
def _add_depth_to_html(
|
||||
html: str,
|
||||
latex: ExtractedLatex,
|
||||
col: anki.collection.Collection,
|
||||
) -> str:
|
||||
"""Add depth information, as provided by preview.sty, to the HTML."""
|
||||
try:
|
||||
with open(
|
||||
os.path.join(col.media.dir(), f"{latex.filename}.depth"), encoding="utf8"
|
||||
) as depth:
|
||||
html = html.replace(
|
||||
f' src="{latex.filename}"',
|
||||
f' style="vertical-align: -{depth.read()}" src="{latex.filename}"',
|
||||
)
|
||||
except Exception: # Depth information is non-critical.
|
||||
pass
|
||||
return html
|
||||
|
||||
|
||||
def render_latex_returning_errors(
|
||||
html: str,
|
||||
model: NotetypeDict,
|
||||
|
|
@ -105,7 +126,8 @@ def render_latex_returning_errors(
|
|||
|
||||
for latex in out.latex:
|
||||
# don't need to render?
|
||||
if col.media.have(latex.filename):
|
||||
if col.media.have(latex.filename) and col.media.have(f"{latex.filename}.depth"):
|
||||
html = _add_depth_to_html(html, latex, col)
|
||||
continue
|
||||
if not render_latex:
|
||||
errors.append(col.tr.preferences_latex_generation_disabled())
|
||||
|
|
@ -114,6 +136,7 @@ def render_latex_returning_errors(
|
|||
err = _save_latex_image(col, latex, header, footer, svg)
|
||||
if err is not None:
|
||||
errors.append(err)
|
||||
html = _add_depth_to_html(html, latex, col)
|
||||
|
||||
return html, errors
|
||||
|
||||
|
|
@ -137,7 +160,7 @@ def _save_latex_image(
|
|||
ext = "png"
|
||||
|
||||
# write into a temp file
|
||||
log = open(namedtmp("latex_log.txt"), "w", encoding="utf8")
|
||||
log = open(namedtmp("latex_log.txt"), "w+", encoding="utf8")
|
||||
texpath = namedtmp("tmp.tex")
|
||||
texfile = open(texpath, "w", encoding="utf8")
|
||||
texfile.write(latex)
|
||||
|
|
@ -155,6 +178,11 @@ def _save_latex_image(
|
|||
data = file.read()
|
||||
col.media.write_data(extracted.filename, data)
|
||||
os.unlink(png_or_svg)
|
||||
# add depth data
|
||||
log.seek(0)
|
||||
match = re.search(r"depth=(.*)", log.read())
|
||||
if match:
|
||||
col.media.write_data(f"{extracted.filename}.depth", match.group(1).encode())
|
||||
return None
|
||||
finally:
|
||||
os.chdir(oldcwd)
|
||||
|
|
|
|||
|
|
@ -2,6 +2,9 @@
|
|||
\special{papersize=3in,5in}
|
||||
\usepackage[utf8]{inputenc}
|
||||
\usepackage{amssymb,amsmath}
|
||||
\usepackage[active,tightpage]{preview}
|
||||
\pagestyle{empty}
|
||||
\setlength{\parindent}{0in}
|
||||
\setlength{\abovedisplayskip}{0pt}
|
||||
\begin{document}
|
||||
\begin{preview}
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ define_newtype!(NotetypeId, i64);
|
|||
pub(crate) const DEFAULT_CSS: &str = include_str!("styling.css");
|
||||
pub(crate) const DEFAULT_CLOZE_CSS: &str = include_str!("cloze_styling.css");
|
||||
pub(crate) const DEFAULT_LATEX_HEADER: &str = include_str!("header.tex");
|
||||
pub(crate) const DEFAULT_LATEX_FOOTER: &str = r"\end{document}";
|
||||
pub(crate) const DEFAULT_LATEX_FOOTER: &str = r"\end{preview}\end{document}";
|
||||
/// New entries must be handled in render.rs/add_special_fields().
|
||||
static SPECIAL_FIELDS: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
|
||||
HashSet::from_iter(vec![
|
||||
|
|
|
|||
Loading…
Reference in a new issue