Technical Articles / Opinions / News / Projects

Theming and Templating

The purpose of this build process is to implement the default layout of this website. To that end, it provides a template file (main.html), and a collection of SASS files that cleopatra then compiles into a single CSS file using sassc.

We first discuss the structure of the website, by defining the default HTML template soupault will use to generate the website. Then, we specify its minimal design, implemented in SASS. Finally, we discuss the necessary build instructions for cleopatra.

1 Main HTML Template

<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta name="viewport"
          content="width=device-width, initial-scale=1.0">
    <title><!-- page title will be inserted here --></title>
    <link
       href="https://soap.coffee/+vendors/normalize.css.8.0.1/normalize.css"
       rel="stylesheet">
    <link rel="stylesheet" href="/style/main.css">
    <link rel="icon" type="image/ico" href="/img/merida.webp">
    <noscript id="asyncloading">
      <link href="https://soap.coffee/+vendors/fira-code.2+swap/font.css"
            rel="stylesheet">
      <link href="https://soap.coffee/+vendors/Linux-Libertine/import.css"
            rel="stylesheet">
      <link href="https://soap.coffee/+vendors/katex.0.11.1+swap/katex.css"
            rel="stylesheet">
      <link href="https://soap.coffee/+vendors/fork-awesome.1.1.7+swap/css/fork-awesome.min.css"
            rel="stylesheet">
    </nolink>
  </head>
  <body>
    <header>
      <a href="/">Technical Articles</a> /
      <a href="/opinions">Opinions</a> /
      <a href="/news">News</a> /
      <a href="/projects">Projects</a>
    </header>
    <main>
    <!-- page content will be inserted here -->
    </main>
    <footer>
      <img src="https://soap.coffee/~lthms/img/merida.webp"
           alt="Merida from the movie Ralph 2.0 from Disney is the
                avatar I use most of the time on the Internet"
           title="lthms’ avatar" />
  
      <p>
        Hi, I’m <strong>lthms</strong>, and this is my humble corner of the
        Internet. You are very welcome here! If you are interested in
        <em>functional programming</em>, <em>formal verification</em>, or <em>free
        software projects in the making</em>, you may even enjoy your stay!
      </p>
  
      <p>
        This website has been generated using a collection of <a
        href="/posts/Thanks.html">awesome free software projects</a>. You can have
        a look at <a href="https://code.soap.coffee/writing/lthms.git/">the source
        of this website</a> or <a href="/cleopatra.html">how it is being
        generated</a>, and if you run into an error, feel free to <a
        href="mailto:lthms@soap.coffee">shoot me a friendly email</a>.
      </p>
    </footer>
    <script>
      let noscript = document.getElementById('asyncloading');
      noscript.insertAdjacentHTML('beforebegin', noscript.innerText);
      noscript.parentNode.removeChild(noscript);
    </script>
  </body>
</html>
templates/main.html

1.1 <head>

<<meta-tags>> :=
<meta charset="utf-8">
<meta name="viewport"
      content="width=device-width, initial-scale=1.0">

1.1.1 Assets Loading

<<syncloading_html>> :=
<link
   href="https://soap.coffee/+vendors/normalize.css.8.0.1/normalize.css"
   rel="stylesheet">
<link rel="stylesheet" href="/style/main.css">
<link rel="icon" type="image/ico" href="/img/merida.webp">
<<asyncloading_js>> :=
let noscript = document.getElementById('asyncloading');
noscript.insertAdjacentHTML('beforebegin', noscript.innerText);
noscript.parentNode.removeChild(noscript);
<<asyncloading_html>> :=
<noscript id="asyncloading">
  <link href="https://soap.coffee/+vendors/fira-code.2+swap/font.css"
        rel="stylesheet">
  <link href="https://soap.coffee/+vendors/Linux-Libertine/import.css"
        rel="stylesheet">
  <link href="https://soap.coffee/+vendors/katex.0.11.1+swap/katex.css"
        rel="stylesheet">
  <link href="https://soap.coffee/+vendors/fork-awesome.1.1.7+swap/css/fork-awesome.min.css"
        rel="stylesheet">
</nolink>

1.2 body

<<body>> :=
<body>
  <header>
    <a href="/">Technical Articles</a> /
    <a href="/opinions">Opinions</a> /
    <a href="/news">News</a> /
    <a href="/projects">Projects</a>
  </header>
  <main>
  <!-- page content will be inserted here -->
  </main>
  <footer>
    <img src="https://soap.coffee/~lthms/img/merida.webp"
         alt="Merida from the movie Ralph 2.0 from Disney is the
              avatar I use most of the time on the Internet"
         title="lthms’ avatar" />

    <p>
      Hi, I’m <strong>lthms</strong>, and this is my humble corner of the
      Internet. You are very welcome here! If you are interested in
      <em>functional programming</em>, <em>formal verification</em>, or <em>free
      software projects in the making</em>, you may even enjoy your stay!
    </p>

    <p>
      This website has been generated using a collection of <a
      href="/posts/Thanks.html">awesome free software projects</a>. You can have
      a look at <a href="https://code.soap.coffee/writing/lthms.git/">the source
      of this website</a> or <a href="/cleopatra.html">how it is being
      generated</a>, and if you run into an error, feel free to <a
      href="mailto:lthms@soap.coffee">shoot me a friendly email</a>.
    </p>
  </footer>
  <script>
    <<asyncloading_js>>
  </script>
</body>

2 Main SASS File

First, we introduce a set of variables.

$content-width : 35rem
$large-side-margin : 5rem
$small-side-margin : 2rem
site/style/main.sass

Then, we introduce a key CSS variable whose definition will change according to the current width of the page (something we cannot achieve with SASS variables, whose behavior is purely static).

\:root
    @media screen and (min-width: calc(#{$content-width} + 2 * #{$large-side-margin}))
        --side-margin : #{$large-side-margin}
    @media screen and (max-width: calc(#{$content-width} + 2 * #{$large-side-margin}))
        --side-margin : #{$small-side-margin}
site/style/main.sass

Then, we style!

*
    box-sizing : border-box

html
    width : 100%
    font-size : 110%

body
    font-family : 'Linux Libertine', serif
    padding : 2rem var(--side-margin)

main p,
main h1,
main h2,
main h3,
main h4,
main h5,
main h6,
main ul,
main dl,
main ol,
header,
footer
    max-width : $content-width
    line-height : 140%

main h1,
main h2,
main h3,
main h4,
main h5,
main h6
    font-weight : 400

header a,
footer p
    font-size : 90%

main
    padding-top : 2rem
    padding-bottom : 2rem

footer img
    border-radius : 100%
    max-width : 7rem
    float : right
    margin-left : 1rem
    margin-bottom : 1rem

pre
    overflow-x : auto

code,
tt,
pre
    font-family : 'Fira Code', monospace
    font-size : 80%
    line-height : 140%

#gallery
    display : flex
    flex-wrap : wrap
    align-content : flex-start

    img
        max-width : 20rem

@import plugins
@import org
@import coq
site/style/main.sass

3 Build Instructions

The build instruction are pretty straightforward. We start by how to compile the main CSS file.

SASS := $(wildcard site/style/*.sass)
MAIN_SASS := site/style/main.sass
CSS := $(MAIN_SASS:.sass=.css)

${CSS} : ${SASS}
        @cleopatra echo Compiling  "${CSS}"
        @sassc --style=compressed --sass ${MAIN_SASS} ${CSS}
theme.mk

Since the HTML template does not need any particular processing, the theme-build phase is only responsible for generating the main CSS file. The soupault build phase needs to start after the CSS file is compiled (since it copies all relevant files to the build/ directory), so we explicit this dependency.

theme-build : ${CSS}
soupault-build : theme-build
theme.mk

Therefore, at the end of this generation process only one file has been generated.

ARTIFACTS += ${CSS}
theme.mk