chiark / gitweb /
Initial documentation and website.
authorVladimír Vondruš <mosra@centrum.cz>
Sun, 22 Oct 2017 13:37:37 +0000 (15:37 +0200)
committerVladimír Vondruš <mosra@centrum.cz>
Sun, 22 Oct 2017 13:37:37 +0000 (15:37 +0200)
38 files changed:
doc/css.rst [new file with mode: 0644]
doc/css/components-test.rst [new file with mode: 0644]
doc/css/components.rst [new file with mode: 0644]
doc/css/grid.rst [new file with mode: 0644]
doc/css/page-layout-test.rst [new file with mode: 0644]
doc/css/page-layout.rst [new file with mode: 0644]
doc/css/themes.rst [new file with mode: 0644]
doc/css/typography-test.rst [new file with mode: 0644]
doc/css/typography.rst [new file with mode: 0644]
doc/examples/article.rst [new file with mode: 0644]
doc/examples/jumbo-article.rst [new file with mode: 0644]
doc/index.rst [new file with mode: 0644]
doc/pelican.rst [new file with mode: 0644]
doc/pelican/theme-test.rst [new file with mode: 0644]
doc/pelican/theme.rst [new file with mode: 0644]
doc/pelican/writing-content.rst [new file with mode: 0644]
doc/plugins.rst [new file with mode: 0644]
doc/plugins/components-test.rst [new file with mode: 0644]
doc/plugins/components.rst [new file with mode: 0644]
doc/plugins/htmlsanity-test.rst [new file with mode: 0644]
doc/plugins/htmlsanity.rst [new file with mode: 0644]
doc/plugins/images-test.rst [new file with mode: 0644]
doc/plugins/images.rst [new file with mode: 0644]
doc/plugins/links.rst [new file with mode: 0644]
doc/plugins/math-and-code-test.rst [new file with mode: 0644]
doc/plugins/math-and-code.rst [new file with mode: 0644]
doc/static/dummy.css [new file with mode: 0644]
doc/static/flowers-small.jpg [new file with mode: 0644]
doc/static/flowers.jpg [new file with mode: 0644]
doc/static/ship-small.jpg [new file with mode: 0644]
doc/static/ship.jpg [new file with mode: 0644]
doc/why.rst [new file with mode: 0644]
site/.gitignore [new file with mode: 0644]
site/Makefile [new file with mode: 0644]
site/content [new symlink]
site/develop_server.sh [new file with mode: 0755]
site/pelicanconf.py [new file with mode: 0644]
site/publishconf.py [new file with mode: 0644]

diff --git a/doc/css.rst b/doc/css.rst
new file mode 100644 (file)
index 0000000..2df810f
--- /dev/null
@@ -0,0 +1,116 @@
+CSS
+###
+
+.. role:: css(code)
+    :language: css
+.. role:: html(code)
+    :language: html
+
+The CSS style is the essence of ``m.css``. It makes use of HTML5 tags as much
+as possible to avoid redundant classes. Contrary to other popular frameworks,
+all custom CSS classes and IDs are prefixed with ``m-`` to avoid conflicts with
+3rd party styles. All sizes, paddings and border widths are specified using
+``rem`` units, relative to base page font size; :css:`box-sizing: border-box`
+is applied to all elements by default.
+
+`Quick start`_
+==============
+
+To make full advantage of ``m.css``, you need just three files written in plain
+CSS. Download them below or :gh:`grab the whole Git repository <mosra/m.css>`:
+
+-   :gh:`m-grid.css <mosra/m.css$master/css/m-grid.css>` with optional
+    :gh:`m-debug.css <mosra/m.css$master/css/m-debug.css>`
+-   :gh:`m-components.css <mosra/m.css$master/css/m-components.css>`
+-   :gh:`m-dark.css <mosra/m.css$master/css/m-dark.css>` or
+    :gh:`m-light.css <mosra/m.css$master/css/m-light.css>`
+
+In addition to the above, if you want to present highlighted code snippets on
+your website, there's also a builtin style for `Pygments <http://pygments.org/>`_,
+matching ``m.css`` themes:
+
+-   :gh:`pygments-dark.css <mosra/m.css$master/css/pygments-dark.css>`,
+    generated from :gh:`pygments-dark.py <mosra/m.css$master/css/pygments-dark.py>`
+
+Once you have the files, include them in your HTML markup. The top-level
+``m-dark.css`` / ``m-light.css`` file includes the other via CSS :css:`@import`
+statement, so you don't need to reference these. The dark theme uses the
+`Source Sans Pro <https://fonts.google.com/specimen/Source+Sans+Pro>`_ font for
+copy and `Source Code Pro <https://fonts.google.com/specimen/Source+Code+Pro>`_
+font for pre-formatted text and code, which you need to reference as well. See
+the `Themes <{filename}/css/themes.rst>`_ page for requirements of other
+themes.
+
+Besides that, in order to have devices recognize your website properly as
+responsive and not zoom it all the way out to an unreadable mess, don't forget
+to include a proper :html:`<meta>` tag. The HTML5 DOCTYPE is also required.
+
+.. code:: html
+
+    <!DOCTYPE html>
+    <html>
+      <head>
+        <link rel="stylesheet" href="m-dark.css" />
+        <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Source+Code+Pro:400,400i,600%7CSource+Sans+Pro:400,400i,600&amp;subset=latin-ext" />
+        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+      </head>
+      ...
+    </html>
+
+.. block-warning:: Browser compatibility
+
+    Note that some older browsers have problems with CSS variables and
+    :css:`@import` statements. Because of that, the builtin themes provide
+    a ``*.compiled.css`` versions that are *post*\ processed without CSS
+    variables or :css:`@import` statements. The compiled version includes also
+    the Pygments style, all combined in one file:
+
+    -   :gh:`m-dark.compiled.css <mosra/m.css$master/css/m-dark.compiled.css>`
+        (:filesize:`{filename}/../css/m-dark.compiled.css`,
+        :filesize-gz:`{filename}/../css/m-dark.compiled.css` compressed)
+    -   :gh:`m-light.compiled.css <mosra/m.css$master/css/m-light.compiled.css>`
+        (:filesize:`{filename}/../css/m-light.compiled.css`,
+        :filesize-gz:`{filename}/../css/m-light.compiled.css` compressed)
+
+    I recommend using the original files for development and switching to the
+    compiled versions when publishing the website.
+
+With this, you can start using the framework right away. Click the headings
+below to get to know more.
+
+`Grid system » <{filename}/css/grid.rst>`_
+==========================================
+
+The ``m-grid.css`` file provides a 12-column layout, inspired by
+`Bootstrap <https://getbootstrap.com>`_. It provides a simple, easy-to-use
+solution for modern responsive web development. It comes together with
+``m-debug.css`` that helps debugging the most common mistakes in grid layouts.
+
+`Typography » <{filename}/css/typography.rst>`_
+===============================================
+
+Sane default style for body text, paragraphs, lists, links, headings and other
+common typographical elements, provided by the ``m-components.css`` file.
+
+`Components » <{filename}/css/components.rst>`_
+===============================================
+
+The ``m-components.css`` file also contains styles for visual elements that add
+more structure to your content. From simple notes and topic blocks, tables,
+images or figures to complex elements like code snippets, math formulas or
+image grid.
+
+`Page layout » <{filename}/css/page-layout.rst>`_
+=================================================
+
+Besides that, ``m-components.css`` has also full-fledged collection of elements
+to form not only the content, but the whole page including navigation ---
+header and footer, section headings, article styling with sidebar and tag cloud
+and more.
+
+`Themes » <{filename}/css/themes.rst>`_
+=======================================
+
+Finally, ``m-dark.css`` and ``m-light.css`` use CSS variables to achieve easy
+theming. Two builtin themes, used by the author himself on a bunch of websites
+to guarantee that everything fits well together.
diff --git a/doc/css/components-test.rst b/doc/css/components-test.rst
new file mode 100644 (file)
index 0000000..254c8d0
--- /dev/null
@@ -0,0 +1,545 @@
+Test
+####
+
+:save_as: css/components/test/index.html
+:breadcrumb: {filename}/css.rst CSS
+             {filename}/css/components.rst Components
+
+Blocks
+======
+
+.. raw:: html
+
+    <div class="m-row">
+      <div class="m-col-m-3 m-col-s-6">
+        <div class="m-block m-default">
+          <h3>Default block</h3>
+          Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus ultrices a erat eu suscipit. <a href="#">Link.</a>
+        </div>
+      </div>
+      <div class="m-col-m-3 m-col-s-6">
+        <div class="m-block m-primary">
+          <h3>Primary block</h3>
+          Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus ultrices a erat eu suscipit. <a href="#">Link.</a>
+        </div>
+      </div>
+      <div class="m-col-m-3 m-col-s-6">
+        <div class="m-block m-success">
+          <h3>Success block</h3>
+          Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus ultrices a erat eu suscipit. <a href="#">Link.</a>
+        </div>
+      </div>
+      <div class="m-col-m-3 m-col-s-6">
+        <div class="m-block m-warning">
+          <h3>Warning block</h3>
+          Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus ultrices a erat eu suscipit. <a href="#">Link.</a>
+        </div>
+      </div>
+      <div class="m-col-m-3 m-col-s-6">
+        <div class="m-block m-danger">
+          <h3>Danger block</h3>
+          Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus ultrices a erat eu suscipit. <a href="#">Link.</a>
+        </div>
+      </div>
+      <div class="m-col-m-3 m-col-s-6">
+        <div class="m-block m-info">
+          <h3>Info block</h3>
+          Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus ultrices a erat eu suscipit. <a href="#">Link.</a>
+        </div>
+      </div>
+      <div class="m-col-m-3 m-col-s-6">
+        <div class="m-block m-dim">
+          <h3>Dim block</h3>
+          Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus ultrices a erat eu suscipit. <a href="#">Link.</a>
+        </div>
+      </div>
+    </div>
+
+Notes, frame
+============
+
+.. raw:: html
+
+    <div class="m-row">
+      <div class="m-col-m-3 m-col-s-6">
+        <div class="m-note m-default">
+          <h3>Default note</h3>
+          Lorem ipsum dolor sit amet, consectetur adipiscing elit. <a href="#">Link.</a>
+        </div>
+      </div>
+      <div class="m-col-m-3 m-col-s-6">
+        <div class="m-note m-primary">
+          <h3>Primary note</h3>
+          Lorem ipsum dolor sit amet, consectetur adipiscing elit. <a href="#">Link.</a>
+        </div>
+      </div>
+      <div class="m-col-m-3 m-col-s-6">
+        <div class="m-note m-success">
+          <h3>Success note</h3>
+          Lorem ipsum dolor sit amet, consectetur adipiscing elit. <a href="#">Link.</a>
+        </div>
+      </div>
+      <div class="m-col-m-3 m-col-s-6">
+        <div class="m-note m-warning">
+          <h3>Warning note</h3>
+          Lorem ipsum dolor sit amet, consectetur adipiscing elit. <a href="#">Link.</a>
+        </div>
+      </div>
+      <div class="m-col-m-3 m-col-s-6">
+        <div class="m-note m-danger">
+          <h3>Danger note</h3>
+          Lorem ipsum dolor sit amet, consectetur adipiscing elit. <a href="#">Link.</a>
+        </div>
+      </div>
+      <div class="m-col-m-3 m-col-s-6">
+        <div class="m-note m-info">
+          <h3>Info note</h3>
+          Lorem ipsum dolor sit amet, consectetur adipiscing elit. <a href="#">Link.</a>
+        </div>
+      </div>
+      <div class="m-col-m-3 m-col-s-6">
+        <div class="m-note m-dim">
+          <h3>Dim note</h3>
+          Lorem ipsum dolor sit amet, consectetur adipiscing elit. <a href="#">Link.</a>
+        </div>
+      </div>
+      <div class="m-col-m-3 m-col-s-6">
+        <div class="m-frame">
+          <h3>Frame</h3>
+          Lorem ipsum dolor sit amet, consectetur adipiscing elit. <a href="#">Link.</a>
+        </div>
+      </div>
+    </div>
+
+Text
+====
+
+.. raw:: html
+
+    <p class="m-text m-default">Default text. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus ultrices a erat eu suscipit. Aliquam pharetra imperdiet tortor sed vehicula. <a href="#">Link.</a></p>
+    <p class="m-text m-primary">Primary text. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus ultrices a erat eu suscipit. Aliquam pharetra imperdiet tortor sed vehicula. <a href="#">Link.</a></p>
+    <p class="m-text m-success">Success text. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus ultrices a erat eu suscipit. Aliquam pharetra imperdiet tortor sed vehicula. <a href="#">Link.</a></p>
+    <p class="m-text m-warning">Warning text. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus ultrices a erat eu suscipit. Aliquam pharetra imperdiet tortor sed vehicula. <a href="#">Link.</a></p>
+    <p class="m-text m-danger">Danger text. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus ultrices a erat eu suscipit. Aliquam pharetra imperdiet tortor sed vehicula. <a href="#">Link.</a></p>
+    <p class="m-text m-info">Info text. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus ultrices a erat eu suscipit. Aliquam pharetra imperdiet tortor sed vehicula. <a href="#">Link.</a></p>
+    <p class="m-text m-dim">Dim text. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus ultrices a erat eu suscipit. Aliquam pharetra imperdiet tortor sed vehicula. <a href="#">Link.</a></p>
+
+Tables
+======
+
+.. raw:: html
+
+    <table class="m-table m-center-t">
+      <caption>Table caption</caption>
+      <thead>
+        <tr>
+          <th>#</th>
+          <th>Heading</th>
+          <th>Second<br/>heading</th>
+        </tr>
+      </thead>
+      <tbody>
+        <tr>
+          <th scope="row">1</th>
+          <td>Cell</td>
+          <td>Second cell</td>
+        </tr>
+      </tbody>
+      <tbody>
+        <tr>
+          <th scope="row">2</th>
+          <td>2nd row cell</td>
+          <td>2nd row 2nd cell</td>
+        </tr>
+      </tbody>
+      <tfoot>
+        <tr>
+          <th>&Sigma;</th>
+          <td>Footer</td>
+          <td>Second<br/>footer</td>
+        </tr>
+      </tfoot>
+    </table>
+    <div class="m-scroll"><table class="m-table m-fullwidth">
+      <caption>Full-width table</caption>
+      <thead>
+        <tr>
+          <th>#</th>
+          <th>Heading text</th>
+          <th>Heading text</th>
+          <th>Heading text</th>
+          <th>Heading text</th>
+          <th>Heading text</th>
+          <th>Heading text</th>
+        </tr>
+      </thead>
+      <tbody>
+        <tr>
+          <th scope="row">1</th>
+          <td>Cell contents</td>
+          <td>Cell contents</td>
+          <td>Cell contents</td>
+          <td>Cell contents</td>
+          <td>Cell contents</td>
+          <td>Cell contents</td>
+        </tr>
+        <tr>
+          <th scope="row">2</th>
+          <td>Cell contents</td>
+          <td>Cell contents</td>
+          <td>Cell contents</td>
+          <td>Cell contents</td>
+          <td>Cell contents</td>
+          <td>Cell contents</td>
+        </tr>
+        <tr>
+          <th scope="row">3</th>
+          <td>Cell contents</td>
+          <td>Cell contents</td>
+          <td>Cell contents</td>
+          <td>Cell contents</td>
+          <td>Cell contents</td>
+          <td>Cell contents</td>
+        </tr>
+      </tbody>
+    </table></div>
+    <div class="m-scroll"><table class="m-table m-center-t">
+      <tbody>
+        <tr class="m-default">
+          <th>Default row</th>
+          <td>Lorem</td>
+          <td>ipsum</td>
+          <td>dolor</td>
+          <td>sit</td>
+          <td>amet</td>
+          <td><a href="#">Link</a></td>
+        </tr>
+        <tr class="m-primary">
+          <th>Primary row</th>
+          <td>Lorem</td>
+          <td>ipsum</td>
+          <td>dolor</td>
+          <td>sit</td>
+          <td>amet</td>
+          <td><a href="#">Link</a></td>
+        </tr>
+        <tr class="m-success">
+          <th>Success row</th>
+          <td>Lorem</td>
+          <td>ipsum</td>
+          <td>dolor</td>
+          <td>sit</td>
+          <td>amet</td>
+          <td><a href="#">Link</a></td>
+        </tr>
+        <tr class="m-warning">
+          <th>Warning row</th>
+          <td>Lorem</td>
+          <td>ipsum</td>
+          <td>dolor</td>
+          <td>sit</td>
+          <td>amet</td>
+          <td><a href="#">Link</a></td>
+        </tr>
+        <tr class="m-danger">
+          <th>Danger row</th>
+          <td>Lorem</td>
+          <td>ipsum</td>
+          <td>dolor</td>
+          <td>sit</td>
+          <td>amet</td>
+          <td><a href="#">Link</a></td>
+        </tr>
+        <tr class="m-info">
+          <th>Info row</th>
+          <td>Lorem</td>
+          <td>ipsum</td>
+          <td>dolor</td>
+          <td>sit</td>
+          <td>amet</td>
+          <td><a href="#">Link</a></td>
+        </tr>
+        <tr class="m-dim">
+          <th>Dim row</th>
+          <td>Lorem</td>
+          <td>ipsum</td>
+          <td>dolor</td>
+          <td>sit</td>
+          <td>amet</td>
+          <td><a href="#">Link</a></td>
+        </tr>
+        <tr>
+          <td class="m-default">Default cell</td>
+          <td class="m-default"><a href="#">Link</a></td>
+          <td class="m-default">Lorem</td>
+          <td class="m-default">ipsum</td>
+          <td class="m-default">dolor</td>
+          <td class="m-default">sit</td>
+          <td class="m-default">amet</td>
+        </tr>
+        <tr>
+          <td class="m-primary">Primary cell</td>
+          <td class="m-primary"><a href="#">Link</a></td>
+          <td>Lorem</td>
+          <td>ipsum</td>
+          <td>dolor</td>
+          <td>sit</td>
+          <td>amet</td>
+        </tr>
+        <tr>
+          <td class="m-default">Lorem</td>
+          <td class="m-success">Success cell</td>
+          <td class="m-success"><a href="#">Link</a></td>
+          <td>ipsum</td>
+          <td>dolor</td>
+          <td>sit</td>
+          <td>amet</td>
+        </tr>
+        <tr>
+          <td>Lorem</td>
+          <td class="m-default">ipsum</td>
+          <td class="m-warning">Warning cell</td>
+          <td class="m-warning"><a href="#">Link</a></td>
+          <td>dolor</td>
+          <td>sit</td>
+          <td>amet</td>
+        </tr>
+        <tr>
+          <td>Lorem</td>
+          <td>ipsum</td>
+          <td class="m-default">dolor</td>
+          <td class="m-danger">Danger cell</td>
+          <td class="m-danger"><a href="#">Link</a></td>
+          <td>sit</td>
+          <td>amet</td>
+        </tr>
+        <tr>
+          <td>Lorem</td>
+          <td>ipsum</td>
+          <td>dolor</td>
+          <td class="m-default">sit</td>
+          <td class="m-info">Info cell</td>
+          <td class="m-info"><a href="#">Link</a></td>
+          <td>amet</td>
+        </tr>
+        <tr>
+          <td>Lorem</td>
+          <td>ipsum</td>
+          <td>dolor</td>
+          <td>sit</td>
+          <td class="m-default">amet</td>
+          <td class="m-dim">Dim cell</td>
+          <td class="m-dim"><a href="#">Link</a></td>
+        </tr>
+        <tr>
+          <th class="m-default">Default header</th>
+          <td class="m-default"><a href="#">Link</a></td>
+          <td class="m-default">Lorem</td>
+          <td class="m-default">ipsum</td>
+          <td class="m-default">dolor</td>
+          <td class="m-default">sit</td>
+          <td class="m-default">amet</td>
+        </tr>
+        <tr>
+          <th class="m-primary">Primary header</th>
+          <td class="m-primary"><a href="#">Link</a></td>
+          <td>Lorem</td>
+          <td>ipsum</td>
+          <td>dolor</td>
+          <td>sit</td>
+          <td>amet</td>
+        </tr>
+        <tr>
+          <td class="m-default">Lorem</td>
+          <th class="m-success">Success header</th>
+          <td class="m-success"><a href="#">Link</a></td>
+          <td>ipsum</td>
+          <td>dolor</td>
+          <td>sit</td>
+          <td>amet</td>
+        </tr>
+        <tr>
+          <td>Lorem</td>
+          <td class="m-default">ipsum</td>
+          <th class="m-warning">Warning header</th>
+          <td class="m-warning"><a href="#">Link</a></td>
+          <td>dolor</td>
+          <td>sit</td>
+          <td>amet</td>
+        </tr>
+        <tr>
+          <td>Lorem</td>
+          <td>ipsum</td>
+          <td class="m-default">dolor</td>
+          <th class="m-danger">Danger header</th>
+          <td class="m-danger"><a href="#">Link</a></td>
+          <td>sit</td>
+          <td>amet</td>
+        </tr>
+        <tr>
+          <td>Lorem</td>
+          <td>ipsum</td>
+          <td>dolor</td>
+          <td class="m-default">sit</td>
+          <th class="m-info">Info header</th>
+          <td class="m-info"><a href="#">Link</a></td>
+          <td>amet</td>
+        </tr>
+        <tr>
+          <td>Lorem</td>
+          <td>ipsum</td>
+          <td>dolor</td>
+          <td>sit</td>
+          <td class="m-default">amet</td>
+          <th class="m-dim">Dim header</th>
+          <td class="m-dim"><a href="#">Link</a></td>
+        </tr>
+      </tbody>
+    </table>
+
+Images
+======
+
+Image, centered:
+
+.. raw:: html
+
+    <img src="{filename}/static/flowers-small.jpg" class="m-image" />
+
+Image, centered, link:
+
+.. raw:: html
+
+    <div class="m-image">
+      <a href="http://blog.mosra.cz/"><img src="{filename}/static/flowers-small.jpg" /></a>
+    </div>
+
+Image, fullwidth (yes, it should be pixelated):
+
+.. raw:: html
+
+    <img src="{filename}/static/flowers-small.jpg" class="m-image m-fullwidth" />
+
+Image, fullwidth, link (yes, it should be pixelated):
+
+.. raw:: html
+
+    <div class="m-image m-fullwidth">
+      <a href="http://blog.mosra.cz/"><img src="{filename}/static/flowers-small.jpg" /></a>
+    </div>
+
+Figures
+=======
+
+Figure, centered:
+
+.. raw:: html
+
+    <figure class="m-figure">
+      <img src="{filename}/static/ship-small.jpg" />
+      <figcaption>A Ship</figcaption>
+      <div>Photo © <a href="http://blog.mosra.cz/">The Author</a></div>
+    </figure>
+
+Figure, centered, image link, flat:
+
+.. raw:: html
+
+    <figure class="m-figure m-flat">
+      <a href="http://blog.mosra.cz/"><img src="{filename}/static/ship-small.jpg" /></a>
+      <figcaption>A Ship</figcaption>
+      <div>Photo © <a href="http://blog.mosra.cz/">The Author</a></div>
+    </figure>
+
+Figure, fullwidth, without description (yes, it should be pixelated):
+
+.. raw:: html
+
+    <figure class="m-figure m-fullwidth">
+      <img src="{filename}/static/ship-small.jpg" />
+      <figcaption>A Ship</figcaption>
+    </figure>
+
+Image grid
+==========
+
+Without the link:
+
+.. raw:: html
+
+    <div class="m-imagegrid m-container-inflate">
+      <div>
+        <figure style="width: 69.127%">
+          <img src="{filename}/static/ship.jpg" />
+          <figcaption>F9.0, 1/250 s, ISO 100</figcaption>
+        </figure>
+        <figure style="width: 30.873%">
+          <img src="{filename}/static/flowers.jpg" />
+          <figcaption>F2.8, 1/1600 s, ISO 100</figcaption>
+        </figure>
+      </div>
+    </div>
+
+With link, without caption, not inflated:
+
+.. raw:: html
+
+    <div class="m-imagegrid">
+      <div>
+        <figure style="width: 30.873%">
+          <a href="{filename}/static/flowers.jpg">
+            <img src="{filename}/static/flowers.jpg" />
+            <div></div>
+          </a>
+        </figure>
+        <figure style="width: 69.127%">
+          <a href="{filename}/static/ship.jpg">
+            <img src="{filename}/static/ship.jpg" />
+            <div></div>
+          </a>
+        </figure>
+      </div>
+    </div>
+
+Without link or caption:
+
+.. raw:: html
+
+    <div class="m-imagegrid m-container-inflate">
+      <div>
+        <figure style="width: 69.127%">
+          <img src="{filename}/static/ship.jpg" />
+          <div></div>
+        </figure>
+        <figure style="width: 30.873%">
+          <img src="{filename}/static/flowers.jpg" />
+          <div></div>
+        </figure>
+      </div>
+    </div>
+
+`Code figure`_
+==============
+
+A flat code figure:
+
+.. raw:: html
+
+    <figure class="m-code-figure m-flat">
+        <pre>Some
+        code
+    snippet</pre>
+        And a resulting output.
+    </figure>
+
+A code figure with :html:`<pre>` in description. Activating the section header
+should not affect it.
+
+.. raw:: html
+
+    <figure class="m-code-figure">
+        <pre>Some
+        code
+    snippet</pre>
+        <pre>And a resulting output.</pre>
+    </figure>
diff --git a/doc/css/components.rst b/doc/css/components.rst
new file mode 100644 (file)
index 0000000..5d7a536
--- /dev/null
@@ -0,0 +1,861 @@
+Components
+##########
+
+:breadcrumb: {filename}/css.rst CSS
+
+``m.css`` provides a set of basic components for further improving the layout
+and display of authored content.
+
+.. contents::
+    :class: m-block m-default
+
+`Colors`_
+=========
+
+Similarly to Bootstrap, ``m.css`` has a set of predefined colors that affect
+how a certain component looks. This works on majority of components shown on
+this page. The colors are:
+
+-   :css:`.m-default` is a default style that doesn't grab attention
+-   :css:`.m-primary` is meant to be used to highlight the primary element on a
+    page
+-   :css:`.m-success` is good to highlight happy things
+-   :css:`.m-warning` catches attention, but doesn't hurt
+-   :css:`.m-danger` brings really bad news
+-   :css:`.m-info` is for side notes
+-   :css:`.m-dim` is shy and doesn't want you to be bothered by the information
+    it brings
+
+`Blocks`_
+=========
+
+Blocks, defined by :css:`.m-block`, wrap the content in a light frame and add a
+bolder colored bar on the left. Use in combination with one of the color styles
+above. Block caption should go into :html:`<h3>` and is colored in respect to
+the color style as well. Text and links always have the default color, except
+for :css:`.m-block.m-dim`. It's also possible to have a block without the
+border, just add :css:`.m-flat` class to it.
+
+.. code-figure::
+
+    .. code:: html
+
+        <div class="m-block m-default">
+          <h3>Default block</h3>
+          Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus ultrices
+          a erat eu suscipit. <a href="#">Link.</a>
+        </div>
+
+    .. raw:: html
+
+        <div class="m-row">
+          <div class="m-col-m-3 m-col-s-6">
+            <div class="m-block m-default">
+              <h3>Default block</h3>
+              Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus ultrices a erat eu suscipit. <a href="#">Link.</a>
+            </div>
+          </div>
+          <div class="m-col-m-3 m-col-s-6">
+            <div class="m-block m-primary">
+              <h3>Primary block</h3>
+              Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus ultrices a erat eu suscipit. <a href="#">Link.</a>
+            </div>
+          </div>
+          <div class="m-col-m-3 m-col-s-6">
+            <div class="m-block m-success">
+              <h3>Success block</h3>
+              Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus ultrices a erat eu suscipit. <a href="#">Link.</a>
+            </div>
+          </div>
+          <div class="m-col-m-3 m-col-s-6">
+            <div class="m-block m-warning">
+              <h3>Warning block</h3>
+              Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus ultrices a erat eu suscipit. <a href="#">Link.</a>
+            </div>
+          </div>
+          <div class="m-col-m-3 m-col-s-6">
+            <div class="m-block m-danger">
+              <h3>Danger block</h3>
+              Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus ultrices a erat eu suscipit. <a href="#">Link.</a>
+            </div>
+          </div>
+          <div class="m-col-m-3 m-col-s-6">
+            <div class="m-block m-info">
+              <h3>Info block</h3>
+              Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus ultrices a erat eu suscipit. <a href="#">Link.</a>
+            </div>
+          </div>
+          <div class="m-col-m-3 m-col-s-6">
+            <div class="m-block m-dim">
+              <h3>Dim block</h3>
+              Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus ultrices a erat eu suscipit. <a href="#">Link.</a>
+            </div>
+          </div>
+          <div class="m-col-m-3 m-col-s-6">
+            <div class="m-block m-flat">
+              <h3>Flat block</h3>
+              Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus ultrices a erat eu suscipit. <a href="#">Link.</a>
+            </div>
+          </div>
+        </div>
+
+`Notes, frame`_
+===============
+
+Unlike blocks, notes are meant to wrap smaller bits of information. Use the
+:css:`.m-note` CSS class together with desired color class. A note is also
+slightly rounded and has everything colored, the background, the caption, text
+and also links. The :html:`<h3>` caption tag is optional.
+
+Besides notes, there is a frame element defined by :css:`.m-frame`, which just
+wraps your content in a slightly rounded border. No color classes apply to a
+frame.
+
+.. code-figure::
+
+    .. code:: html
+
+        <div class="m-note m-success">
+          <h3>Success note</h3>
+          Lorem ipsum dolor sit amet, consectetur adipiscing elit. <a href="#">Link.</a>
+        </div>
+
+    .. raw:: html
+
+        <div class="m-row">
+          <div class="m-col-m-3 m-col-s-6">
+            <div class="m-note m-default">
+              <h3>Default note</h3>
+              Lorem ipsum dolor sit amet, consectetur adipiscing elit. <a href="#">Link.</a>
+            </div>
+          </div>
+          <div class="m-col-m-3 m-col-s-6">
+            <div class="m-note m-primary">
+              <h3>Primary note</h3>
+              Lorem ipsum dolor sit amet, consectetur adipiscing elit. <a href="#">Link.</a>
+            </div>
+          </div>
+          <div class="m-col-m-3 m-col-s-6">
+            <div class="m-note m-success">
+              <h3>Success note</h3>
+              Lorem ipsum dolor sit amet, consectetur adipiscing elit. <a href="#">Link.</a>
+            </div>
+          </div>
+          <div class="m-col-m-3 m-col-s-6">
+            <div class="m-note m-warning">
+              <h3>Warning note</h3>
+              Lorem ipsum dolor sit amet, consectetur adipiscing elit. <a href="#">Link.</a>
+            </div>
+          </div>
+          <div class="m-col-m-3 m-col-s-6">
+            <div class="m-note m-danger">
+              <h3>Danger note</h3>
+              Lorem ipsum dolor sit amet, consectetur adipiscing elit. <a href="#">Link.</a>
+            </div>
+          </div>
+          <div class="m-col-m-3 m-col-s-6">
+            <div class="m-note m-info">
+              <h3>Info note</h3>
+              Lorem ipsum dolor sit amet, consectetur adipiscing elit. <a href="#">Link.</a>
+            </div>
+          </div>
+          <div class="m-col-m-3 m-col-s-6">
+            <div class="m-note m-dim">
+              <h3>Dim note</h3>
+              Lorem ipsum dolor sit amet, consectetur adipiscing elit. <a href="#">Link.</a>
+            </div>
+          </div>
+          <div class="m-col-m-3 m-col-s-6">
+            <div class="m-frame">
+              <h3>Frame</h3>
+              Lorem ipsum dolor sit amet, consectetur adipiscing elit. <a href="#">Link.</a>
+            </div>
+          </div>
+        </div>
+
+`Text`_
+=======
+
+Use :css:`.m-text` CSS class together with desired color class to color a
+paragraph or inline text.
+
+.. code-figure::
+
+    .. code:: html
+
+        <p class="m-text m-warning">Warning text. Lorem ipsum dolor sit amet,
+        consectetur adipiscing elit. Vivamus ultrices a erat eu suscipit. Aliquam
+        pharetra imperdiet tortor sed vehicula. <a href="#">Link.</a></p>
+
+    .. raw:: html
+
+        <div class="m-row">
+          <div class="m-col-m-3 m-col-s-6">
+            <p class="m-text m-default m-noindent">Default text. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus ultrices a erat eu suscipit. Aliquam pharetra imperdiet tortor sed vehicula. <a href="#">Link.</a></p>
+          </div>
+          <div class="m-col-m-3 m-col-s-6">
+            <p class="m-text m-primary m-noindent">Primary text. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus ultrices a erat eu suscipit. Aliquam pharetra imperdiet tortor sed vehicula. <a href="#">Link.</a></p>
+          </div>
+          <div class="m-col-m-3 m-col-s-6">
+            <p class="m-text m-success m-noindent">Success text. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus ultrices a erat eu suscipit. Aliquam pharetra imperdiet tortor sed vehicula. <a href="#">Link.</a></p>
+          </div>
+          <div class="m-col-m-3 m-col-s-6">
+            <p class="m-text m-warning m-noindent">Warning text. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus ultrices a erat eu suscipit. Aliquam pharetra imperdiet tortor sed vehicula. <a href="#">Link.</a></p>
+          </div>
+          <div class="m-col-m-3 m-col-s-6">
+            <p class="m-text m-danger m-noindent">Danger text. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus ultrices a erat eu suscipit. Aliquam pharetra imperdiet tortor sed vehicula. <a href="#">Link.</a></p>
+          </div>
+          <div class="m-col-m-3 m-col-s-6">
+            <p class="m-text m-info m-noindent">Info text. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus ultrices a erat eu suscipit. Aliquam pharetra imperdiet tortor sed vehicula. <a href="#">Link.</a></p>
+          </div>
+          <div class="m-col-m-3 m-col-s-6">
+            <p class="m-text m-dim m-noindent">Dim text. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus ultrices a erat eu suscipit. Aliquam pharetra imperdiet tortor sed vehicula. <a href="#">Link.</a></p>
+          </div>
+        </div>
+
+Apply :css:`.m-small` or :css:`.m-big` CSS class together with :css:`.m-text`
+to make the text appear smaller or larger.
+
+.. code-figure::
+
+    .. code:: html
+
+        <p class="m-text m-big">Larger text. Lorem ipsum dolor sit amet, consectetur
+        adipiscing elit. Vivamus ultrices a erat eu suscipit. Aliquam pharetra
+        imperdiet tortor sed vehicula.</p>
+        <p class="m-text m-small">Smaller text. Lorem ipsum dolor sit amet, consectetur
+        adipiscing elit. Vivamus ultrices a erat eu suscipit. Aliquam pharetra
+        imperdiet tortor sed vehicula.</p>
+
+    .. raw:: html
+
+        <p class="m-text m-big">Larger text. Lorem ipsum dolor sit amet, consectetur
+        adipiscing elit. Vivamus ultrices a erat eu suscipit. Aliquam pharetra
+        imperdiet tortor sed vehicula.</p>
+        <p class="m-text m-small">Smaller text. Lorem ipsum dolor sit amet, consectetur
+        adipiscing elit. Vivamus ultrices a erat eu suscipit. Aliquam pharetra
+        imperdiet tortor sed vehicula.</p>
+
+`Button links`_
+===============
+
+To highlight important links such as file download, you can style them as
+buttons. Use :css:`.m-button` CSS class together with desired color class on an
+:html:`<a>` tag. The button is by default displayed as inline block, either
+wrap it in :css:`.m-text-center` etc. :html:`<div>` to make it centered or
+apply a :css:`.m-fullwidth` class to it to display it as a full-width block
+with center-aligned label.
+
+.. code-figure::
+
+    .. code:: html
+
+        <a class="m-button m-success" href="#">Success button</a>
+
+    .. raw:: html
+
+        <div class="m-row">
+          <div class="m-col-m-3 m-col-s-6">
+            <a class="m-button m-default m-fullwidth" href="#">Default button</a>
+          </div>
+          <div class="m-col-m-3 m-col-s-6">
+            <a class="m-button m-primary m-fullwidth" href="#">Primary button</a>
+          </div>
+          <div class="m-col-m-3 m-col-s-6">
+            <a class="m-button m-success m-fullwidth" href="#">Success button</a>
+          </div>
+          <div class="m-col-m-3 m-col-s-6">
+            <a class="m-button m-warning m-fullwidth" href="#">Warning button</a>
+          </div>
+          <div class="m-col-m-3 m-col-s-6">
+            <a class="m-button m-danger m-fullwidth" href="#">Danger button</a>
+          </div>
+          <div class="m-col-m-3 m-col-s-6">
+            <a class="m-button m-info m-fullwidth" href="#">Info button</a>
+          </div>
+          <div class="m-col-m-3 m-col-s-6">
+            <a class="m-button m-dim m-fullwidth" href="#">Dim button</a>
+          </div>
+        </div>
+
+You can put two :html:`<div>`\ s with :css:`.m-big` and :css:`.m-small` CSS
+class inside the :html:`<a>` to achieve the following effect:
+
+.. code-figure::
+
+    .. code:: html
+
+        <div class="m-text-center">
+          <a class="m-button m-primary" href="#">
+            <div class="m-big">Download the thing</div>
+            <div class="m-small">Any platform, 5 kB.</div>
+          </a>
+        </div>
+
+    .. raw:: html
+
+        <div class="m-text-center">
+          <a class="m-button m-primary" href="#">
+            <div class="m-big">Download the thing</div>
+            <div class="m-small">Any platform, 5 kB.</div>
+          </a>
+        </div>
+
+`Tables`_
+=========
+
+Use :css:`.m-table` to apply styling to a table. The table is centered by
+default; rows are separated by lines, with :html:`<thead>` and :html:`<tfoot>`
+being separated by a thicker line. Rows are highlighted on hover, :html:`<th>`
+is rendered in bold, all :html:`<th>` and :html:`<td>` are aligned to left
+while table :html:`<caption>` is centered. Example table:
+
+.. code-figure::
+
+    .. code:: html
+
+        <table class="m-table">
+          <caption>Table caption</caption>
+          <thead>
+            <tr>
+              <th>#</th>
+              <th>Heading</th>
+              <th>Second<br/>heading</th>
+            </tr>
+          </thead>
+          <tbody>
+            <tr>
+              <th scope="row">1</th>
+              <td>Cell</td>
+              <td>Second cell</td>
+            </tr>
+          </tbody>
+          <tbody>
+            <tr>
+              <th scope="row">2</th>
+              <td>2nd row cell</td>
+              <td>2nd row 2nd cell</td>
+            </tr>
+          </tbody>
+          <tfoot>
+            <tr>
+              <th>&Sigma;</th>
+              <td>Footer</td>
+              <td>Second<br/>footer</td>
+            </tr>
+          </tfoot>
+        </table>
+
+    .. raw:: html
+
+        <table class="m-table">
+          <caption>Table caption</caption>
+          <thead>
+            <tr>
+              <th>#</th>
+              <th>Heading</th>
+              <th>Second<br/>heading</th>
+            </tr>
+          </thead>
+          <tbody>
+            <tr>
+              <th scope="row">1</th>
+              <td>Cell</td>
+              <td>Second cell</td>
+            </tr>
+          </tbody>
+          <tbody>
+            <tr>
+              <th scope="row">2</th>
+              <td>2nd row cell</td>
+              <td>2nd row 2nd cell</td>
+            </tr>
+          </tbody>
+          <tfoot>
+            <tr>
+              <th>&Sigma;</th>
+              <td>Footer</td>
+              <td>Second<br/>footer</td>
+            </tr>
+          </tfoot>
+        </table>
+
+Similarly to other components, you can color particular :html:`<tr>` or
+:html:`<td>` elements using the color classes from above:
+
+.. raw:: html
+
+    <div class="m-scroll"><table class="m-table m-fullwidth">
+      <tbody>
+        <tr class="m-default">
+          <td>Default row</td>
+          <td>Lorem</td>
+          <td>ipsum</td>
+          <td>dolor</td>
+          <td>sit</td>
+          <td>amet</td>
+          <td><a href="#">Link</a></td>
+        </tr>
+        <tr class="m-primary">
+          <td>Primary row</td>
+          <td>Lorem</td>
+          <td>ipsum</td>
+          <td>dolor</td>
+          <td>sit</td>
+          <td>amet</td>
+          <td><a href="#">Link</a></td>
+        </tr>
+        <tr class="m-success">
+          <td>Success row</td>
+          <td>Lorem</td>
+          <td>ipsum</td>
+          <td>dolor</td>
+          <td>sit</td>
+          <td>amet</td>
+          <td><a href="#">Link</a></td>
+        </tr>
+        <tr class="m-warning">
+          <td>Warning row</td>
+          <td>Lorem</td>
+          <td>ipsum</td>
+          <td>dolor</td>
+          <td>sit</td>
+          <td>amet</td>
+          <td><a href="#">Link</a></td>
+        </tr>
+        <tr class="m-danger">
+          <td>Danger row</td>
+          <td>Lorem</td>
+          <td>ipsum</td>
+          <td>dolor</td>
+          <td>sit</td>
+          <td>amet</td>
+          <td><a href="#">Link</a></td>
+        </tr>
+        <tr class="m-info">
+          <td>Info row</td>
+          <td>Lorem</td>
+          <td>ipsum</td>
+          <td>dolor</td>
+          <td>sit</td>
+          <td>amet</td>
+          <td><a href="#">Link</a></td>
+        </tr>
+        <tr class="m-dim">
+          <td>Dim row</td>
+          <td>Lorem</td>
+          <td>ipsum</td>
+          <td>dolor</td>
+          <td>sit</td>
+          <td>amet</td>
+          <td><a href="#">Link</a></td>
+        </tr>
+      </tbody>
+    </table>
+
+`Images`_
+=========
+
+Putting :css:`.m-image` class onto the :html:`<img>` tag makes it centered,
+slightly rounded and sets its max width to 100%. Adding :css:`.m-fullwidth` on
+the image element works as expected. For accessibility reasons it's a good
+practice to include the ``alt`` attribute.
+
+.. code-figure::
+
+    .. code:: html
+
+        <img src="flowers.jpg" alt="Flowers" class="m-image" />
+
+    .. raw:: html
+
+        <img src="{filename}/static/flowers-small.jpg" alt="Flowers" class="m-image" />
+
+To make the image clickable, wrap the :html:`<a>` tag in an additional
+:html:`<div>` and put the :css:`.m-image` class on the :html:`<div>` element
+instead of on the image. This will ensure that only the image is clickable and
+not the surrounding area:
+
+.. code-figure::
+
+    .. code:: html
+
+        <div class="m-image">
+          <a href="flowers.jpg"><img src="flowers.jpg" /></a>
+        </div>
+
+    .. raw:: html
+
+        <div class="m-image">
+          <a href="{filename}/static/flowers.jpg"><img src="{filename}/static/flowers-small.jpg" /></a>
+        </div>
+
+`Figures`_
+==========
+
+Use the HTML5 :html:`<figure>` tag together with :css:`.m-figure` to style it.
+As with plain image, it's by default centered, slightly rounded and has a
+border around the caption and description. The caption is expected to be in the
+:html:`<figcaption>` element. The description is optional, but should be
+wrapped in some tag as well (for example a :html:`<div>`). The
+:css:`.m-fullwidth` class works here too and you can also wrap the
+:html:`<img>` element in an :html:`<a>` tag to make it clickable.
+
+Figure always expects at least the caption to be present. If you want just an
+image, use the plain image tag. If you have a lot of figures on the page and
+the border is distracting, apply the :css:`.m-flat` class to hide it.
+
+.. code-figure::
+
+    .. code:: html
+
+        <figure class="m-figure">
+          <img src="ship.jpg" alt="Ship" />
+          <figcaption>A Ship</figcaption>
+          <div>Photo © <a href="http://blog.mosra.cz/">The Author</a></div>
+        </figure>
+
+    .. raw:: html
+
+        <figure class="m-figure">
+          <img src="{filename}/static/ship-small.jpg" alt="Ship" />
+          <figcaption>A Ship</figcaption>
+          <div>Photo © <a href="http://blog.mosra.cz/">The Author</a></div>
+        </figure>
+
+`Image grid`_
+=============
+
+Inspired by `image grids on Medium <https://blog.medium.com/introducing-image-grids-c592e5bc16d8>`_,
+its purpose is to present photos in a beautiful way. Wrap one or more
+:html:`<figure>` elements in a :html:`<div class="m-imagegrid">` element and
+delimit each row with a wrapper :html:`<div>`. Each :html:`<figure>` element
+needs to contain an :html:`<img>` and a :html:`<figcaption>` with image caption
+that appears on hover; these two elements can be optionally wrapped in an
+:html:`<a>` to make the image clickable. If you don't want a caption, use an
+empty :html:`<div>` instead of :html:`<figcaption>`. If you want the grid to
+`inflate to full container width <{filename}/css/grid.rst#inflatable-nested-grid>`_,
+add a :css:`.m-container-inflate` CSS class to it.
+
+.. note-warning::
+
+    The inner :html:`<div>` or :html:`<figcaption>` element is *important*,
+    without it the grid won't look as desired.
+
+Example usage (stupidly showing the two images all over again --- sorry):
+
+.. code:: html
+
+    <div class="m-imagegrid m-container-inflate">
+      <div>
+        <figure style="width: 69.127%">
+          <a href="ship.jpg">
+            <img src="ship.jpg" />
+            <figcaption>F9.0, 1/250 s, ISO 100</figcaption>
+          </a>
+        </figure>
+        <figure style="width: 30.873%">
+          <a href="flowers.jpg">
+            <img src="flowers.jpg" />
+            <figcaption>F2.8, 1/1600 s, ISO 100</figcaption>
+          </a>
+        </figure>
+      </div>
+      <div>
+        <figure style="width: 30.873%">
+          <a href="flowers.jpg">
+            <img src="flowers.jpg" />
+            <figcaption>F2.8, 1/1600 s, ISO 100</figcaption>
+          </a>
+        </figure>
+        <figure style="width: 69.127%">
+          <a href="ship.jpg">
+            <img src="ship.jpg" />
+            <figcaption>F9.0, 1/250 s, ISO 100</figcaption>
+          </a>
+        </figure>
+      </div>
+    </div>
+
+.. raw:: html
+
+    <div class="m-imagegrid m-container-inflate">
+      <div>
+        <figure style="width: 69.127%">
+          <a href="{filename}/static/ship.jpg">
+            <img src="{filename}/static/ship.jpg" />
+            <figcaption>F9.0, 1/250 s, ISO 100</figcaption>
+          </a>
+        </figure>
+        <figure style="width: 30.873%">
+          <a href="{filename}/static/flowers.jpg">
+            <img src="{filename}/static/flowers.jpg" />
+            <figcaption>F2.8, 1/1600 s, ISO 100</figcaption>
+          </a>
+        </figure>
+      </div>
+      <div>
+        <figure style="width: 30.873%">
+          <a href="{filename}/static/flowers.jpg">
+            <img src="{filename}/static/flowers.jpg" />
+            <figcaption>F2.8, 1/1600 s, ISO 100</figcaption>
+          </a>
+        </figure>
+        <figure style="width: 69.127%">
+          <a href="{filename}/static/ship.jpg">
+            <img src="{filename}/static/ship.jpg" />
+            <figcaption>F9.0, 1/250 s, ISO 100</figcaption>
+          </a>
+        </figure>
+      </div>
+    </div>
+
+The core idea behind the image grid is scaling particular images to occupy the
+same height on given row. First, a sum :math:`W` of image aspect ratios is
+calculated for the whole row:
+
+.. math::
+
+    W = \sum_{i=0}^{n-1} \cfrac{w_i}{h_i}
+
+Then, percentage width :math:`p_i` of each image is calculated as:
+
+.. math::
+
+    p_i = W \cfrac{w_i}{h_i} \cdot 100 \%
+
+.. note-info::
+
+    The image width calculation is quite annoying to do manually, that's why
+    ``m.css`` provides a `Pelican plugin <{filename}/plugins/images.rst#image-grid>`_
+    that does the hard work for you.
+
+`Code`_
+=======
+
+``m.css`` recognizes code highlighting compatible with `Pygments <http://pygments.org/>`_
+and provides additional styling for it. There's a set of builtin `pygments-*.css <{filename}/css.rst>`_
+styles that match the ``m.css`` themes.
+
+For example, code highlighted using:
+
+.. code:: sh
+
+    echo -e "int main() {\n    return 0;\n}" | pygmentize -f html -l c++ -O nowrap
+
+Will spit out a bunch of :html:`<span>` elements like below. To create a code
+block, wrap the output in :html:`<pre class="m-code">` (note that whitespace
+matters inside this tag):
+
+.. code-figure::
+
+    .. code:: html
+
+        <pre class="m-code"><span class="kt">int</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
+            <span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
+        <span class="p">}</span></pre>
+
+    .. raw:: html
+
+        <pre class="m-code"><span class="kt">int</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
+            <span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
+        <span class="p">}</span></pre>
+
+Pygments allow to highlight arbitrary lines, which affect the rendering in this
+way:
+
+.. code:: c++
+    :hl_lines: 2 3
+
+    int main() {
+        std::cout << "Hello world!" << std::endl;
+        return 0;
+    }
+
+Sometimes you want to focus on code that has been changed / added and mute the
+rest. Add an additional :css:`.m-inverted` CSS class to the
+:html:`<pre class="m-code">` to achieve this effect:
+
+.. code:: c++
+    :hl_lines: 4 5
+    :class: m-inverted
+
+    #include <iostream>
+
+    int main() {
+        std::cout << "Hello world!" << std::endl;
+        return 0;
+    }
+
+To have code highlighting inline, wrap the output in :html:`<code class="m-code">`
+instead of :html:`<pre>`:
+
+.. code-figure::
+
+    .. code:: html
+
+        <p>The <code class="m-code"><span class="n">main</span><span class="p">()</span></code>
+        function doesn't need to have a <code class="m-code"><span class="k">return</span></code>
+        statement.</p>
+
+    .. raw:: html
+
+        <p>The <code class="m-code"><span class="n">main</span><span class="p">()</span></code>
+        function doesn't need to have a <code class="m-code"><span class="k">return</span></code>
+        statement.</p>
+
+.. note-success::
+
+    To make your life easier, ``m.css`` provides a
+    `Pelican plugin <{filename}/plugins/math-and-code.rst#code>`__
+    that integrates Pygments code highlighting as a :abbr:`reST <reStructuredText>`
+    directive.
+
+`Code figure`_
+==============
+
+It often happens that you want to present code with corresponding result
+together. The code figure looks similar to `image figures <#figures>`_ and
+consists of a :html:`<figure class="m-code-figure">` element containing a
+:html:`<pre>` block and whatever else you want to put in as the result. The
+:html:`<pre>` element has to be the very first child of the :html:`<figure>`
+for the markup to work correctly. Similar to image figure, you can apply the
+:css:`.m-flat` CSS class to remove the border.
+
+Example (note that this page uses code figure for all code examples, so it's a
+bit of a figure inception shown here):
+
+.. code-figure::
+
+    .. code:: html
+
+        <figure class="m-code-figure">
+          <pre>Some
+            code
+        snippet</pre>
+          And a resulting output.
+        </figure>
+
+    .. raw:: html
+
+        <figure class="m-code-figure">
+          <pre>Some
+            code
+        snippet</pre>
+          And a resulting output.
+        </figure>
+
+`Math`_
+=======
+
+:html:`<svg>` elements containing math can be wrapped in
+:html:`<div class="m-math">` to make it centered. `CSS color classes <#colors>`_
+can be applied to the :html:`<div>` as well. It's a good practice to include
+:html:`<title>` and :html:`<description>` elements for accessibility reasons.
+
+.. code-figure::
+
+    .. code:: html
+
+        <div class="m-math m-success">
+          <svg>
+            <title>LaTeX Math </title>
+            <description>a^2 = b^2 + c^2</description>
+            <g>...</g>
+          </svg>
+        </div>
+
+    .. raw:: html
+
+        <div class="m-math m-success">
+          <svg height='13.7321pt' version='1.1' viewBox='164.011 -10.9857 60.0231 10.9857' width='75.0289pt'>
+            <title>LaTeX Math</title>
+            <description>a^2 = b^2 + c^2</description>
+            <defs>
+              <path d='M3.59851 -1.42267C3.53873 -1.21943 3.53873 -1.19552 3.37136 -0.968369C3.10834 -0.633624 2.58232 -0.119552 2.02042 -0.119552C1.53026 -0.119552 1.25529 -0.561893 1.25529 -1.26725C1.25529 -1.92478 1.6259 -3.26376 1.85305 -3.76588C2.25953 -4.60274 2.82142 -5.03313 3.28767 -5.03313C4.07671 -5.03313 4.23213 -4.0528 4.23213 -3.95716C4.23213 -3.94521 4.19626 -3.78979 4.18431 -3.76588L3.59851 -1.42267ZM4.36364 -4.48319C4.23213 -4.79402 3.90934 -5.27223 3.28767 -5.27223C1.93674 -5.27223 0.478207 -3.52677 0.478207 -1.75741C0.478207 -0.573848 1.17161 0.119552 1.98456 0.119552C2.64209 0.119552 3.20399 -0.394521 3.53873 -0.789041C3.65828 -0.0836862 4.22017 0.119552 4.57883 0.119552S5.22441 -0.0956413 5.4396 -0.526027C5.63088 -0.932503 5.79826 -1.66177 5.79826 -1.70959C5.79826 -1.76936 5.75044 -1.81719 5.6787 -1.81719C5.57111 -1.81719 5.55915 -1.75741 5.51133 -1.57808C5.332 -0.872727 5.10486 -0.119552 4.61469 -0.119552C4.268 -0.119552 4.24408 -0.430386 4.24408 -0.669489C4.24408 -0.944458 4.27995 -1.07597 4.38755 -1.54222C4.47123 -1.8411 4.53101 -2.10411 4.62665 -2.45081C5.06899 -4.24408 5.17659 -4.67447 5.17659 -4.7462C5.17659 -4.91357 5.04508 -5.04508 4.86575 -5.04508C4.48319 -5.04508 4.38755 -4.62665 4.36364 -4.48319Z' id='g0-97'/>
+              <path d='M2.76164 -7.99801C2.7736 -8.04583 2.79751 -8.11756 2.79751 -8.17733C2.79751 -8.29689 2.67796 -8.29689 2.65405 -8.29689C2.64209 -8.29689 2.21171 -8.26102 1.99651 -8.23711C1.79328 -8.22516 1.61395 -8.20125 1.39875 -8.18929C1.11183 -8.16538 1.02814 -8.15342 1.02814 -7.93823C1.02814 -7.81868 1.1477 -7.81868 1.26725 -7.81868C1.87696 -7.81868 1.87696 -7.71108 1.87696 -7.59153C1.87696 -7.50785 1.78132 -7.16115 1.7335 -6.94595L1.44658 -5.79826C1.32702 -5.32005 0.645579 -2.60623 0.597758 -2.39103C0.537983 -2.09215 0.537983 -1.88892 0.537983 -1.7335C0.537983 -0.514072 1.21943 0.119552 1.99651 0.119552C3.38331 0.119552 4.81793 -1.66177 4.81793 -3.39527C4.81793 -4.49514 4.19626 -5.27223 3.29963 -5.27223C2.67796 -5.27223 2.11606 -4.75816 1.88892 -4.51905L2.76164 -7.99801ZM2.00847 -0.119552C1.6259 -0.119552 1.20747 -0.406476 1.20747 -1.33898C1.20747 -1.7335 1.24334 -1.96065 1.45853 -2.79751C1.4944 -2.95293 1.68568 -3.71806 1.7335 -3.87347C1.75741 -3.96912 2.46276 -5.03313 3.27572 -5.03313C3.80174 -5.03313 4.04085 -4.5071 4.04085 -3.88543C4.04085 -3.31158 3.7061 -1.96065 3.40722 -1.33898C3.10834 -0.6934 2.55841 -0.119552 2.00847 -0.119552Z' id='g0-98'/>
+              <path d='M4.67447 -4.49514C4.44732 -4.49514 4.33973 -4.49514 4.17235 -4.35168C4.10062 -4.29191 3.96912 -4.11258 3.96912 -3.9213C3.96912 -3.68219 4.14844 -3.53873 4.37559 -3.53873C4.66252 -3.53873 4.98531 -3.77783 4.98531 -4.25604C4.98531 -4.82989 4.43537 -5.27223 3.61046 -5.27223C2.04433 -5.27223 0.478207 -3.56264 0.478207 -1.86501C0.478207 -0.824907 1.12379 0.119552 2.34321 0.119552C3.96912 0.119552 4.99726 -1.1477 4.99726 -1.30311C4.99726 -1.37484 4.92553 -1.43462 4.87771 -1.43462C4.84184 -1.43462 4.82989 -1.42267 4.72229 -1.31507C3.95716 -0.298879 2.82142 -0.119552 2.36712 -0.119552C1.54222 -0.119552 1.2792 -0.836862 1.2792 -1.43462C1.2792 -1.85305 1.48244 -3.0127 1.91283 -3.82565C2.22366 -4.38755 2.86924 -5.03313 3.62242 -5.03313C3.77783 -5.03313 4.43537 -5.00922 4.67447 -4.49514Z' id='g0-99'/>
+              <path d='M4.77011 -2.76164H8.06974C8.23711 -2.76164 8.4523 -2.76164 8.4523 -2.97684C8.4523 -3.20399 8.24907 -3.20399 8.06974 -3.20399H4.77011V-6.50361C4.77011 -6.67098 4.77011 -6.88618 4.55492 -6.88618C4.32777 -6.88618 4.32777 -6.68294 4.32777 -6.50361V-3.20399H1.02814C0.860772 -3.20399 0.645579 -3.20399 0.645579 -2.98879C0.645579 -2.76164 0.848817 -2.76164 1.02814 -2.76164H4.32777V0.537983C4.32777 0.705355 4.32777 0.920548 4.54296 0.920548C4.77011 0.920548 4.77011 0.71731 4.77011 0.537983V-2.76164Z' id='g2-43'/>
+              <path d='M8.06974 -3.87347C8.23711 -3.87347 8.4523 -3.87347 8.4523 -4.08867C8.4523 -4.31582 8.24907 -4.31582 8.06974 -4.31582H1.02814C0.860772 -4.31582 0.645579 -4.31582 0.645579 -4.10062C0.645579 -3.87347 0.848817 -3.87347 1.02814 -3.87347H8.06974ZM8.06974 -1.64981C8.23711 -1.64981 8.4523 -1.64981 8.4523 -1.86501C8.4523 -2.09215 8.24907 -2.09215 8.06974 -2.09215H1.02814C0.860772 -2.09215 0.645579 -2.09215 0.645579 -1.87696C0.645579 -1.64981 0.848817 -1.64981 1.02814 -1.64981H8.06974Z' id='g2-61'/>
+              <path d='M2.24757 -1.6259C2.37509 -1.74545 2.70984 -2.00847 2.83736 -2.12005C3.33151 -2.57435 3.80174 -3.0127 3.80174 -3.73798C3.80174 -4.68643 3.00473 -5.30012 2.00847 -5.30012C1.05205 -5.30012 0.422416 -4.57484 0.422416 -3.8655C0.422416 -3.47497 0.73325 -3.41918 0.844832 -3.41918C1.0122 -3.41918 1.25928 -3.53873 1.25928 -3.84159C1.25928 -4.25604 0.860772 -4.25604 0.765131 -4.25604C0.996264 -4.83786 1.53026 -5.03711 1.9208 -5.03711C2.66202 -5.03711 3.04458 -4.40747 3.04458 -3.73798C3.04458 -2.90909 2.46276 -2.30336 1.52229 -1.33898L0.518057 -0.302864C0.422416 -0.215193 0.422416 -0.199253 0.422416 0H3.57061L3.80174 -1.42665H3.55467C3.53076 -1.26725 3.467 -0.868742 3.37136 -0.71731C3.32354 -0.653549 2.71781 -0.653549 2.59029 -0.653549H1.17161L2.24757 -1.6259Z' id='g1-50'/>
+            </defs>
+            <g id='page1'>
+              <use x='164.011' xlink:href='#g0-97' y='-0.913201'/>
+              <use x='170.156' xlink:href='#g1-50' y='-5.84939'/>
+              <use x='178.209' xlink:href='#g2-61' y='-0.913201'/>
+              <use x='190.634' xlink:href='#g0-98' y='-0.913201'/>
+              <use x='195.612' xlink:href='#g1-50' y='-5.84939'/>
+              <use x='203.001' xlink:href='#g2-43' y='-0.913201'/>
+              <use x='214.762' xlink:href='#g0-99' y='-0.913201'/>
+              <use x='219.8' xlink:href='#g1-50' y='-5.84939'/>
+            </g>
+          </svg>
+        </div>
+
+For inline math, add the :css:`.m-math` class to the :html:`<svg>` tag
+directly. Note that you'll probably need to manually specify
+:css:`vertical-align` style to make the formula align well with surrounding
+text. You can use CSS color classes here as well.
+
+.. code-figure::
+
+    .. code:: html
+
+        <p>There is <a href="https://tauday.com/">a movement</a> for replacing circle
+        constant <svg class="m-math" style="vertical-align: 0.0pt">...</svg> with the
+        <svg class="m-math m-warning" style="vertical-align: 0.0pt">...</svg> character.
+
+    .. raw:: html
+
+        <p>There is <a href="https://tauday.com/">a movement</a> for replacing
+        circle constant <svg class="m-math" style="vertical-align: -0.0pt;" height='9.63055pt' version='1.1' viewBox='0 -7.70444 12.9223 7.70444' width='16.1528pt'>
+          <title>LaTeX Math</title>
+          <description>2 \pi</description>
+          <defs>
+            <path d='M3.09639 -4.5071H4.44732C4.12453 -3.16812 3.9213 -2.29539 3.9213 -1.33898C3.9213 -1.17161 3.9213 0.119552 4.41146 0.119552C4.66252 0.119552 4.87771 -0.107597 4.87771 -0.310834C4.87771 -0.37061 4.87771 -0.394521 4.79402 -0.573848C4.47123 -1.39875 4.47123 -2.4269 4.47123 -2.51059C4.47123 -2.58232 4.47123 -3.43113 4.72229 -4.5071H6.06127C6.21669 -4.5071 6.61121 -4.5071 6.61121 -4.88966C6.61121 -5.15268 6.38406 -5.15268 6.16887 -5.15268H2.23562C1.96065 -5.15268 1.55417 -5.15268 1.00423 -4.56687C0.6934 -4.22017 0.310834 -3.58655 0.310834 -3.51482S0.37061 -3.41918 0.442341 -3.41918C0.526027 -3.41918 0.537983 -3.45504 0.597758 -3.52677C1.21943 -4.5071 1.8411 -4.5071 2.13998 -4.5071H2.82142C2.55841 -3.61046 2.25953 -2.57036 1.2792 -0.478207C1.18356 -0.286924 1.18356 -0.263014 1.18356 -0.191283C1.18356 0.0597758 1.39875 0.119552 1.50635 0.119552C1.85305 0.119552 1.94869 -0.191283 2.09215 -0.6934C2.28344 -1.30311 2.28344 -1.32702 2.40299 -1.80523L3.09639 -4.5071Z' id='g0-25'/>
+            <path d='M5.26027 -2.00847H4.99726C4.96139 -1.80523 4.86575 -1.1477 4.7462 -0.956413C4.66252 -0.848817 3.98107 -0.848817 3.62242 -0.848817H1.41071C1.7335 -1.12379 2.46276 -1.88892 2.7736 -2.17584C4.59078 -3.84956 5.26027 -4.47123 5.26027 -5.65479C5.26027 -7.02964 4.17235 -7.95019 2.78555 -7.95019S0.585803 -6.76663 0.585803 -5.73848C0.585803 -5.12877 1.11183 -5.12877 1.1477 -5.12877C1.39875 -5.12877 1.70959 -5.30809 1.70959 -5.69066C1.70959 -6.0254 1.48244 -6.25255 1.1477 -6.25255C1.0401 -6.25255 1.01619 -6.25255 0.980324 -6.2406C1.20747 -7.05355 1.85305 -7.60349 2.63014 -7.60349C3.64633 -7.60349 4.268 -6.75467 4.268 -5.65479C4.268 -4.63861 3.68219 -3.75392 3.00075 -2.98879L0.585803 -0.286924V0H4.94944L5.26027 -2.00847Z' id='g1-50'/>
+          </defs>
+          <g id='page1'>
+            <use x='0' xlink:href='#g1-50' y='0'/>
+            <use x='5.85299' xlink:href='#g0-25' y='0'/>
+          </g>
+        </svg> with the <svg class="m-math m-primary" style="vertical-align: -0.0pt;" height='6.43422pt' version='1.1' viewBox='0 -5.14737 6.41894 5.14737' width='8.02368pt'>
+          <title>LaTeX Math</title>
+            <description>\tau</description>
+          <defs>
+            <path d='M3.43113 -4.5071H5.41569C5.57111 -4.5071 5.96563 -4.5071 5.96563 -4.88966C5.96563 -5.15268 5.73848 -5.15268 5.52329 -5.15268H2.23562C1.96065 -5.15268 1.55417 -5.15268 1.00423 -4.56687C0.6934 -4.22017 0.310834 -3.58655 0.310834 -3.51482S0.37061 -3.41918 0.442341 -3.41918C0.526027 -3.41918 0.537983 -3.45504 0.597758 -3.52677C1.21943 -4.5071 1.8411 -4.5071 2.13998 -4.5071H3.13225L1.88892 -0.406476C1.82914 -0.227148 1.82914 -0.203238 1.82914 -0.167372C1.82914 -0.0358655 1.91283 0.131507 2.15193 0.131507C2.52254 0.131507 2.58232 -0.191283 2.61818 -0.37061L3.43113 -4.5071Z' id='g0-28'/>
+          </defs>
+          <g id='page1'>
+            <use x='0' xlink:href='#g0-28' y='0'/>
+          </g>
+        </svg> character.</p>
+
+.. note-warning::
+
+    Producing SVG manually using command-line tools is no fun, so ``m.css``
+    provides a `Pelican plugin <{filename}/plugins/math-and-code.rst#math>`__
+    that integrates latex math directly into your markup. Check it out!
+
+`Padding`_
+==========
+
+Similarly to `typography elements <{filename}/css/typography.rst#padding>`_;
+blocks, notes, frames, tables, images, figures, image grids, code and math
+blocks and code figures have :css:`1rem` padding after, except when they are
+the last element, to avoid excessive spacing.
+
+`Responsive utilities`_
+=======================
+
+If you have some element that will certainly overflow on smaller screen sizes
+(such as wide table or image that can't be scaled), wrap it in a
+:css:`.m-scroll`. This will put a horizontal scrollbar under in case the
+element overflows.
+
+There's also :css:`.m-fullwidth` that will make your element always occupy 100%
+of the parent element width. Useful for tables or images.
+
+.. note-dim::
+    :class: m-text-center
+
+    `« Typography <{filename}/css/typography.rst>`_ | `CSS <{filename}/css.rst>`_ | `Page layout » <{filename}/css/page-layout.rst>`_
diff --git a/doc/css/grid.rst b/doc/css/grid.rst
new file mode 100644 (file)
index 0000000..7fd2b44
--- /dev/null
@@ -0,0 +1,349 @@
+Grid system
+###########
+
+:breadcrumb: {filename}/css.rst CSS
+
+.. role:: css(code)
+    :language: css
+
+Inspired by `Bootstrap <http://getbootstrap.com>`_, the grid system is the
+heart of a responsive website layout. The `m-grid.css <{filename}/css.rst>`_
+file contains all the setup you need for it. Besides that, in order to have
+devices recognize your website properly as responsive and not zoom it out all
+the way to an unreadable mess, don't forget to add this to your :html:`<head>`:
+
+.. code:: html
+
+    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+
+.. contents::
+    :class: m-block m-default
+
+`Overview`_
+===========
+
+If you have never heard of it, it all boils down to a few breakpoints that
+define how the website is wide on various screen sizes. For every one of them
+you can define how your page and content layout will look like. In every case
+you have 12 columns and it's completely up to you how you use them. Let's start
+with an example.
+
+.. code:: html
+
+    <div class="m-container">
+      <div class="m-row">
+        <div class="m-col-t-6">.m-col-t-6</div>
+        <div class="m-col-t-6">.m-col-t-6</div>
+      </div>
+      <div class="m-row">
+        <div class="m-col-s-4 m-col-m-6">.m-col-s-4 .m-col-m-6</div>
+        <div class="m-col-s-4 m-col-m-3">.m-col-s-4 .m-col-m-3</div>
+        <div class="m-col-s-4 m-col-m-3">.m-col-s-4 .m-col-m-3</div>
+      </div>
+      <div class="m-row">
+        <div class="m-col-l-7"><div class="m-frame m-center">.m-col-l-7</div></div>
+        <div class="m-col-l-5"><div class="m-frame m-center">.m-col-l-5</div></div>
+      </div>
+    </div>
+
+.. raw:: html
+
+    <div class="m-row">
+      <div class="m-col-t-6 m-nopad"><div class="m-frame m-text-center">.m-col-t-6</div></div>
+      <div class="m-col-t-6 m-nopad"><div class="m-frame m-text-center">.m-col-t-6</div></div>
+    </div>
+    <div class="m-row">
+      <div class="m-col-s-4 m-col-m-6 m-nopad"><div class="m-frame m-text-center">.m-col-s-4 .m-col-m-6</div></div>
+      <div class="m-col-s-4 m-col-m-3 m-nopad"><div class="m-frame m-text-center">.m-col-s-4 .m-col-m-3</div></div>
+      <div class="m-col-s-4 m-col-m-3 m-nopad"><div class="m-frame m-text-center">.m-col-s-4 .m-col-m-3</div></div>
+    </div>
+    <div class="m-row">
+      <div class="m-col-l-7 m-nopady m-nopadx"><div class="m-frame m-text-center">.m-col-l-7</div></div>
+      <div class="m-col-l-5 m-nopadt m-nopadx"><div class="m-frame m-text-center">.m-col-l-5</div></div>
+    </div>
+
+.. note-info::
+
+    To see the effect, try to resize your browser window (or rotate the screen
+    of your mobile device). Please note that the live examples here are not
+    *exactly* matching the code --- I added a bunch of HTML elements and CSS
+    classes to improve clarity.
+
+In the above code, the outer :html:`<div class="m-container">` is taking care
+of limiting the website layout width. On very narrow devices, the whole screen
+width is used, on wider screens fixed sizes are used in order to make the
+content layouting manageable. The :css:`.m-container` usually has :css:`.m-row`
+items directly inside, but that's not a requirement --- you can put anything
+there, if you just want to have some predictable width limitation to your
+content.
+
+The :html:`<div class="m-row">` denotes a row. The row is little more than
+a delimiter for columns --- it just makes sure that two neighboring rows don't
+interact with each other in a bad way.
+
+The actual magic is done by the row elements denoted by :css:`.m-col-B-N`. The
+``B`` is one of four breakpoints --- ``t`` for tiny, ``s`` for small, ``m`` for
+medium and ``l`` for large --- based on screen width. The ``N`` is number of
+columns that given element will span. So, looking at the code above,
+:css:`.m-col-m-3` will span three columns out of twelve on medium-sized screen.
+
+This setting is inherited upwards --- if you specify a column span for a
+smaller screen width, it will get applied on larger width as well, unless you
+override it with a setting for larger screen width. On the other hand, if given
+screen width has no column width specified, the element will span the whole
+row. So, again from above, the :css:`.m-col-s-4 .m-col-m-6` element will span
+the whole row on tiny screen sizes, four columns on small screen sizes and six
+columns on medium and large screen sizes.
+
+`Detailed grid properties`_
+===========================
+
+.. class:: m-table
+
++-------------------+-----------------------+---------------------------+-------------------------------+
+| Breakpoint        | Screen width range    | ``.m-container`` width    | Classes applied, ordered by   |
+|                   | (inclusive)           |                           | priority                      |
++===================+=======================+===========================+===============================+
+| ``t``, "tiny",    | less than 576px       | full screen width         | ``.m-col-t-*``                |
+| portrait phones   |                       |                           |                               |
++-------------------+-----------------------+---------------------------+-------------------------------+
+| ``s``, "small",   | 576px - 767px         | 560px                     | ``.m-col-s-*``,               |
+| landscape phones  |                       |                           | ``.m-col-t-*``                |
++-------------------+-----------------------+---------------------------+-------------------------------+
+| ``m``, "medium",  | 768px - 991px         | 750px                     | ``.m-col-m-*``,               |
+| tablets, small    |                       |                           | ``.m-col-s-*``,               |
+| desktops          |                       |                           | ``.m-col-t-*``                |
++-------------------+-----------------------+---------------------------+-------------------------------+
+| ``l``, "large",   | 992px and up          | 960px                     | ``.m-col-l-*``,               |
+| desktops, very    |                       |                           | ``.m-col-m-*``,               |
+| large tablets     |                       |                           | ``.m-col-s-*``,               |
+|                   |                       |                           | ``.m-col-t-*``                |
++-------------------+-----------------------+---------------------------+-------------------------------+
+
+`Wrapping around`_
+==================
+
+Besides the above "all or nothing" scenario, where all the elements either form
+a single row or are laid out one after another in separate rows, it's possible
+to wrap the items around so they for example take four columns in a large
+screen width and two rows of two columns in a small screen width. In such case
+it's important to account for elements with different heights using a
+:css:`.m-clearfix-*` for given breakpoint:
+
+.. code:: html
+
+    <div class="m-container">
+      <div class="m-row">
+        <div class="m-col-s-6 m-col-m-3">.m-col-s-6 .m-col-m-3<br/>...<br/>...</div>
+        <div class="m-col-s-6 m-col-m-3">.m-col-s-6 .m-col-m-3</div>
+        <div class="m-clearfix-s"></div>
+        <div class="m-col-s-6 m-col-m-3">.m-col-s-6 .m-col-m-3<br/>...</div>
+        <div class="m-col-s-6 m-col-m-3">.m-col-s-6 .m-col-m-3<br/>...</div>
+      </div>
+    </div>
+
+.. raw:: html
+
+    <div class="m-row">
+      <div class="m-col-s-6 m-col-m-3 m-nopadx m-nopadt"><div class="m-frame m-text-center">.m-col-s-6 .m-col-m-3<br/>...<br/>...</div></div>
+      <div class="m-col-s-6 m-col-m-3 m-nopadx m-nopadt"><div class="m-frame m-text-center">.m-col-s-6 .m-col-m-3</div></div>
+      <div class="m-clearfix-s"></div>
+      <div class="m-col-s-6 m-col-m-3 m-nopadx m-nopadt"><div class="m-frame m-text-center">.m-col-s-6 .m-col-m-3<br/>...</div></div>
+      <div class="m-col-s-6 m-col-m-3 m-nopadx m-nopadt"><div class="m-frame m-text-center">.m-col-s-6 .m-col-m-3<br/>...</div></div>
+    </div>
+
+.. note-success::
+
+    Shrink your browser window and then try to remove the
+    :html:`<div class="m-clearfix-s">` element to see what it does in the above
+    markup.
+
+`Pushing and pulling`_
+======================
+
+It's possible to push and pull the elements around using :css:`.m-push-*` and
+:css:`.m-pull-*` and even use this functionality to horizontally reorder
+content based on screen width. Learn by example:
+
+.. code:: html
+
+    <div class="m-container">
+      <div class="m-row">
+        <div class="m-col-l-6 m-push-l-3">.m-col-l-6 .m-push-l-3</div>
+      </div>
+      <div class="m-row">
+        <div class="m-col-s-8 m-push-s-4">.m-col-s-8 .m-push-s-4<br/>first</div>
+        <div class="m-col-s-4 m-pull-s-8">.m-col-s-4 .m-pull-s-8<br/>second</div>
+      </div>
+    </div>
+
+.. raw:: html
+
+    <div class="m-row">
+      <div class="m-col-l-6 m-push-l-3 m-nopad"><div class="m-frame m-text-center">.m-col-l-6 .m-push-l-3</div></div>
+    </div>
+    <div class="m-row">
+      <div class="m-col-s-8 m-push-s-4 m-nopadx m-nopadt"><div class="m-frame m-text-center">.m-col-s-8 .m-push-s-4<br/>first</div></div>
+      <div class="m-col-s-4 m-pull-s-8 m-nopadx m-nopadt"><div class="m-frame m-text-center">.m-col-s-4 .m-pull-s-8<br/>second</div></div>
+    </div>
+
+.. note-warning::
+
+    There may be some corner cases related to column span inheritance and
+    pushing/pulling. If the output is not desired, try specifying the
+    :css:`.m-push-*` and :css:`.m-pull-*` explicitly for all breakpoints.
+
+`Floating around`_
+==================
+
+It's also possible to responsively float or align the elements around using
+:css:`m-left-*`, :css:`m-right-*` and :css:`m-center-*` if you put the
+:css:`.m-col-*` elements directly into text flow without wrapping them in a
+:css:`.m-row` element. The following example will float the contents to the
+right on medium-size screens, center them on small and put them full-width
+on tiny screens:
+
+.. code:: html
+
+    <div class="m-col-s-6 m-center-s m-col-m-4 m-right-m">
+      .m-col-s-6 .m-center-s .m-col-m-4 .m-right-m
+    </div>
+    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod
+    tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
+    quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
+    consequat.</p>
+
+.. frame::
+
+    .. raw:: html
+
+        <div class="m-col-s-6 m-center-s m-col-m-4 m-right-m">
+        <div class="m-note m-primary m-text-center">.m-col-s-6 .m-center-s .m-col-m-4 .m-right-m</div>
+        </div>
+        <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod
+        tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
+        quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
+        consequat.</p>
+
+.. note-info::
+
+    The floating works on any element, not just those that are :css:`.m-col-*`.
+
+`Grid padding`_
+===============
+
+The :css:`.m-container` element pads its contents from left and right by
+:css:`1rem`; the :css:`.m-row` adds a negative :css:`-1rem` margin on left and
+right to reset it. Finally, the :css:`.m-col-*` elements have :css:`1rem`
+padding on all sides to separate the contents. It's possible to override this
+on the :css:`.m-container` and/or on :css:`.m-col-*` elements using
+:css:`.m-nopad`, :css:`.m-nopadx`, :css:`m-nopady`, :css:`.m-nopadt`,
+:css:`.m-nopadb`, :css:`.m-nopadl`, :css:`.m-nopadr` which remove all, just
+horizontal or vertical padding, or padding on the top/bottom/left/right,
+respectively.
+
+`Grid nesting`_
+===============
+
+It's possible to nest the grid. Just place a :css:`.m-row` element inside an
+:css:`.m-col-*` (it *doesn't* need to be a direct child) and put your
+:css:`.m-col-*` elements inside. The inner grid will also have 12 columns, but
+smaller ones.
+
+.. note-info::
+
+    Because the :css:`.m-container` element specifies a fixed width, it's not
+    desirable to wrap the nested grid with it again.
+
+`Removing the grid on larger screen sizes`_
+===========================================
+
+The usual behavior is to *add* the grid for larger screen sizes, but sometimes
+you might want to do the opposite. It's possible to do that just by specifying
+:css:`.m-col-*-12` for given breakpoint, but sometimes the CSS :css:`float`
+property might cause problems. The :css:`.m-col-*-none` classes completely
+remove all grid-related CSS styling for given screen size and up so the element
+behaves like in its initial state.
+
+.. code:: html
+
+    <div class="m-container">
+      <div class="m-row">
+        <div class="m-col-s-8 m-col-l-none">.m-col-s-8 .m-col-l-none</div>
+        <div class="m-col-s-4 m-col-l-none">.m-col-s-4 .m-col-l-none</div>
+      </div>
+    </div>
+
+.. raw:: html
+
+    <div class="m-row">
+      <div class="m-col-s-8 m-col-l-none m-nopad"><div class="m-frame m-text-center">.m-col-s-8 .m-col-l-none</div></div>
+      <div class="m-col-s-4 m-col-l-none m-nopad"><div class="m-frame m-text-center">.m-col-s-4 .m-col-l-none</div></div>
+    </div>
+
+`Hiding elements based on screen size`_
+=======================================
+
+The :css:`.m-show-*` and :css:`.m-hide-*` classes hide or show the element on
+given screen size and up. Useful for example to show a different kind of
+navigation on different devices.
+
+.. code:: html
+
+    <div class="m-show-m">.m-show-m<br/>shown on M and up</div>
+    <div class="m-hide-l">.m-hide-l<br/>hidden on L and up</div>
+
+.. raw:: html
+
+    <div class="m-row">
+        <div class="m-col-m-6 m-col-l-12 m-show-m m-nopad"><div class="m-frame m-text-center">.m-show-m<br/>shown on M and up</div></div>
+        <div class="m-col-m-6 m-col-l-12 m-hide-l m-nopad"><div class="m-frame m-text-center">.m-hide-l<br/>hidden on L and up</div></div>
+    </div>
+
+`Inflatable nested grid`_
+=========================
+
+It's usual that the content area of the page doesn't span the full 12-column
+width in order to avoid long unreadable lines. But sometimmes one might want to
+use the full available width --- for example to show big pictures or to fit
+many things next to each other.
+
+If you have a ten-column content area with one column space on each side, mark
+your :css:`.m-container` element with :css:`#m-container-inflatable` and then
+put your nested content in elements marked with :css:`.m-container-inflate`.
+
+.. code:: html
+
+    <div class="m-container" id="m-container-inflatable">
+      <div class="m-row">
+        <div class="m-col-l-10 m-push-l-1">
+          <div class="m-container-inflate">.m-container-inflate</div>
+        </div>
+      </div>
+    </div>
+
+.. raw:: html
+
+    <div class="m-container-inflate"><div class="m-frame m-text-center">.m-container-inflate</div></div>
+
+`Debug CSS`_
+============
+
+It's sometimes hard to see why the layout isn't working as expected. Including
+the `m-debug.css <{filename}/css.rst>`_ file will highlight the most usual
+mistakes --- such as :css:`.m-row` not directly containing :css:`.m-col-*` or
+two :css:`.m-container`\ s nested together --- with bright red background for
+you to spot the problems better:
+
+.. code:: html
+
+    <link rel="stylesheet" href="m-dark.css" />
+
+Other than highlighting problems, this file doesn't alter your website
+appearance in any way. To save unnecessary requests and bandwidth, I recommend
+that you remove the reference again when publishing the website.
+
+.. note-dim::
+    :class: m-text-center
+
+    `CSS <{filename}/css.rst>`_ | `Typography » <{filename}/css/typography.rst>`_
diff --git a/doc/css/page-layout-test.rst b/doc/css/page-layout-test.rst
new file mode 100644 (file)
index 0000000..5d95c47
--- /dev/null
@@ -0,0 +1,104 @@
+Test
+####
+
+:save_as: css/page-layout/test/index.html
+:breadcrumb: {filename}/css.rst CSS
+             {filename}/css/page-layout.rst Page layout
+
+`Components in highlighted sections`_
+=====================================
+
+Click on the section header above to see the effect. Left border radius on all
+elements should be flattened and nothing should jump when highlighted.
+
+.. note-default::
+
+    Default note
+
+.. note-primary::
+
+    Primary note
+
+.. note-success::
+
+    Success note
+
+.. note-warning::
+
+    Warning note
+
+.. note-danger::
+
+    Danger note
+
+.. note-info::
+
+    Info note
+
+.. note-dim::
+
+    Dim note
+
+`Subsections`_
+--------------
+
+.. code:: c++
+
+    int main() { }
+
+.. block-default:: Default block
+
+    Blocks don't change their appearance much.
+
+.. block-flat:: Flat block
+
+    Flat blocks don't change their appearance at all.
+
+.. frame:: Frame
+
+    Frame will have its left border fattened.
+
+`Nested components`_
+--------------------
+
+Shouldn't be any difference.
+
+.. container:: m-row
+
+    .. container:: m-col-m-4 m-col-s-6
+
+        .. note-default::
+
+            Default note.
+
+    .. container:: m-col-m-4 m-col-s-6
+
+        .. block-primary:: Primary block
+
+            Text.
+
+    .. container:: m-col-m-4 m-col-s-6
+
+        .. frame::
+
+            A frame.
+
+    .. container:: m-clearfix-m
+
+        ..
+
+    .. container:: m-col-m-4 m-col-s-6
+
+        .. code:: hs
+
+            :: -> :: -> ::
+
+    .. container:: m-col-m-4 m-col-s-6
+
+        .. class:: m-inverted-highlight
+        .. code:: c++
+            :hl_lines: 2
+
+            int main() {
+                return 666;
+            }
diff --git a/doc/css/page-layout.rst b/doc/css/page-layout.rst
new file mode 100644 (file)
index 0000000..bbd9bee
--- /dev/null
@@ -0,0 +1,621 @@
+Page layout
+###########
+
+:breadcrumb: {filename}/css.rst CSS
+
+.. role:: raw-html(raw)
+   :format: html
+
+.. role:: sh(code)
+    :language: sh
+
+Besides separate components, ``m.css`` provides a fully-fledged whole page
+layout, including top navigation bar, footer navigation, article styling and
+more.
+
+.. contents::
+    :class: m-block m-default
+
+`Basic markup structure`_
+=========================
+
+A barebones HTML markup structure using ``m.css`` looks like below. There is
+the usual preamble, with :html:`<html lang="en">` and a :html:`<meta>` tag
+specifying the file encoding. Some browsers assume UTF-8 by default (as per the
+`HTML5 standard <https://www.w3schools.com/html/html_charset.asp>`__), but some
+not, so it's better to always include it. In the :html:`<head>`
+element it's important to also specify that the site is responsive via the
+:html:`<meta name="viewport">` tag.
+
+The :html:`<body>` element is divided into three parts --- top navigation bar,
+main page content and the footer navigation, explained below. Their meaning is
+implicit, so it's not needed to put any CSS classes on these elements, but you
+have to stick to the shown structure.
+
+.. code:: html
+
+    <!DOCTYPE html>
+    <html lang="en">
+      <head>
+        <title>Page title</title>
+        <link rel="stylesheet" href="m-dark.css" />
+        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+        <meta charset="UTF-8" />
+      </head>
+      <body>
+        <header><nav>
+          <!-- here comes the top navbar -->
+        </nav></header>
+        <main>
+          <!-- here comes the main page content -->
+        </main>
+        <footer><nav>
+          <!-- here comes the footer navigation -->
+        </nav></footer>
+      </body>
+    </html>
+
+`Theme color`_
+==============
+
+Some browsers (such as Vivaldi or Chrome on Android) are able to color the
+tab based on page theme color. This can be specified using the following
+:html:`<meta>` tag. The color shown matches the default (dark) style, see the
+`CSS themes <{filename}/css/themes.rst>`_ page for colors matching other
+themes.
+
+.. code:: html
+
+    <meta name="theme-color" content="#22272e" />
+
+`Top navigation bar`_
+=====================
+
+The top navigation bar is linear on
+`medium and larger screens <{filename}/css/grid.rst#detailed-grid-properties>`__
+and hidden under a "hamburger menu" on smaller screens. It has a distinct
+background that spans the whole window width, but the content is limited to
+page width as defined by the grid system.
+
+A very simple navigation bar with a homepage link and three additional menu
+items is shown below.
+
+.. code:: html
+
+    <header><nav id="navigation">
+      <div class="m-container">
+        <div class="m-row">
+          <a href="#" id="m-navbar-brand" class="m-col-t-9 m-col-m-none m-left-m">Your Brand</a>
+          <a id="m-navbar-show" href="#navigation" title="Show navigation" class="m-col-t-3 m-hide-m m-text-right">&#9776;</a>
+          <a id="m-navbar-hide" href="#" title="Hide navigation" class="m-col-t-3 m-hide-m m-text-right">&#9776;</a>
+          <div id="m-navbar-collapse" class="m-col-t-12 m-show-m m-col-m-none m-right-m">
+            <ol>
+              <li><a href="#">Features</a></li>
+              <li><a href="#">Showcase</a></li>
+              <li><a href="#">Download</a></li>
+            </ol>
+          </div>
+        </div>
+      </div>
+    </nav></header>
+
+The :css:`#m-navbar-brand` element is positioned on the left, in the default
+dark theme shown in bold and uppercase. On medium and large screens, the
+contents of :css:`#m-navbar-collapse` are shown, linearly, aligned to the right.
+
+On small and tiny screens, the :css:`#m-navbar-show` and :css:`#m-navbar-hide`
+show the :raw-html:`&#9776;` glyph aligned to the right instead of
+:css:`#m-navbar-collapse`. Clicking on this "hamburger menu" icon will append
+either ``#navigation`` or ``#`` to the page URL, which triggers the
+:css:`#m-navbar-collapse` element to be shown under as a list or hidden again.
+
+.. note-info::
+
+    You can change the :css:`#navigation` ID to a different name, if you want,
+    for example for localization --- it won't do any harm to the functionality.
+    Just be sure that the :html:`<a href="#navigation">` part is updated as
+    well.
+
+`Two-column navigation on small screens`_
+-----------------------------------------
+
+To save vertical space on small screens, it's possible to split the navbar
+contents into two (or more) columns using standard ``m.css``
+`grid functionality <{filename}/css/grid.rst>`_:
+
+.. code:: html
+    :hl_lines: 7 8 9 10 11 12 13 14 15 16 17 18 19
+    :class: m-inverted
+
+    <header><nav id="navigation">
+      <div class="m-container">
+        <div class="m-row">
+          <a href="#" id="m-navbar-brand" class="m-col-t-9 m-col-m-none m-left-m">Your Brand</a>
+          <a id="m-navbar-show" href="#navigation" title="Show navigation" class="m-col-t-3 m-hide-m m-text-right">&#9776;</a>
+          <a id="m-navbar-hide" href="#" title="Hide navigation" class="m-col-t-3 m-hide-m m-text-right">&#9776;</a>
+          <div id="m-navbar-collapse" class="m-col-t-12 m-show-m m-col-m-none m-right-m">
+            <div class="m-row">
+              <ol class="m-col-t-6 m-col-m-none">
+                <li><a href="#">Features</a></li>
+                <li><a href="#">Showcase</a></li>
+                <li><a href="#">Download</a></li>
+              </ol>
+              <ol class="m-col-t-6 m-col-m-none">
+                <li><a href="#">Blog</a></li>
+                <li><a href="#">Contact</a></li>
+              </ol>
+            </div>
+          </div>
+        </div>
+      </div>
+    </nav></header>
+
+`Sub-menus in the navbar`_
+--------------------------
+
+For each menu item it's also possible to add single-level sub-menu. On larger
+screens the menu will be shown on hover, on small screens the sub-menu will
+appear as an indented sub-list.
+
+.. code:: html
+    :hl_lines: 15 16 17 18 19 20 21
+    :class: m-inverted
+
+    <header><nav id="navigation">
+      <div class="m-container">
+        <div class="m-row">
+          <a href="#" id="m-navbar-brand" class="m-col-t-9 m-col-m-none m-left-m">Your Brand</a>
+          <a id="m-navbar-show" href="#navigation" title="Show navigation" class="m-col-t-3 m-hide-m m-text-right">&#9776;</a>
+          <a id="m-navbar-hide" href="#" title="Hide navigation" class="m-col-t-3 m-hide-m m-text-right">&#9776;</a>
+          <div id="m-navbar-collapse" class="m-col-t-12 m-show-m m-col-m-none m-right-m">
+            <div class="m-row">
+              <ol class="m-col-t-6 m-col-m-none">
+                <li><a href="#">Features</a></li>
+                <li><a href="#">Showcase</a></li>
+                <li><a href="#">Download</a></li>
+              </ol>
+              <ol class="m-col-t-6 m-col-m-none">
+                <li>
+                  <a href="#">Blog</a>
+                  <ol>
+                    <li><a href="#">News</a></li>
+                    <li><a href="#">Archive</a></li>
+                  </ol>
+                </li>
+                <li>
+                  <a href="#">Contact</a>
+                </li>
+              </ol>
+            </div>
+          </div>
+        </div>
+      </div>
+    </nav></header>
+
+`Active menu item highlighting`_
+--------------------------------
+
+Add :css:`#m-navbar-current` ID to the :html:`<a>` element of a menu item
+that's currently active to highlight it. This works for both top-level menu
+items and sub-menus. Doesn't do anything on the :css:`#m-navbar-brand` element.
+
+.. note-success::
+
+    See the top of the page for live example of all navbar features and view
+    page source to see how it's done here. Don't forget to try to shrink your
+    browser window to see its behavior in various cases.
+
+`Footer navigation`_
+====================
+
+The :html:`<footer>` has a slightly different background color to separate
+itself from the main page content, slightly dimmer text color and smaller font
+size and is padded from top and bottom by :css:`1rem` to make it feel less
+crowded. It's meant to be used for navigation, but besides that it gives you a
+complete freedom. As an example, you can populate it with four columns (which
+become two columns on narrow screens) of navigation and a fine print, using
+just the builtin ``m.css`` grid features:
+
+.. code:: html
+
+    <footer><nav>
+      <div class="m-container">
+        <div class="m-row">
+          <div class="m-col-s-3 m-col-t-6">
+            <h3><a href="#">Your Brand</a></h3>
+            <ul>
+              <li><a href="#">Features</a></li>
+              <li><a href="#">Showcase</a></li>
+            </ul>
+          </div>
+          <div class="m-col-s-3 m-col-t-6">
+            <h3><a href="#">Download</a></h3>
+            <ul>
+              <li><a href="#">Packages</a></li>
+              <li><a href="#">Source</a></li>
+            </ul>
+          </div>
+          <div class="m-clearfix-t"></div>
+          <div class="m-col-s-3 m-col-t-6">
+            <h3><a href="#">Contact</a></h3>
+            <ul>
+              <li><a href="#">E-mail</a></li>
+              <li><a href="#">GitHub</a></li>
+            </ul>
+          </div>
+          <div class="m-col-s-3 m-col-t-6">
+            <h3><a href="#">Blog</a></h3>
+            <ul>
+              <li><a href="#">News</a></li>
+              <li><a href="#">Archive</a></li>
+            </ul>
+          </div>
+        </div>
+        <div class="m-row">
+          <div class="m-col-l-10 m-push-l-1">
+            <p>Your Brand. Copyright &copy; <a href="mailto:you@your.brand">You</a>,
+            2017. All rights reserved.</p>
+          </div>
+        </div>
+      </div>
+    </nav></footer>
+
+.. note-info::
+
+    See the bottom of the page for a live example of footer navigation.
+
+`Main content`_
+===============
+
+The :html:`<main>` content is separated from the header and footer by
+:css:`1rem` padding, besides that there is no additional implicit styling. It's
+recommended to make use of ``m.css`` `grid features <{filename}/css/grid.rst>`_
+for content layout --- in particular, the :html:`<main>` element by itself
+doesn't even put any width restriction on the content.
+
+To follow HTML5 semantic features, ``m.css`` expects you to put your main page
+content into an :html:`<article>` element, be it an article or not. Heading is
+always in an :html:`<h1>` inside the article element, sub-sections are wrapped
+in nested :html:`<section>` elements with :html:`<h2>` and further. Example
+markup together with 10-column grid setup around the main content:
+
+.. code:: html
+
+    <main><div class="m-container">
+      <div class="m-row">
+        <article class="m-col-m-10 m-push-m-1">
+          <h1>A page</h1>
+          <p>Some introductionary paragraph.</p>
+          <section>
+            <h2>Features</h2>
+            <p>Section providing feature overview.</p>
+          </section>
+          <section>
+            <h2>Pricing</h2>
+            <p>Information about product pricing.</p>
+          </section>
+        </article>
+      </div>
+    </div></main>
+
+`Landing pages`_
+----------------
+
+Besides usual pages, which have the :html:`<article>` element filled with
+:html:`<h1>` followed by a wall of content, ``m.css`` has first-class support
+for landing pages. The major component of a landing page is a cover image in
+the background, spanning the whole page width in a :css:`#m-landing-image`
+element. The image is covered by :css:`#m-landing-cover` element that blends
+the image into the background on the bottom. On top of it you have full freedom
+to put any layout you need, for example a logo, a short introductionary
+paragraph and a download button. Note that the grid setup has to only wrap the
+content "below the fold", *not* the cover image.
+
+.. code:: html
+
+    <main><article>
+      <div id="m-landing-image" style="background-image: url('ship.jpg');">
+        <div id="m-landing-cover">
+          <div class="m-container">
+            <!-- content displayed over the cover image -->
+          </div>
+        </div>
+      </div>
+      <div class="m-container">
+        <!-- content "below the fold" folows -->
+      </div>
+    </article></main>
+
+The cover image always spans the whole screen width and goes also under the top
+navbar. In order to make the navbar aware of the image, put a :css:`.m-navbar-landing`
+CSS class on the :html:`<nav>` element --- this makes navbar dimmer with
+transparent background and hides the brand link on the left (with the
+assumption that the landing page includes a bigger version of it). While the
+landing page is designed to catch attention of new users, it shouldn't prevent
+regular visitors from navigating the website --- because of that the top navbar
+is not hidden completely and hovering it will make it more visible. This works
+similarly with the hamburger menu on small screen sizes.
+
+.. note-info::
+
+    You can see landing page in action `on the main page <{filename}/index.rst>`_.
+
+`Breadcrumb navigation`_
+------------------------
+
+For pages that are part of a nested structure, the :html:`<h1>` element can
+contain breadcrumb navigation back to pages up in the hierarchy in a
+:html:`<span class="m-breadcrumb">` element. Consider this example:
+
+.. code-figure::
+
+    .. code:: html
+
+        <h1>
+          <span class="m-breadcrumb">
+            <a href="#">Help</a> &raquo;
+            <a href="#">Components</a> &raquo;
+          </span>
+          Steam engine
+        </h1>
+        <p>Page content. Lorem ipsum dolor sit amet, consectetur adipiscing elit.
+        Aenean id elit posuere, consectetur magna congue, sagittis est.</p>
+
+    .. raw:: html
+
+        <h1>
+          <span class="m-breadcrumb">
+            <a href="#">Help</a> &raquo;
+            <a href="#">Components</a> &raquo;
+          </span>
+          Steam engine
+        </h1>
+        <p>Page content. Lorem ipsum dolor sit amet, consectetur adipiscing elit.
+        Aenean id elit posuere, consectetur magna congue, sagittis est.</p>
+
+`Clickable sections`_
+---------------------
+
+Using the :html:`<section>` elements gives you one advantage --- it gives you
+the foundation that makes linking to particular article sections possible.
+Consider the following code snippet:
+
+.. code:: html
+    :hl_lines: 4 5 8 9
+    :class: m-inverted
+
+    <article>
+      <h1>A page</h1>
+      <p>Some introductionary paragraph.</p>
+      <section id="features">
+        <h2><a href="#features">Features</a></h2>
+        <p>Section providing feature overview.</p>
+      </section>
+      <section id="pricing">
+        <h2><a href="#pricing">Pricing</a></h2>
+        <p>Information about product pricing.</p>
+      </section>
+    </article>
+
+Clicking on either the "Features" or "Pricing" heading will give the user a
+direct link to given section and the section will be highlighed accordingly.
+This works for nested sections as well.
+
+.. note-success::
+
+    You can observe the feature on this very page --- just click on any header
+    and see how the corresponding section gets highlighted.
+
+`Articles`_
+-----------
+
+For blog-like articles, ``m.css`` provides styling for article header, summary
+and footer --- just put :html:`<header>` and :html:`<footer>` elements directly
+into the surrounding :html:`<article>` tag. Article header is rendered in a
+bigger and brighter font, while footer is rendered in a smaller and dimmer
+font. Example markup and corresponding rendering:
+
+.. code-figure::
+
+    .. code:: html
+
+        <article>
+          <header>
+            <h1><a href="#" rel="bookmark" title="Permalink to An Article">
+              <time class="m-date" datetime="2017-09-08T00:00:00+02:00">
+              Sep <span class="m-date-day">8</span> 2017
+              </time>
+              An Article
+            </a></h1>
+            <p>Article summary paragraph. Lorem ipsum dolor sit amet, consectetur
+            adipiscing elit. Aenean id elit posuere, consectetur magna congue, sagittis
+            est.</p>
+          </header>
+          <p>Article contents. Pellentesque est neque, aliquet nec consectetur in,
+          mattis ac diam. Aliquam placerat justo ut purus interdum, ac placerat lacus
+          consequat. Mauris id suscipit mauris, in scelerisque lectus. Aenean nec nunc eu
+          sem tincidunt imperdiet ut non elit. Integer nisi tellus, ullamcorper vitae
+          euismod quis, venenatis eu nulla.</p>
+          <footer>
+            <p>Posted by <a href="#">The Author</a> on
+            <time datetime="2017-09-08T00:00:00+02:00">Sep 8 2017</time>.</p>
+          </footer>
+        </article>
+
+    .. raw:: html
+
+        <article>
+          <header>
+            <h1><a href="#" rel="bookmark" title="Permalink to An Article">
+              <time class="m-date" datetime="2017-09-08T00:00:00+02:00">
+              Sep <span class="m-date-day">8</span> 2017
+              </time>
+              An Article
+            </a></h1>
+            <p>Article summary paragraph. Lorem ipsum dolor sit amet, consectetur
+            adipiscing elit. Aenean id elit posuere, consectetur magna congue, sagittis
+            est.</p>
+          </header>
+          <p>Article contents. Pellentesque est neque, aliquet nec consectetur in,
+          mattis ac diam. Aliquam placerat justo ut purus interdum, ac placerat lacus
+          consequat. Mauris id suscipit mauris, in scelerisque lectus. Aenean nec nunc eu
+          sem tincidunt imperdiet ut non elit. Integer nisi tellus, ullamcorper vitae
+          euismod quis, venenatis eu nulla.</p>
+          <footer>
+            <p>Posted by <a href="#">The Author</a> on
+            <time datetime="2017-09-08T00:00:00+02:00">Sep 8 2017</time>.</p>
+          </footer>
+        </article>
+
+There's a dedicated styling for article date in the :css:`time.m-date` element
+to go into :html:`<h1>` of article :html:`<header>`. For semantic purposes and
+SEO it's good to include the date/time in a machine-readable format as well.
+You can get this formatting via :sh:`date -Iseconds` Unix command. The same is
+then repeated in article :html:`<footer>`.
+
+It's good to include the :html:`<a rel="bookmark">` attribute in the permalink
+to hint search engines about purpose of the link and then give the same via the
+``title`` attribute.
+
+.. note-info::
+
+    You can also see `how the article looks <{filename}/examples/article.rst>`_
+    on its own dedicated page.
+
+`Jumbo articles`_
+-----------------
+
+For "jumbo" articles with a big cover image, a different layout is available.
+Example markup, corresponding in content to the above article, but with a cover
+image in background, is shown below. The markup is meant to be straight in
+:html:`<main>` as it arranges the content by itself in the center 10 columns.
+Date and author name is rendered on top left and right in front of the cover
+image, the heading (and optional subheading) as well. By default, the text on
+top of the cover image is rendered white, add an additional :css:`.m-inverted`
+CSS class to have it black. The article contents are marked with
+:css:`#m-container-inflatable` to make
+`inflated nested layouts <{filename}/css/grid.rst#inflatable-nested-grid>`_
+such as `image grid <{filename}/css/components.rst#image-grid>`_ possible.
+
+.. code:: html
+
+    <article id="m-jumbo">
+      <header>
+        <div id="m-jumbo-image" style="background-image: url('ship.jpg');">
+          <div id="m-jumbo-cover">
+            <div class="m-container">
+              <div class="m-row">
+                <div class="m-col-t-6 m-col-s-5 m-push-s-1 m-text-left">Sep 8 2017</div>
+                <div class="m-col-t-6 m-col-s-5 m-push-s-1 m-text-right"><a href="#">An Au­thor</a></div>
+              </div>
+              <div class="m-row">
+                <div class="m-col-t-12 m-col-s-10 m-push-s-1 m-col-m-8 m-push-m-2">
+                  <h1><a href="#" rel="bookmark" title="Permalink to An Ar­ti­cle — a jum­bo one">
+                    An Article
+                  </a></h1>
+                  <h2>a jumbo one</h2>
+                </div>
+              </div>
+            </div>
+          </div>
+        </div>
+        <div class="m-container">
+          <div class="m-row">
+            <div class="m-col-m-10 m-push-m-1 m-nopady">
+              <p>Article summary paragraph. Lorem ipsum dolor sit amet, consectetur
+              adipiscing elit. Aenean id elit posuere, consectetur magna congue,
+              sagittis est.</p>
+            </div>
+          </div>
+        </div>
+      </header>
+      <div class="m-container" id="m-container-inflatable">
+        <div class="m-row">
+          <div class="m-col-m-10 m-push-m-1 m-nopady">
+          Article contents. Pellentesque est neque, aliquet nec consectetur in,
+          mattis ac diam. Aliquam placerat justo ut purus interdum, ac placerat
+          lacus consequat. Mauris id suscipit mauris, in scelerisque lectus.
+          Aenean nec nunc eu sem tincidunt imperdiet ut non elit. Integer nisi
+          tellus, ullamcorper vitae euismod quis, venenatis eu nulla.
+          </div>
+        </div>
+      </div>
+      <footer class="m-container">
+        <div class="m-row">
+          <div class="m-col-m-10 m-push-m-1 m-nopadb">
+            <p>Posted by <a href="#">An Au­thor</a> on
+            <time datetime="2017-09-08T00:00:00+02:00">Sep 8 2017</time>.</p>
+          </div>
+        </div>
+      </footer>
+    </article>
+
+Similarly to `landing pages <#landing-pages>`_, the cover image of the jumbo
+article always spans the whole screen width and goes below the top navbar. If
+you want the navbar to be semi-transparent, put :css:`.m-navbar-jumbo` on the
+:html:`<nav>` element. Compared to `landing pages <#landing-pages>`_ the navbar
+retains semi-transparent background and the brand link is not hidden, as brand
+name is not expected to be duplicated in article header.
+
+.. note-info::
+
+    See `how the jumbo article looks <{filename}/examples/jumbo-article.rst>`_.
+
+`Category list and tag cloud`_
+------------------------------
+
+Wrap :html:`<h3>` headers and :html:`<ol>` list in :css:`nav.m-navpanel`, you
+can also make use of the :css:`.m-block-bar-*` CSS class to
+`make the list linear on small screen sizes <{filename}/css/typography.rst#lists-diaries>`_
+and save vertical space. For a tag cloud, mark the :html:`<ul>` with
+:css:`.m-tagcloud` and wrap individual :html:`<li>` in :css:`.m-tag-1` to
+:css:`.m-tag-5` CSS classes to scale them from smallest to largest.
+
+.. note-warning::
+
+    The tag cloud has currently hardcoded exactly five steps.
+
+.. code-figure::
+
+    .. code:: html
+
+        <nav class="m-navpanel">
+          <h3>Categories</h3>
+          <ol class="m-block-bar-m">
+            <li><a href="#">News</a></li>
+            <li><a href="#">Archive</a></li>
+          </ol>
+          <h3>Tag cloud</h3>
+          <ul class="m-tagcloud">
+            <li class="m-tag-1"><a href="#">Announcement</a></li>
+            <li class="m-tag-5"><a href="#">C++</a></li>
+            <li class="m-tag-3"><a href="#">Games</a></li>
+            <li class="m-tag-4"><a href="#">Rants</a></li>
+          </ul>
+        </nav>
+
+    .. raw:: html
+
+        <nav class="m-row m-navpanel">
+          <div class="m-col-s-6 m-col-m-3 m-push-m-3">
+            <h3>Categories</h3>
+            <ol class="m-block-bar-m">
+              <li><a href="#">News</a></li>
+              <li><a href="#">Archive</a></li>
+            </ol>
+          </div>
+          <div class="m-col-s-6 m-col-m-3 m-push-m-3">
+            <h3>Tag cloud</h3>
+            <ul class="m-tagcloud">
+              <li class="m-tag-1"><a href="#">Announcement</a></li>
+              <li class="m-tag-5"><a href="#">C++</a></li>
+              <li class="m-tag-3"><a href="#">Games</a></li>
+              <li class="m-tag-4"><a href="#">Rants</a></li>
+            </ul>
+          </div>
+        </nav>
+
+.. note-dim::
+    :class: m-text-center
+
+    `« Components <{filename}/css/components.rst>`_ | `CSS <{filename}/css.rst>`_ | `Themes » <{filename}/css/themes.rst>`_
diff --git a/doc/css/themes.rst b/doc/css/themes.rst
new file mode 100644 (file)
index 0000000..2c67759
--- /dev/null
@@ -0,0 +1,105 @@
+Themes
+######
+
+:breadcrumb: {filename}/css.rst CSS
+
+.. role:: css(code)
+    :language: css
+
+``m.css`` provides two themes, a dark and a light one. A theme consists of just
+a set of CSS variables, which affect fonts, colors and other properties. The
+theme file is also an self-contained entry point for the whole ``m.css``
+framework --- it includes all the other necessary CSS files except fonts via
+CSS :css:`@import` statements.
+
+.. block-info:: Browser support
+
+    Note that :abbr:`some older browsers have problems <IE and Edge, I'm looking at you>`
+    with CSS variables and :css:`@import` statements. Because of that, the
+    builtin themes provide a ``*.compiled.css`` version that contains a
+    preprocessed version without CSS variables or :css:`import` statements;
+    which also make it smaller in total. This compiled version includes also
+    the Pygments code highlighting style, all combined in one file.
+
+    I recommend using the original files for development and switching to the
+    compiled version when publishing the website.
+
+.. contents::
+    :class: m-block m-default
+
+`Dark`_
+=======
+
+The dark theme is described in the `m-dark.css <{filename}/css.rst>`_ (or
+``m-dark.compiled.css``) file. Besides that, you need to reference also
+`Source Sans Pro <https://fonts.google.com/specimen/Source+Sans+Pro>`_ font
+(used for page copy) and `Source Code Pro <https://fonts.google.com/specimen/Source+Code+Pro>`_
+(used for pre-formatted text and code). You can get them on Google Fonts. Full
+markup including theme color (used for example by Vivaldi or Android browser)
+is below:
+
+.. code:: html
+
+    <link rel="stylesheet" href="m-dark.css" /> <!-- or m-dark.compiled.css -->
+    <link rel="stylesheet" href="https://fonts.googleapis.com/css?Source+Sans+Pro:400,400i,600%7Cfamily=Source+Code+Pro:400,400i,600" />
+    <meta name="theme-color" content="#22272e" />
+
+This theme is used on this site and also on http://magnum.graphics.
+
+`Light`_
+========
+
+The light theme is described in the `m-light.css <{filename}/css.rst>`_ file.
+Besides that, you need to reference also
+`Libre Baskerville <https://fonts.google.com/specimen/Libre+Baskerville>`_ font
+(used for page copy) and `Source Code Pro <https://fonts.google.com/specimen/Source+Code+Pro>`_
+(used for pre-formatted text and code). You can get them on Google Fonts.
+
+.. code:: html
+
+    <link rel="stylesheet" href="m-light.css" /> <!-- or m-light.compiled.css -->
+    <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Libre+Baskerville:400,400i,700%7CSource+Code+Pro:400,400i,600" />
+    <meta name="theme-color" content="#cb4b16" />
+
+If you want to see this theme live, go to http://blog.mosra.cz.
+
+`Make your own`_
+================
+
+Making your own theme is a matter of taking one of the above files and
+modifying it to your liking. The project also bundles a Python script for
+*post*\ processing the CSS files into a ``*.compiled.css`` file without
+:css:`@import` statements and variables, if you need. Download it here:
+
+-   :gh:`postprocess.py <mosra/m.css$master/css/postprocess.py>`
+
+Its usage is simple --- just call it with the files you want to compile
+together and it will create a ``*.compiled.css`` file in the same directory:
+
+.. code:: sh
+
+    # Creates a m-dark.compiled.css file
+    ./postprocess.py m-dark.css
+
+If you want to modify the Pygments style, it's a bit more involved. You need to
+edit the ``*.py`` file instead of the ``*.css``:
+
+-   :gh:`pygments-dark.py <mosra/m.css$master/css/pygments-dark.py>`
+
+After making changes, copy it somewhere so Pygments can load it as a style and
+then generate a CSS file out of it:
+
+.. code:: sh
+
+    sudo cp pygments-dark.py /usr/lib/python3*/site-packages/pygments/styles/dark.py
+    pygmentize -f html -S dark -a .m-code > pygments-dark.css
+
+.. note-success::
+
+    Made a theme and want to share it with the world? I'm happy to
+    :gh:`incorporate your contributions <mosra/m.css/pulls/new>`.
+
+.. note-dim::
+    :class: m-text-center
+
+    `« Page layout <{filename}/css/page-layout.rst>`_ | `CSS <{filename}/css.rst>`_
diff --git a/doc/css/typography-test.rst b/doc/css/typography-test.rst
new file mode 100644 (file)
index 0000000..d2c0bc8
--- /dev/null
@@ -0,0 +1,32 @@
+Test
+####
+
+:save_as: css/typography/test/index.html
+:breadcrumb: {filename}/css.rst CSS
+             {filename}/css/typography.rst Typography
+
+.. frame::
+
+    .. class:: m-text-left
+
+        Text aligned left.
+
+    .. class:: m-text-left m-noindent
+
+        No-indent text aligned left.
+
+    .. class:: m-text-right
+
+        Text aligned right.
+
+    .. class:: m-text-right m-noindent
+
+        No-indent text aligned right.
+
+    .. class:: m-text-center
+
+        Centered text.
+
+    .. class:: m-text-center m-noindent
+
+        Centered text without indentation.
diff --git a/doc/css/typography.rst b/doc/css/typography.rst
new file mode 100644 (file)
index 0000000..0f77dea
--- /dev/null
@@ -0,0 +1,270 @@
+Typography
+##########
+
+:breadcrumb: {filename}/css.rst CSS
+
+.. role:: css(code)
+    :language: css
+
+Right after being responsive, typography is the second most important thing in
+``m.css`` and so the most often used HTML elements are styled to make them look
+great by default.
+
+.. contents::
+    :class: m-block m-default
+
+`Paragraphs, quotes and poems`_
+===============================
+
+Each :html:`<p>` element inside :html:`<main>` has the first line indented, is
+justified and is separated from the following content by some padding. The
+:html:`<blockquote>` elements are, in addition, indented with a distinctive
+line on the left. Because the indentation may look distracting for manually
+wrapped line blocks, assign :css:`.m-poem` to such paragraph to indent all
+lines the same way. To remove the indentation and justification altogether, use
+:css:`.m-noindent`.
+
+.. code-figure::
+
+    .. code:: html
+
+        <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean id elit
+        posuere, consectetur magna congue, sagittis est. Pellentesque est neque,
+        aliquet nec consectetur in, mattis ac diam. Aliquam placerat justo ut purus
+        interdum, ac placerat lacus consequat.</p>
+
+        <blockquote>Ut dictum enim posuere metus porta, et aliquam ex condimentum.
+        Proin sagittis nisi leo, ac pellentesque purus bibendum sit amet.</blockquote>
+
+        <p class="m-poem">
+        Curabitur<br/>
+        sodales<br/>
+        arcu<br/>
+        elit</p>
+
+        <p class="m-noindent">Mauris id suscipit mauris, in scelerisque lectus. Aenean
+        nec nunc eu sem tincidunt imperdiet ut non elit. Integer nisi tellus,
+        ullamcorper vitae euismod quis, venenatis eu nulla.</p>
+
+    .. raw:: html
+
+        <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean id elit
+        posuere, consectetur magna congue, sagittis est. Pellentesque est neque,
+        aliquet nec consectetur in, mattis ac diam. Aliquam placerat justo ut purus
+        interdum, ac placerat lacus consequat.</p>
+
+        <blockquote>Ut dictum enim posuere metus porta, et aliquam ex condimentum.
+        Proin sagittis nisi leo, ac pellentesque purus bibendum sit amet.</blockquote>
+
+        <p class="m-poem">
+        Curabitur<br/>
+        sodales<br/>
+        arcu<br/>
+        elit</p>
+
+        <p class="m-noindent">Mauris id suscipit mauris, in scelerisque lectus. Aenean
+        nec nunc eu sem tincidunt imperdiet ut non elit. Integer nisi tellus,
+        ullamcorper vitae euismod quis, venenatis eu nulla.</p>
+
+`Lists, diaries`_
+=================
+
+Ordered and unordered lists have padding on bottom only on the first level.
+Mark the list with :css:`.m-unstyled` to remove the asterisks/numbers and
+indentation.
+
+.. code-figure::
+
+    .. code:: html
+
+        <ul>
+          <li>Item 1</li>
+          <li>
+            Item 2
+            <ol>
+              <li>An item</li>
+              <li>Another item</li>
+            </ol>
+          </li>
+          <li>Item 3</li>
+        </ul>
+
+        <ol class="m-unstyled">
+          <li>Item of an unstyled list</li>
+          <li>Another item of an unstyled list</li>
+        </ol>
+
+    .. raw:: html
+
+        <ul>
+        <li>Item 1</li>
+        <li>
+          Item 2
+          <ol>
+            <li>An item</li>
+            <li>Another item</li>
+          </ol>
+        </li>
+        <li>Item 3</li>
+        </ul>
+
+        <ol class="m-unstyled">
+          <li>Item of an unstyled list</li>
+          <li>Another item of an unstyled list</li>
+        </ol>
+
+It's possible to convert a list to a single line with items separated by ``|``
+to save vertical space on mobile devices and responsively change it back on
+larger screens. Mark such list with :css:`.m-block-bar-*`:
+
+.. code-figure::
+
+    .. code:: html
+
+        <ul class="m-block-bar-m">
+          <li>Item 1</li>
+          <li>Item 2</li>
+          <li>Item 3</li>
+        </ul>
+
+    .. raw:: html
+
+        <ul class="m-block-bar-m">
+          <li>Item 1</li>
+          <li>Item 2</li>
+          <li>Item 3</li>
+        </ul>
+
+.. note-success::
+
+    Shrink your browser window to see the effect in the above list.
+
+Mark your definition list with :css:`.m-diary` to put the titles next to
+definitions.
+
+.. code-figure::
+
+    .. code:: html
+
+        <dl class="m-diary">
+          <dt>07:30:15</dt>
+          <dd>Woke up. The hangover is crazy today.</dd>
+          <dt>13:47:45</dt>
+          <dd>Got up from bed. Trying to find something to eat.</dd>
+          <dt>23:34:13</dt>
+          <dd>Finally put my pants on. Too late.</dd>
+        </dl>
+
+    .. raw:: html
+
+        <dl class="m-diary">
+          <dt>07:30:15</dt>
+          <dd>Woke up. The hangover is crazy today.</dd>
+          <dt>13:47:45</dt>
+          <dd>Got up from bed. Trying to find something to eat.</dd>
+          <dt>23:34:13</dt>
+          <dd>Finally put my pants on. Too late.</dd>
+        </dl>
+
+`Transitions`_
+==============
+
+Horizontal line is centered and fills 75% of the parent element. For a more
+fancy transition, use :css:`.m-transition` on a paragraph.
+
+.. code-figure::
+
+    .. code:: html
+
+        ...
+        <hr/>
+        ...
+        <p class="m-transition">~ ~ ~</p>
+        ...
+
+    .. raw:: html
+
+        <p>Vivamus dui quam, volutpat eu lorem sit amet, molestie tristique erat.
+        Vestibulum dapibus est eu risus pellentesque volutpat.</p>
+        <hr/>
+        <p>Aenean tellus turpis, suscipit quis iaculis ut, suscipit nec magna.
+        Vestibulum finibus sit amet neque nec volutpat. Suspendisse sit amet nisl in
+        orci posuere mattis.</p>
+        <p class="m-transition">~ ~ ~</p>
+        <p> Praesent eu metus sed felis faucibus placerat ut eu quam. Aliquam convallis
+        accumsan ante sit amet iaculis. Phasellus rhoncus hendrerit leo vitae lacinia.
+        Maecenas iaculis dui ex, eu interdum lacus ornare sit amet.</p>
+
+`Preformatted blocks`_
+======================
+
+The :html:`pre` element preserves your whitespace and adds a convenient
+scrollbar if the content is too wide. If inside an
+`inflatable nested grid <{filename}/css/grid.rst#inflatable-nested-grid>`_, it
+will have negative margin to make its contents aligned with surrounding text.
+
+.. code-figure::
+
+    .. code:: html
+
+        <pre>
+        int main() {
+            return 0;
+        }
+        </pre>
+
+    .. raw:: html
+
+        <pre>
+        int main() {
+            return 0;
+        }
+        </pre>
+
+.. note-info::
+
+    The Components page has additional information about
+    `code blocks styling <{filename}/css/components.rst#code-blocks>`_.
+
+`Inline elements`_
+==================
+
+.. code-figure::
+
+    .. code:: html
+
+        A <a href="#">link</a>, <em>emphasised text</em>, <strong>strong text</strong>,
+        <abbr title="abbreviation">abbr</abbr> shown inside a normal text flow to
+        verify that they don't break text flow. Then there is <small>small text</small>,
+        <sup>super</sup>, <sub>sub</sub> and <s>that is probably all I can think of
+        right now</s> oh, there is also <mark>marked text</mark> and
+        <code>int a = some_code();</code>.
+
+    .. raw:: html
+
+        A <a href="#">link</a>, <em>emphasised text</em>, <strong>strong text</strong>,
+        <abbr title="abbreviation">abbr</abbr> shown inside a normal text flow to
+        verify that they don't break text flow. Then there is <small>small text</small>,
+        <sup>super</sup>, <sub>sub</sub> and <s>that is probably all I can think of
+        right now</s> oh, there is also <mark>marked text</mark> and
+        <code>int a = some_code();</code>.
+
+`Text alignment`_
+=================
+
+Use :css:`.m-text-left`, :css:`.m-text-right` or :css:`.m-text-center` to
+align text inside its parent element. See
+`Floating around <{filename}/css/grid.rst#floating-around>`_ in the grid system
+for aligning and floating blocks in a similar way.
+
+`Padding`_
+==========
+
+Block elements :html:`<p>`, :html:`<ol>`, :html:`<ul>`, :html:`<dl>`,
+:html:`<blockqote>`, :html:`<pre>` and :html:`<hr>` by default have :css:`1rem`
+padding after, except when they are the last child, to avoid excessive spacing.
+
+.. note-dim::
+    :class: m-text-center
+
+    `« Grid <{filename}/css/grid.rst>`_ | `CSS <{filename}/css.rst>`_ | `Components » <{filename}/css/components.rst>`_
diff --git a/doc/examples/article.rst b/doc/examples/article.rst
new file mode 100644 (file)
index 0000000..b25c04c
--- /dev/null
@@ -0,0 +1,20 @@
+An Article
+##########
+
+.. role:: language-la
+    :class: language-la
+
+:date: 2017-09-08
+:category: Examples
+:tags: Example, Article
+:author: An Author
+:slug: article
+:summary: Article summary paragraph. :language-la:`Lorem ipsum dolor sit amet,
+    consectetur adipiscing elit. Aenean id elit posuere, consectetur magna
+    congue, sagittis est.`
+
+Article contents. :language-la:`Pellentesque est neque, aliquet nec consectetur
+in, mattis ac diam. Aliquam placerat justo ut purus interdum, ac placerat lacus
+consequat. Mauris id suscipit mauris, in scelerisque lectus. Aenean nec nunc eu
+sem tincidunt imperdiet ut non elit. Integer nisi tellus, ullamcorper vitae
+euismod quis, venenatis eu nulla.`
diff --git a/doc/examples/jumbo-article.rst b/doc/examples/jumbo-article.rst
new file mode 100644 (file)
index 0000000..35c34f5
--- /dev/null
@@ -0,0 +1,23 @@
+An Article --- a jumbo one
+##########################
+
+.. role:: language-la
+    :class: language-la
+
+:cover: {filename}/static/ship.jpg
+:date: 2017-09-08
+:category: Examples
+:tags: Example, Article, Jumbo
+:author: An Author
+:slug: jumbo-article
+:summary: Article summary paragraph. :language-la:`Lorem ipsum dolor sit amet,
+    consectetur adipiscing elit. Aenean id elit posuere, consectetur magna
+    congue, sagittis est.`
+
+.. todo: have the slug implicit
+
+Article contents. :language-la:`Pellentesque est neque, aliquet nec consectetur
+in, mattis ac diam. Aliquam placerat justo ut purus interdum, ac placerat lacus
+consequat. Mauris id suscipit mauris, in scelerisque lectus. Aenean nec nunc eu
+sem tincidunt imperdiet ut non elit. Integer nisi tellus, ullamcorper vitae
+euismod quis, venenatis eu nulla.`
diff --git a/doc/index.rst b/doc/index.rst
new file mode 100644 (file)
index 0000000..751cc54
--- /dev/null
@@ -0,0 +1,83 @@
+m.css
+#####
+
+:save_as: index.html
+:url:
+:cover: {filename}/static/cover.jpg
+:summary: A no-bullshit, no-JavaScript CSS framework and Pelican theme for
+    content-oriented websites
+:landing:
+    .. container:: m-row
+
+        .. container:: m-col-l-6 m-push-l-1 m-col-m-7 m-nopadb
+
+            .. raw:: html
+
+                <h1>m.css</h1>
+
+    .. container:: m-row
+
+        .. container:: m-col-l-6 m-push-l-1 m-col-m-7 m-nopadt
+
+            *A no-bullshit, no-JavaScript CSS framework and Pelican theme for content-oriented websites.*
+
+            Do you *hate* contemporary web development like I do? Do you also feel that
+            it's not right for a web page to take *seconds* and *megabytes* to render? Do
+            you want to write beautiful content but *can't* because the usual CMS tools
+            make your blood boil and so you rather stay silent? Well, I have something for
+            you.
+
+        .. container:: m-col-l-3 m-push-l-2 m-col-m-4 m-push-m-1 m-col-s-6 m-push-s-3 m-col-t-8 m-push-t-2
+
+            .. button-primary:: https://github.com/mosra/m.css/tree/master/css/m-dark.compiled.css
+                :class: m-fullwidth
+
+                Get the essence
+
+                :filesize-gz:`{filename}/../css/m-dark.compiled.css` of compressed CSS
+
+.. container:: m-row m-container-inflate
+
+    .. container:: m-col-m-4
+
+        .. block-success:: *Pure* CSS and HTML
+
+            Everything you need is :filesize-gz:`{filename}/../css/m-dark.compiled.css`
+            of compressed CSS. This framework has exactly 0 bytes of JavaScript
+            because *nobody actually needs it*. Even for responsive websites.
+
+            .. button-success:: {filename}/css.rst
+                :class: m-fullwidth
+
+                Get the CSS
+
+    .. container:: m-col-m-4
+
+        .. block-warning:: Designed for *content*
+
+            If you just want to write content with beautiful typography, you
+            don't need forms, progressbars, popups, dropdowns or other shit.
+            You want fast iteration times.
+
+            .. button-warning:: {filename}/pelican.rst
+                :class: m-fullwidth
+
+                Use it with Pelican
+
+    .. container:: m-col-m-4
+
+        .. block-info:: Authoring made *easy*
+
+            Code snippets, math, linking to docs, presenting photography in a
+            beautiful way? Or making a complex page without even needing to
+            touch HTML? Everything is possible.
+
+            .. button-info:: {filename}/plugins.rst
+                :class: m-fullwidth
+
+                Get Pelican plugins
+
+.. class:: m-text-center m-noindent
+
+*Still not convinced?* Head over to a `detailed explanation <{filename}/why.rst>`_
+of this project goals and design decisions.
diff --git a/doc/pelican.rst b/doc/pelican.rst
new file mode 100644 (file)
index 0000000..3318262
--- /dev/null
@@ -0,0 +1,99 @@
+Pelican
+#######
+
+.. role:: sh(code)
+    :language: sh
+
+`Pelican <https://getpelican.com/>`_ is a static site generator powered by
+Python and unlike most other static site generators, it uses
+`reStructuredText <http://docutils.sourceforge.net/rst.html>`_ instead of
+Markdown for authoring content. ``m.css`` provides a theme for it, together
+with a set of useful `plugins <{filename}/plugins.rst>`_.
+
+.. note-warning::
+
+    Please, in this case, don't judge the book by its cover --- the
+    :abbr:`reST <reStructuredText>` website might look like it was made in 1992
+    and never updated since, but believe me, it's a remarkably designed format.
+    Once you dive into it, you will not want to go back to Markdown.
+
+`Quick start`_
+==============
+
+Note that currently most of the functionality provided by ``m.css`` requires
+patches that aren't integrated into any released version yet, so it's
+recommended to install a patched version using Python's ``pip`` instead of
+using the stable 3.7.1 release. Note that in order to use ``m.css`` plugins
+later, you want to install the Python 3 version:
+
+.. code:: sh
+
+    pip install git+https://github.com/mosra/pelican.git@mosra-master
+
+Once you have Pelican installed, create a directory for your website and
+bootstrap it:
+
+.. code:: sh
+
+    mkdir ~/my-cool-site/
+    cd ~/my-cool-site/
+    pelican-quickstart
+
+This command will ask you a few questions. You don't need the URL prefix for
+now, but you definitely want a Makefile and an auto-reload script to be
+generated. Leave the rest at its defaults. Once the quickstart script finishes,
+you can run the auto-reloading like this:
+
+.. todo: remove the auto-reload script when Pelican has it builtin
+
+.. code:: sh
+
+    make devserver
+
+It will print quite some output about processing things and serving the data to
+the console. Open your fresh website at http://localhost:8000. The site is now
+empty, so let's create a simple article and put it into ``content/``
+subdirectory with a ``.rst`` extension. For this example that would be
+``~/my-cool-site/content/my-cool-article.rst``:
+
+.. code:: rst
+
+    My cool article
+    ###############
+
+    :date: 2017-09-14 23:04
+    :category: Cool things
+    :tags: cool, article, mine
+    :summary: This article has a cool summary.
+
+    This article has not only cool summary, but also has cool contents. Lorem?
+    *Ipsum.* `Hi, google! <http://google.com>`_
+
+If you did everything right, the auto-reload script should pick the file up and
+process it (check the console output). Then it's just a matter of refreshing
+your browser to see it on the page.
+
+.. note-info::
+
+    Currently, if Pelican encounters an error when processing the article, it
+    will just stop refreshing and you need to restart it by executing
+    :sh:`make devserver` again.
+
+*That's it!* Congratulations, you successfully made your first steps with
+Pelican. The default theme might be a bit underwhelming, so let's fix that.
+Click on the headers below to get to know more.
+
+`Writing content » <{filename}/pelican/writing-content.rst>`_
+=============================================================
+
+Quick guide and tips for writing content using :abbr:`reST <reStructuredText>`.
+Chances are that you already know your way around from Sphinx or other
+documentation tools, nevertheless there are some hidden tricks that you might
+not know about yet.
+
+`Theme » <{filename}/pelican/theme.rst>`_
+=========================================
+
+A feature-packed theme with modern and responsive design that exposes all of
+``m.css`` functionality with goodies on top such as social meta tags,
+breadcrumb navigation and more.
diff --git a/doc/pelican/theme-test.rst b/doc/pelican/theme-test.rst
new file mode 100644 (file)
index 0000000..d837e0d
--- /dev/null
@@ -0,0 +1,12 @@
+Test
+####
+
+:save_as: pelican/theme/test/index.html
+:breadcrumb: {filename}/pelican.rst Pelican
+             {filename}/pelican/theme.rst Theme
+:css: {filename}/static/dummy.css
+      {filename}/static/dummy.css
+:summary: um
+
+This page should have a breadcrumb and also two additional links to
+``/static/dummy.css``.
diff --git a/doc/pelican/theme.rst b/doc/pelican/theme.rst
new file mode 100644 (file)
index 0000000..d6e975c
--- /dev/null
@@ -0,0 +1,407 @@
+Theme
+#####
+
+:breadcrumb: {filename}/pelican.rst Pelican
+
+.. role:: rst(code)
+    :language: rst
+
+The second largest offering of ``m.css`` is a full-featured theme for the
+`Pelican static site generator <https://getpelican.com/>`_. The theme is
+designed to fit both the use case of a simple blog consisting of just articles
+or a full product/project/portfolio website where the blog is only a side dish.
+
+.. contents::
+    :class: m-block m-default
+
+`Quick start`_
+==============
+
+The easiest way to start is putting the :gh:`whole Git repository <mosra/m.css>`
+of ``m.css`` into your project, for example as a submodule:
+
+.. code:: sh
+
+    git submodule add git://github.com/mosra/m.css
+
+The most minimal configuration to use the theme is the following. Basically you
+need to tell Pelican where the theme resides (it's in the ``pelican-theme/``
+subdir of your ``m.css`` submodule), then you tell it to put the static
+contents of the theme into a ``static/`` directory in the root of your
+webserver; the ``CSS_FILES`` variable is a list of CSS files that the theme
+needs. You can put there any files you need, but there need to be at least the
+files mentioned on the `CSS themes <{filename}/css/themes.rst>`_ page.
+
+.. code:: py
+
+    THEME = 'm.css/pelican-theme'
+    THEME_STATIC_DIR = 'static'
+    CSS_FILES = ['https://fonts.googleapis.com/css?family=Source+Code+Pro:400,400i,600%7CSource+Sans+Pro:400,400i,600&amp;subset=latin-ext',
+                 '/static/m-dark.css']
+    DIRECT_TEMPLATES = ['index']
+
+Here you can take advantage of the ``pelicanconf.py`` and ``publishconf.py``
+distinction --- use ``m-dark.css`` for local development and override the
+:py:`CSS_FILES` to use the smaller, faster and more compatible ``m-dark.compiled.css``
+for publishing.
+
+.. note-info::
+
+    The above configuration should be enough to produce a (mostly empty)
+    version of your website using the theme without any errors during
+    processing. If that's not the case, please :gh:`report a bug <mosra/m.css/issues/new>`.
+    Thank you!
+
+`Configuration`_
+================
+
+Theme color :html:`<meta>` tag used by `CSS themes`_ can be specified with
+the :py:`THEME_COLOR` variable. If not set, no theme color :html:`<meta>` tag
+is present. Example configuration for the builtin dark theme:
+
+.. code:: py
+
+    THEME_COLOR = '#22272e'
+
+Value of :py:`SITENAME` is used in the :html:`<title>` tag, separated with a
+``|`` character from page / article name.
+
+`Top navbar`_
+-------------
+
+:py:`SITE_LOGO` is an image file that will be used as a brand logo on left side
+of the navbar, :py:`SITE_LOGO_TEXT` is brand logo text. Specifying just one of
+these does the expected thing. The brand logo/text is a link that leads to
+:py:`SITTEURL`.
+
+:py:`LINKS_NAVBAR1` and :py:`LINKS_NAVBAR2` variables contain links to put in
+the top navbar. On narrow screens, the navbar is divided into two columns,
+links from the first variable are in the left column while links from the
+second variable are in the right column. Omit the second variable if you want
+the links to be in a single column.
+
+Both variables have the same format --- a list of 4-tuples, where first item is
+link title, second the URL, third page slug of the corresponding page (used
+to highlight currently active menu item) and fourth is a list of sub-menu items
+(which are 3-tuples --- link title, URL and page slug). Providing an empty slug
+will make the menu item never highlighted; providing an empty list of sub-menu
+items will not add any submenu.
+
+Example configuration, matching example markup from the
+`CSS page layout <{filename}/css/page-layout.rst#sub-menus-in-the-navbar>`__
+documentation:
+
+.. code:: py
+
+    SITE_LOGO_TEXT = 'Your Brand'
+
+    LINKS_NAVBAR1 = [('Features', '/features/', 'features', []),
+                     ('Showcase', '/showcase/', 'showcase', []),
+                     ('Download', '/download/', 'download', [])]
+
+    LINKS_NAVBAR2 = [('Blog', '/blog/', 'blog', [
+                        ('News', '/blog/news/', ''),
+                        ('Archive', '/blog/archive/', '')]),
+                     ('Contact', '/contact/', 'contact', [])]
+
+`Footer navigation`_
+--------------------
+
+Similarly to the top navbar, :py:`LINKS_FOOTER1`, :py:`LINKS_FOOTER2`,
+:py:`LINKS_FOOTER3` and :py:`LINKS_FOOTER4` variables contain links to put in
+the footer navigation. The links are arranged in four columns, which get
+reduced to just two columns on small screens. Omitting :py:`LINKS_FOOTER4` will
+fill the last column with a *Blog* entry, linking to the Archives page and
+listing all blog categories; omitting any of the remaining variables will make
+given column empty.
+
+The variables are lists of 2-tuples, containing link title and URL. First item
+is used for column header, if link URL of the first item is empty, given column
+header is just a plain :html:`<h3>` without a link.
+
+Footer fine print can be specified via :py:`FINE_PRINT`. Contents of the
+variable are processed as :abbr:`reST <reStructuredText>`, so you can use all
+the formatting and linking capabilities in there.
+
+Example configuration, again matching example markup from the
+`CSS page layout <{filename}/css/page-layout.rst#footer-navigation>`__
+documentation, populating the last column implicitly:
+
+.. code:: py
+
+    LINKS_FOOTER1 = [('Your Brand', '/'),
+                     ('Features', '/features/'),
+                     ('Showcase', '/showcase/')]
+
+    LINKS_FOOTER2 = [('Download', '/download/'),
+                     ('Packages', '/download/packages/'),
+                     ('Source', '/download/source/')]
+
+    LINKS_FOOTER3 = [('Contact', '/contact/'),
+                     ('E-mail', '#'),
+                     ('GitHub', '#')]
+
+    FINE_PRINT = """
+    Your Brand. Copyright © `You <mailto:you@your.brand>`_, 2017. All rights
+    reserved.
+    """
+
+`Pages`_
+========
+
+Page content is simply put into :html:`<main>`, wrapped in an :html:`<article>`,
+in the center 10 columns on large screens and spanning the full 12 columns
+elsewhere. Page title is rendered in an :html:`<h1>` and there's nothing else
+apart from the page content.
+
+`Extra CSS`_
+------------
+
+The :rst:`:css:` field can be used to link additional CSS files in page header.
+Put one URL per line, internal link targets are expanded. Example:
+
+.. code:: rst
+
+    Showcase
+    ########
+
+    :css:
+        {filename}/static/webgl.css
+        {filename}/static/canvas-controls.css
+
+`Breadcrumb navigation`_
+------------------------
+
+It's common for pages to be organized in a hierarchy and the user should be
+aware of it. ``m.css`` Pelican theme provides breadcrumb navigation, which is
+rendered in main page heading (as described in the
+`CSS page layout <{filename}/css/page-layout.rst#breadcrumb-navigation>`__
+documentation) and also in page title. Breadcrumb links are taken from the
+:rst:`:breadcrumb:` field, where every line is one level of hierarchy,
+consisting of an internal target link (which gets properly expanded) and title
+separated by whitespace.
+
+Example usage:
+
+.. code:: rst
+
+    Steam engine
+    ############
+
+    :breadcrumb: {filename}/help.rst Help
+                 {filename}/help/components.rst Components
+
+.. note-info::
+
+    You can see the breadcrumb in action on the top and bottom of this
+    documentation page (and others).
+
+`Landing pages`_
+----------------
+
+It's possible to override the default 10-column behavior for pages to make a
+`landing page <{filename}/css/page-layout.rst#landing-pages>`__ with large
+cover image spanning the whole window width. Put cover image URL into a
+:rst:`:cover:` field, the :rst:`:landing:` field then contains
+:abbr:`reST <reStructuredText>`-processed content that appears on top of the
+cover image. Contents of the :rst:`:landing:` are put into a
+:html:`<div class="m-container">`, you are expected to fully take care of rows
+and columns in it.
+
+.. block-warning:: Configuration
+
+    Currently, in order to have the :rst:`:landing:` field properly parsed, you
+    need to explicitly list it in :py:`FORMATTED_FIELDS`. Don't forget that
+    :py:`'summary'` is already listed there.
+
+    .. code:: py
+
+        FORMATTED_FIELDS += ['landing']
+
+Example of a fully custom index page that overrides the default theme index
+page (which would just list all the articles) is below. Note the overriden save
+destination and URL.
+
+.. code:: rst
+
+    Your Brand
+    ##########
+
+    :save_as: index.html
+    :url:
+    :cover: {filename}/static/cover.jpg
+    :landing:
+        .. container:: m-row
+
+            .. container:: m-col-m-6 m-push-m-5
+
+                .. raw:: html
+
+                    <h1>Your Brand</h1>
+
+                *This is the brand you need.*
+
+.. block-warning:: Landing page title
+
+    To give you full control over the landing page appearance, the page title
+    is not rendered in :html:`<h1>` on top of the content as with usual pages.
+    Instead you are expected to provide a heading inside the :rst:`:landing:`
+    field. However, due to semantic restrictions of :abbr:`reST <reStructuredText>`,
+    it's not possible to use section headers inside the :rst:`:landing:` field
+    and you have to work around it using raw HTML blocks, as shown in the above
+    example.
+
+.. note-info::
+
+    You can see the landing page in action on the `main project page <{filename}/index.rst>`_.
+
+`(Social) meta tags for pages`_
+-------------------------------
+
+You can use :rst:`:description:` field to populate :html:`<meta name="description">`,
+which can be then shown in search engine results. Other than that, the field
+does not appear anywhere on the rendered page. For sharing pages on Twitter,
+Facebook and elsewhere, both `Open Graph <http://ogp.me/>`_ and
+`Twitter Card <https://developer.twitter.com/en/docs/tweets/optimize-with-cards/overview/summary-card-with-large-image>`_
+:html:`<meta>` tags are supported:
+
+-   Page title is mapped to ``og:title`` / ``twitter:title``
+-   Page URL is mapped to ``og:url`` / ``twitter:url``
+-   The :rst:`:summary:` field is mapped to ``og:description`` /
+    ``twitter:description``. Note that if the page doesn't have explicit
+    summary, Pelican takes it from the first few sentences of the content and
+    that may not be what you want. This is also different from the
+    :rst:`:description:` field mentioned above and, unlike with articles,
+    :rst:`:summary:` doesn't appear anywhere on the rendered page.
+-   The :rst:`:cover:` field (e.g. the one used on `landing pages <#landing-pages>`_),
+    if present, is mapped to ``og:image`` / ``twitter:image``. The exact same
+    file is used without any resizing or cropping and is assumed to be in
+    landscape.
+-   ``twitter:card`` is set to ``summary_large_image`` if :rst:`:cover:` is
+    present and to ``summary`` otherwise
+-   ``og:type`` is set to ``website``
+
+Example overriding the index page with essential properties for nice-looking
+social links:
+
+.. code:: rst
+
+    Your Brand
+    ##########
+
+    :save_as: index.html
+    :url:
+    :cover: {filename}/static/cover.jpg
+    :summary: This is the brand you need.
+
+.. note-success::
+
+    You can see how page links will display by pasting
+    URL of the `index page <{filename}/index.rst>`_ into either
+    `Facebook Debugger <https://developers.facebook.com/tools/debug/>`_ or
+    `Twitter Card Validator <https://cards-dev.twitter.com/validator>`_.
+
+`Articles`_
+===========
+
+`Jumbo articles`_
+-----------------
+
+`Jumbo articles <{filename}/css/page-layout.rst#jumbo-articles>`__ are made
+by including the :rst:`:cover:` field containing URL of the cover image.
+Besides that, if the title contains an em-dash (---), it gets split into a
+title and subtitle that's then rendered in a different font size. Example:
+
+.. code:: rst
+
+    An Article --- a jumbo one
+    ##########################
+
+    :cover: {filename}/static/ship.jpg
+    :slug: jumbo-article
+    :summary: Article summary paragraph.
+
+.. note-info::
+
+    You can compare how an article with nearly the same contents looks as
+    `a normal article <{filename}/examples/article.rst>`_ and a
+    `jumbo article <{filename}/examples/jumbo-article.rst>`_.
+
+`(Social) meta tags for articles`_
+----------------------------------
+
+Like with pages, you can use :rst:`:description:` field to populate
+:html:`<meta name="description">`, which can be then shown in search engine
+results. Other than that, the field doesn't appear anywhere in the rendered
+article. `Open Graph`_ and `Twitter Card`_ :html:`<meta>` tags are also
+supported in a similar way:
+
+-   Article title is mapped to ``og:title`` / ``twitter:title``
+-   Pernament article URL is mapped to ``og:url`` / ``twitter:url``
+-   The :rst:`:summary:` field is mapped to ``og:description`` /
+    ``twitter:description``. Note that if the article doesn't have explicit
+    summary, Pelican takes it from the first few sentences of the content and
+    that may not be what you want. This is also different from the
+    :rst:`:description:` field mentioned above.
+-   The :rst:`:cover:` field from `jumbo articles <#jumbo-articles>`_, if
+    present, is mapped to ``og:image`` / ``twitter:image``. The exact same
+    file is used without any resizing or cropping and is assumed to be in
+    landscape.
+-   ``twitter:card`` is set to ``summary_large_image`` if :rst:`:cover:` is
+    present and to ``summary`` otherwise
+-   ``og:type`` is set to ``article``
+
+.. note-success::
+
+    You can see how article links will display by pasting
+    URL of e.g. the `jumbo article`_ into either `Facebook Debugger`_ or
+    `Twitter Card Validator`_.
+
+`Pre-defined pages`_
+====================
+
+With the default configuration above the index page is just a list of articles
+with the first being expanded, the same is for the archives page. If you want
+to have a custom index page (for example a `landing page <#landing-pages>`_),
+remove :py:`'index'` from the :py:`DIRECT_TEMPLATES` setting:
+
+.. code:: py
+
+    DIRECT_TEMPLATES = []
+
+Every category, tag and author has its own page that lists corresponding
+articles in a way similar to the index or archives page, but without the first
+article expanded. On the top of the page there is a note stating what condition
+the articles are filtered with.
+
+.. note-info::
+
+    See how an example `category page looks <{category}Examples>`_.
+
+Index, archive and all category/tag/author pages are paginated based on the
+:py:`DEFAULT_PAGINATION` setting --- on the bottom of each page there are link
+to prev and next page, besides that there's :html:`<link rel="prev">` and
+:html:`<link rel="next">` that provides the same as a hint to search engines.
+
+.. note-warning::
+
+    The ``m.css`` Pelican theme doesn't provide per-year, per-month or per-day
+    archive pages or category, tag, author *list* pages at the moment. List of
+    categories and tags is available in a sidebar from any article or article
+    listing page.
+
+`Theme properties`_
+===================
+
+The theme markup is designed to have readable, nicely indented output. The code
+is valid HTML5 and should be parsable as XML.
+
+.. note-danger::
+
+    This is one of the main goals of this project. Please
+    :gh:`report a bug <mosra/m.css/issues/new>` if it's not like that.
+
+.. note-dim::
+    :class: m-text-center
+
+    `« Writing content <{filename}/pelican/writing-content.rst>`_ | `Pelican <{filename}/pelican.rst>`_
diff --git a/doc/pelican/writing-content.rst b/doc/pelican/writing-content.rst
new file mode 100644 (file)
index 0000000..ba52523
--- /dev/null
@@ -0,0 +1,417 @@
+Writing content
+###############
+
+:breadcrumb: {filename}/pelican.rst Pelican
+
+While the official `reStructuredText <http://docutils.sourceforge.net/rst.html>`_
+documentation provides an extensive syntax guide, the info is scattered across
+many pages. The following page will try to explain the basics and mention a
+bunch of tricks that might not be immediately obvious.
+
+.. note-warning::
+
+    Be sure to read the
+    `Pelican docs about writing content <http://docs.getpelican.com/en/stable/content.html>`_
+    as well to get overview of how Pelican treats the files and various
+    metadata.
+
+.. contents::
+    :class: m-block m-default
+
+`Basic syntax`_
+===============
+
+:abbr:`reST <reStructuredText>` is at its core optimized for fast content
+authoring --- the text is easily human-readable, with no excessive markup,
+often-used formatting is kept simple and everything is extensible to allow
+intuitive usage in many use cases. The basic rules are not far from Markdown:
+
+-   Headers are made by underlining a line of text with some non-alphabetic
+    character. Length of the underline has to be same as length of the title.
+    Using a different character will create a next level heading, there's no
+    rule which character means what (but following some consistent rules across
+    all your content is encouraged).
+-   Paragraphs are separated from each other by a blank line. Consecutive lines
+    of text are concatenated together using spaces, ignoring the newlines. See
+    the `Block elements <#block-elements>`_ section below for more options.
+-   Multiple consecutive whitespace characters are rendered as a single space
+    (but that's largely due to how HTML behaves).
+-   Everything is escaped when converting to HTML, so inline HTML will appear
+    as-is, unlike Markdown.
+-   As with Python, indentation matters in :abbr:`reST <reStructuredText>`.
+    Differently indented lines of text are usually separated via a newline, but exceptions to this rule exist.
+-   Lines starting with :rst:`..` are treated as comment together with
+    following indented lines as long as the indentation level is not less than
+    indentation of the first line.
+
+Example:
+
+.. code:: rst
+
+    Heading 1
+    #########
+
+    First paragraph with a bunch of text. Some more text in that paragraph. You can
+    wrap your paragraph nicely to fit on your editor screen, the lines will be
+    concatenated together with a space in between.
+
+    Second paragraph of text. Each of these paragraphs is rendered as a HTML <p>
+    character. The main document heading is not part of the content, but rather an
+    implicit document title metadata.
+
+    Heading 2
+    =========
+
+    The above heading is using a different underline character so it will be
+    rendered as <h2> in the output. Also, the whole section (heading + content
+    until the next heading) is rendered as HTML5 <section> element.
+
+    Heading 3
+    ---------
+
+    Another character used, another level of headings.
+
+    .. a comment which is rendered to HTML output enclosed in <!-- -->
+        characters. This is still a comment.
+
+        This as well.
+            and
+            this
+        also
+
+    This is not a comment anymore.
+
+    Heading 2
+    =========
+
+    Going back to already used character, reST remembers for which heading
+    level it was used the first time, so it goes back to <h2>.
+
+`Metadata fields`_
+-------------------
+
+Each document can have a bunch of metadata fields that are not rendered as part
+of the main document content. Example of these is an article summary, date or
+overriding where given page is saved. Metadata field starts with :rst:`:name:`,
+where *name* is field name. After the colon there is a space and field
+contents. Consecutive indented lines are treated as part of the same field.
+
+.. code:: rst
+
+    An article
+    ##########
+
+    :date: 2017-10-11
+    :author: Vladimír Vondruš
+    :summary: Article summary. Because article summary can be quite long, let's
+        wrap it on multiple lines.
+
+    Article content starts here.
+
+`Directives`_
+-------------
+
+Special block elements (for example to include an image) are called
+*directives*, are introduced by a line starting with :rst:`.. name::`, where
+*name* is directive name, after the :rst:`::` there can be optional positional
+arguments. After that there can be an optional set of named directive options
+(indented lines starting with :rst:`:name:` where *name* is option name) and
+after that optional directive content, also indented. Unindenting will escape
+the directive. Directives can be nested and it's possible to provide
+user-defined directives via plugins.
+
+.. note-warning::
+
+    Note that it's possible to use headings only as top-level elements, *not*
+    inside any directive or other block element.
+
+Example and corresponding output, note the indentation:
+
+.. code-figure::
+
+    .. code:: rst
+
+        Paragraph with text.
+
+        .. block-info:: Info block title
+
+            Info block content.
+
+            .. figure:: ship.jpg
+                :alt: Image alt text
+
+                Figure title
+
+                Figure content.
+
+                .. math::
+
+                    A = \pi r^2
+
+                This is again figure content.
+
+            This is again info block content.
+
+        And this is another paragraph of text, outside of the info block.
+
+    Paragraph with text.
+
+    .. block-info:: Info block title
+
+        Info block content.
+
+        .. figure:: {filename}/static/ship-small.jpg
+            :alt: Image alt text
+
+            Figure title
+
+            Figure content.
+
+            .. math::
+
+                A = \pi r^2
+
+            This is again figure content.
+
+        This is again info block content.
+
+    And this is another paragraph of text, outside of the info block.
+
+.. note-info::
+
+    Please note that the above example code uses some directives provided by
+    ``m.css`` `Pelican plugins <{filename}/plugins.rst>`_ that are not builtin
+    in the :abbr:`reST <reStructuredText>` parser itself.
+
+`Interpreted text roles`_
+-------------------------
+
+While directives are for block elements, interpreted text roles are for inline
+elements. They are part of a paragraph and are in form of :rst:`:name:\`contents\``,
+where *name* is role name and *contents* are role contents. The role has to be
+separated with non-alphanumeric character from the surroundings; if you need
+to avoid the space, escape it with ``\``; similarly with the ````` character,
+if you need to use it inside. Unlike directives, roles can't be nested. Roles
+are also extensible via plugins.
+
+Roles, like directives, also have options, but the only way to use them is to
+define a new role based off the original one with the options you need. Use
+the :rst:`.. role::` directive like in the following snippet, where *original*
+is optional name of the original role to derive from, *new* is the name of new
+role and follows a list of options:
+
+.. code:: rst
+
+    .. role:: new(original)
+        :option1: value1
+        :option2: value2
+
+Example and a corresponding output:
+
+.. code-figure::
+
+    .. code:: rst
+
+        .. role:: red
+            :class: m-text m-danger
+
+        A text paragraph with :emphasis:`emphasised text`, :strong:`strong text`
+        and :literal:`typewriter`\ y text. :red:`This text is red.`
+
+    .. role:: red
+        :class: m-text m-danger
+
+    A text paragraph with :emphasis:`emphasised text`, :strong:`strong text`
+    and :literal:`typewriter`\ y text. :red:`This text is red.`
+
+.. note-success::
+
+    Don't worry, there are less verbose ways to achieve the above formatting.
+    Read about `basic inline elements below <#basic-inline-elements>`_.
+
+`Basic block elements`_
+=======================
+
+Besides headings and simple paragraphs, there are more block elements like
+quotes, literal blocks, tables etc. with implicit syntax. Sometimes you might
+want to separate two indented blocks, use a blank line containing just :rst:`..`
+to achieve that. Like directives, block elements are also nestable, so you can
+have lists inside quotes and the like.
+
+.. code-figure::
+
+    .. code:: rst
+
+        | Line block
+        | will
+        | preserve the newlines
+
+            A quote is simply an indented block.
+
+        ..
+
+            A different quote.
+
+        ::
+
+            Literal block is itroduced with ::, which can be even part of previous
+            paragraph (in which case it's reduced to a single colon).
+
+        ========= ============
+        Heading 1 Heading 2
+        ========= ============
+        Cell 1    Table cell 2
+        Row 2     Row 2 cell 2
+        Row 3     Row 3 cell 3
+        ========= ============
+
+        -   An unordered list
+        -   Another item
+
+            1.  Sub-list, ordered
+            2.  Another item
+            3.  Note that the sub-list is separated by blank lines
+
+        -   Third item of the top-level list
+
+        Term 1
+            Description
+        Term 2
+            Description of term 2
+
+    .. class:: m-noindent
+
+    | Line block
+    | will
+    | preserve the newlines
+
+        A quote is simply an indented block.
+
+    ..
+
+        A different quote.
+
+    ::
+
+        Literal block is itroduced with ::, which can be even the ending of
+        previous paragraph (in which case it's reduced to a single colon).
+
+    .. class:: m-table
+
+    ========= ============
+    Heading 1 Heading 2
+    ========= ============
+    Cell 1    Cell 2
+    Row 2     Row 2 cell 2
+    Row 3     Cell 3
+    ========= ============
+
+    -   An unordered list
+    -   Another item
+
+        1.  Sub-list, ordered
+        2.  Another item
+        3.  Note that the sub-list is separated by blank lines
+
+    -   Third item of the top-level list
+
+    .. class:: m-diary
+
+    Term 1
+        Description
+    Term 2
+        Description of term 2
+
+`Basic inline elements`_
+========================
+
+The :rst:`:emphasis:` role can be written shorter by wrapping the content in
+``*``, :rst:`:strong:` using ``**`` and :rst:`:literal:` with ``````. A single
+backtick :rst:`\`` is reserved and you can redefine to whatever you need in
+given scope using the `default-role <http://docutils.sourceforge.net/docs/ref/rst/directives.html#default-role>`_
+directive.
+
+Links are written using :rst:`\`title <URL>\`_`, where *title* is link text and
+*URL* is the link destination. The link title can be then used again to link to
+the same URL as simply :rst:`\`title\`_`. Note that specifying two links with
+the same title and different URLs is an error --- if you need that, use
+anonymous links that are in a form of :rst:`\`title <URL>\`__` (two underscores
+after). It's also possible to wrap section headings in a :rst:`\`heading\`_` to
+make them into clickable headers that you can link to later.
+
+.. code-figure::
+
+    .. code:: rst
+
+        An *emphasised text*, **strong text** and a ``literal``. Link to
+        `Google <https://google.com>`_, `the heading below <#a-heading>`_ or just an
+        URL as-is: https://mcss.mosra.cz/.
+
+        `A heading`_
+        ============
+
+        Repeated link to `Google`_. Anonymous links that share the same titles
+        `here <http://blog.mosra.cz>`__ and `here <http://magnum.graphics/>`__.
+
+    An *emphasised text*, **strong text** and a ``literal``. Link to
+    `Google <https://google.com>`_, `the heading below <#a-heading>`_ or just an
+    URL as-is: https://mcss.mosra.cz/.
+
+    .. raw:: html
+
+        <section id="a-heading">
+        <h2><a href="#a-heading">A heading</a></h2>
+
+    Repeated link to `Google`_. Anonymous links that share the same titles
+    `here <http://blog.mosra.cz>`__ and `here <http://magnum.graphics/>`__.
+
+    .. raw:: html
+
+        </section>
+
+.. note-info::
+
+    There are some special features in Pelican for easier linking to internal
+    content. Be sure to `check out the documentation <http://docs.getpelican.com/en/stable/content.html#linking-to-internal-content>`_.
+
+`Essential directives`_
+=======================
+
+-   A `container <http://docutils.sourceforge.net/docs/ref/rst/directives.html#container>`_
+    directive will just put a :html:`<div>` around its contents and its
+    arguments will be put as CSS classes to that element.
+-   A `class <http://docutils.sourceforge.net/docs/ref/rst/directives.html#class>`_
+    directive will put its argument as CSS class to the immediately following
+    element. Besides that, most of the directives also accept a :rst:`:class:`
+    option that does the same.
+-   Sometimes you need to put raw HTML code onto your page (for example to
+    embed a third-party widget). Use the `raw <http://docutils.sourceforge.net/docs/ref/rst/directives.html#raw-data-pass-through>`_
+    directive to achieve that.
+-   The `contents <http://docutils.sourceforge.net/docs/ref/rst/directives.html#contents>`_
+    directive will automatically make a Table of Contents list out of headings
+    in your document. Very useful for navigation in large pages and articles.
+
+For stuff like images, figures, code blocks, math listing etc., ``m.css``
+provides `Pelican plugins <{filename}/plugins.rst>`_ that do it better than the
+builtin way. Head over to the official :abbr:`reST <reStructuredText>`
+documentation for `more info about builtin directives <http://docutils.sourceforge.net/docs/ref/rst/directives.html>`_.
+
+`Essential interpreted text roles`_
+===================================
+
+-   Besides the already mentioned roles, there's also a
+    `sup <http://docutils.sourceforge.net/docs/ref/rst/roles.html#superscript>`_
+    and `sub <http://docutils.sourceforge.net/docs/ref/rst/roles.html#subscript>`_
+    role for superscript and subscript text.
+-   It's also possible to put raw HTML code inline by deriving from the
+    `raw <http://docutils.sourceforge.net/docs/ref/rst/roles.html#raw>`__ role.
+
+Again, ``m.css`` provides `Pelican plugins`_ that allow you to have inline
+code, math, GitHub and Doxygen links and much more. Head over to the official
+:abbr:`reST <reStructuredText>` documentation for
+`more info about builtin roles <http://docutils.sourceforge.net/docs/ref/rst/roles.html>`_.
+
+.. note-dim::
+    :class: m-text-center
+
+    `Pelican <{filename}/pelican.rst>`_ | `Theme » <{filename}/pelican/theme.rst>`_
diff --git a/doc/plugins.rst b/doc/plugins.rst
new file mode 100644 (file)
index 0000000..5ca30ec
--- /dev/null
@@ -0,0 +1,67 @@
+Pelican plugins
+###############
+
+.. role:: py(code)
+    :language: py
+
+The `Pelican theme <{filename}/pelican/theme.rst>`_ provided by ``m.css``
+uses only a part of the functionality on its own, the rest is exposed by
+various plugins.
+
+`Usage`_
+========
+
+Each plugin is a standalone ``*.py`` file that is meant to be downloaded and
+put into a ``m/`` subdirectory into one of your :py:`PLUGIN_PATHS`. Then you
+add given :py:`m.something` package to your :py:`PLUGINS` in ``pelicanconf.py``
+and restart Pelican. Download the plugins below or
+:gh:`grab the whole Git repository <mosra/m.css>`:
+
+-   :gh:`m.htmlsanity <mosra/m.css$master/pelican-plugins/m/htmlsanity.py>`
+-   :gh:`m.components <mosra/m.css$master/pelican-plugins/m/components.py>`
+-   :gh:`m.images <mosra/m.css$master/pelican-plugins/m/images.py>`
+-   :gh:`m.math  <mosra/m.css$master/pelican-plugins/m/math.py>` (needs also :gh:`latex2svg <mosra/m.css$master/pelican-plugins/m/latex2svg.py>`),
+    :gh:`m.code <mosra/m.css$master/pelican-plugins/m/code.py>`
+-   :gh:`m.gh <mosra/m.css$master/pelican-plugins/m/gh.py>`,
+    :gh:`m.dox <mosra/m.css$master/pelican-plugins/m/dox.py>`,
+    :gh:`m.gl <mosra/m.css$master/pelican-plugins/m/gl.py>`,
+    :gh:`m.abbr <mosra/m.css$master/pelican-plugins/m/abbr.py>`,
+    :gh:`m.filesize <mosra/m.css$master/pelican-plugins/m/filesize.py>`
+
+Click on the headings below to get to know more.
+
+`HTML sanity » <{filename}/plugins/htmlsanity.rst>`_
+====================================================
+
+The :py:`m.htmlsanity` plugin is essential for ``m.css``. It makes your markup
+valid HTML5, offers a few opt-in typographical improvements and enables you to
+make full use of features provided by other plugins.
+
+`Components » <{filename}/plugins/components.rst>`_
+===================================================
+
+All `CSS components <{filename}/css/components.rst>`_ are exposed by the
+:py:`m.components` plugin, so you can use them via :abbr:`reST <reStructuredText>`
+directives without needing to touch HTML and CSS directly.
+
+`Images » <{filename}/plugins/images.rst>`_
+===========================================
+
+Image-related CSS components are implemented by the :py:`m.images` plugin,
+overriding builtin :abbr:`reST <reStructuredText>` functionality and providing
+a convenient automatic way to arrange photos in an image grid.
+
+`Math and code » <{filename}/plugins/math-and-code.rst>`_
+=========================================================
+
+The :py:`m.math` and :py:`m.code` plugins use external libraries for math
+rendering and syntax highlighting, so they are provided as separate packages
+that you can but don't have to use. With these, math and code snippets can be
+entered directly in your :abbr:`reST <reStructuredText>` sources.
+
+`Links » <{filename}/plugins/links.rst>`_
+=========================================
+
+The :py:`m.gh`, :py:`m.dox`, :py:`m.gl`, :py:`m.abbr` and :py:`m.fiilesize`
+plugins make it easy for you to link to GitHub projects, issues or PRs, to
+Doxygen documentation and do more useful things.
diff --git a/doc/plugins/components-test.rst b/doc/plugins/components-test.rst
new file mode 100644 (file)
index 0000000..a4ae469
--- /dev/null
@@ -0,0 +1,165 @@
+Test
+####
+
+:save_as: plugins/components/test/index.html
+:breadcrumb: {filename}/plugins.rst Pelican plugins
+             {filename}/plugins/components.rst Components
+
+Should match the rendering of
+`CSS components test page <{filename}/css/components-test.rst>`_.
+
+Blocks_
+=======
+
+.. container:: m-row
+
+    .. container:: m-col-m-3 m-col-s-6
+
+        .. block-default:: Default block
+
+            Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus
+            ultrices a erat eu suscipit. `Link. <#>`_
+
+    .. container:: m-col-m-3 m-col-s-6
+
+        .. block-primary:: Primary block
+
+            Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus
+            ultrices a erat eu suscipit. `Link. <#>`_
+
+    .. container:: m-col-m-3 m-col-s-6
+
+        .. block-success:: Success block
+
+            Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus
+            ultrices a erat eu suscipit. `Link. <#>`_
+
+    .. container:: m-col-m-3 m-col-s-6
+
+        .. block-warning:: Warning block
+
+            Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus
+            ultrices a erat eu suscipit. `Link. <#>`_
+
+    .. container:: m-col-m-3 m-col-s-6
+
+        .. block-danger:: Danger block
+
+            Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus
+            ultrices a erat eu suscipit. `Link. <#>`_
+
+    .. container:: m-col-m-3 m-col-s-6
+
+        .. block-info:: Info block
+
+            Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus
+            ultrices a erat eu suscipit. `Link. <#>`_
+
+    .. container:: m-col-m-3 m-col-s-6
+
+        .. block-dim:: Dim block
+
+            Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus
+            ultrices a erat eu suscipit. `Link. <#>`_
+
+    .. container:: m-col-m-3 m-col-s-6
+
+        .. block-flat:: Flat block
+
+            Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus
+            ultrices a erat eu suscipit. `Link. <#>`_
+
+`Notes, frame`_
+===============
+
+.. container:: m-row
+
+    .. container:: m-col-m-3 m-col-s-6
+
+        .. note-default:: Default note
+
+            Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus
+            ultrices a erat eu suscipit. `Link. <#>`_
+
+    .. container:: m-col-m-3 m-col-s-6
+
+        .. note-primary:: Primary note
+
+            Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus
+            ultrices a erat eu suscipit. `Link. <#>`_
+
+    .. container:: m-col-m-3 m-col-s-6
+
+        .. note-success:: Success note
+
+            Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus
+            ultrices a erat eu suscipit. `Link. <#>`_
+
+    .. container:: m-col-m-3 m-col-s-6
+
+        .. note-warning:: Warning note
+
+            Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus
+            ultrices a erat eu suscipit. `Link. <#>`_
+
+    .. container:: m-col-m-3 m-col-s-6
+
+        .. note-danger:: Danger note
+
+            Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus
+            ultrices a erat eu suscipit. `Link. <#>`_
+
+    .. container:: m-col-m-3 m-col-s-6
+
+        .. note-info:: Info note
+
+            Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus
+            ultrices a erat eu suscipit. `Link. <#>`_
+
+    .. container:: m-col-m-3 m-col-s-6
+
+        .. note-dim:: Dim note
+
+            Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus
+            ultrices a erat eu suscipit. `Link. <#>`_
+
+    .. container:: m-col-m-3 m-col-s-6
+
+        .. frame:: Frame
+
+            Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus
+            ultrices a erat eu suscipit. `Link. <#>`_
+
+Note w/o title, with applied class:
+
+.. note-default::
+    :class: m-text-center
+
+    Some center-aligned content.
+
+Block, with applied class:
+
+.. block-warning:: Warning block
+    :class: m-text-right
+
+    Aligned to the right
+
+Frame, w/o title, with applied class:
+
+.. frame::
+    :class: m-text-center
+
+    Centered frame content
+
+Flat code figure:
+
+.. code-figure::
+    :class: m-flat
+
+    ::
+
+        Some
+            code
+        snippet
+
+    And a resulting output.
diff --git a/doc/plugins/components.rst b/doc/plugins/components.rst
new file mode 100644 (file)
index 0000000..6cc1899
--- /dev/null
@@ -0,0 +1,315 @@
+Components
+##########
+
+:breadcrumb: {filename}/plugins.rst Pelican plugins
+
+.. role:: rst(code)
+    :language: rst
+
+.. role:: html(code)
+    :language: html
+
+.. role:: css(code)
+    :language: css
+
+Most of ``m.css`` `CSS components <{filename}/css/components.rst>`_ are exposed
+to Pelican via custom :abbr:`reST <reStructuredText>` directives. Unlike with
+pure CSS, the directives are *not* prefixed with ``m-`` to save some typing ---
+which is the most important thing when authoring content.
+
+.. contents::
+    :class: m-block m-default
+
+`How to use`_
+=============
+
+Download the `m/components.py <{filename}/plugins.rst>`_ file, put it
+including the ``m/`` directory into one of your :py:`PLUGIN_PATHS` and add
+:py:`m.components` package to your :py:`PLUGINS` in ``pelicanconf.py``. This
+plugin assumes presence of `m.htmlsanity <{filename}/plugins/htmlsanity.rst>`_.
+
+.. code:: python
+
+    PLUGINS += ['m.htmlsanity', 'm.components']
+
+`Transitions`_
+==============
+
+Use :rst:`.. transition::` directive to create a `transition <{filename}/css/typography.rst#transitions>`_:
+
+.. code-figure::
+
+    .. code:: rst
+
+        Aenean tellus turpis, suscipit quis iaculis ut, suscipit nec magna. Vestibulum
+        finibus sit amet neque nec volutpat. Suspendisse sit amet nisl in orci posuere
+        mattis.
+
+        .. transition:: ~ ~ ~
+
+        Praesent eu metus sed felis faucibus placerat ut eu quam. Aliquam convallis
+        accumsan ante sit amet iaculis. Phasellus rhoncus hendrerit leo vitae lacinia.
+        Maecenas iaculis dui ex, eu interdum lacus ornare sit amet.
+
+    Aenean tellus turpis, suscipit quis iaculis ut, suscipit nec magna.
+    Vestibulum finibus sit amet neque nec volutpat. Suspendisse sit amet nisl
+    in orci posuere mattis.
+
+    .. transition:: ~ ~ ~
+
+    Praesent eu metus sed felis faucibus placerat ut eu quam. Aliquam convallis
+    accumsan ante sit amet iaculis. Phasellus rhoncus hendrerit leo vitae
+    lacinia. Maecenas iaculis dui ex, eu interdum lacus ornare sit amet.
+
+`Blocks, notes, frame`_
+=======================
+
+Use :rst:`.. block-default::`, :rst:`.. block-primary::` etc. directives to create
+`blocks <{filename}/css/components.rst#blocks>`_; use :rst:`.. note-default::`,
+:rst:`.. note-primary::` etc. or :rst:`.. frame::` directives to create
+`notes and frames <{filename}/css/components.rst#notes-frame>`_. Blocks require
+title to be present, notes and frames have it optional. Internally, these
+elements are represented as a
+`topic directive <http://docutils.sourceforge.net/docs/ref/rst/directives.html#topic>`_.
+Use the :rst:`:class:` option to specify additional CSS classes.
+
+.. code-figure::
+
+    .. code:: rst
+
+        .. block-danger:: Danger block
+
+            Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus ultrices a
+            erat eu suscipit. `Link. <#>`_
+
+        .. note-success:: Success note
+
+            Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus ultrices a
+            erat eu suscipit. `Link. <#>`_
+
+        .. frame:: Frame
+
+            Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus ultrices a
+            erat eu suscipit. `Link. <#>`_
+
+    .. container:: m-row
+
+        .. container:: m-col-m-4
+
+            .. block-danger:: Danger block
+
+                Lorem ipsum dolor sit amet, consectetur adipiscing elit.
+                Vivamus ultrices a erat eu suscipit. `Link. <#>`_
+
+        .. container:: m-col-m-4
+
+            .. note-success:: Success note
+
+                Lorem ipsum dolor sit amet, consectetur adipiscing elit.
+                Vivamus ultrices a erat eu suscipit. `Link. <#>`_
+
+        .. container:: m-col-m-4
+
+            .. frame:: Frame
+
+                Lorem ipsum dolor sit amet, consectetur adipiscing elit.
+                Vivamus ultrices a erat eu suscipit. `Link. <#>`_
+
+`Code figure`_
+==============
+
+Use :rst:`.. code-figure::` to denote a `code figure <{filename}/css/components.rst#code-figure>`_.
+Then put a literal code block denoted by :rst:`::` or a :rst:`.. code::`
+directive as the first element inside. Use the :rst:`:class:` option to specify
+additional CSS classes.
+
+.. code-figure::
+
+    .. code:: rst
+
+        .. code-figure::
+
+            ::
+
+                Some
+                    sample
+                code
+
+            And a resulting output.
+
+    .. code-figure::
+
+        ::
+
+            Some
+                sample
+            code
+
+        And a resulting output.
+
+`Text`_
+=======
+
+Use :rst:`.. text-default::`, :rst:`.. text-primary::` etc. directives to
+`color a block of text <{filename}/css/components.rst#text>`_. Internally,
+these elements are represented as a `container directive <http://docutils.sourceforge.net/docs/ref/rst/directives.html#container>`_.
+Use the :rst:`:class:` option to specify additional CSS classes.
+
+.. code-figure::
+
+    .. code:: rst
+
+        .. text-info::
+            :class: m-text-center
+
+            Info text. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus
+            ultrices a erat eu suscipit. Aliquam pharetra imperdiet tortor sed
+            vehicula. `Link. <#>`_
+
+    .. text-info::
+        :class: m-text-center
+
+        Info text. Lorem ipsum dolor sit amet, consectetur adipiscing elit.
+        Vivamus ultrices a erat eu suscipit. Aliquam pharetra imperdiet tortor
+        sed vehicula. `Link. <#>`_
+
+There are no interpreted text roles provided for inline colored text, but you
+can define a custom one and add the CSS classes to it, potentially deriving it
+from either the :rst:`:emphasis:` or :rst:`:strong:` role to combine color with
+emphasis or strong text:
+
+.. code-figure::
+
+    .. code:: rst
+
+        .. role:: text-dim
+            :class: m-text m-dim
+
+        .. role:: text-warning-strong(strong)
+            :class: m-text m-warning
+
+        Aenean id elit posuere, consectetur magna congue, sagittis est.
+        :text-dim:`Dim inline text.` Pellentesque est neque, aliquet nec consectetur
+        in, mattis ac diam. :text-warning-strong:`Warning strong text.`
+
+    .. role:: text-dim
+        :class: m-text m-dim
+
+    .. role:: text-warning-strong(strong)
+        :class: m-text m-warning
+
+    Aenean id elit posuere, consectetur magna congue, sagittis est.
+    :text-dim:`Dim inline text.` Pellentesque est neque, aliquet nec
+    consectetur in, mattis ac diam. :text-warning-strong:`Warning strong text.`
+
+`Button links`_
+===============
+
+Use :rst:`.. button-default::`, :rst:`.. button-primary::` etc. directives to
+create a `button link <{filename}/css/components.rst#button-links>`_. Directive
+argument is the URL, directive contents are button title. Use the :rst:`:class:`
+option to specify additional CSS classes. Use two paragraphs of content to
+create a button with title and description.
+
+.. code-figure::
+
+    .. code:: rst
+
+            .. button-danger:: #
+
+                Order now!
+
+            .. button-primary:: #
+
+                Download the thing
+
+                Any platform, 5 kB.
+
+    .. container:: m-text-center
+
+        .. button-danger:: #
+
+            Order now!
+
+        .. container:: m-clearfix-t
+
+            ..
+
+        .. button-primary:: #
+
+            Download the thing
+
+            Any platform, 5 kB.
+
+`Tables`_
+=========
+
+Mark your reST table with :rst:`..class:: m-table` to give it styling.
+
+.. code-figure::
+
+    .. code:: rst
+
+        .. class:: m-table
+
+        = ============= ================
+        # Heading       Second heading
+        = ============= ================
+        1 Cell          Second cell
+        2 2nd row cell  2nd row 2nd cell
+        = ============= ================
+
+    .. class:: m-table m-center-t
+
+    = ============= ================
+    # Heading       Second heading
+    = ============= ================
+    1 Cell          Second cell
+    2 2nd row cell  2nd row 2nd cell
+    = ============= ================
+
+.. todo: cell coloring, footer etc.
+
+`Other m.css features`_
+=======================
+
+You can use :rst:`.. container::` directive to add a wrapping :html:`<div>`
+around most elements. Parameters of the directive are CSS classes. For example,
+arranging content in three-column grid can be done like this:
+
+.. code-figure::
+
+    .. code:: rst
+
+        .. container:: m-row
+
+            .. container:: m-col-m-4
+
+                Left column content.
+
+            .. container:: m-col-m-4
+
+                Middle column content.
+
+            .. container:: m-col-m-4
+
+                Right column content.
+
+    .. container:: m-row
+
+        .. container:: m-col-m-4 m-text-center
+
+            Left column content.
+
+        .. container:: m-col-m-4 m-text-center
+
+            Middle column content.
+
+        .. container:: m-col-m-4 m-text-center
+
+            Right column content.
+
+.. note-dim::
+    :class: m-text-center
+
+    `« HTML sanity <{filename}/plugins/htmlsanity.rst>`_ | `Pelican plugins <{filename}/plugins.rst>`_ | `Images » <{filename}/plugins/images.rst>`_
diff --git a/doc/plugins/htmlsanity-test.rst b/doc/plugins/htmlsanity-test.rst
new file mode 100644 (file)
index 0000000..91dabd3
--- /dev/null
@@ -0,0 +1,18 @@
+Test
+####
+
+:save_as: plugins/htmlsanity/test/index.html
+:breadcrumb: {filename}/plugins.rst Pelican plugins
+             {filename}/plugins/htmlsanity.rst HTML sanity
+
+Inline preformatted blocks should be escaped: ``<hr>``
+
+Inline preformatted blocks should have whitespace preserved: ``two  spaces  between  words``
+
+Preformatted blocks should have sane rendering::
+
+    helllo
+
+      world
+
+Inline code shouldn't be hyphenated or with smart quotes applied: ``"hello" --- isn't this working?"``.
diff --git a/doc/plugins/htmlsanity.rst b/doc/plugins/htmlsanity.rst
new file mode 100644 (file)
index 0000000..8b95612
--- /dev/null
@@ -0,0 +1,314 @@
+HTML sanity
+###########
+
+:breadcrumb: {filename}/plugins.rst Pelican plugins
+
+.. role:: html(code)
+    :language: html
+
+.. role:: py(code)
+    :language: py
+
+Base plugin that makes your Pelican HTML output and typography look like from
+the current century.
+
+.. contents::
+    :class: m-block m-default
+
+`How to use`_
+=============
+
+Download the `m/htmlsanity.py <{filename}/plugins.rst>`_ file, put it
+including the ``m/`` directory into one of your :py:`PLUGIN_PATHS` and add
+:py:`m.htmlsanity` package to your :py:`PLUGINS` in ``pelicanconf.py``.
+
+.. code:: python
+
+    PLUGINS += ['m.htmlsanity']
+    HTMLSANITY_SMART_QUOTES = True
+    HTMLSANITY_HYPHENATION = True
+
+.. note-warning::
+
+    Note that you need Pelican with :gh:`getpelican/pelican@7336de45cbb5f60e934b65f823d0583b48a6c96b`
+    applied for this to work properly. It's scheduled to be part of
+    yet-to-be-released version 3.8.
+
+`What it does`_
+===============
+
+This plugin replaces the default Pelican HTML4/CSS1 writer (it already sounds
+horrible, right?) with a custom HTML5 writer derived from
+``docutils.writers.html5_polyglot`` that does the following better:
+
+-   Document sections are using HTML5 :html:`<section>` tag instead of
+    :html:`<div class="section">`
+-   Images don't have the ``alt`` attribute populated with URI, if not
+    specified otherwise
+-   Figures are using HTML5 :html:`<figure>` tag instead of
+    :html:`<div class="figure">`, figure caption is using HTML5 :html:`<figcaption>`
+    instead of :html:`<p class="caption">`
+-   Drops *a lot of* useless classes from elements such as :html:`<div class="docutils">`
+-   Makes it possible to have :html:`<a>` elements with block contents (allowed
+    in HTML5)
+-   Even the Docutils HTML5 writer was putting *frightening* :html:`<colgroup>`
+    things into HTML tables. Not anymore.
+-   Topics are using HTML5 :html:`<aside>` tag, topic headers are using
+    :html:`<h3>` instead of a nondescript :html:`<div>`
+-   Line blocks are simply :html:`<p>` elements with lines delimited using
+    :html:`<br>`
+-   The :html:`<abbr>` tag now properly includes a ``title`` attribute
+
+`Typography`_
+=============
+
+The Pelican builtin ``TYPOGRIFY`` option is using
+`SmartyPants <https://daringfireball.net/projects/smartypants/>`_ for
+converting ``"``, ``'``, ``---``, ``--``, ``...`` into smart double and single
+quote, em-dash, en-dash and ellipsis, respectively. Unfortunately SmartyPants
+have this hardcoded for just English, so one can't easily get German or
+French-style quotes.
+
+.. note-info::
+
+    I find it hilarious that SmartyPants author complains that everyone is
+    careless about web typography, but *dares to assume* that there's just the
+    English quote style and nothing else.
+
+This plugin contains a patched version of
+`smart_quotes option <http://docutils.sourceforge.net/docs/user/smartquotes.html>`_
+from Docutils, which is based off SmartyPants, but with proper language awareness
+on top. See for yourself:
+
+.. code-figure::
+
+    .. code:: rst
+
+        .. class:: language-en
+
+        *"A satisfied customer is the best business strategy of all"*
+
+        .. class:: language-de
+
+        *"Andere Länder, andere Sitten"*
+
+        .. class:: language-fr
+
+        *"Autres temps, autres mœurs"*
+
+    .. class:: language-en
+
+    *"A satisfied customer is the best business strategy of all"*
+
+    .. class:: language-de
+
+    *"Andere Länder, andere Sitten"*
+
+    .. class:: language-fr
+
+    *"Autres temps, autres mœurs"*
+
+The default language is of course taken from the standard :py:`DEFAULT_LANG`
+option, which defaults to :py:`'en'`. This feature is controlled by the
+:py:`HTMLSANITY_SMART_QUOTES` option, which, similarly to the builtin
+:py:`TYPOGRIFY` option, defaults to :py:`False`.
+
+.. note-warning::
+
+    Note that due to inherent complexity of smart quotes, only paragraph-level
+    language setting is taken into account, not inline language specification.
+
+`Hyphenation`_
+==============
+
+Or word wrap. CSS has a standard way to hyphenate words, however it's quite
+hard to control from a global place and I've not yet seen any browser actually
+implementing that feature. Lack of word wrap is visible especially on narrow
+screens of mobile devices, where there is just way too much blank space because
+of long words being wrapped on new lines.
+
+The hyphenation is done using `Pyphen <http://pyphen.org/>`_ and is applied to
+whole document contents and article summaries (except for literal and raw
+blocks, of course). All other fields including document title are excluded from
+hyphenation. You can see it in practice in the following convoluted example,
+it's also language-aware:
+
+.. code-figure::
+
+    .. code:: rst
+
+        .. class:: language-en
+
+        incomprehensibilities
+
+        .. class:: language-de
+
+        Bezirksschornsteinfegermeister
+
+        .. class:: language-fr
+
+        anticonstitutionnellement
+
+    .. container:: m-row
+
+        .. container:: m-col-m-2 m-push-m-3 m-col-t-4 m-nopady
+
+            .. class:: language-en m-noindent
+
+            incomprehensibilities
+
+        .. container:: m-col-m-2 m-push-m-3 m-col-t-4 m-nopady
+
+            .. class:: language-de m-noindent
+
+            Bezirksschornsteinfegermeister
+
+        .. container:: m-col-m-2 m-push-m-3 m-col-t-4 m-nopady
+
+            .. class:: language-fr m-noindent
+
+            anticonstitutionnellement
+
+The resulting HTML code looks like this, with :html:`&shy;` added to places
+that are candidates for a word break:
+
+.. code:: html
+
+    <p lang="en">in&shy;com&shy;pre&shy;hen&shy;si&shy;bil&shy;i&shy;ties</p>
+    <p lang="de">Be&shy;zirks&shy;schorn&shy;stein&shy;fe&shy;ger&shy;meis&shy;ter</p>
+    <p lang="fr">an&shy;ti&shy;cons&shy;ti&shy;tu&shy;tion&shy;nel&shy;le&shy;ment</p>
+
+Thanks to Unicode magic this is either hidden or converted to a real hyphen and
+*doesn't* break search or SEO. This feature is controlled by the
+:py:`HTMLSANITY_HYPHENATION` option, which also defaults to :py:`False`.
+
+.. note-success::
+
+    Unlike smart quotes, the hyphenation works even with inline language
+    specifiers, so you can have part of a paragraph in English and part in
+    French and still have both hyphenated correctly.
+
+`Jinja2 goodies`_
+=================
+
+`reST rendering`_
+-----------------
+
+It's possible to use the reST-to-HTML5 renderer from your Jinja2 template (for
+example to render a custom fine print text in the footer, specified through
+settings). Just pipe your variable through the ``render_rst`` filter:
+
+.. code:: html+jinja
+
+    <html>
+      ...
+      <body>
+        ...
+        <footer>{{ FINE_PRINT|render_rst }}</footer>
+      </body>
+    </html>
+
+The filter is fully equivalent to the builtin reST rendering and the above
+:py:`HTMLSANITY_SMART_QUOTES` and :py:`HTMLSANITY_HYPHENATION` options affect
+it as well.
+
+.. note-warning::
+
+    For content coming from document metadata fields you still have to use the
+    builtin :py:`FORMATTED_FIELDS` option, otherwise additional formatting will
+    get lost.
+
+`Internal link expansion`_
+--------------------------
+
+By default, link expansion works only in document content and article
+summaries. In order to expand links in additional fields and arbitrary strings,
+this plugin provides two Jinja2 filters, producing results equivalent to
+`links expanded by Pelican <http://docs.getpelican.com/en/stable/content.html#linking-to-internal-content>`_.
+
+For fields that are referenced in the :py:`FORMATTED_FIELDS` setting, one can
+use the ``expand_links`` Jinja2 filter in the template. The link expansion
+needs the content object (either ``article`` or ``page``) as a parameter.
+
+.. code:: jinja
+
+    {{ article.legal|expand_links(article) }}
+
+If the custom field consists of just one link (for example a link to article
+cover image for a social meta tag), one can use the ``expand_link`` Jinja2
+filter:
+
+.. code:: jinja
+
+    {{ article.cover|expand_link(article) }}
+
+With the above being in a template and with the :py:`FORMATTED_FIELDS` setting
+containing the :py:`'legal'` field, a :abbr:`reST <reStructuredText>` article
+making use of both fields could look like this:
+
+.. code:: rst
+
+    An article
+    ##########
+
+    :date: 2017-06-22
+    :legal: This article is released under `CC0 {filename}/license.rst`_.
+    :cover: {filename}/img/article-cover.jpg
+
+`Text hyphenation`_
+-------------------
+
+If you need to hyphenate text that was not already processed using the
+hyphenation filter (for example to wrap article titles or long words in menu
+items), use the ``hyphenate`` filter:
+
+.. code:: html+jinja
+
+    <nav>
+      <ul>
+        {% for title, link in LINKS %}
+        <li><a href="{{ link }}">{{ title|hyphenate }}</a></li>
+        {% endfor %}
+      </ul>
+    </nav>
+
+The hyphenation is by default controlled by the :py:`HTMLSANITY_HYPHENATION`
+option. If you want to control this separately, pass a boolean variable or
+simply :py:`True` to the filter ``enable`` argument. The language is by default
+taken from the standard :py:`DEFAULT_LANG` option, if you want to override it,
+pass language name to the ``lang`` argument. You can also take the value from
+:py:`article.lang` or :py:`page.lang` attributes provided by Pelican.
+
+.. code:: jinja
+
+    {{ title|hyphenate(enable=TEMPLATE_HYPHENATION, lang='fr_FR') }}
+
+Sometimes, on the other hand, you might want to de-hyphenate text that was
+already hyphenated, for example to avoid potential issues in :html:`<meta>`
+tags. The ``dehyphenate`` filter simply removes all occurences of :html:`&shy;`
+from passed text. The ``enable`` argument works the same as with the
+``hyphenate`` filter.
+
+.. code:: html+jinja
+
+    <html>
+      <head>
+        <meta name="description" content="{{ article.summary|dehyphenate|striptags }}" />
+      </head>
+      ...
+
+`Why choose this over ...`_
+===========================
+
+There are already
+`numerous <https://github.com/getpelican/pelican-plugins/tree/master/better_figures_and_images>`_
+`Pelican <https://github.com/classner/better_code_samples/tree/91717a204bbd0ae4a1af6fe25ac5dd783fb4a7db>`_
+`plugins <https://github.com/getpelican/pelican-plugins/tree/master/better_tables>`_
+that try to do similar things, but they *attempt* to fix it using BeautifulSoup
+on top of the generated HTML. That's a horrendous thing to do, so why not just
+prevent the horror from happening?
+
+.. note-dim::
+    :class: m-text-center
+
+    `Pelican plugins <{filename}/plugins.rst>`_ | `Components » <{filename}/plugins/components.rst>`_
diff --git a/doc/plugins/images-test.rst b/doc/plugins/images-test.rst
new file mode 100644 (file)
index 0000000..e879f37
--- /dev/null
@@ -0,0 +1,59 @@
+Test
+####
+
+:save_as: plugins/images/test/index.html
+:breadcrumb: {filename}/plugins.rst Pelican plugins
+             {filename}/plugins/images.rst
+
+`Images, figures`_
+==================
+
+All images should have no ``alt`` text, unless specified manually.
+
+Image with link:
+
+.. image:: {filename}/static/ship-small.jpg
+    :target: {filename}/static/ship.jpg
+
+Image, class on top, custom alt:
+
+.. image:: {filename}/static/ship.jpg
+    :class: m-fullwidth
+    :alt: A Ship
+
+Image with link, class on top:
+
+.. image:: {filename}/static/ship.jpg
+    :target: {filename}/static/ship.jpg
+    :class: m-fullwidth
+
+Figure with link and only a caption:
+
+.. figure:: {filename}/static/ship-small.jpg
+    :target: {filename}/static/ship.jpg
+
+    A Ship
+
+Figure with link and class on top:
+
+.. figure:: {filename}/static/ship-small.jpg
+    :target: {filename}/static/ship.jpg
+    :figclass: m-fullwidth
+
+    A Ship
+
+Image grid, not inflated:
+
+.. image-grid::
+
+    {filename}/static/ship.jpg
+    {filename}/static/flowers.jpg
+
+Image grid, inflated:
+
+.. container:: m-container-inflated
+
+    .. image-grid::
+
+        {filename}/static/flowers.jpg
+        {filename}/static/ship.jpg
diff --git a/doc/plugins/images.rst b/doc/plugins/images.rst
new file mode 100644 (file)
index 0000000..1a30b74
--- /dev/null
@@ -0,0 +1,119 @@
+Images
+######
+
+:breadcrumb: {filename}/plugins.rst Pelican plugins
+
+Gives sane defaults to images and figures and provides a way to present
+beautiful image galleries.
+
+.. contents::
+    :class: m-block m-default
+
+`How to use`_
+=============
+
+Download the `m/images.py <{filename}/plugins.rst>`_ file, put it including the
+``m/`` directory into one of your :py:`PLUGIN_PATHS` and add ``m.images``
+package to your :py:`PLUGINS` in ``pelicanconf.py``. To use the image grid
+feature, in addition you need the `Pillow <https://pypi.python.org/pypi/Pillow>`_
+library installed. This plugin assumes presence of
+`m.htmlsanity <{filename}/plugins/htmlsanity.rst>`_.
+
+.. code:: python
+
+    PLUGINS += ['m.htmlsanity', 'm.images']
+
+`Images, figures`_
+==================
+
+The plugin overrides the builtin
+`image <http://docutils.sourceforge.net/docs/ref/rst/directives.html#image>`__
+and `figure <http://docutils.sourceforge.net/docs/ref/rst/directives.html#figure>`__
+directives and:
+
+-   Adds :css:`.m-image` / :css:`.m-figure` CSS classes to them so they have
+    the expected ``m.css`` `image <{filename}/css/components.rst#images>`_ and
+    `figure <{filename}/css/components.rst#figures>`_ styling.
+-   Removes the :rst:`:align:`, :rst:`:figwidth:` and :rst:`:scale:` options,
+    as this is better handled by ``m.css`` features.
+
+You can add `additional CSS classes <{filename}/css/components.rst#images>`_ to
+images or figures via the :rst:`:class:` or :rst:`:figclass:` options,
+respectively. If you want the image or figure to be clickable, use the
+:rst:`:target:` option. The alt text can be specified using the :rst:`:alt:`
+option for both images and figures.
+
+.. code-figure::
+
+    .. code:: rst
+
+        .. image:: flowers.jpg
+            :target: flowers.jpg
+            :alt: Flowers
+
+        .. figure:: ship.jpg
+            :alt: Ship
+
+            A Ship
+
+            Photo © `The Author <http://blog.mosra.cz/>`_
+
+    .. container:: m-row
+
+        .. container:: m-col-m-6
+
+            .. image:: {filename}/static/flowers-small.jpg
+                :target: {filename}/static/flowers.jpg
+
+        .. container:: m-col-m-6
+
+            .. figure:: {filename}/static/ship-small.jpg
+
+                A Ship
+
+                Photo © `The Author <http://blog.mosra.cz/>`_
+
+`Image grid`_
+=============
+
+Use the :rst:`.. image-grid::` directive for creating
+`image grid <{filename}/css/components.rst#image-grid>`_. Directive contents
+are a list of image URLs, blank lines separate grid rows. The plugin
+automatically extracts size information and scales the images accordingly, in
+addition EXIF properties such as aperture, shutter speed and ISO are extracted
+and displayed in the caption on hover. The images are also made clickable, the
+target is the image file itself.
+
+Example of a two-row image grid is below. Sorry for reusing the same two images
+all over (I'm making it easier for myself); if you want to see a live example
+with non-repeating images, head over to `my blog <http://blog.mosra.cz/cesty/mainau/>`_.
+
+.. code:: rst
+
+    .. image-grid::
+
+        {filename}/ship.jpg
+        {filename}/flowers.jpg
+
+        {filename}/flowers.jpg
+        {filename}/ship.jpg
+
+.. image-grid::
+
+    {filename}/static/ship.jpg
+    {filename}/static/flowers.jpg
+
+    {filename}/static/flowers.jpg
+    {filename}/static/ship.jpg
+
+.. note-warning::
+
+    Unlike with the image and figure directives above, Pelican *needs* to have
+    the images present on a filesystem to extract size information. It's
+    advised to use the builtin *absolute* ``{filename}`` or ``{attach}`` syntax
+    for `linking to internal content <http://docs.getpelican.com/en/stable/content.html#linking-to-internal-content>`_.
+
+.. note-dim::
+    :class: m-text-center
+
+    `« Components <{filename}/plugins/components.rst>`_ | `Pelican plugins <{filename}/plugins.rst>`_ | `Math and code » <{filename}/plugins/math-and-code.rst>`_
diff --git a/doc/plugins/links.rst b/doc/plugins/links.rst
new file mode 100644 (file)
index 0000000..a03d7f8
--- /dev/null
@@ -0,0 +1,218 @@
+Links
+#####
+
+:breadcrumb: {filename}/plugins.rst Pelican plugins
+
+.. role:: py(code)
+    :language: py
+
+.. role:: rst(code)
+    :language: rst
+
+``m.css`` plugins make linking to external content almost too easy. If your
+website is about coding, chances are quite high that you will be linking to
+repositories, documentation or bugtrackers. Manually copy-pasting links from
+the browser gets quite annoying after a while and also doesn't really help with
+keeping the reST sources readable.
+
+Because not everybody needs to link to all services provided here, the
+functionality is separated into a bunch of separate plugins, each having its
+own requirements.
+
+.. contents::
+    :class: m-block m-default
+
+`GitHub`_
+=========
+
+Download the `m/gh.py <{filename}/plugins.rst>`_ file, put it
+including the ``m/`` directory into one of your :py:`PLUGIN_PATHS` and add
+:py:`m.gh` package to your :py:`PLUGINS` in ``pelicanconf.py``:
+
+.. code:: python
+
+    PLUGINS += ['m.gh']
+
+Use the :rst:`:gh:` interpreted text role for linking. The plugin mimics how
+`GitHub Flavored Markdown <https://help.github.com/articles/autolinked-references-and-urls/>`_
+parses inter-site links, with some extensions on top. In addition to well-known
+references to commits and issues/PRs via ``@`` and ``#``, ``$`` is for linking
+to a tree (or file in given tree) and ``^`` is for linking to a tag/release. If
+your link target doesn't contain any of these characters and contains more than
+one slash, the target is simply prepended with ``https://github.com/``.
+
+Link text is equal to link target for repository, commit and issue/PR links,
+otherwise the full expanded URL is used. Similarly to builtin linking
+functionality, if you want a custom text for a link, use the
+:rst:`:gh:`link text <link-target>`` syntax.
+
+.. code-figure::
+
+    .. code:: rst
+
+        -   Profile link: :gh:`mosra`
+        -   Repository link: :gh:`mosra/m.css`
+        -   Commit link: :gh:`mosra/m.css@4d362223f107cffd8731a0ea031f9353a0a2c7c4`
+        -   Issue/PR link: :gh:`mosra/magnum#123`
+        -   Tree link: :gh:`mosra/m.css$next`
+        -   Tag link: :gh:`mosra/magnum^snapshot-2015-05`
+        -   File link: :gh:`mosra/m.css$master/css/m-dark.css`
+        -   Arbitrary link: :gh:`mosra/magnum/graphs/contributors`
+        -   :gh:`Link with custom title <getpelican/pelican>`
+
+    -   Profile link: :gh:`mosra`
+    -   Repository link: :gh:`mosra/m.css`
+    -   Commit link: :gh:`mosra/m.css@4d362223f107cffd8731a0ea031f9353a0a2c7c4`
+    -   Issue/PR link: :gh:`mosra/magnum#123`
+    -   Tree link: :gh:`mosra/m.css$next`
+    -   Tag link: :gh:`mosra/magnum^snapshot-2015-05`
+    -   File link: :gh:`mosra/m.css$master/css/m-dark.css`
+    -   Arbitrary link: :gh:`mosra/magnum/graphs/contributors`
+    -   :gh:`Link with custom title <getpelican/pelican>`
+
+`OpenGL functions and extensions`_
+==================================
+
+Download the `m/gl.py <{filename}/plugins.rst>`_ file, put it
+including the ``m/`` directory into one of your :py:`PLUGIN_PATHS` and add
+:py:`m.gl` package to your :py:`PLUGINS` in ``pelicanconf.py``:
+
+.. code:: python
+
+    PLUGINS += ['m.gl']
+
+Use the :rst:`:glfn:` interpreted text role for linking to functions,
+:rst:`:glext:` for linking to extensions and :rst:`:glfnext:` for linking to
+extension functions. In the link target the leading ``gl`` prefix of functions
+and the leading ``GL_`` prefix of extensions is prepended automatically.
+
+Link text is equal to full function name including the ``gl`` prefix and
+``()`` for functions, equal to extension name or equal to extension function
+link, including the vendor suffix. For :rst:`:glfn:` and :rst:`:glext:` it's
+possible to specify alternate link text using the well-known syntax.
+
+.. code-figure::
+
+    .. code:: rst
+
+        -   Function link: :glfn:`DispatchCompute`
+        -   Extension link: :glext:`ARB_direct_state_access`
+        -   Extension function link: :glfnext:`SpecializeShader <ARB_gl_spirv>`
+        -   :glfn:`Custom link title <DrawElementsIndirect>`
+
+    -   Function link: :glfn:`DispatchCompute`
+    -   Extension link: :glext:`ARB_direct_state_access`
+    -   Extension function link: :glfnext:`SpecializeShader <ARB_gl_spirv>`
+    -   :glfn:`Custom link title <DrawElementsIndirect>`
+
+`Doxygen documentation`_
+========================
+
+Download the `m/dox.py <{filename}/plugins.rst>`_ file, put it
+including the ``m/`` directory into one of your :py:`PLUGIN_PATHS` and add
+:py:`m.dox` package to your plugins in ``pelicanconf.py``. The plugin uses
+Doxygen tag files to get a list of linkable symbols and you need to provide
+list of 3-tuples containing tag file path, URL prefix and list of implicitly
+prepended namespaces in :py:`DOXYGEN_TAGFILES` configuration to make the plugin
+work. Example configuration:
+
+.. code:: python
+
+    PLUGINS += ['m.dox']
+    DOXYGEN_TAGFILES = [
+        ('doxygen/corrade.tag', 'http://doc.magnum.graphics/corrade/', ['Corrade::']),
+        ('doxygen/magnum.tag', 'http://doc.magnum.graphics/magnum/', ['Magnum::'])]
+
+Use the :rst:`:dox:` interpreted text role for linking to documented symbols.
+All link targets understood by Doxygen's ``@ref`` or ``@link`` commands are
+understood by this plugin as well. In order to save you some typing, the
+leading namespace(s) mentioned in the :py:`DOXYGEN_TAGFILES` setting can be
+omitted when linking to given symbol. If a symbol can't be found, a warning is
+printed to output and the link text is rendered in monospace font.
+
+Link text is equal to link target in all cases. It's possible to specify
+alternate link text using the :rst:`:dox:`link text <link-target>`` syntax.
+
+.. code-figure::
+
+    .. code:: rst
+
+        -   Function link: :dox:`Utility::Directory::mkpath()`
+        -   Class link: :dox:`Interconnect::Emitter`
+        -   Page link: :dox:`building-corrade`
+        -   :dox:`Custom link title <testsuite>`
+
+    -   Function link: :dox:`Utility::Directory::mkpath()`
+    -   Class link: :dox:`Interconnect::Emitter`
+    -   Page link: :dox:`building-corrade`
+    -   :dox:`Custom link title <testsuite>`
+
+`Abbreviations`_
+================
+
+While not exactly a link but rather a way to produce correct :html:`<abbr>`
+elements, it belongs here as it shares a similar syntax.
+
+Download the `m/abbr.py <{filename}/plugins.rst>`_ file, put it
+including the ``m/`` directory into one of your :py:`PLUGIN_PATHS` and add
+:py:`m.abbr` package to your :py:`PLUGINS` in ``pelicanconf.py``. This plugin
+assumes presence of `m.htmlsanity <{filename}/plugins/htmlsanity.rst>`_.
+
+.. code:: python
+
+    PLUGINS += ['m.htmlsanity', 'm.abbr']
+
+The plugin overrides the builtin Pelican
+`abbr interpreted text role <http://docs.getpelican.com/en/stable/content.html#file-metadata>`_
+and makes its syntax consistent with other common roles of :abbr:`reST <reStructuredText>`
+and ``m.css``.
+
+Use the :rst:`:abbr:` interpreted text role for creating abbreviations with
+title in angle brackets:
+
+.. code-figure::
+
+    .. code:: rst
+
+        :abbr:`HTML <HyperText Markup Language>` and :abbr:`CSS <Cascading Style Sheets>`
+        are *all you need* for producing rich content-oriented websites.
+
+    :abbr:`HTML <HyperText Markup Language>` and :abbr:`CSS <Cascading Style Sheets>`
+    are *all you need* for producing rich content-oriented websites.
+
+`File size queries`_
+====================
+
+Okay, this is not a link at all, but --- sometimes you might want to display
+size of a file, for example to tell the users how big the download will be.
+
+Download the `m/filesize.py <{filename}/plugins.rst>`_ file, put it
+including the ``m/`` directory into one of your :py:`PLUGIN_PATHS` and add
+:py:`m.filesize` package to your :py:`PLUGINS` in ``pelicanconf.py``.
+
+.. code:: python
+
+    PLUGINS += ['m.filesize']
+
+Use the :rst:`filesize` interpreted text role to display the size of a file
+including units. The :rst:`filesize-gz` role compresses the file using GZip
+first before calculating the size.
+
+.. code-figure::
+
+    .. code:: rst
+
+        The compiled ``m-dark.compiled.css`` CSS file has
+        :filesize:`{filename}/../css/m-dark.compiled.css` but only
+        :filesize-gz:`{filename}/../css/m-dark.compiled.css` when the server
+        sends it compressed.
+
+    The compiled ``m-dark.compiled.css`` CSS file has
+    :filesize:`{filename}/../css/m-dark.compiled.css` but only
+    :filesize-gz:`{filename}/../css/m-dark.compiled.css` when the server
+    sends it compressed.
+
+.. note-dim::
+    :class: m-text-center
+
+    `« Math and code <{filename}/plugins/math-and-code.rst>`_ | `Pelican plugins <{filename}/plugins.rst>`_
diff --git a/doc/plugins/math-and-code-test.rst b/doc/plugins/math-and-code-test.rst
new file mode 100644 (file)
index 0000000..e85aa72
--- /dev/null
@@ -0,0 +1,18 @@
+Test
+####
+
+:save_as: plugins/math-and-code/test/index.html
+:breadcrumb: {filename}/plugins.rst Pelican plugins
+             {filename}/plugins/math-and-code.rst Math and code
+
+.. role:: tex(code)
+    :language: latex
+
+Properly align *huge* formulas vertically on a line: :math:`\hat q^{-1} = \frac{\hat q^*}{|\hat q|^2}`
+and make sure there's enough space for all the complex :math:`W` things between
+the lines :math:`W = \sum_{i=0}^{n} \frac{w_i}{h_i}` because  :math:`Y = \sum_{i=0}^{n} B`
+
+The :tex:`\\cfrac` thing doesn't align well: :math:`W = \sum_{i=0}^{n} \cfrac{w_i}{h_i}`
+
+Huh, apparently backslashes have to be escaped in things like this:
+:tex:`\frac`
diff --git a/doc/plugins/math-and-code.rst b/doc/plugins/math-and-code.rst
new file mode 100644 (file)
index 0000000..e6cfa21
--- /dev/null
@@ -0,0 +1,179 @@
+Math and code
+#############
+
+:breadcrumb: {filename}/plugins.rst Pelican plugins
+
+.. role:: css(code)
+    :language: css
+.. role:: html(code)
+    :language: html
+.. role:: py(code)
+    :language: py
+.. role:: rst(code)
+    :language: rst
+
+These plugins use external libraries to produce beautiful math and code
+rendering directly from your :abbr:`reST <reStructuredText>` sources.
+
+.. contents::
+    :class: m-block m-default
+
+`Math`_
+=======
+
+Download the `m/math.py and m/latex2svg.py <{filename}/plugins.rst>`_ files,
+put them including the ``m/`` directory into one of your :py:`PLUGIN_PATHS` and
+add :py:`m.math` package to your :py:`PLUGINS` in ``pelicanconf.py``. In
+addition you need some LaTeX distribution and `dvisvgm <http://dvisvgm.bplaced.net/>`_
+installed. This plugin assumes presence of
+`m.htmlsanity <{filename}/plugins/htmlsanity.rst>`_.
+
+.. code:: python
+
+    PLUGINS += ['m.htmlsanity', 'm.math']
+
+The plugin overrides the builtin docutils
+`math directive <http://docutils.sourceforge.net/docs/ref/rst/directives.html#math>`_
+and `math interpreted text role <http://docutils.sourceforge.net/docs/ref/rst/roles.html#math>`_
+and:
+
+-   Instead of relying on MathML or MathJax, uses
+    `latex2svg <https://github.com/tuxu/latex2svg>`_ to convert input LaTeX
+    math formula to a SVG file, which is then embedded directly to the page.
+    All glyphs are converted to paths.
+-   Adds a :html:`<title>` and :html:`<description>` containing the original
+    formula to the generated :html:`<svg>` element for accessibility.
+
+Put `math blocks <{filename}/css/components.rst#math>`_ into the :rst:`.. math::`
+directive; if you want to color the equations, add corresponding
+`CSS class <{filename}/css/components.rst#colors>`_ via a :rst:`:class:`
+option.
+
+.. code-figure::
+
+    .. code:: rst
+
+        .. math::
+            :class: m-success
+
+            \boldsymbol{A} = \begin{pmatrix}
+                \frac{2n}{s_x} & 0 & 0 & 0 \\
+                0 & \frac{2n}{s_y} & 0 & 0 \\
+                0 & 0 & \frac{n + f}{n - f} & \frac{2nf}{n - f} \\
+                0 & 0 & -1 & 0
+            \end{pmatrix}
+
+    .. math::
+        :class: m-success
+
+        \boldsymbol{A} = \begin{pmatrix}
+            \frac{2n}{s_x} & 0 & 0 & 0 \\
+            0 & \frac{2n}{s_y} & 0 & 0 \\
+            0 & 0 & \frac{n + f}{n - f} & \frac{2nf}{n - f} \\
+            0 & 0 & -1 & 0
+        \end{pmatrix}
+
+Inline math can be wrapped in the :rst:`:math:` interpreted text role. If you
+want to add additional CSS classes, derive a custom role from it.
+
+.. code-figure::
+
+    .. code:: rst
+
+        .. role:: math-info(math)
+            :class: m-info
+
+        Quaternion-conjugated dual quaternion is :math-info:`\hat q^* = q_0^* + q_\epsilon^*`,
+        while dual-conjugation gives :math:`\overline{\hat q} = q_0 - \epsilon q_\epsilon`.
+
+    .. role:: math-info(math)
+        :class: m-info
+
+    Quaternion-conjugated dual quaternion is :math-info:`\hat q^* = q_0^* + q_\epsilon^*`,
+    while dual-conjugation gives :math:`\overline{\hat q} = q_0 - \epsilon q_\epsilon`.
+
+`Code`_
+=======
+
+Download the `m/code.py <{filename}/plugins.rst>`_ file, put it including the
+``m/`` directory into one of your :py:`PLUGIN_PATHS` and add :py:`m.code`
+package to your :py:`PLUGINS` in ``pelicanconf.py``. In addition you need to
+have `Pygments <http://pygments.org>`_ installed. This plugin assumes presence
+of `m.htmlsanity <{filename}/plugins/htmlsanity.rst>`_.
+
+.. code:: python
+
+    PLUGINS += ['m-htmlsanity', 'm.code']
+
+The plugin overrides the builtin docutils
+`code directive <http://docutils.sourceforge.net/docs/ref/rst/directives.html#code>`_
+and `code interpreted text role <http://docutils.sourceforge.net/docs/ref/rst/roles.html#code>`_,
+replaces `Pelican code-block directive <http://docs.getpelican.com/en/3.6.3/content.html#syntax-highlighting>`_ and:
+
+-   Wraps Pygments output in :html:`<code>` element for inline code and
+    :html:`<pre>` element for code blocks with :css:`.m-code` CSS class
+    applied.
+-   Removes useless CSS classes from the output.
+
+Put `code blocks <{filename}/css/components.rst#code>`_ into the :rst:`.. code::`
+directive and specify the language via a parameter. Use :rst:`:hl_lines:`
+option to highlight lines; if you want to add additional CSS classes, use the
+:rst:`:class:` option.
+
+.. code-figure::
+
+    .. code:: rst
+
+        .. code:: c++
+            :hl_lines: 4 5
+            :class: m-inverted
+
+            #include <iostream>
+
+            int main() {
+                std::cout << "Hello world!" << std::endl;
+                return 0;
+            }
+
+    .. code:: c++
+        :hl_lines: 4 5
+        :class: m-inverted
+
+        #include <iostream>
+
+        int main() {
+            std::cout << "Hello world!" << std::endl;
+            return 0;
+        }
+
+For inline code highlighting, use :rst:`:code:` interpreted text role. To
+specify which language should be highlighted, derive a custom role from it:
+
+.. code-figure::
+
+    .. code:: rst
+
+        .. role:: cmake(code)
+            :language: cmake
+
+        .. role:: cpp(code)
+            :language: cpp
+
+        With the :cmake:`add_executable(foo bar.cpp)` CMake command you can create an
+        executable from a file that contains just :cpp:`int main() { return 666; }` and
+        nothing else.
+
+    .. role:: cmake(code)
+        :language: cmake
+
+    .. role:: cpp(code)
+        :language: cpp
+
+    With the :cmake:`add_executable(foo bar.cpp)` CMake command you can create
+    an executable from a file that contains just :cpp:`int main() { return 666; }`
+    and nothing else.
+
+.. note-dim::
+    :class: m-text-center
+
+    `« Images <{filename}/plugins/images.rst>`_ | `Pelican plugins <{filename}/plugins.rst>`_ | `Links » <{filename}/plugins/links.rst>`_
diff --git a/doc/static/dummy.css b/doc/static/dummy.css
new file mode 100644 (file)
index 0000000..8b13789
--- /dev/null
@@ -0,0 +1 @@
+
diff --git a/doc/static/flowers-small.jpg b/doc/static/flowers-small.jpg
new file mode 100644 (file)
index 0000000..0fda5eb
Binary files /dev/null and b/doc/static/flowers-small.jpg differ
diff --git a/doc/static/flowers.jpg b/doc/static/flowers.jpg
new file mode 100644 (file)
index 0000000..fe2c6a8
Binary files /dev/null and b/doc/static/flowers.jpg differ
diff --git a/doc/static/ship-small.jpg b/doc/static/ship-small.jpg
new file mode 100644 (file)
index 0000000..e78120d
Binary files /dev/null and b/doc/static/ship-small.jpg differ
diff --git a/doc/static/ship.jpg b/doc/static/ship.jpg
new file mode 100644 (file)
index 0000000..47fe78c
Binary files /dev/null and b/doc/static/ship.jpg differ
diff --git a/doc/why.rst b/doc/why.rst
new file mode 100644 (file)
index 0000000..cecd1e9
--- /dev/null
@@ -0,0 +1,101 @@
+Why?
+####
+
+Let's start with some history. Back in 2002, when I star---
+
+Eh, everybody already heard this. Old man yells at cloud. Complaining that
+before a webpage had 50 kB, now it has 5 MB, still taking *ten seconds* to
+load, even though the connections are hundreds times faster. But why is that?
+Because *nobody cares*.
+
+I am a GPU developer. My usual Mondays are about having a handful of
+milliseconds to do complex image processing in real time. So I am furious if a
+page that presents mainly *text* takes *seconds* to appear on my screen. And I
+would despise myself for presenting GPU-related content using such tools. So I
+made this thing. This thing has no JavaScript, just a few kilobytes of pure CSS
+and is meant to be used with static site generators.
+
+.. note-danger:: Warning: opinions
+
+    This page presents my opinions. Not everybody likes my opinions.
+
+Why no JavaScript?
+==================
+
+Responsive page layout? Yes! Popup menus? Check! Expanding hamburger
+navigation? Sure! With pure CSS features, supported *for years* by all
+browsers. The goal of this framework is presenting *content* in the most
+unobtrusive and lightweight way possible --- if you are looking for something
+that would display a spinner while *the megabytes* are loading, something that
+can open a "SIGN UP" popup on page load or interrupt the reading experience
+with a noisy full-page ad every once a while, this is not what you are looking
+for.
+
+.. note-info::
+
+    Well, while ``m.css`` itself doesn't *need* JavaScript, it doesn't prevent
+    you from using it -- put in as many jQueries as you want.
+
+Why no CSS preprocessors?
+=========================
+
+The stylesheets consist of only `three files <{filename}/css.rst>`_, written in
+pure CSS. No CSS preprocessor needed --- in my experience the main reason for a
+preprocessor was an ability to use variables, but that's implemented in CSS
+itself with universal support across browsers, so why bother? Besides that, the
+files are so small that there's no need for any minification --- server-side
+compression is simply good enough.
+
+.. note-dim::
+
+    Actually, in order to support old Edge versions and IE, I *had to* create a
+    *post*\ processed versions of the CSS files. But that still doesn't prevent
+    you from using pure CSS.
+
+Why a static site generator?
+============================
+
+If you are like me, you want a website that presents your main work, not that
+your main work is presenting websites. So remove the unneeded hassle of paying
+extra for a dynamic webhosting, installing and maintaining a huge CMS and
+patching it twice a month for a neverending stream new CVEs. Together with
+`Pelican <{filename}/pelican.rst>`_, ``m.css`` provides a solution harnessing
+the endless possibilities of your local machine to generate a bunch of static
+HTML files, which you can then upload *anywhere*. And as a bonus, you have the
+full control over your content --- nothing's hidden in opaque databases.
+
+.. note-success::
+
+    This is all optional, though --- ``m.css`` can work with a dynamic CMS
+    below as well. Or with your hand-written HTML. Not sure about WYSIWYG
+    editors, tho.
+
+Why Pelican and not Jekyll or ...?
+==================================
+
+I *love* Python and while I'm probably not very good at it (having spent over a
+decade writing purely C++), I wanted to finally put it into practical use,
+instead of learning a completely new language. There I also discovered
+reStructuredText, which, compared to various flavors of Markdown, is very well
+thought out, amazingly flexible and easily extensible to support
+`everything I need <{filename}/plugins.rst>`_.
+
+.. note-warning::
+
+    By all means, use Jekyll or Hugo, if you want --- but I can't promise that
+    all the :abbr:`reST <reStructuredText>` extensions I did are transferrable
+    elsewhere.
+
+Why the name?
+=============
+
+To underline that this project is driven by a need for a simple, tiny,
+nameless low-maintenance thing to power my websites. That my focus is on
+presenting content with it, not on shifting my career back to web development
+to flesh this thing out to be the Greatest Web Framework Ever™.
+
+.. note-primary::
+
+    Contributions welcome, though! Does it look like I'm not putting enough
+    effort in? Submit an improvement! Make a difference
+    :gh:`over at GitHub <mosra/m.css/issues/new>`.
diff --git a/site/.gitignore b/site/.gitignore
new file mode 100644 (file)
index 0000000..ee56e81
--- /dev/null
@@ -0,0 +1,4 @@
+__pycache__
+*.pid
+output
+published
diff --git a/site/Makefile b/site/Makefile
new file mode 100644 (file)
index 0000000..5f9b820
--- /dev/null
@@ -0,0 +1,124 @@
+PY?=python3
+PELICAN?=pelican
+PELICANOPTS=
+
+BASEDIR=$(CURDIR)
+INPUTDIR=$(BASEDIR)/content
+OUTPUTDIR=$(BASEDIR)/output
+CONFFILE=$(BASEDIR)/pelicanconf.py
+PUBLISHCONF=$(BASEDIR)/publishconf.py
+
+FTP_HOST=localhost
+FTP_USER=anonymous
+FTP_TARGET_DIR=/
+
+SSH_HOST=localhost
+SSH_PORT=22
+SSH_USER=root
+SSH_TARGET_DIR=/var/www
+
+S3_BUCKET=my_s3_bucket
+
+CLOUDFILES_USERNAME=my_rackspace_username
+CLOUDFILES_API_KEY=my_rackspace_api_key
+CLOUDFILES_CONTAINER=my_cloudfiles_container
+
+DROPBOX_DIR=~/Dropbox/Public/
+
+GITHUB_PAGES_BRANCH=gh-pages
+
+DEBUG ?= 0
+ifeq ($(DEBUG), 1)
+       PELICANOPTS += -D
+endif
+
+RELATIVE ?= 0
+ifeq ($(RELATIVE), 1)
+       PELICANOPTS += --relative-urls
+endif
+
+help:
+       @echo 'Makefile for a pelican Web site                                           '
+       @echo '                                                                          '
+       @echo 'Usage:                                                                    '
+       @echo '   make html                           (re)generate the web site          '
+       @echo '   make clean                          remove the generated files         '
+       @echo '   make regenerate                     regenerate files upon modification '
+       @echo '   make publish                        generate using production settings '
+       @echo '   make serve [PORT=8000]              serve site at http://localhost:8000'
+       @echo '   make serve-global [SERVER=0.0.0.0]  serve (as root) to $(SERVER):80    '
+       @echo '   make devserver [PORT=8000]          start/restart develop_server.sh    '
+       @echo '   make stopserver                     stop local server                  '
+       @echo '   make ssh_upload                     upload the web site via SSH        '
+       @echo '   make rsync_upload                   upload the web site via rsync+ssh  '
+       @echo '   make dropbox_upload                 upload the web site via Dropbox    '
+       @echo '   make ftp_upload                     upload the web site via FTP        '
+       @echo '   make s3_upload                      upload the web site via S3         '
+       @echo '   make cf_upload                      upload the web site via Cloud Files'
+       @echo '   make github                         upload the web site via gh-pages   '
+       @echo '                                                                          '
+       @echo 'Set the DEBUG variable to 1 to enable debugging, e.g. make DEBUG=1 html   '
+       @echo 'Set the RELATIVE variable to 1 to enable relative urls                    '
+       @echo '                                                                          '
+
+html:
+       $(PELICAN) $(INPUTDIR) -o $(OUTPUTDIR) -s $(CONFFILE) $(PELICANOPTS)
+
+clean:
+       [ ! -d $(OUTPUTDIR) ] || rm -rf $(OUTPUTDIR)
+
+regenerate:
+       $(PELICAN) -r $(INPUTDIR) -o $(OUTPUTDIR) -s $(CONFFILE) $(PELICANOPTS)
+
+serve:
+ifdef PORT
+       cd $(OUTPUTDIR) && $(PY) -m pelican.server $(PORT)
+else
+       cd $(OUTPUTDIR) && $(PY) -m pelican.server
+endif
+
+serve-global:
+ifdef SERVER
+       cd $(OUTPUTDIR) && $(PY) -m pelican.server 80 $(SERVER)
+else
+       cd $(OUTPUTDIR) && $(PY) -m pelican.server 80 0.0.0.0
+endif
+
+
+devserver:
+ifdef PORT
+       $(BASEDIR)/develop_server.sh restart $(PORT)
+else
+       $(BASEDIR)/develop_server.sh restart
+endif
+
+stopserver:
+       $(BASEDIR)/develop_server.sh stop
+       @echo 'Stopped Pelican and SimpleHTTPServer processes running in background.'
+
+publish:
+       $(PELICAN) $(INPUTDIR) -s $(PUBLISHCONF) $(PELICANOPTS)
+
+ssh_upload: publish
+       scp -P $(SSH_PORT) -r $(OUTPUTDIR)/* $(SSH_USER)@$(SSH_HOST):$(SSH_TARGET_DIR)
+
+rsync_upload: publish
+       rsync -e "ssh -p $(SSH_PORT)" -P -rvzc --delete $(OUTPUTDIR)/ $(SSH_USER)@$(SSH_HOST):$(SSH_TARGET_DIR) --cvs-exclude
+
+dropbox_upload: publish
+       cp -r $(OUTPUTDIR)/* $(DROPBOX_DIR)
+
+ftp_upload: publish
+       lftp ftp://$(FTP_USER)@$(FTP_HOST) -e "mirror -R $(OUTPUTDIR) $(FTP_TARGET_DIR) ; quit"
+
+s3_upload: publish
+       s3cmd sync $(OUTPUTDIR)/ s3://$(S3_BUCKET) --acl-public --delete-removed --guess-mime-type --no-mime-magic --no-preserve
+
+cf_upload: publish
+       cd $(OUTPUTDIR) && swift -v -A https://auth.api.rackspacecloud.com/v1.0 -U $(CLOUDFILES_USERNAME) -K $(CLOUDFILES_API_KEY) upload -c $(CLOUDFILES_CONTAINER) .
+
+github: publish
+       ghp-import -m "Generate Pelican site" -b $(GITHUB_PAGES_BRANCH) $(OUTPUTDIR)
+       git push origin $(GITHUB_PAGES_BRANCH)
+
+.PHONY: html help clean regenerate serve serve-global devserver stopserver publish ssh_upload rsync_upload dropbox_upload ftp_upload s3_upload cf_upload github
diff --git a/site/content b/site/content
new file mode 120000 (symlink)
index 0000000..f430755
--- /dev/null
@@ -0,0 +1 @@
+../doc/
\ No newline at end of file
diff --git a/site/develop_server.sh b/site/develop_server.sh
new file mode 100755 (executable)
index 0000000..4721d64
--- /dev/null
@@ -0,0 +1,103 @@
+#!/usr/bin/env bash
+##
+# This section should match your Makefile
+##
+PY=${PY:-python3}
+PELICAN=${PELICAN:-pelican}
+PELICANOPTS=
+
+BASEDIR=$(pwd)
+INPUTDIR=$BASEDIR/content
+OUTPUTDIR=$BASEDIR/output
+CONFFILE=$BASEDIR/pelicanconf.py
+
+###
+# Don't change stuff below here unless you are sure
+###
+
+SRV_PID=$BASEDIR/srv.pid
+PELICAN_PID=$BASEDIR/pelican.pid
+
+function usage(){
+  echo "usage: $0 (stop) (start) (restart) [port]"
+  echo "This starts Pelican in debug and reload mode and then launches"
+  echo "an HTTP server to help site development. It doesn't read"
+  echo "your Pelican settings, so if you edit any paths in your Makefile"
+  echo "you will need to edit your settings as well."
+  exit 3
+}
+
+function alive() {
+  kill -0 $1 >/dev/null 2>&1
+}
+
+function shut_down(){
+  PID=$(cat $SRV_PID)
+  if [[ $? -eq 0 ]]; then
+    if alive $PID; then
+      echo "Stopping HTTP server"
+      kill $PID
+    else
+      echo "Stale PID, deleting"
+    fi
+    rm $SRV_PID
+  else
+    echo "HTTP server PIDFile not found"
+  fi
+
+  PID=$(cat $PELICAN_PID)
+  if [[ $? -eq 0 ]]; then
+    if alive $PID; then
+      echo "Killing Pelican"
+      kill $PID
+    else
+      echo "Stale PID, deleting"
+    fi
+    rm $PELICAN_PID
+  else
+    echo "Pelican PIDFile not found"
+  fi
+}
+
+function start_up(){
+  local port=$1
+  echo "Starting up Pelican and HTTP server"
+  shift
+  $PELICAN --debug --autoreload -r $INPUTDIR -o $OUTPUTDIR -s $CONFFILE $PELICANOPTS &
+  pelican_pid=$!
+  echo $pelican_pid > $PELICAN_PID
+  mkdir -p $OUTPUTDIR && cd $OUTPUTDIR
+  $PY -m pelican.server $port &
+  srv_pid=$!
+  echo $srv_pid > $SRV_PID
+  cd $BASEDIR
+  sleep 1
+  if ! alive $pelican_pid ; then
+    echo "Pelican didn't start. Is the Pelican package installed?"
+    return 1
+  elif ! alive $srv_pid ; then
+    echo "The HTTP server didn't start. Is there another service using port" $port "?"
+    return 1
+  fi
+  echo 'Pelican and HTTP server processes now running in background.'
+}
+
+###
+#  MAIN
+###
+[[ ($# -eq 0) || ($# -gt 2) ]] && usage
+port=''
+[[ $# -eq 2 ]] && port=$2
+
+if [[ $1 == "stop" ]]; then
+  shut_down
+elif [[ $1 == "restart" ]]; then
+  shut_down
+  start_up $port
+elif [[ $1 == "start" ]]; then
+  if ! start_up $port; then
+    shut_down
+  fi
+else
+  usage
+fi
diff --git a/site/pelicanconf.py b/site/pelicanconf.py
new file mode 100644 (file)
index 0000000..0012ff2
--- /dev/null
@@ -0,0 +1,127 @@
+AUTHOR = 'Vladimír Vondruš'
+
+SITE_LOGO_TEXT = 'm.css'
+
+SITENAME = 'm.css'
+SITEURL = ''
+STATIC_URL = '/{path}'
+
+PATH = 'content'
+ARTICLE_PATHS = ['examples']
+PAGE_PATHS = ['']
+
+TIMEZONE = 'Europe/Prague'
+
+DEFAULT_LANG = 'en'
+DATE_FORMATS = {'en': ('en_US', '%b %d %Y')}
+
+# Feed generation is usually not desired when developing
+FEED_ATOM = None
+FEED_ALL_ATOM = None
+CATEGORY_FEED_ATOM = None
+TRANSLATION_FEED_ATOM = None
+AUTHOR_FEED_ATOM = None
+AUTHOR_FEED_RSS = None
+
+LINKS_NAVBAR1 = [('Why?', '/why/', 'why', []),
+                 ('CSS', '/css/', 'css', [
+                    ('Grid system', '/css/grid/', 'css/grid'),
+                    ('Typography', '/css/typography/', 'css/typography'),
+                    ('Components', '/css/components/', 'css/components'),
+                    ('Page layout', '/css/page-layout/', 'css/page-layout'),
+                    ('Themes', '/css/themes/', 'css/themes')]),
+                 ('Pelican', '/pelican/', 'pelican', [
+                    ('Writing content', '/pelican/writing-content/', 'pelican/writing-content'),
+                    ('Theme', '/pelican/theme/', 'pelican/theme')])]
+
+LINKS_NAVBAR2 = [('Pelican plugins', '/plugins/', 'plugins', [
+                    ('HTML sanity', '/plugins/htmlsanity/', 'plugins/htmlsanity'),
+                    ('Components', '/plugins/components/', 'plugins/components'),
+                    ('Images', '/plugins/images/', 'plugins/images'),
+                    ('Math and code', '/plugins/math-and-code/', 'plugins/math-and-code'),
+                    ('Links', '/plugins/links/', 'plugins/links')]),
+                 ('GitHub', 'https://github.com/mosra/m.css', '', [])]
+
+LINKS_FOOTER1 = [('m.css', '/'),
+                 ('Why?', '/why/'),
+                 ('GitHub', 'https://github.com/mosra/m.css'),
+                 ('Twitter', 'https://twitter.com/czmosra')]
+
+LINKS_FOOTER2 = [('CSS', '/css/'),
+                 ('Grid system', '/css/grid/'),
+                 ('Typography', '/css/typography/'),
+                 ('Components', '/css/components/'),
+                 ('Page layout', '/css/page-layout/'),
+                 ('Themes', '/css/themes/')]
+
+LINKS_FOOTER3 = [('Pelican', '/pelican/'),
+                 ('Writing content', '/pelican/writing-content/'),
+                 ('Theme', '/pelican/theme/')]
+
+LINKS_FOOTER4 = [('Pelican plugins', '/plugins/'),
+                 ('HTML sanity', '/plugins/htmlsanity/'),
+                 ('Components', '/plugins/components/'),
+                 ('Images', '/plugins/images/'),
+                 ('Math and code', '/plugins/math-and-code/'),
+                 ('Links', '/plugins/links/')]
+
+FINE_PRINT = """
+m.css. Copyright © Vladimír Vondruš 2017. Site powered by Pelican and ``m.css``
+(yes, I am eating my own dog food). Contact the author via
+`e-mail <mosra@centrum.cz>`_, :abbr:`Jabber <mosra@jabbim.cz>`,
+`Twitter <https://twitter.com/czmosra>`_ or smoke signals.
+"""
+
+DEFAULT_PAGINATION = 10
+
+STATIC_PATHS = ['static']
+
+PLUGIN_PATHS = ['../pelican-plugins']
+PLUGINS = ['m.abbr',
+           'm.code',
+           'm.components',
+           'm.dox',
+           'm.filesize',
+           'm.gl',
+           'm.gh',
+           'm.htmlsanity',
+           'm.images',
+           'm.math']
+
+THEME = '../pelican-theme'
+THEME_STATIC_DIR = 'static'
+THEME_COLOR = '#22272e'
+CSS_FILES = ['https://fonts.googleapis.com/css?family=Source+Code+Pro:400,400i,600%7CSource+Sans+Pro:400,400i,600&amp;subset=latin-ext',
+             STATIC_URL.format(path='static/m-dark.css'),
+             #STATIC_URL.format(path='static/m-debug.css')
+             ]
+#CSS_FILES = ['https://fonts.googleapis.com/css?family=Libre+Baskerville:400,400i,700%7CSource+Code+Pro:400,400i,600',
+             #STATIC_URL.format(path='static/m-light.css')]
+
+FORMATTED_FIELDS = ['summary', 'landing']
+
+HTMLSANITY_SMART_QUOTES = True
+HTMLSANITY_HYPHENATION = True
+
+DOXYGEN_TAGFILES = [
+    ('../doc/doxygen/corrade.tag', 'http://doc.magnum.graphics/corrade/', ['Corrade::'])]
+
+DIRECT_TEMPLATES = []
+
+PAGE_URL = '/{slug}/'
+PAGE_SAVE_AS = '{slug}/index.html'
+ARTICLE_URL = '/{category}/{slug}/'
+ARTICLE_SAVE_AS = '{category}/{slug}/index.html'
+AUTHOR_URL = '/author/{slug}/'
+AUTHOR_SAVE_AS = 'author/{slug}/index.html'
+CATEGORY_URL = '/{slug}/'
+CATEGORY_SAVE_AS = '{slug}/index.html'
+TAG_URL = '/tag/{slug}/'
+TAG_SAVE_AS = 'tag/{slug}/index.html'
+
+AUTHORS_SAVE_AS = None # Not used
+CATEGORIES_SAVE_AS = None # Not used
+TAGS_SAVE_AS = None # Not used
+
+SLUGIFY_SOURCE = 'basename'
+PATH_METADATA = '(?P<slug>.+).rst'
diff --git a/site/publishconf.py b/site/publishconf.py
new file mode 100644 (file)
index 0000000..cbe85e9
--- /dev/null
@@ -0,0 +1,17 @@
+#!/usr/bin/env python
+
+import os
+import sys
+sys.path.append(os.curdir)
+from pelicanconf import *
+
+SITEURL = 'http://mcss.mosra.cz'
+
+OUTPUT_PATH = 'published/'
+DELETE_OUTPUT_DIRECTORY = True
+
+CSS_FILES = ['https://fonts.googleapis.com/css?family=Source+Code+Pro:400,400i,600%7CSource+Sans+Pro:400,400i,600&amp;subset=latin-ext',
+             STATIC_URL.format(path='static/m-dark.compiled.css')]
+
+PAGE_URL = 'http://mcss.mosra.cz/{slug}/'
+ARTICLE_URL = 'http://mcss.mosra.cz/{category}/{slug}/'