<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.10.0">Jekyll</generator><link href="https://www.kodymirus.cz/testblog/feed.xml" rel="self" type="application/atom+xml" /><link href="https://www.kodymirus.cz/testblog/" rel="alternate" type="text/html" /><updated>2025-11-27T12:07:05+00:00</updated><id>https://www.kodymirus.cz/testblog/feed.xml</id><title type="html">TeX4ht Blog Sample</title><subtitle>This site provides sample configuration for blog authored in LaTeX</subtitle><entry><title type="html">Setup Blog with GitHub Actions</title><link href="https://www.kodymirus.cz/testblog/2025/07/01/setup-blog-with-github-actions.html" rel="alternate" type="text/html" title="Setup Blog with GitHub Actions" /><published>2025-07-01T16:04:49+00:00</published><updated>2025-07-01T16:04:49+00:00</updated><id>https://www.kodymirus.cz/testblog/2025/07/01/setup-blog-with-github-actions</id><content type="html" xml:base="https://www.kodymirus.cz/testblog/2025/07/01/setup-blog-with-github-actions.html"><![CDATA[<!--   l. 9   --><p class='indent'>   This article describes how to configure GitHub Actions to automatically compile
LaTeX sources for a static blog built with tools like <span class='ec-lmtt-10'>make4ht </span>and Jekyll. It covers file
tracking, automatic build triggering, and committing generated files back to the
repository.
</p><!--   l. 13   --><p class='indent'>   You can find the YAML configuration in the <a href='https://github.com/michal-h21/testblog/blob/main/.github/workflows/main.yml'>.github/workflows/main.yml</a>
file.

</p>   
<h3 class='likesectionHead' id='contents'><a id='x1-1000'></a>Contents</h3>
<div class='tableofcontents'>   
<span class='sectionToc'>1 <a href='#problem-git-and-modification-times' id='QQ2-1-2'>Problem: Git and Modification Times</a></span>
<br />   <span class='subsectionToc'>1.1 <a href='#restoring-timestamps-with-github-actions' id='QQ2-1-3'>Restoring Timestamps with GitHub Actions</a></span>
<br />   <span class='sectionToc'>2 <a href='#working-with-multiple-branches' id='QQ2-1-4'>Working with Multiple Branches</a></span>
<br />   <span class='sectionToc'>3 <a href='#compiling-latex-on-github' id='QQ2-1-5'>Compiling LaTeX on GitHub</a></span>
<br />   <span class='subsectionToc'>3.1 <a href='#using-a-marker-file-to-trigger-compilation' id='QQ2-1-6'>Using a Marker File to Trigger Compilation</a></span>
<br />   <span class='subsectionToc'>3.2 <a href='#compilation-with-texlive-action' id='QQ2-1-7'>Compilation with TexLive Action</a></span>
<br />   <span class='sectionToc'>4 <a href='#committing-generated-files-back-to-github' id='QQ2-1-8'>Committing Generated Files Back to GitHub</a></span>
<br />   <span class='sectionToc'>5 <a href='#configure-github-pages' id='QQ2-1-9'>Configure Github Pages</a></span>
<br />   <span class='sectionToc'>6 <a href='#preventing-infinite-build-loops' id='QQ2-1-11'>Preventing Infinite Build Loops</a></span>
</div>   

<h3 class='sectionHead' id='problem-git-and-modification-times'><span class='titlemark'>1   </span> <a id='x1-20001'></a>Problem: Git and Modification Times</h3>
<!--   l. 21   --><p class='noindent'>Git does not preserve file modification times when cloning or checking out
repositories. However, tools like <span class='ec-lmtt-10'>make4ht </span>or other build systems may rely on these
timestamps to detect changed files. To compile only updated LaTeX sources, we need
to <span class='ec-lmri-10'>restore original modification times </span>from the commit history.
                                                                  

                                                                  

</p>   
<h4 class='subsectionHead' id='restoring-timestamps-with-github-actions'><span class='titlemark'>1.1   </span> <a id='x1-30001.1'></a>Restoring Timestamps with GitHub Actions</h4>
<!--   l. 28   --><p class='noindent'>We can restore modification times using a custom script that extracts timestamps
from git history:
                                                                  

                                                                  
</p>   
<pre class='verbatim' id='verbatim-1'>
- name: Restore timestamps
  run: |
    git ls-files -z | while read -d ’’ file; do
      if [ -f "$file" ]; then
        timestamp=$(git log --pretty=format:%cd -n 1 --date=iso -- "$file")
        if [ -n "$timestamp" ]; then
          touch -d "$timestamp" "$file"
        fi
      fi
    done
</pre>
<!--   l. 41   --><p class='nopar'>
</p><!--   l. 43   --><p class='indent'>   This requires the full commit history, not just the latest commit. You must ensure
the following step is included in your GitHub Actions workflow:
                                                                  

                                                                  
</p>   
<pre class='verbatim' id='verbatim-2'>
- uses: actions/checkout@v4
  with:
    fetch-depth: 0
</pre>
<!--   l. 50   --><p class='nopar'>
</p><!--   l. 52   --><p class='indent'>   This fetches the complete Git history so the script can determine modification
times correctly.

</p>   
<h3 class='sectionHead' id='working-with-multiple-branches'><span class='titlemark'>2   </span> <a id='x1-40002'></a>Working with Multiple Branches</h3>
<!--   l. 56   --><p class='noindent'>For better organization, we use two branches: </p>
<ul class='itemize1'>     
<li class='itemize'><span class='ec-lmtt-10'>main </span>branch: Contains source LaTeX files and build scripts
</li>
<li class='itemize'><span class='ec-lmtt-10'>html </span>branch: Contains generated HTML files served by GitHub Pages</li></ul>
<!--   l. 62   --><p class='indent'>   The workflow checks out both branches and synchronizes changes from <span class='ec-lmtt-10'>main </span>to
<span class='ec-lmtt-10'>html </span>before compilation.

</p>   
<h3 class='sectionHead' id='compiling-latex-on-github'><span class='titlemark'>3   </span> <a id='x1-50003'></a>Compiling LaTeX on GitHub</h3>
<!--   l. 66   --><p class='noindent'>It is possible to run the full LaTeX to HTML compilation process directly on
GitHub, without needing to generate files locally.

</p>   
<h4 class='subsectionHead' id='using-a-marker-file-to-trigger-compilation'><span class='titlemark'>3.1   </span> <a id='x1-60003.1'></a>Using a Marker File to Trigger Compilation</h4>
<!--   l. 71   --><p class='noindent'>To control whether a file should be rebuilt, we use a marker file named after the
source file with the extension <span class='ec-lmtt-10'>.published</span>. It stores the timestamp of the last
successful publication.
                                                                  

                                                                  
</p><!--   l. 74   --><p class='indent'>   It is created automatically if you use the <span class='ec-lmtt-10'>staticsite </span>extension, but you can also
create it manually, if you want to compile your file only on Github, without local
testing.
</p><!--   l. 77   --><p class='indent'>   For example, for a file named <span class='ec-lmtt-10'>tex_filename.tex</span>, create a corresponding marker
file:
                                                                  

                                                                  
</p>   
<pre class='verbatim' id='verbatim-3'>
$ date +%s &gt; tex_filename.published
</pre>
<!--   l. 81   --><p class='nopar'>
</p><!--   l. 83   --><p class='indent'>   This command stores the current UNIX timestamp in the marker file. The build
script on the GitHub server can then compare this value with the file’s modification
time to decide whether recompilation is needed.
</p><!--   l. 87   --><p class='indent'>   Whether the <span class='ec-lmtt-10'>.published </span>file was created manually or by the <span class='ec-lmtt-10'>staticsite</span>
extension, make sure to commit it to the repository—GitHub Actions needs it to be
present during the build.

</p>   
<h4 class='subsectionHead' id='compilation-with-texlive-action'><span class='titlemark'>3.2   </span> <a id='x1-70003.2'></a>Compilation with TexLive Action</h4>
<!--   l. 93   --><p class='noindent'>The compilation process uses the <a href='https://github.com/xu-cheng/texlive-action'><span class='ec-lmtt-10'>xu-cheng/texlive-action</span></a> which provides a full
TeX Live environment. The workflow changes to the <span class='ec-lmtt-10'>texposts </span>directory and
executes the <span class='ec-lmtt-10'>rebuild.sh </span>script. This script handles the compilation of modified
LaTeX documents into HTML format by processing only the files that have changed
since the last build, ensuring efficient compilation of large documentation
projects.

</p>   
<h3 class='sectionHead' id='committing-generated-files-back-to-github'><span class='titlemark'>4   </span> <a id='x1-80004'></a>Committing Generated Files Back to GitHub</h3>
<!--   l. 101   --><p class='noindent'>Every build generates HTML and CSS files, and these are automatically
committed to the <span class='ec-lmtt-10'>html </span>branch for publishing with GitHub Pages, using the
<a href='https://github.com/stefanzweifel/git-auto-commit-action'><span class='ec-lmtt-10'>git-auto-commit-action</span></a>.
</p><!--   l. 105   --><p class='indent'>   A typical workflow step might look like this:
                                                                  

                                                                  
</p>   
<pre class='verbatim' id='verbatim-4'>
- name: Autocommit generated files
  uses: stefanzweifel/git-auto-commit-action@v4
  with:
    commit_message: "Save generated files"
    file_pattern: docs/*
    branch: html
    push_options: --force
</pre>
<!--   l. 115   --><p class='nopar'>
</p><!--   l. 117   --><p class='indent'>   This commits and pushes the generated files to the <span class='ec-lmtt-10'>html </span>branch automatically,
making them available to GitHub Pages.

</p>   
<h3 class='sectionHead' id='configure-github-pages'><span class='titlemark'>5   </span> <a id='x1-90005'></a>Configure Github Pages</h3>
<!--   l. 122   --><p class='noindent'>To configure GitHub Pages to serve content from the <span class='ec-lmtt-10'>docs </span>directory in the <span class='ec-lmtt-10'>html</span>
branch, follow these steps:
</p><!--   l. 124   --><p class='indent'>     
</p>
<ol class='enumerate1'>
<li class='enumerate' id='x1-9002x1'>Open your repository on GitHub.
</li>
<li class='enumerate' id='x1-9004x2'>Navigate to the <span class='ec-lmbx-10'>Settings </span>tab.
</li>
<li class='enumerate' id='x1-9006x3'>In the left-hand menu, select <span class='ec-lmbx-10'>Pages</span>.
</li>
<li class='enumerate' id='x1-9008x4'>     
<!--   l. 128   --><p class='noindent'>Under the <span class='ec-lmbx-10'>Source </span>section: </p>
                                                                  

                                                                  
<ul class='itemize1'>         
<li class='itemize'>Set the branch to <span class='ec-lmtt-10'>html</span>.
</li>
<li class='itemize'>Set the folder to <span class='ec-lmtt-10'>/docs</span>.</li></ul>
</li>
<li class='enumerate' id='x1-9010x5'>Click <span class='ec-lmbx-10'>Save</span>.</li></ol>
   
<h4 class='likesubsectionHead' id='accessing-your-blog'><a id='x1-10000'></a>Accessing your blog</h4>
<!--   l. 138   --><p class='noindent'>Once GitHub Pages is configured, your blog will be available at:
</p><!--   l. 140   --><p class='indent'>     
</p>
<blockquote class='quote'>     
<!--   l. 141   --><p class='noindent'><span class='ec-lmtt-10'>https://</span><span class='ec-lmtti-10'>username</span><span class='ec-lmtt-10'>.github.io/</span><span class='ec-lmtti-10'>repository-name</span><span class='ec-lmtt-10'>/</span></p></blockquote>
<!--   l. 144   --><p class='indent'>   For example, if your GitHub username is <span class='ec-lmtt-10'>janedoe </span>and your repository is named
<span class='ec-lmtt-10'>tex-blog</span>, the blog will be published at:
</p><!--   l. 146   --><p class='indent'>     
</p>
<blockquote class='quote'>     
<!--   l. 147   --><p class='noindent'><span class='ec-lmtt-10'>https://janedoe.github.io/tex-blog/</span></p></blockquote>
   
<h3 class='sectionHead' id='preventing-infinite-build-loops'><span class='titlemark'>6   </span> <a id='x1-110006'></a>Preventing Infinite Build Loops</h3>
<!--   l. 152   --><p class='noindent'>To prevent infinite build loops when generated files are committed back
to the repository, configure the workflow to ignore changes in the <span class='ec-lmtt-10'>docs/</span>
directory:
                                                                  

                                                                  
</p>   
<pre class='verbatim' id='verbatim-5'>
on:
  push:
    branches: [main]
    paths-ignore:
      - ’docs/**’
</pre>
<!--   l. 161   --><p class='nopar'>
</p><!--   l. 163   --><p class='indent'>   This ensures that commits containing only generated files won’t trigger new
workflow runs.
</p>]]></content><author><name></name></author><summary type="html"><![CDATA[This article describes how to configure GitHub Actions to automatically compile LaTeX sources for a static blog built with tools like make4ht and Jekyll. It covers file tracking, automatic build triggering, and committing generated files back to the repository.]]></summary></entry><entry><title type="html">Jekyll Setup</title><link href="https://www.kodymirus.cz/testblog/2025/07/01/jekyll-setup.html" rel="alternate" type="text/html" title="Jekyll Setup" /><published>2025-07-01T14:43:54+00:00</published><updated>2025-07-01T14:43:54+00:00</updated><id>https://www.kodymirus.cz/testblog/2025/07/01/jekyll-setup</id><content type="html" xml:base="https://www.kodymirus.cz/testblog/2025/07/01/jekyll-setup.html"><![CDATA[<!--   l. 15   --><p class='indent'>   I’ve shown how to use the <span class='ec-lmtt-10'>make4ht</span> <span class='ec-lmtt-10'>staticsite </span>extension in the <a href='/testblog/2021/07/30/how-to-blog-with-tex4ht.html'>previous
article</a>. In this article, I’ll show how to set it up with <a href='https://jekyllrb.com/'>Jekyll</a> to create a simple
blog.

</p>   
<h3 class='likesectionHead' id='contents'><a id='x1-1000'></a>Contents</h3>
<div class='tableofcontents'>   
<span class='sectionToc'>1 <a href='#create-a-new-jekyll-site' id='QQ2-1-2'>Create a new Jekyll site</a></span>
<br />   <span class='sectionToc'>2 <a href='#configure-jekyll' id='QQ2-1-3'>Configure Jekyll</a></span>
<br />   <span class='subsectionToc'>2.1 <a href='#customizing-the-layout' id='QQ2-1-4'>Customizing the layout</a></span>
<br />   <span class='subsectionToc'>2.2 <a href='#insert-document-stylesheet' id='QQ2-1-5'>Insert document stylesheet</a></span>
<br />   <span class='sectionToc'>3 <a href='#latex-compilation' id='QQ2-1-6'>LaTeX compilation</a></span>
<br />   <span class='sectionToc'>4 <a href='#conclusion' id='QQ2-1-7'>Conclusion</a></span>
</div>   

<h3 class='sectionHead' id='create-a-new-jekyll-site'><span class='titlemark'>1   </span> <a id='x1-20001'></a>Create a new Jekyll site</h3>
<!--   l. 21   --><p class='noindent'>We assume that the HTML files generated from LaTeX using <span class='ec-lmtt-10'>make4ht</span> are stored in
a directory called <span class='ec-lmtt-10'>docs</span>. The LaTeX source files will be located in the <span class='ec-lmtt-10'>_posts</span>
subdirectory. You can initialize a new Jekyll site in the <span class='ec-lmtt-10'>docs </span>directory using the
following commands:
                                                                  

                                                                  
</p>   
<pre class='verbatim' id='verbatim-1'>
$ cd docs
$ jekyll new .
</pre>
<!--   l. 26   --><p class='nopar'>
</p><!--   l. 28   --><p class='indent'>   This command creates a new Jekyll site in the current directory without
overwriting existing files.

</p>   
<h3 class='sectionHead' id='configure-jekyll'><span class='titlemark'>2   </span> <a id='x1-30002'></a>Configure Jekyll</h3>
<!--   l. 32   --><p class='noindent'>To improve how Jekyll handles the content, update the <span class='ec-lmtt-10'>_config.yml </span>file with the
following options:
                                                                  

                                                                  
</p>   
<pre class='verbatim' id='verbatim-2'>
show_excerpts: true
excerpt_separator: "&lt;/p&gt;"
</pre>
<!--   l. 37   --><p class='nopar'>
</p><!--   l. 39   --><p class='indent'>   This enables post excerpts and specifies that the excerpt ends at the first closing
paragraph tag.

</p>   
<h4 class='subsectionHead' id='customizing-the-layout'><span class='titlemark'>2.1   </span> <a id='x1-40002.1'></a>Customizing the layout</h4>
<!--   l. 43   --><p class='noindent'>You can modify the default HTML layout by editing files in the <span class='ec-lmtt-10'>_includes </span>and
<span class='ec-lmtt-10'>_layouts </span>folders. For example, create a custom layout that uses the styles and
metadata provided by your LaTeX output.
</p><!--   l. 45   --><p class='indent'>   Edit the file:
                                                                  

                                                                  
</p>   
<pre class='verbatim' id='verbatim-3'>
_includes/head.html
</pre>
<!--   l. 49   --><p class='nopar'>   

</p>   
<h4 class='subsectionHead' id='insert-document-stylesheet'><span class='titlemark'>2.2   </span> <a id='x1-50002.2'></a>Insert document stylesheet</h4>
<!--   l. 53   --><p class='noindent'>In the <span class='ec-lmtt-10'>head.html </span>file, make sure to include both the default Jekyll styles and any
additional styles generated by <span class='ec-lmtt-10'>make4ht</span>. Here’s an example of a complete <span class='ec-lmtt-10'>&lt;head&gt;</span>
section:
</p><!--   l. 55   --><p class='indent'>     </p><p> 

                                                                  

                                                                  
</p><pre class='verbatim' id='verbatim-4'>
&lt;head&gt;
  &lt;meta charset="utf-8"&gt;
  &lt;meta http-equiv="X-UA-Compatible" content="IE=edge"&gt;
  &lt;meta name="viewport" content="width=device-width, initial-scale=1"&gt;
  {%- seo -%}
  &lt;link rel="stylesheet" href="{{ "/assets/main.css" | relative_url }}" /&gt;
  {% for style in page.styles %}
  &lt;link rel="stylesheet" href="/css/{{style}}" /&gt;
  {%- endfor -%}
  {%- feed_meta -%}
  {%- if jekyll.environment == ’production’ and site.google_analytics -%}
    {%- include google-analytics.html -%}
  {%- endif -%}
&lt;/head&gt;
</pre>
<!--   l. 71   --><p class='nopar'>   </p><p> 

The loop over <span class='ec-lmtt-10'>page.styles </span>allows for the dynamic inclusion of CSS files exported
during the LaTeX to HTML conversion.
   
</p><h3 class='sectionHead' id='latex-compilation'><span class='titlemark'>3   </span> <a id='x1-60003'></a>LaTeX compilation</h3>
<!--   l. 78   --><p class='noindent'>To generate clean HTML that is compatible with Jekyll, use the <span class='ec-lmtt-10'>staticsite</span>
extension of <span class='ec-lmtt-10'>make4ht</span>. I’ve described how to use it in the <a href='/testblog/2021/07/30/how-to-blog-with-tex4ht.html'>previous post</a>.

</p>   
<h3 class='sectionHead' id='conclusion'><span class='titlemark'>4   </span> <a id='x1-70004'></a>Conclusion</h3>
<!--   l. 82   --><p class='noindent'>Using <span class='ec-lmtt-10'>make4ht</span> together with Jekyll allows you to write blog posts in LaTeX while
benefiting from static site generation.
</p>]]></content><author><name></name></author><summary type="html"><![CDATA[I’ve shown how to use the make4ht staticsite extension in the previous article. In this article, I’ll show how to set it up with Jekyll to create a simple blog.]]></summary></entry><entry><title type="html">How to Blog With TeX4ht</title><link href="https://www.kodymirus.cz/testblog/2021/07/30/how-to-blog-with-tex4ht.html" rel="alternate" type="text/html" title="How to Blog With TeX4ht" /><published>2021-07-30T22:12:12+00:00</published><updated>2021-07-30T22:12:12+00:00</updated><id>https://www.kodymirus.cz/testblog/2021/07/30/how-to-blog-with-tex4ht</id><content type="html" xml:base="https://www.kodymirus.cz/testblog/2021/07/30/how-to-blog-with-tex4ht.html"><![CDATA[<!--   l. 9   --><p class='indent'>   This post is part of a series on how to set up <a href='https://tug.org/tex4ht/'>TeX4ht</a>, the LaTeX to XML
converter, for use with Static Site Generators. In this article, we’ll discuss how to
configure it to produce suitable HTML.

</p>   
<h3 class='likesectionHead' id='contents'><a id='x1-1000'></a>Contents</h3>
<div class='tableofcontents'>   
<span class='sectionToc'>1 <a href='#static-site-extension-for-makeht' id='QQ2-1-2'>Static site extension for make4ht</a></span>
<br />   <span class='sectionToc'>2 <a href='#copy-the-generated-files-to-the-static-site' id='QQ2-1-3'>Copy the generated files to the static site</a></span>
<br />   <span class='sectionToc'>3 <a href='#automatic-compilation-of-changed-latex-files' id='QQ2-1-4'>Automatic compilation of changed LaTeX files</a></span>
<br />   <span class='subsectionToc'>3.1 <a href='#rebuildsh-script-functionality' id='QQ2-1-5'><span class='ec-lmtt-10'>rebuild.sh </span>Script Functionality</a></span>
</div>   

<h3 class='sectionHead' id='static-site-extension-for-makeht'><span class='titlemark'>1   </span> <a id='x1-20001'></a>Static site extension for make4ht</h3>
<!--   l. 15   --><p class='noindent'>The conversion process used by TeX4ht is quite complex. It requires compiling a
LaTeX file to a DVI file with special instructions inserted by the <span class='ec-lmtt-10'>tex4ht.sty</span>
package. This DVI file is then processed by the <span class='ec-lmtt-10'>tex4ht </span>command, which produces
HTML or XML files, along with instructions for the final command, <span class='ec-lmtt-10'>t4ht</span>, which
generates CSS files and images.
</p><!--   l. 17   --><p class='indent'>   Traditionally, this process was handled by the <span class='ec-lmtt-10'>htlatex </span>script, but it had many
weaknesses. The currently recommended build tool is <span class='ec-lmtt-10'>make4ht</span>. You can find
some details about the differences between <span class='ec-lmtt-10'>htlatex </span>and <span class='ec-lmtt-10'>make4ht</span> in the
<a href='https://www.kodymirus.cz/make4ht/make4ht-doc.html#difference-of-texttt-makeht'><span class='ec-lmtt-10'>make4ht</span> documentation</a>.
</p><!--   l. 19   --><p class='indent'>   Among the features provided by <span class='ec-lmtt-10'>make4ht</span> are Lua build files, post-processing
filters, and extensions. We can use these features to transform HTML files produced
by TeX4ht into the format required by static site generators.
                                                                  

                                                                  
</p><!--   l. 21   --><p class='indent'>   Filters can clean up the generated files and fix common issues that are difficult to
address at the TeX level. They can be applied either from Lua build files or using
<span class='ec-lmtt-10'>make4ht</span> extensions.
</p><!--   l. 23   --><p class='indent'>   <span class='ec-lmtt-10'>make4ht</span> provides an extension that specifically supports static site generators.
Let’s demonstrate its usage with a simple example:
                                                                  

                                                                  
</p>   
<pre class='verbatim' id='verbatim-1'>
\documentclass{article}
\begin{document}
\title{Hello world test}
\author{Michal}
\maketitle

This is my test post.
\end{document}
</pre>
<!--   l. 34   --><p class='nopar'>
</p><!--   l. 36   --><p class='indent'>   You can use the following command to generate a file suitable for static site
generators:
                                                                  

                                                                  
</p>   
<pre class='verbatim' id='verbatim-2'>
make4ht -f html5+staticsite filename.tex
</pre>
<!--   l. 40   --><p class='nopar'>
</p><!--   l. 42   --><p class='indent'>   By default, the <span class='ec-lmtt-10'>staticsite </span>extension produces a file named as
<span class='obeylines-h'><code class='verb'>YYYY-MM-DD-&lt;filename&gt;</code></span>, so this example might be named <span class='ec-lmtt-10'>2021-07-25-filename.html</span>.
It’s not an ordinary HTML file, but it contains a YAML header with document
metadata:
                                                                  

                                                                  
</p>   
<pre class='verbatim' id='verbatim-3'>
---
meta:
- charset: ’utf-8’
- name: ’generator’
  content: ’TeX4ht (https://tug.org/tex4ht/)’
- name: ’viewport’
  content: ’width=device-width,initial-scale=1’
- name: ’src’
  content: ’2021-07-18-hello-world.tex’
time: 1626619562
updated: 1627244699
styles:
- ’2021-07-18-hello-world.css’
title: ’Hello world test’
---
   
&lt;p class=’indent’&gt;   This is my test post.
&lt;/p&gt;
    
</pre>
<!--   l. 64   --><p class='nopar'>
</p><!--   l. 66   --><p class='indent'>   Although most static site generators expect Markdown, they also accept HTML
files in this format. When <span class='ec-lmtt-10'>staticsite </span>is used for the first time, it creates a file with
a <span class='ec-lmtt-10'>.published </span>extension. This file contains a timestamp of the moment it was
first used. This timestamp is then used for the date part of the generated
filename.

</p>   
<h3 class='sectionHead' id='copy-the-generated-files-to-the-static-site'><span class='titlemark'>2   </span> <a id='x1-30002'></a>Copy the generated files to the static site</h3>
<!--   l. 70   --><p class='noindent'>The <span class='ec-lmtt-10'>staticsite </span>extension can copy the generated files to the locations where the
static site generator expects to find files to process.
</p><!--   l. 72   --><p class='indent'>   Let’s say we have the following directory structure, suitable for the <a href='https://jekyllrb.com/'>Jekyll</a> static
site generator:
                                                                  

                                                                  
</p>   
<pre class='verbatim' id='verbatim-4'>
blog/
.. texposts_root/
.... first_post/
...... first_post.tex
.... second_post/
...... second_post.tex
.. docs/_posts/
.. .make4ht
</pre>
<!--   l. 83   --><p class='nopar'>
</p><!--   l. 85   --><p class='indent'>   The blog’s main directory contains the file <span class='ec-lmtt-10'>.make4ht</span>, and two directories:
<span class='obeylines-h'><code class='verb'>texposts_root</code></span> and <span class='obeylines-h'><code class='verb'>docs/_posts</code></span>. Jekyll has built-in support for blogs. It uses all
HTML documents contained within the <span class='obeylines-h'><code class='verb'>_posts</code></span> subdirectory. We’ll then use the <span class='ec-lmtt-10'>docs</span>
directory as the source directory for GitHub Pages.
</p><!--   l. 91   --><p class='indent'>   The source LaTeX files are stored in subdirectories of <span class='obeylines-h'><code class='verb'>texposts_root</code></span>. We
want to automatically copy the generated HTML files to <span class='obeylines-h'><code class='verb'>docs/_posts/</code></span>.
The <span class='ec-lmtt-10'>staticsite </span>extension can be configured to do this using the <span class='ec-lmtt-10'>.make4ht</span>
configuration file. This file is used to pass shared configuration to <span class='ec-lmtt-10'>make4ht</span>, such as
specifying that all generated files should be copied to the <span class='obeylines-h'><code class='verb'>docs/_posts/</code></span>
directory.
</p><!--   l. 98   --><p class='indent'>   The basic format of the <span class='ec-lmtt-10'>.make4ht </span>file necessary for the <span class='ec-lmtt-10'>staticsite </span>extension can
look like this:
                                                                  

                                                                  
</p>   
<pre class='verbatim' id='verbatim-5'>
filter_settings "staticsite" {
  site_root = "../../docs/_posts/"
  header = {
    layout="post",
  },
}

if mode=="publish" then
  Make:enable_extension "staticsite"
  Make:htlatex {}
  Make:htlatex {}
end
</pre>
<!--   l. 113   --><p class='nopar'>
</p><!--   l. 115   --><p class='indent'>   The <span class='obeylines-h'><code class='verb'>filter_settings</code></span> function passes a table with settings for the extension. The
<span class='obeylines-h'><code class='verb'>site_root</code></span> field specifies the path to the directory for the generated files. It can be
specified in a relative form, as in this example. Two <span class='obeylines-h'><code class='verb'>..</code></span> are necessary because the
output directory is located two levels up in the directory hierarchy from the directory
of the compiled TeX file.
</p><!--   l. 121   --><p class='indent'>   We also specify the build sequence for site generation. If we pass the
<span class='obeylines-h'><code class='verb'>--mode publish</code></span> option to <span class='ec-lmtt-10'>make4ht</span>, the <span class='ec-lmtt-10'>staticsite </span>extension will be enabled, and
LaTeX will be executed twice. This is important because the contents of the <span class='obeylines-h'><code class='verb'>\title</code></span>
and <span class='obeylines-h'><code class='verb'>\author</code></span> commands are only available in the second LaTeX run. They are then
included in the YAML header.
</p><!--   l. 127   --><p class='indent'>   You can now execute the following command in the <span class='obeylines-h'><code class='verb'>texposts_root/first_post</code></span>
directory:
                                                                  

                                                                  
</p>   
<pre class='verbatim' id='verbatim-6'>
make4ht -m publish first_post.tex
</pre>
<!--   l. 131   --><p class='nopar'>
</p><!--   l. 133   --><p class='indent'>   This will automatically load the <span class='ec-lmtt-10'>staticsite </span>extension, thanks to our <span class='ec-lmtt-10'>.make4ht</span>
file, so it’s not necessary to enable it on the command line. The generated HTML and
CSS files will be placed in the <span class='obeylines-h'><code class='verb'>docs/_posts/</code></span> directory.
</p><!--   l. 135   --><p class='indent'>   In the next post, we will look at how to use this setup with Jekyll to create a
simple blog.
</p><!--   l. 137   --><p class='indent'>   The <a href='https://github.com/michal-h21/testblog/blob/main/.make4ht'>.make4ht</a> file provided in this blog repository also adds a new function that
writes a <span class='obeylines-h'><code class='verb'>&lt;input&gt;.published</code></span> file. This file is used by the <span class='ec-lmtt-10'>staticsite </span>extension to
find the original publication date of a post. You should add the <span class='ec-lmtt-10'>published </span>file to
your source repository so the correct date is used in future updates of the
site.

</p>   
<h3 class='sectionHead' id='automatic-compilation-of-changed-latex-files'><span class='titlemark'>3   </span> <a id='x1-40003'></a>Automatic compilation of changed LaTeX files</h3>
<!--   l. 141   --><p class='noindent'>Instead of compiling documents manually after each change, you can automate the
build process using the <a href='https://github.com/michal-h21/siterebuild'>siterebuild</a> script.
</p><!--   l. 143   --><p class='indent'>   This tool checks all TeX files in your document directory tree for changes and
lists only the modified files. This is especially important as your blog grows, as it
would be wasteful to compile all source files on every update.

</p>   
<h4 class='subsectionHead' id='rebuildsh-script-functionality'><span class='titlemark'>3.1   </span> <a id='x1-50003.1'></a><span class='ec-lmtt-10'>rebuild.sh </span>Script Functionality</h4>
<!--   l. 147   --><p class='noindent'>I’ve provided a shell script named <a href='https://github.com/michal-h21/testblog/blob/main/texposts/rebuild.sh'>rebuild.sh</a>, which is included in the TeX files
root directory. It uses <span class='ec-lmtt-10'>siterebuild </span>to automatically compile the changed
TeX files:
                                                                  

                                                                  
</p>   
<pre class='verbatim' id='verbatim-7'>
#!/bin/sh
if ! command -v siterebuild &amp;&gt; /dev/null
then
SITEREBUILD=../siterebuild/siterebuild
else
SITEREBUILD=siterebuild
fi

export TEXINPUTS=.:/root/texmf//:

$SITEREBUILD -l debug
# we use the custom output format for siterebuild, to be able to easily extract directory and filename in the later steps
for i in ‘$SITEREBUILD -o %dir@%file‘
do
  texdir=‘echo $i | cut -d@ -f1 -‘
  texfile=‘echo $i | cut -d@ -f2 -‘
  # either execute Makefile, or run make4ht directly
  cd "$texdir"
  if test -f Makefile; then
    make
  else
    TEXINPUTS=.:/root/texmf//: make4ht -a debug -m publish -l "$texfile"
  fi
  cd ..
done
</pre>
<!--   l. 175   --><p class='nopar'>
</p><!--   l. 177   --><p class='indent'>   It first checks for the availability of the <span class='ec-lmtt-10'>siterebuild </span>command, using either a
system-wide installation or a local version from the repository. The script then
executes <span class='ec-lmtt-10'>siterebuild </span>with debug logging to identify modified LaTeX files that
require recompilation.
</p><!--   l. 182   --><p class='indent'>   Using a custom output format (<span class='obeylines-h'><code class='verb'>%dir@%file</code></span>), it extracts both the directory path
and filename for each changed document. For each detected file, the script navigates
to the corresponding directory and checks for a <span class='ec-lmtt-10'>Makefile</span>. If one is present, it uses
the existing build system; otherwise, it directly invokes <span class='ec-lmtt-10'>make4ht </span>with publishing
options to generate the HTML output.
</p><!--   l. 189   --><p class='indent'>   If you want to change the options for <span class='ec-lmtt-10'>make4ht </span>used for the compilation, you can
edit the <span class='ec-lmtt-10'>rebuild.sh </span>file. If you want to change options for only one file, you can
create a <span class='ec-lmtt-10'>Makefile </span>in that file’s directory and put the necessary compilation
commands in that <span class='ec-lmtt-10'>Makefile</span>.
</p>]]></content><author><name></name></author><summary type="html"><![CDATA[This post is part of a series on how to set up TeX4ht, the LaTeX to XML converter, for use with Static Site Generators. In this article, we’ll discuss how to configure it to produce suitable HTML.]]></summary></entry><entry><title type="html">Blogging in LaTeX, 2025 edition</title><link href="https://www.kodymirus.cz/testblog/2021/07/21/blogging-in-latex-2021-edition.html" rel="alternate" type="text/html" title="Blogging in LaTeX, 2025 edition" /><published>2021-07-21T12:32:29+00:00</published><updated>2021-07-21T12:32:29+00:00</updated><id>https://www.kodymirus.cz/testblog/2021/07/21/blogging-in-latex-2021-edition</id><content type="html" xml:base="https://www.kodymirus.cz/testblog/2021/07/21/blogging-in-latex-2021-edition.html"><![CDATA[<!--   l. 11   --><p class='indent'>   This is the first post in a series about blogging with LaTeX using <a href='https://tug.org/tex4ht/'>TeX4ht</a>. I
originally set it up as a showcase of TeX4ht’s features for the <a href='https://tug.org/tug2021/'>TUG 2021</a> conference.
Unfortunately, I didn’t get to present it in the end—I ran out of time during my
allocated slot, and I also didn’t manage to finish all the posts I had planned by the
deadline. Fast forward to July 2025, and I thought, why not finally complete this
series? Better late than never, right?

</p>   
<h3 class='likesectionHead' id='contents'><a id='x1-1000'></a>Contents</h3>
<div class='tableofcontents'>   
<span class='sectionToc'>1 <a href='#why-would-you-do-such-a-crazy-thing' id='QQ2-1-2'>Why would you do such a crazy thing?</a></span>
<br />   <span class='sectionToc'>2 <a href='#overview-of-the-setup' id='QQ2-1-3'>Overview of the setup</a></span>
</div>   

<h3 class='sectionHead' id='why-would-you-do-such-a-crazy-thing'><span class='titlemark'>1   </span> <a id='x1-20001'></a>Why would you do such a crazy thing?</h3>
<!--   l. 25   --><p class='noindent'>I really enjoy writing my documents in LaTeX, and I want to offer a solid alternative
to other markup languages like Markdown or HTML. The beauty of LaTeX lies in its
incredible flexibility—it lets you structure your documents exactly how you want,
without being tied down by the limitations of more rigid systems. Whether you’re
writing a quick report or a full-blown book, LaTeX gives you the tools to make it
look polished and professional.
</p><!--   l. 32   --><p class='indent'>   Of course, LaTeX isn’t for everyone, and that’s totally fine! Some people prefer
the instant visual feedback you get with WYSIWYG editors like Word or Google
Docs, and there’s absolutely nothing wrong with that. Others might like
the simplicity of plain text but find LaTeX’s syntax too complicated or
                                                                  

                                                                  
even a bit ugly—and hey, that’s fair too. Markdown and other lightweight
markup languages are great alternatives, and there’s no shame in using
them.
</p><!--   l. 39   --><p class='indent'>   Let’s be honest, LaTeX can be pretty complex, and a lot of people won’t even
scratch the surface of what it can do. And that’s okay—not everyone needs
that level of control or customization. Personally, though, I’ve never been
a fan of Word or Markdown. Word feels too restrictive for my taste, and
Markdown, while simple, just doesn’t give me the power I need. That’s
why I’ve turned to LaTeX as my go-to tool. It’s my way of creating an
alternative for myself and others who feel the same way—people who want more
flexibility and precision without being tied down by the limitations of other
tools.
</p><!--   l. 48   --><p class='indent'>   One of the coolest things about LaTeX is how customizable it is. You can create
your own environments and commands, which is a game-changer when it comes to
organizing your content. This is super handy for big projects like theses or
books, where you need everything to be consistent, but it’s also great for
smaller stuff like articles or essays. Plus, once you’ve set up your custom
commands, you can reuse them across different documents, saving you a ton of
time.
</p><!--   l. 56   --><p class='indent'>   Another reason I love LaTeX is the sheer number of packages available.
These packages let you do pretty much anything you can think of. Need
to draw diagrams? Check out <span class='ec-lmtt-10'>TikZ </span>or <span class='ec-lmtt-10'>PGFPlots</span>. Writing a math-heavy
paper? <span class='ec-lmtt-10'>Amsmath </span>has got your back. Managing references? <span class='ec-lmtt-10'>BibLaTeX </span>makes it a
breeze. The possibilities are endless, and it’s one of the reasons LaTeX is so
powerful.
</p><!--   l. 63   --><p class='indent'>   Now, some people say that converting LaTeX to HTML is a pain, but honestly,
it’s not that hard if you know what you’re doing. I’m the author of <a href='https://tug.org/tex4ht/'>TeX4ht</a>, a
tool that makes this process a lot smoother. It’s a great way to make your
content more accessible online without losing the precision and beauty of
LaTeX.

</p>   
<h3 class='sectionHead' id='overview-of-the-setup'><span class='titlemark'>2   </span> <a id='x1-30002'></a>Overview of the setup</h3>
<!--   l. 71   --><p class='noindent'>In the upcoming posts, we’ll dive into how TeX4ht works and how to configure it to
generate HTML files that play nicely with static site generators. After that, I’ll share
how I used Jekyll to build this series of posts. Finally, we’ll wrap things up by
exploring how to use GitHub Actions to automatically rebuild your website whenever
you update your LaTeX documents.
</p><!--   l. 77   --><p class='indent'>   Here is an outline of the steps we’ll cover:
</p><!--   l. 79   --><p class='indent'>     
</p>
<ol class='enumerate1'>
                                                                  

                                                                  
<li class='enumerate' id='x1-3002x1'>Use <a href='/testblog/2021/07/30/how-to-blog-with-tex4ht.html'>TeX4ht to produce files suitable for static site generators</a>.
</li>
<li class='enumerate' id='x1-3004x2'>Use a static site generator, such as <a href='https://jekyllrb.com/'>Jekyll</a> or <a href='https://gohugo.io/'>Hugo</a>, to generate a website.
</li>
<li class='enumerate' id='x1-3006x3'>Use GitHub Actions to automatically compile LaTeX files pushed to the
repository and rebuild the website.</li></ol>
<!--   l. 89   --><p class='indent'>   If you’re curious to check out the source code for this blog, you can find it at this
link: <a class='url' href='https://github.com/michal-h21/testblog'><span class='ec-lmtt-10'>https://github.com/michal-h21/testblog</span></a>.
</p><!--   l. 92   --><p class='indent'>   Notable files and directories include:
</p>     
<ul class='itemize1'>
<li class='itemize'><a href='https://github.com/michal-h21/testblog/blob/main/.make4ht'>Build file for make4ht.</a>
</li>
<li class='itemize'><a href='https://github.com/michal-h21/testblog/tree/main/texposts'>Root directory for LaTeX documents.</a>
</li>
<li class='itemize'><a href='https://github.com/michal-h21/testblog/blob/main/texposts/rebuild.sh'>Script to force rebuild only for changed files</a>, as we don’t want to compile
all LaTeX files on every blog update.
</li>
<li class='itemize'><a href='https://github.com/michal-h21/testblog/blob/main/.github/workflows/main.yml'>GitHub Actions workflow file.</a></li></ul>]]></content><author><name></name></author><summary type="html"><![CDATA[This is the first post in a series about blogging with LaTeX using TeX4ht. I originally set it up as a showcase of TeX4ht’s features for the TUG 2021 conference. Unfortunately, I didn’t get to present it in the end—I ran out of time during my allocated slot, and I also didn’t manage to finish all the posts I had planned by the deadline. Fast forward to July 2025, and I thought, why not finally complete this series? Better late than never, right?]]></summary></entry></feed>