Cecil logo Cecil
What's on this page

Markdown

Cecil supports Markdown format, but also Markdown Extra.

Cecil also provides extra features to enhance your content, see below.

Attributes

With Markdown Extra you can set an id, class and custom attributes on certain elements using an attribute block.
For instance, put the desired attribute(s) after a heading, a fenced code block, a link or an image at the end of the line inside curly brackets, like this:

## Header {#id .class attribute=value}

You can create a link with the syntax [Text](url), where url can be a path, a relative path to a Markdown file, an external URL, etc.

Example:

[Link to a path](/about/)
[Link to a Markdown file](about.md)
[Link to Cecil website](https://cecil.app)

You can easily create a link to a page with the syntax [Page title](page:page-id).

Example:

[Link to a blog post](page:blog/post-1)

External

By default external links have the following value for rel attribute: noopener noreferrer.

Example:

<a href="<url>" rel="noopener noreferrer">Link to another website</a>

You can change this behavior with pages.body.links.external options.

Cecil can try to turn a link into embedded content by using the {embed} attribute or by setting the global configuration option pages.body.links.embed.enabled to true.

Example:

[CECIL : LE générateur de SITES STATIQUES en PHP](https://www.youtube.com/watch?v=ur8koU0iYvc){embed}

Local video/audio files

Cecil can also create <video> and <audio> HTML elements, based on the file extension (mp4 and webm for video, mp3, ogg and wav for audio, see pages.body.links.embed).

Example:

[Video file](video.mp4){embed controls poster=/images/video-test.png}
[Audio file](song.mp3){embed controls}

Is converted to:

<video src="/video.mp4" controls poster="/images/video-test.png" style="max-width:100%;height:auto;background-color:#d8d8d8;"></video>
<audio src="/song.mp3" controls></audio>

With {embed=false} (or when embedding is disabled), a local video/audio file stays a link, but its URL points to the published file (fingerprinted if assets.fingerprint is enabled).

Images

To add an image, use an exclamation mark (!) followed by an alternative description in brackets ([]), and the path or URL to the image in parentheses (()).
You can optionally add a title in quotation marks.

![Alternative description](/image.jpg "Image title")

Lazy loading

Cecil adds the attribute loading="lazy" to each image.

Example:

![](/image.jpg)

Is converted to:

<img src="/image.jpg" loading="lazy">

Decoding

Cecil adds the attribute decoding="async" to each image.

Example:

![](/image.jpg)

Is converted to:

<img src="/image.jpg" decoding="async">

Resize

Each image in the body can be resized automatically by setting a smaller width than the original one, with the extra attribute {width=X}.

Example:

![](/image.jpg){width=800}

Is converted to:

<img src="/thumbnails/800/image.jpg" width="800" height="600">

Formats

If the formats option is defined, alternative images are created and added.

Example:

![](/image.jpg)

Could be converted to:

<picture>
  <source srcset="/image.avif" type="image/avif">
  <source srcset="/image.webp" type="image/webp">
  <img src="/image.jpg">
</picture>

Responsive

If the responsive option is enabled, then all images in the body will be made responsive automatically.

Example:

![](/image.jpg){width=800}

will be converted to:

<img src="/thumbnails/800/image.jpg" width="800" height="600"
  srcset="/thumbnails/480/image.jpg 480w,
          /thumbnails/640/image.jpg 640w,
          /thumbnails/768/image.jpg 768w,
          /thumbnails/800/image.jpg 800w"
  sizes="100vw"
>

The sizes attribute takes the value of the assets.images.responsive.sizes.default configuration option, but it can be changed by creating a new entry named after a class added to the image.

Example:

assets:
  images:
    responsive:
      sizes:
        default: 100vw
        my_class: "(max-width: 800px) 768px, 1024px"
![](/image.jpg){.my_class}

CSS class

You can set a default value to the class attribute of each image with the class option.

Caption

The optional title can be used to create a caption (figcaption) automatically by enabling the caption option.

Example:

![](/image.jpg "Title")

Is converted to:

<figure>
  <img src="/image.jpg" title="Title">
  <figcaption>Title</figcaption>
</figure>

Localized image

For translated pages, Cecil first looks for a language-suffixed file when resolving Markdown image paths.

Example:

![](/images/cecil-logo.png)

With a French page (fr), Cecil tries /images/cecil-logo.fr.png first, then falls back to /images/cecil-logo.png.

Dark and mobile variants

If the dark_suffix option is defined (e.g.: .dark), Cecil looks for a dark variant of each image (e.g.: image.dark.jpg alongside image.jpg) and adds it as a <source media="(prefers-color-scheme: dark)"> in a <picture> element.

In the same way, if the mobile_suffix option is defined (e.g.: .mobile), Cecil looks for a mobile variant of each image (e.g.: image.mobile.jpg) and adds it as a <source> with the mobile_media_query media query.

Placeholder

As images are typically heavier and slower resources, and they don’t block rendering, we should attempt to give users something to look at while they wait for the image to arrive.

The placeholder attribute accepts two options:

  1. color: display a colored background (based on image dominant color)
  2. lqip: Low-Quality Image Placeholder

Examples:

![](/images/img.jpg){placeholder=color}
![](/images/img.jpg){placeholder=lqip}

Heading anchors

An anchor link is added at the end of h2 and h3 headings (see the pages.body.anchors option), to link to a heading of a page:

<h2 id="heading">Heading<a class="heading-anchor" href="#heading" aria-hidden="true" tabindex="-1"></a></h2>

The link is empty: the default templates display a # on hover.

Table of contents

You can add a table of contents with the following Markdown syntax:

[toc]

Excerpt

An excerpt can be defined in the body with one of the following HTML comments: <!-- excerpt --> or <!-- break --> (see the pages.body.excerpt option).

Example:

Introduction.
<!-- excerpt -->
Main content.

Then use the excerpt_html filter in your template.

Notes

Create a Note block (info, tip, important, etc.).

Example:

:::tip
**Tip:** This is advice.
:::

Is converted to:

<aside class="note note-tip">
  <p>
    <strong>Tip:</strong> This is advice.
  </p>
</aside>

Other examples:

Nested notes

A note is closed by a line made of at least as many : as its opening line: to nest notes, use a longer fence for the parent note (::::, then ::::: for a third level, etc.).

::::info
Before.

:::tip
**Tip:** This is advice.
:::

After.
::::

A longer fence also lets you show the note syntax in a code block, inside a note.

Templates

A note is rendered with the partials/notes/<type>.html.twig template, if it exists (in the site layouts/, in a theme or built-in), instead of the <aside> element.

Cecil provides templates for the following types, rendered without JavaScript: a theme can style them, override them and add interactivity. Unlike other notes, their root element is a <div class="note note-<type>"> (not an <aside>), as their content is part of the main content.

Type Items Rendering
tabs one per #### heading stacked panels (<section class="note-tab">)
code-group one per #### heading, or one per code block (titled with its language) same as tabs
steps one per #### heading ordered list (<ol class="note-steps-list">)
accordion one per #### heading <details class="note-accordion-item">
cards one per list entry (a leading link is the card title), or per #### heading list (<ul class="note-cards-list">)

The examples below are themselves nested notes: a tabs note (with a :::: fence) shows the Markdown source and its rendering.

Tabs

Alternative contents, one per #### heading (e.g.: per operating system).

Markdown

:::tabs
#### macOS and Linux

```bash
brew install cecilapp/tap/cecil
```

#### Windows

```bash
scoop install https://cecil.app/scoop/cecil.json
```
:::

Result

macOS and Linux

brew install cecilapp/tap/cecil

Windows

scoop install https://cecil.app/scoop/cecil.json

Code group

Like tabs, with code blocks only: without heading, each code block is titled with its language.

Markdown

:::code-group
```bash
curl -LO https://cecil.app/cecil.phar
```

```powershell
Invoke-WebRequest https://cecil.app/cecil.phar -OutFile cecil.phar
```
:::

Result

bash

curl -LO https://cecil.app/cecil.phar

powershell

Invoke-WebRequest https://cecil.app/cecil.phar -OutFile cecil.phar

Steps

A numbered procedure, one step per #### heading.

Markdown

:::steps
#### Create a site

```bash
php cecil.phar new:site
```

#### Preview it

```bash
php cecil.phar serve
```
:::

Result

  1. Create a site

    php cecil.phar new:site
  2. Preview it

    php cecil.phar serve

Accordion

Collapsible items, one per #### heading (e.g.: a FAQ).

Markdown

:::accordion
#### Is PHP required?

No: the standalone binary embeds PHP.

#### Where is the generated site?

In the `_site` directory.
:::

Result

Is PHP required?

No: the standalone binary embeds PHP.

Where is the generated site?

In the _site directory.

Cards

Links to other pages, one card per list entry: a leading link is the card title.

Markdown

:::cards
- [Installation](../getting-started/2-installation.md): download and install Cecil.
- [Configuration](../configuration/index.md): configure your site.
:::

Result

Custom template

The template receives a note variable:

  • note.type: note type (e.g.: tabs)
  • note.id: unique ID in the page (e.g.: note-tabs-1)
  • note.content: HTML of the whole note
  • note.intro: HTML of the content before the first #### heading
  • note.items: list of items, each with:
    • title: title (HTML)
    • heading: heading element (HTML), with its id attribute
    • id: heading ID, if any
    • link: leading link element (HTML) of a list entry
    • url: leading link URL of a list entry
    • language: language of a code block
    • content: content (HTML)

To override the rendering of a note type, create the template in your site (or theme), for example layouts/partials/notes/tip.html.twig:

<div class="callout callout-{{ note.type }}">
  {{ note.content|raw }}
</div>

Syntax highlight

Code block syntax highlighting is enabled by default with the pages.body.highlight option.

If needed, you can disable it with:

pages:
  body:
    highlight: false

Example:

```php
echo "Hello world";
```

Is rendered to:

echo "Hello world";

The language of a code block is added to the data-lang attribute of the <pre> element (e.g.: <pre data-lang="php">): the default templates display it as a label.

Inserted text

Represents a range of text that has been added.

++text++

Is converted to:

<ins>text</ins>