Skip to content

Commit

Permalink
LaTeX to PreTeXt importer (#719)
Browse files Browse the repository at this point in the history
* initial setup for plastex conversion

* Some progress

* work in temp directory

* get themes working

* closer to math working

* further improvements

* add more templates

* more templates

* add more templates

* update index

* work on sections

* allow input/includes

* put introductions only when needed into chapters

* smart switch between book and article

* nicer file names

* set default chunking

* fix up strange characters

* improve citations

* update changelog

* update poetry.lock

* format

* update types

* update types

* revert
  • Loading branch information
oscarlevin authored May 1, 2024
1 parent de80558 commit 6798022
Show file tree
Hide file tree
Showing 44 changed files with 1,668 additions and 440 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ Instructions: Add a subsection under `[UNRELEASED]` for additions, fixes, change

## [UNRELEASED]

### Added

- `pretext import` command. Pass a path to a `.tex` file and it will use PlasTeX to do its best to convert the latex to pretext.

## [2.3.10] - 2024-04-10

## [2.3.9] - 2024-03-02
Expand Down
32 changes: 0 additions & 32 deletions CHANGELOG.md.tmp

This file was deleted.

1,300 changes: 892 additions & 408 deletions poetry.lock

Large diffs are not rendered by default.

46 changes: 46 additions & 0 deletions pretext/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,13 @@
from typing import Any, Callable, List, Literal, Optional
from functools import update_wrapper


from . import (
utils,
templates,
core,
constants,
plastex,
VERSION,
CORE_COMMIT,
)
Expand Down Expand Up @@ -822,3 +824,47 @@ def deploy(
ctx.invoke(view, stage=True)
else:
project.deploy(update_source=update_source, skip_staging=True)


# pretext import
@main.command(
short_help="Experimental: convert a latex file to pretext",
context_settings=CONTEXT_SETTINGS,
name="import",
)
@nice_errors
@click.pass_context
@click.argument("latex_file", required=True)
@click.option("-o", "--output", help="Specify output directory", required=False)
def import_command(ctx: click.Context, latex_file: str, output: str) -> None:
"""
Experimental: convert a latex file to pretext
"""
latex_file_path = Path(latex_file).resolve()
if not latex_file_path.exists():
log.error(f"File {latex_file_path} does not exist.")
return
if output is not None:
output_path = Path(output).resolve()
if not output_path.exists():
log.warning("Output directory does not exist. Creating it.")
output_path.mkdir(parents=True)
else:
output_path = Path.cwd() / "imports" / latex_file_path.stem
output_path.mkdir(parents=True, exist_ok=True)
# Now we use plastex to convert:
log.info(f"Converting {latex_file_path} to PreTeXt.")
with tempfile.TemporaryDirectory(prefix="pretext_") as tmpdirname:
temp_path = Path(tmpdirname) / "import"
temp_path.mkdir()
log.info(f"Using temporary directory {temp_path}")
# change to this directory to run plastex
with utils.working_directory(temp_path):
try:
plastex.convert(latex_file_path, output_path)
shutil.copytree(temp_path, output_path, dirs_exist_ok=True)
log.debug(f"Conversion done in {temp_path}")
except Exception as e:
log.error(e)
log.debug("Exception info:\n------------------------\n", exc_info=True)
raise SystemExit(1)
24 changes: 24 additions & 0 deletions pretext/plastex/Alignment.jinja2s
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
name: center centering centerline
<!-- \begin{center} -->
{{ obj }}
<!-- \end{center} -->
{# #}

name: flushleft raggedright leftline
<!-- \begin{flushleft} -->
{{ obj }}
<!-- \end{flushleft} -->
{# #}


name: raggedleft flushright llap
<!-- \begin{flushright} -->
{{ obj }}
<!-- \end{flushright} -->
{# #}

name: raggedbottom
<!-- \begin{raggedbottom} -->
{{ obj }}
<!-- \end{raggedbottom} -->
{# #}
15 changes: 15 additions & 0 deletions pretext/plastex/Arrays.jinja2s
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
name: tabular array tabular* tabularx
<tabular>
{% for row in obj %}
<row>
{% for cell in row %}
<cell>{{ cell }}</cell>
{% endfor %}
</row>
{% endfor %}
</tabular>

name: multicolumn
{{ obj }}

name: cline toprule bottomrule midrule cmidrule morecmidrules addlinespace specialrule
15 changes: 15 additions & 0 deletions pretext/plastex/Bibliography.jinja2s
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
name: thebibliography
<references>
{% for item in obj %}
<biblio xml:id="{{ item.id }}">{{ item }}</biblio>
{% endfor %}
</references>

name: bibliography
<references>

{{ obj }}

</references>


13 changes: 13 additions & 0 deletions pretext/plastex/Boxes.jinja2s
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
name: mbox makebox
<!-- \mbox{ -->{{ obj }}<!-- } -->

name: fbox framebox
<!-- \fbox{ -->{{ obj }}<!-- } -->

name: parbox
<!-- \parbox -->{{ obj }}<!-- } -->

name: minipage
<!-- \minipage{ -->{{ obj }}<!-- } -->

name: raisebox rule
2 changes: 2 additions & 0 deletions pretext/plastex/Breaking.jinja2s
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
name: linebreak \ newline pagebreak newpage clearpage cleardoublepage
<!-- break: {{ obj.nodeName }} -->
13 changes: 13 additions & 0 deletions pretext/plastex/Crossref.jinja2s
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
name: ref
{% if 'label' in obj.idref and obj.idref.label.ref %}<xref ref="{{obj.idref.label.url}}">{{obj.idref.label.ref}}</xref>{% else %}??{% endif %}

name: eqref
{% if 'label' in obj.idref and obj.idref.label.ref %}<xref ref="{{obj.idref.label.url}}">{{obj.idref.label.ref}}</xref>{% else %}??{% endif %}

name: cref Cref
{% if 'label' in obj.idref and obj.idref.label.ref %}<xref ref="{{obj.idref.label.url}}">{{ obj.refname() }} {{obj.idref.label.ref}}</xref>{% else %}??{% endif %}

name: pageref
{% if 'label' in obj.idref and obj.idref.label.ref %}<xref ref="{{ obj.idref.label.url }}"/>{% else %}??{% endif %}

name: label
17 changes: 17 additions & 0 deletions pretext/plastex/Floats.jinja2s
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
name: figure figure*
<figure {% if obj.title %}xml:id="{{ obj.title.id }}"{% endif %}>
{{ obj }}
</figure>

name: table table*
<table xml:id="{% if obj.title %}{{ obj.title.id}}{% else %}{{ obj.id }}{% endif %}">
{{ obj }}
</table>

name: marginpar
<aside>{{ obj.attributes.right }}</aside>

name: caption
<caption>
{{ obj }}
</caption>
87 changes: 87 additions & 0 deletions pretext/plastex/FontSelection.jinja2s
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
name: mdseries textmd
<!-- \textmd{ -->{{ obj }}<!-- }-->

name: bfseries textbf
<!-- \textbf --><term>{{ obj }}</term>

name: rmfamily textrm
<!-- \textrm{ -->{{ obj }}<!-- } -->

name: sffamily textsf
<!-- \textsf --><init>{{ obj }}</init>

name: ttfamily texttt
<!-- \texttt --><c>{{ obj }}</c>

name: upshape textup
<!-- \textup --><init>{{ obj }}</init>

name: itshape textit
<!-- \textit --><em>{{ obj }}</em>

name: slshape textsl
<!-- \textsl --><em>{{ obj }}</em>

name: scshape textsc
<!-- \textsc --><init>{{ obj }}</init>

name: textnormal
<!-- \textnormal{ -->{{ obj }}<!-- } -->

name: rm
<!-- \rm{ -->{{ obj }}<!-- } -->

name: cal
<!-- \cal{ -->{{ obj }}<!-- } -->

name: it
<!-- \it --><em>{{ obj }}</em>

name: sl
<!-- \sl{ -->{{ obj }}<!-- } -->

name: bf
<!-- \bf{ -->{{ obj }}<!-- } -->

name: tt
<!-- \tt --><init>{{ obj }}</inti>

name: sc
<!-- \sc --><init>{{ obj }}</init>


name: tiny
<!-- \tiny{ -->{{ obj }}<!-- } -->


name: scriptsize
<!-- \scriptsize{ -->{{ obj }}<!-- } -->

name: footnotesize
<!-- \footnotesize{ -->{{ obj }}<!-- } -->

name: small
<!-- \small{ -->{{ obj }}<!-- } -->

name: normalsize
<!-- \normalsize{ -->{{ obj }}<!-- } -->

name: large
<!-- \large{ -->{{ obj }}<!-- } -->

name: Large
<!-- \xlarge{ -->{{ obj }}<!-- } -->

name: LARGE
<!-- \xxlarge{ -->{{ obj }}<!-- } -->

name: huge
<!-- \huge{ -->{{ obj }}<!-- } -->

name: Huge
<!-- \xhuge{ -->{{ obj }}<!-- } -->


name: symbol
<!-- \symbol{} -->{{obj}}<!-- } -->

7 changes: 7 additions & 0 deletions pretext/plastex/Footnotes.jinja2s
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
name: footnote
<fn>{{ obj }}</fn>

name: footnotemark
<fn>{{ obj }}</fn>

name: footnotetext
11 changes: 11 additions & 0 deletions pretext/plastex/Index.jinja2s
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
name: theindex printindex
<index>
<title>Index</title>
<index-list />
</index>

name: index
<idx><h>{{obj.argSource[1:-1]}}</h></idx>

name: see seealso
<idx><h>{{ obj.captionName }}</h></idx>
21 changes: 21 additions & 0 deletions pretext/plastex/Lists.jinja2s
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
name: itemize
<ul>
{% for item in obj %}
<li>{{ item }}</li>
{% endfor %}
</ul>

name: enumerate
<ol>
{% for item in obj %}
<li>{{ item }}</li>
{% endfor %}
</ol>

name: list trivlist description
<dl>
{% for item in obj %}
<title>{{ item.attributes.term or obj.attributes.defaultlabel }}</title>
<li>{{ item }}</li>
{% endfor %}
</dl>
6 changes: 6 additions & 0 deletions pretext/plastex/Pictures.jinja2s
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
name: picture
<image source="{{ obj.image.url }}" alt="{{ obj.source }}" width="{{ obj.image.width.px }}">
<shortdescription>
{{ obj.source }}
</shortdescription>
</image>
14 changes: 14 additions & 0 deletions pretext/plastex/Quotations.jinja2s
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
name: quote
<blockquote>
{{ obj }}
</blockquote>

name: quotation
<blockquote>
{{ obj }}
</blockquote>

name: verse
<poem>
{{ obj }}
</poem>
Loading

0 comments on commit 6798022

Please sign in to comment.