Building a Website with Make4ht: Raster and Vector Images

David Friant
April 12th, 2026
Abstract
Raster and vector images are fundamental pieces of media which must be well-handled in the process of converting LaTeX documents to HTML documents. Fortunately, this more-or-less the case with the default or near-default behavior of Make4ht. However, the special case of TIKZ and PGFplot images raises certain concerns which must be addressed in order to maintain a consistent look and feel across both the light and dark color modes of the website. A combination of the Externalization TIKZ package, the Inkscape vector drawing program, and some clever post-processing are presented in this article to fully address those concerns.
Keywords: LaTeX, Make4ht, Raster Images, Vector Images, IndieWeb

Introduction  

With basic text, references and footnotes, equations, tables, and code listings all implemented, the last major form of content to set up for this website is graphics. Images are the most ubiquitous form of content on the internet after text, thus requiring that they be handled well and robustly. Fortunately, this is remarkably easy when simply inserting a typical raster1Wikipedia: Raster Graphics. https://en.wikipedia.org/wiki/Raster_graphics. Accessed: 2026-03-29. or vector2Wikipedia: Vector Graphics. https://en.wikipedia.org/wiki/Vector_graphics. Accessed: 2026-03-29. graphic from an external file into the document. Indeed, the standard LaTeX tools work without any problems. However, the TIKZ and PGFplots packages for LaTeX provide powerful drawing and plotting tools which will take some small effort to properly implement.

Raster Images  

Raster graphics are commonly used throughout both the internet and documents typically produced by LaTeX such as scientific publications. Hence, there is already robust support for them in place in both LuaTeX and Make4ht. Figure 1 demonstrates that even very small raster images can be cleanly displayed. Juxtapose this to Figure 1 of the first article in this series, a 1080×1080 pixel image which is also handled without issue.

Figure 1:A 17×17 pixel raster image showing combinations of colors. The initial colors are the greyscale, RGB, and CMY colors along the upper and left edges of the image.  
PIC

Though it is not strictly necessary, the system presented here does make a small modification to the standard \includegraphics command in the configuration file such that the output of Make4ht is somewhat cleaner. This can be found in Listing 1.

Vector Images  

Vector images are rather less common, but by no means unknown to either LaTeX or HTML. Indeed, the most common vector format, SVG, is directly embeddable into HTML documents3MDN Web Docs: SVG in HTML. https://developer.mozilla.org/en-US/docs/Web/SVG/Guides/SVG_in_HTML. Accessed: 2026-03-29. as they share a common XML file structure. Unfortunately, the SVG format is not natively supported by LaTeX, and thus the SVG package4CTAN: SVG. https://ctan.org/pkg/svg. Accessed: 2026-03-29. must be used to include an external SVG into the document. Fortunately, the interface, \includesvg, is extremely similar to the normal LaTeX command for including graphics. Thus far, there has not been any need to modify or customize the process for the inclusion of external SVG files. Figure 2 provides an example of the inclusion of an external SVG file.

Figure 2:An SVG color wheel. Note the increasing transparency as one moves towards the middle of the image. In the HTML version of this document, changing the color mode of the website will illustrate the effect very clearly.  
PIC
Listing 1:The code added to the configuration file for simplifying the output for the inclusion of graphics. Note that this extends to SVG files included via the svg package as well.  
\renewcommand{\includegraphics}[2][]{
    \HCode{
        <div class="figure">
            <img alt="PIC" src="#2">
        </div>
    }
}

TIKZ and PGFplots  

TIKZ5TIKZ Manual. https://tikz.dev. Accessed: 2026-04-06. and the related PGFplots6PGFplots Manual. https://tikz.dev/pgfplots. Accessed: 2026-04-06. packages provide some of the most sophisticated diagram and plot generation capabilities for LaTeX. Typically, one would simply create their image as normal and allow Make4ht to create an independent PDF of it that would then be embedded into the HTML document like any other. However, one of the goals for this website is to ensure a clear and consistent experience across both light and dark modes. This would be lost if vector images were stuck with a white background or, worse, had a transparent background coupled with dark lines that would be lost on a dark background.

Fortunately, there is a way to work around this by ensuring that vector images created using TIKZ and PGFplots are embedded directly into the HTML document such that CSS styling can be used to modify the colors displayed in the embedded SVGs. The manner in which to do this is described starting with Listing 2 which provides a small addition to the HTMLArticle class file defining a command through which all TIKZ and PGFplots images must be made. Note that this requires that each image be defined in its own file, but this is good practice regardless.

Listing 2:The code added to the HTMLArticle class file for inputting TIKZ and PGFplot images.  
\newcommand{\inputtikz}[1]{
    \tikzsetnextfilename{Figure_\thefigure}
    \input{#1}
}

The code in Listing 2 also requires that the externalize package for TIKZ be used. This ensures that independent PDF files are created for each TIKZ image. These PDF files are then converted to SVG images using Inkscape7Inkscape. https://inkscape.org/. Accessed: 2026-04-06. when running Make4ht as defined in the configuration file with the addition of the code in Listing 3 to it.

Listing 3:The code added to the HTMLArticle configuration file for inputting TIKZ and PGFplot images.  
\renewcommand{\inputtikz}[1]{
    \HCode{<div class="figure">
        <stub class="tikz" file="figures/Figure_\thefigure.svg">
        </stub></div>}
    \ShellEscape{inkscape --export-type=svg --export-plain-svg \
        --pdf-font-strategy=keep figures/Figure_\thefigure.pdf}
}

Before progressing to the post-processing phase, there is the matter of how precisely to define which colors will be substituted when swapping between color modes on the website. Listing 4 provides the definition of a number of commonly used colors across both the PDF and light-mode HTML versions of these documents. More accurately, it defines colors which are imperceptibly different from the actual target values such that the actual colors themselves may be used without worry of them being altered during a color mode change if the need should arise. At present, the only colors defined are those typically used for the text, background, borders, and accents in addition to two data series color sets, one in grey scale and the other using color palette but forward by Okabe and Ito8Color Universal Design (CUD) - How to make figures and presentations that are friendly to Colorblind people -. https://jfly.uni-koeln.de/color/index.html. Accessed: 2026-04-12. .

Listing 4:A LaTeX file which defines default values for many of the colors to be commonly used throughout these documents.  
% Basic colors for foreground/background/border
\definecolor{textcolor}{RGB}{1, 1, 1}
\definecolor{backgroundcolor}{RGB}{254,254,254}
\definecolor{bordercolor}{RGB}{134, 135, 136}
\definecolor{primaryaccentcolor}{RGB}{182, 183, 184}
\definecolor{secondaryaccentcolor}{RGB}{86, 87, 88}

% Data series colors: Grey scale
\definecolor{dataBW0}{RGB}{ 61,  61,  61}
\definecolor{dataBW1}{RGB}{112, 112, 112}
\definecolor{dataBW2}{RGB}{163, 163, 163}
\definecolor{dataBW3}{RGB}{214, 214, 214}

% Data series colors: Okabe and Ito
\definecolor{dataOAI0}{RGB}{  2,   2,   2}
\definecolor{dataOAI1}{RGB}{  2, 158, 115}
\definecolor{dataOAI2}{RGB}{  2, 114, 178}
\definecolor{dataOAI3}{RGB}{ 86, 180, 233}
\definecolor{dataOAI4}{RGB}{220, 208,  46}
\definecolor{dataOAI5}{RGB}{230, 159,   2}
\definecolor{dataOAI6}{RGB}{213,  94,   2}
\definecolor{dataOAI7}{RGB}{204, 121, 167}
Listing 5:The post-processing code for injecting the SVG files directly into the body of the HTML documents such that they may take advantage of dynamic recoloring based on the color mode of the website.  
#Factor by which to scale SVG images during the processing
svgScaleFactor = 4.0 / 3.0

#list of svgColor / class tuples to allow for dynamic css styling
svgColorMap = [
    ("#010101", "text"),
    ("#fefefe", "background"),
    ("#b6b7b8", "primary-accent"),
    ("#565758", "secondary-accent"),
    ("#3d3d3d", "data-series-bw-0"),
    ("#707070", "data-series-bw-1"),
    ("#a3a3a3", "data-series-bw-2"),
    ("#d6d6d6", "data-series-bw-3"),
    ("#020202", "data-series-oai-0"),
    ("#029e73", "data-series-oai-1"),
    ("#0272b2", "data-series-oai-2"),
    ("#56b4e9", "data-series-oai-3"),
    ("#dcd02e", "data-series-oai-4"),
    ("#e69f02", "data-series-oai-5"),
    ("#d55e02", "data-series-oai-6"),
    ("#cc79a7", "data-series-oai-7")
]

# Helper function for the replacement of the initial width and height of an svg
def replaceDimension(match):
    out = str(svgScaleFactor * float(match.group(2)))
    return match.group(1) + "=\"" + out + "\""
#

# Helper function for the replacment of colors in the insertTIKZImages function
def replaceColors(match):
    out = match.group(2)
    for map in svgColorMap:
        if match.group(2) == map[0]:
            out = "var(--" + map[1] + ")"
            break
        #
    #
    return match.group(1) + ":" + out
#

# Find all tikz images that need to be replaced and perform the substitution
def insertTIKZImages():
    images = findTags(0, "stub", [("class", "tikz")])
    for image in images:
        fileName = ""
        for attr in nodes[image].value[1]:
            if[attr[0] == "file"]:
                fileName = attr[1]
            #
        #
        imageFile = open(fileName, "rt")
        imageText = imageFile.read()
        imageFile.close()

        # Regex Operations:
        ## Scale graphic by svgScaleFactor
        imageText = re.sub("(width)=\"(\d+?\.\d+|\d+)\"",
                           replaceDimension,
                           imageText,
                           1)
        imageText = re.sub("(height)=\"(\d+?\.\d+|\d+)\"",
                           replaceDimension,
                           imageText,
                           1)

        ## Substitute colors for reactive content controlled by CSS
        imageText = re.sub("(fill|stroke):(#\w{6})", replaceColors, imageText)
        
        ## Remove font-family attributes
        imageText = re.sub("font-family:.+?;", "", imageText)

        nodes.append(TreeNode(HTMLContentType.CONTENT,
                              imageText,
                              nodes[image].parent,
                              []))
        imageIndex = nodes[nodes[image].parent].children.index(image)
        nodes[nodes[image].parent].children[imageIndex] = len(nodes) - 1
    #
#

The color definitions (specifically their hexcode representations) are sought out in the post-processing step as provided by Listing 5. Here, each of the colors defined in Listing 4 are replaced with CSS var() functions which reference variables that define the color currently in use for that part of the document. Discussion of defining the colors for the light and dark modes of the website is reserved for the next article. The post-processing also scales the images in the HTML version of the document up by about 33% and removes any font-family information such that the font used in the images will be the same as that used for the rest of the website.

Summary  

Overall, the process of getting images to be correctly translated from the PDF files to the HTML documents is generally straightforward, at least in comparison to getting tables to a functional state. Even the special case of TIKZ and PGFplot images is fairly simple, though it does require the use of an unusually large number of specific tools such the externalize package, Inkscape, and some very specific CSS. On that note, it is important to keep in mind that the system as it is presented here relies on the close coordination of the colors defined in Listing 4, the substitution table of hexcode-CSS variable tuples in Listing 5, and the CSS variables as defined in the style file. Any mismatch between these three may result in broken behavior.

Before progressing to the next article which is dedicated to the CSS styling of the website, readers may wish to take a moment and examine the examples below. They were all generated with TIKZ and/or PGFplots and showcase a mere fraction of the capabilities of the two packages. Indeed, Figures 2 and 3 of the first article in this series also demonstrate the use of the packages.

Examples  

Figure 3:The geometric construction of a perpendicular bisector of the line segment AB. Note that the circles centered on points A and B must be congruent.  
ABCDE

Figure 4:A basic circuit diagram for a full-wave bridge rectifier for converting from AC to DC. 9Wikipedia: Diode Bridge. https://en.wikipedia.org/wiki/Diode_bridge. Accessed: 2026-04-11.   
+Vout-Vout

Figure 5:The normal distribution10Wikipedia: Normal Distribution. https://en.wikipedia.org/wiki/Normal_distribution. Accessed: 2026-04-11. and its cumulative distribution with lines denoting each standard deviation.  
321012300.20.40.60.81NormalDist.CumulativeDist.

Figure 6:Quasi-uniformly distributed points in the unit circle using Vogel’s Method. 11Wikipedia: Fermat's Spiral. https://en.wikipedia.org/wiki/Fermat%27s_spiral. Accessed: 2026-04-11. ,12H. Vogel. A better way to construct the sunflower head. Mathematical Biosciences, 44(3):179-189, 1979.   
10.500.5110.500.51

References  

  1. Wikipedia: Raster Graphics. https://en.wikipedia.org/wiki/Raster_graphics. Accessed: 2026-03-29.
  2. Wikipedia: Vector Graphics. https://en.wikipedia.org/wiki/Vector_graphics. Accessed: 2026-03-29.
  3. MDN Web Docs: SVG in HTML. https://developer.mozilla.org/en-US/docs/Web/SVG/Guides/SVG_in_HTML. Accessed: 2026-03-29.
  4. CTAN: SVG. https://ctan.org/pkg/svg. Accessed: 2026-03-29.
  5. TIKZ Manual. https://tikz.dev. Accessed: 2026-04-06.
  6. PGFplots Manual. https://tikz.dev/pgfplots. Accessed: 2026-04-06.
  7. Inkscape. https://inkscape.org/. Accessed: 2026-04-06.
  8. Color Universal Design (CUD) - How to make figures and presentations that are friendly to Colorblind people -. https://jfly.uni-koeln.de/color/index.html. Accessed: 2026-04-12.
  9. Wikipedia: Diode Bridge. https://en.wikipedia.org/wiki/Diode_bridge. Accessed: 2026-04-11.
  10. Wikipedia: Normal Distribution. https://en.wikipedia.org/wiki/Normal_distribution. Accessed: 2026-04-11.
  11. Wikipedia: Fermat's Spiral. https://en.wikipedia.org/wiki/Fermat%27s_spiral. Accessed: 2026-04-11.
  12. H. Vogel. A better way to construct the sunflower head. Mathematical Biosciences, 44(3):179-189, 1979.