pyladoc/index.html

539 lines
23 KiB
HTML
Raw Normal View History

<!DOCTYPE html>
<html lang="en" data-content_root="./" >
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Pyladoc &#8212; pyladoc documentation</title>
<script data-cfasync="false">
document.documentElement.dataset.mode = localStorage.getItem("mode") || "";
document.documentElement.dataset.theme = localStorage.getItem("theme") || "";
</script>
<!--
this give us a css class that will be invisible only if js is disabled
-->
<noscript>
<style>
.pst-js-only { display: none !important; }
</style>
</noscript>
<!-- Loaded before other Sphinx assets -->
<link href="_static/styles/theme.css?digest=8878045cc6db502f8baf" rel="stylesheet" />
<link href="_static/styles/pydata-sphinx-theme.css?digest=8878045cc6db502f8baf" rel="stylesheet" />
<link rel="stylesheet" type="text/css" href="_static/pygments.css?v=8f2a1f02" />
<!-- So that users can add custom icons -->
<script src="_static/scripts/fontawesome.js?digest=8878045cc6db502f8baf"></script>
<!-- Pre-loaded scripts that we'll load fully later -->
<link rel="preload" as="script" href="_static/scripts/bootstrap.js?digest=8878045cc6db502f8baf" />
<link rel="preload" as="script" href="_static/scripts/pydata-sphinx-theme.js?digest=8878045cc6db502f8baf" />
<script src="_static/documentation_options.js?v=5929fcd5"></script>
<script src="_static/doctools.js?v=9bcbadda"></script>
<script src="_static/sphinx_highlight.js?v=dc90522c"></script>
<script>DOCUMENTATION_OPTIONS.pagename = 'index';</script>
<link rel="index" title="Index" href="genindex.html" />
<link rel="search" title="Search" href="search.html" />
<link rel="next" title="Classes and functions" href="_autogenerated/index.html" />
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<meta name="docsearch:language" content="en"/>
<meta name="docsearch:version" content="" />
</head>
<body data-bs-spy="scroll" data-bs-target=".bd-toc-nav" data-offset="180" data-bs-root-margin="0px 0px -60%" data-default-mode="">
<div id="pst-skip-link" class="skip-link d-print-none"><a href="#main-content">Skip to main content</a></div>
<div id="pst-scroll-pixel-helper"></div>
<button type="button" class="btn rounded-pill" id="pst-back-to-top">
<i class="fa-solid fa-arrow-up"></i>Back to top</button>
<dialog id="pst-search-dialog">
<form class="bd-search d-flex align-items-center"
action="search.html"
method="get">
<i class="fa-solid fa-magnifying-glass"></i>
<input type="search"
class="form-control"
name="q"
placeholder="Search the docs ..."
aria-label="Search the docs ..."
autocomplete="off"
autocorrect="off"
autocapitalize="off"
spellcheck="false"/>
<span class="search-button__kbd-shortcut"><kbd class="kbd-shortcut__modifier">Ctrl</kbd>+<kbd>K</kbd></span>
</form>
</dialog>
<div class="pst-async-banner-revealer d-none">
<aside id="bd-header-version-warning" class="d-none d-print-none" aria-label="Version warning"></aside>
</div>
<header class="bd-header navbar navbar-expand-lg bd-navbar d-print-none">
<div class="bd-header__inner bd-page-width">
<button class="pst-navbar-icon sidebar-toggle primary-toggle" aria-label="Site navigation">
<span class="fa-solid fa-bars"></span>
</button>
<div class="col-lg-3 navbar-header-items__start">
<div class="navbar-item">
<a class="navbar-brand logo" href="#">
<p class="title logo__title">pyladoc documentation</p>
</a></div>
</div>
<div class="col-lg-9 navbar-header-items">
<div class="me-auto navbar-header-items__center">
<div class="navbar-item">
<nav>
<ul class="bd-navbar-elements navbar-nav">
<li class="nav-item ">
<a class="nav-link nav-internal" href="_autogenerated/index.html">
Classes and functions
</a>
</li>
</ul>
</nav></div>
</div>
<div class="navbar-header-items__end">
<div class="navbar-item navbar-persistent--container">
<button class="btn search-button-field search-button__button pst-js-only" title="Search" aria-label="Search" data-bs-placement="bottom" data-bs-toggle="tooltip">
<i class="fa-solid fa-magnifying-glass"></i>
<span class="search-button__default-text">Search</span>
<span class="search-button__kbd-shortcut"><kbd class="kbd-shortcut__modifier">Ctrl</kbd>+<kbd class="kbd-shortcut__modifier">K</kbd></span>
</button>
</div>
<div class="navbar-item">
<button class="btn btn-sm nav-link pst-navbar-icon theme-switch-button pst-js-only" aria-label="Color mode" data-bs-title="Color mode" data-bs-placement="bottom" data-bs-toggle="tooltip">
<i class="theme-switch fa-solid fa-sun fa-lg" data-mode="light" title="Light"></i>
<i class="theme-switch fa-solid fa-moon fa-lg" data-mode="dark" title="Dark"></i>
<i class="theme-switch fa-solid fa-circle-half-stroke fa-lg" data-mode="auto" title="System Settings"></i>
</button></div>
</div>
</div>
<div class="navbar-persistent--mobile">
<button class="btn search-button-field search-button__button pst-js-only" title="Search" aria-label="Search" data-bs-placement="bottom" data-bs-toggle="tooltip">
<i class="fa-solid fa-magnifying-glass"></i>
<span class="search-button__default-text">Search</span>
<span class="search-button__kbd-shortcut"><kbd class="kbd-shortcut__modifier">Ctrl</kbd>+<kbd class="kbd-shortcut__modifier">K</kbd></span>
</button>
</div>
<button class="pst-navbar-icon sidebar-toggle secondary-toggle" aria-label="On this page">
<span class="fa-solid fa-outdent"></span>
</button>
</div>
</header>
<div class="bd-container">
<div class="bd-container__inner bd-page-width">
<dialog id="pst-primary-sidebar-modal"></dialog>
<div id="pst-primary-sidebar" class="bd-sidebar-primary bd-sidebar hide-on-wide">
<div class="sidebar-header-items sidebar-primary__section">
<div class="sidebar-header-items__center">
<div class="navbar-item">
<nav>
<ul class="bd-navbar-elements navbar-nav">
<li class="nav-item ">
<a class="nav-link nav-internal" href="_autogenerated/index.html">
Classes and functions
</a>
</li>
</ul>
</nav></div>
</div>
<div class="sidebar-header-items__end">
<div class="navbar-item">
<button class="btn btn-sm nav-link pst-navbar-icon theme-switch-button pst-js-only" aria-label="Color mode" data-bs-title="Color mode" data-bs-placement="bottom" data-bs-toggle="tooltip">
<i class="theme-switch fa-solid fa-sun fa-lg" data-mode="light" title="Light"></i>
<i class="theme-switch fa-solid fa-moon fa-lg" data-mode="dark" title="Dark"></i>
<i class="theme-switch fa-solid fa-circle-half-stroke fa-lg" data-mode="auto" title="System Settings"></i>
</button></div>
</div>
</div>
<div class="sidebar-primary-items__end sidebar-primary__section">
<div class="sidebar-primary-item">
<div id="ethical-ad-placement"
class="flat"
data-ea-publisher="readthedocs"
data-ea-type="readthedocs-sidebar"
data-ea-manual="true">
</div></div>
</div>
</div>
<main id="main-content" class="bd-main" role="main">
<div class="bd-content">
<div class="bd-article-container">
<div class="bd-header-article d-print-none"></div>
<div id="searchbox"></div>
<article class="bd-article">
<div class="toctree-wrapper compound">
</div>
<section id="pyladoc">
<h1>Pyladoc<a class="headerlink" href="#pyladoc" title="Link to this heading">#</a></h1>
<section id="description">
<h2>Description<a class="headerlink" href="#description" title="Link to this heading">#</a></h2>
<p>Pyladoc is a Python package for programmatically generating HTML and
PDF/LaTeX output. This package specifically targets applications where reports
or results with Pandas tables and Matplotlib figures are generated
to be displayed as a website and as a PDF document without involving any manual
formatting steps.</p>
<p>This package focuses on the “Document in Code” approach for cases
where a lot of calculations and data handling is done but not a lot of
document text needs to be displayed. The multiline string capability of Python
handles this very well. In comparison to “Code in Document” templates,
Python tools support this approach out of the box—similar to docstrings.</p>
<p>LaTeX is used as the backend for PDF generation. There are excellent engines for
rendering HTML to PDF, but even if there is no requirement for
accurate typesetting, placing programmatically generated content of variable
composition and element sizes on fixed-size pages without manual intervention
is a hard problem where LaTeX is superior.</p>
</section>
<section id="example-outputs">
<h2>Example outputs<a class="headerlink" href="#example-outputs" title="Link to this heading">#</a></h2>
<p><a class="reference external" href="https://raw.githubusercontent.com/Nonannet/pyladoc/refs/heads/main/tests/out/test_latex_render1.pdf"><img alt="example output" src="_images/output_example.png" /></a></p>
<ul class="simple">
<li><p>HTML: <a class="reference external" href="https://html-preview.github.io/?url=https://github.com/Nonannet/pyladoc/blob/main/tests/out/test_html_render1.html">test_html_render1.html</a> (<a class="reference external" href="https://github.com/Nonannet/pyladoc/blob/main/tests/out/test_html_render1.html">code</a>)</p></li>
<li><p>PDF: <a class="reference external" href="https://raw.githubusercontent.com/Nonannet/pyladoc/refs/heads/main/tests/out/test_latex_render1.pdf">test_latex_render1.pdf</a> (<a class="reference external" href="https://github.com/Nonannet/pyladoc/blob/main/tests/out/test_html_render1.tex">code</a>)</p></li>
</ul>
<p>The documents are generated by the script <a class="reference download internal" download="" href="_downloads/93efa674efb48f743263074a28a5345b/test_rendering_example1_doc.py"><span class="xref download myst">tests/test_rendering_example1_doc.py</span></a>.</p>
<section id="supported-primitives">
<h3>Supported primitives<a class="headerlink" href="#supported-primitives" title="Link to this heading">#</a></h3>
<ul class="simple">
<li><p>Text (can be Markdown or HTML formatted)</p></li>
<li><p>Headings</p></li>
<li><p>Tables (Pandas, Markdown or HTML)</p></li>
<li><p>Matplotlib figures</p></li>
<li><p>LaTeX equations (block or inline)</p></li>
<li><p>Named references for figures, tables, and equations</p></li>
</ul>
</section>
<section id="key-features">
<h3>Key Features<a class="headerlink" href="#key-features" title="Link to this heading">#</a></h3>
<ul class="simple">
<li><p>HTML and PDF/LaTeX rendering of the same document</p></li>
<li><p>Single file output including figures</p></li>
<li><p>Figure and equation embedding in HTML by inline SVG, SVG in Base64, or PNG in Base64</p></li>
<li><p>Figure embedding in LaTeX as PGF/TikZ</p></li>
<li><p>Tested on Linux and Windows</p></li>
</ul>
</section>
<section id="usage-scenarios">
<h3>Usage Scenarios<a class="headerlink" href="#usage-scenarios" title="Link to this heading">#</a></h3>
<ul class="simple">
<li><p>Web services</p></li>
<li><p>Report generation for lab equipment</p></li>
</ul>
</section>
</section>
<section id="installation">
<h2>Installation<a class="headerlink" href="#installation" title="Link to this heading">#</a></h2>
<p>It can be installed with pip:</p>
<div class="highlight-bash notranslate"><div class="highlight"><pre><span></span>pip<span class="w"> </span>install<span class="w"> </span>pyladoc
</pre></div>
</div>
<p>As well as with conda:</p>
<div class="highlight-bash notranslate"><div class="highlight"><pre><span></span>conda<span class="w"> </span>install<span class="w"> </span>conda-forge::pyladoc
</pre></div>
</div>
</section>
<section id="dependencies">
<h2>Dependencies<a class="headerlink" href="#dependencies" title="Link to this heading">#</a></h2>
<p>Pyladoc depends on the markdown package.</p>
<p>Optional dependencies are:</p>
<ul class="simple">
<li><p>Matplotlib Python package for rendering LaTeX equations for HTML output</p></li>
<li><p>LaTeX for exporting to PDF or exporting Matplotlib figures to LaTeX (PGF/TikZ rendering)</p></li>
<li><p>Pandas and Jinja2 for rendering Pandas tables</p></li>
<li><p>Matplotlib for rendering Matplotlib figures (obviously)</p></li>
</ul>
<p>For the included template, the <code class="docutils literal notranslate"><span class="pre">miktex</span></code> LaTeX distribution works on Windows
and the following LaTeX setup works on Ubuntu (both tested in CI):</p>
<div class="highlight-bash notranslate"><div class="highlight"><pre><span></span>sudo<span class="w"> </span>apt-get<span class="w"> </span>update
sudo<span class="w"> </span>apt-get<span class="w"> </span>install<span class="w"> </span>-y<span class="w"> </span>texlive-latex-extra<span class="w"> </span>texlive-fonts-recommended<span class="w"> </span>lmodern<span class="w"> </span>texlive-xetex<span class="w"> </span>texlive-science
</pre></div>
</div>
</section>
<section id="usage">
<h2>Usage<a class="headerlink" href="#usage" title="Link to this heading">#</a></h2>
<p>It is easy to use, as the following example code shows:</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span><span class="w"> </span><span class="nn">pyladoc</span>
<span class="kn">import</span><span class="w"> </span><span class="nn">pandas</span><span class="w"> </span><span class="k">as</span><span class="w"> </span><span class="nn">pd</span>
<span class="n">doc</span> <span class="o">=</span> <span class="n">pyladoc</span><span class="o">.</span><span class="n">DocumentWriter</span><span class="p">()</span>
<span class="n">doc</span><span class="o">.</span><span class="n">add_markdown</span><span class="p">(</span><span class="s2">&quot;&quot;&quot;</span>
<span class="s2"> # Example</span>
<span class="s2"> This is inline LaTeX: $$</span><span class="se">\\</span><span class="s2">lambda$$</span>
<span class="s2"> This is a LaTeX block with a number:</span>
<span class="s2"> $$</span>
<span class="s2"> </span><span class="se">\\</span><span class="s2">label{eq:test1}</span>
<span class="s2"> </span><span class="se">\\</span><span class="s2">lambda_{</span><span class="se">\t</span><span class="s2">ext</span><span class="si">{mix}</span><span class="s2">} = </span><span class="se">\\</span><span class="s2">sum_{i=1}^</span><span class="si">{n}</span><span class="s2"> </span><span class="se">\\</span><span class="s2">frac{x_i </span><span class="se">\\</span><span class="s2">lambda_i}{</span><span class="se">\\</span><span class="s2">sum_{j=1}^</span><span class="si">{n}</span><span class="s2"> x_j </span><span class="se">\\</span><span class="s2">Phi_</span><span class="si">{ij}</span><span class="s2">}</span>
<span class="s2"> $$</span>
<span class="s2"> This is an example table. The table @table:pandas_example shows some random data.</span>
<span class="s2"> &quot;&quot;&quot;</span><span class="p">)</span>
<span class="n">some_data</span> <span class="o">=</span> <span class="p">{</span>
<span class="s1">&#39;Row1&#39;</span><span class="p">:</span> <span class="p">[</span><span class="s2">&quot;Line1&quot;</span><span class="p">,</span> <span class="s2">&quot;Line2&quot;</span><span class="p">,</span> <span class="s2">&quot;Line3&quot;</span><span class="p">],</span>
<span class="s1">&#39;Row2&#39;</span><span class="p">:</span> <span class="p">[</span><span class="mi">120</span><span class="p">,</span> <span class="mi">100</span><span class="p">,</span> <span class="mi">110</span><span class="p">],</span>
<span class="s1">&#39;Row3&#39;</span><span class="p">:</span> <span class="p">[</span><span class="s1">&#39;12 g/km&#39;</span><span class="p">,</span> <span class="s1">&#39;&gt; 150 g/km&#39;</span><span class="p">,</span> <span class="s1">&#39;110 g/km&#39;</span><span class="p">]</span>
<span class="p">}</span>
<span class="n">df</span> <span class="o">=</span> <span class="n">pd</span><span class="o">.</span><span class="n">DataFrame</span><span class="p">(</span><span class="n">some_data</span><span class="p">)</span>
<span class="n">doc</span><span class="o">.</span><span class="n">add_table</span><span class="p">(</span><span class="n">df</span><span class="p">,</span> <span class="s1">&#39;This is a pandas example table&#39;</span><span class="p">,</span> <span class="s1">&#39;pandas_example&#39;</span><span class="p">)</span>
<span class="n">html_code</span> <span class="o">=</span> <span class="n">doc</span><span class="o">.</span><span class="n">to_html</span><span class="p">()</span>
<span class="nb">print</span><span class="p">(</span><span class="n">html_code</span><span class="p">)</span>
<span class="n">doc</span><span class="o">.</span><span class="n">to_pdf</span><span class="p">(</span><span class="s1">&#39;test.pdf&#39;</span><span class="p">)</span>
</pre></div>
</div>
</section>
<section id="contributing">
<h2>Contributing<a class="headerlink" href="#contributing" title="Link to this heading">#</a></h2>
<p>Contributions are welcome; please open an issue or submit a pull request on GitHub.</p>
</section>
<section id="developer-guide">
<h2>Developer Guide<a class="headerlink" href="#developer-guide" title="Link to this heading">#</a></h2>
<p>To get started with developing the <code class="docutils literal notranslate"><span class="pre">pyladoc</span></code> package, follow these steps.</p>
<p>First, clone the repository to your local machine using Git:</p>
<div class="highlight-bash notranslate"><div class="highlight"><pre><span></span>git<span class="w"> </span>clone<span class="w"> </span>https://github.com/Nonannet/pyladoc.git
<span class="nb">cd</span><span class="w"> </span>pyladoc
</pre></div>
</div>
<p>Its recommended to set up a venv:</p>
<div class="highlight-bash notranslate"><div class="highlight"><pre><span></span>python<span class="w"> </span>-m<span class="w"> </span>venv<span class="w"> </span>.venv
<span class="nb">source</span><span class="w"> </span>.venv/bin/activate<span class="w"> </span><span class="c1"># On Windows use `.venv\Scripts\activate`</span>
</pre></div>
</div>
<p>Install the package and development dependencies while keeping files in the
current directory:</p>
<div class="highlight-bash notranslate"><div class="highlight"><pre><span></span>pip<span class="w"> </span>install<span class="w"> </span>-e<span class="w"> </span>.<span class="o">[</span>dev<span class="o">]</span>
</pre></div>
</div>
<p>Ensure that everything is set up correctly by running the tests:</p>
<div class="highlight-bash notranslate"><div class="highlight"><pre><span></span>pytest
</pre></div>
</div>
</section>
<section id="license">
<h2>License<a class="headerlink" href="#license" title="Link to this heading">#</a></h2>
<p>This project is licensed under the MIT License - see the <a class="reference internal" href="LICENSE.html"><span class="doc std std-doc">LICENSE</span></a> file for details.</p>
</section>
</section>
</article>
<footer class="prev-next-footer d-print-none">
<div class="prev-next-area">
<a class="right-next"
href="_autogenerated/index.html"
title="next page">
<div class="prev-next-info">
<p class="prev-next-subtitle">next</p>
<p class="prev-next-title">Classes and functions</p>
</div>
<i class="fa-solid fa-angle-right"></i>
</a>
</div>
</footer>
</div>
<dialog id="pst-secondary-sidebar-modal"></dialog>
<div id="pst-secondary-sidebar" class="bd-sidebar-secondary bd-toc"><div class="sidebar-secondary-items sidebar-secondary__inner">
<div class="sidebar-secondary-item">
<div
id="pst-page-navigation-heading-2"
class="page-toc tocsection onthispage">
<i class="fa-solid fa-list"></i> On this page
</div>
<nav class="bd-toc-nav page-toc" aria-labelledby="pst-page-navigation-heading-2">
<ul class="visible nav section-nav flex-column">
<li class="toc-h2 nav-item toc-entry"><a class="reference internal nav-link" href="#description">Description</a></li>
<li class="toc-h2 nav-item toc-entry"><a class="reference internal nav-link" href="#example-outputs">Example outputs</a><ul class="nav section-nav flex-column">
<li class="toc-h3 nav-item toc-entry"><a class="reference internal nav-link" href="#supported-primitives">Supported primitives</a></li>
<li class="toc-h3 nav-item toc-entry"><a class="reference internal nav-link" href="#key-features">Key Features</a></li>
<li class="toc-h3 nav-item toc-entry"><a class="reference internal nav-link" href="#usage-scenarios">Usage Scenarios</a></li>
</ul>
</li>
<li class="toc-h2 nav-item toc-entry"><a class="reference internal nav-link" href="#installation">Installation</a></li>
<li class="toc-h2 nav-item toc-entry"><a class="reference internal nav-link" href="#dependencies">Dependencies</a></li>
<li class="toc-h2 nav-item toc-entry"><a class="reference internal nav-link" href="#usage">Usage</a></li>
<li class="toc-h2 nav-item toc-entry"><a class="reference internal nav-link" href="#contributing">Contributing</a></li>
<li class="toc-h2 nav-item toc-entry"><a class="reference internal nav-link" href="#developer-guide">Developer Guide</a></li>
<li class="toc-h2 nav-item toc-entry"><a class="reference internal nav-link" href="#license">License</a></li>
</ul>
</nav></div>
<div class="sidebar-secondary-item">
<div role="note" aria-label="source link">
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="_sources/index.md.txt"
rel="nofollow">Show Source</a></li>
</ul>
</div></div>
</div></div>
</div>
<footer class="bd-footer-content">
</footer>
</main>
</div>
</div>
<!-- Scripts loaded after <body> so the DOM is not blocked -->
<script defer src="_static/scripts/bootstrap.js?digest=8878045cc6db502f8baf"></script>
<script defer src="_static/scripts/pydata-sphinx-theme.js?digest=8878045cc6db502f8baf"></script>
<footer class="bd-footer">
<div class="bd-footer__inner bd-page-width">
<div class="footer-items__start">
<div class="footer-item">
<p class="copyright">
© Copyright 2025, Nicolas Kruse.
<br/>
</p>
</div>
<div class="footer-item">
<p class="sphinx-version">
Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 8.2.3.
<br/>
</p>
</div>
</div>
<div class="footer-items__end">
<div class="footer-item">
<p class="theme-version">
<!-- # L10n: Setting the PST URL as an argument as this does not need to be localized -->
Built with the <a href="https://pydata-sphinx-theme.readthedocs.io/en/stable/index.html">PyData Sphinx Theme</a> 0.16.1.
</p></div>
</div>
</div>
</footer>
</body>
</html>