Inline CSS with Pandoc
Asked Answered
I

4

18

I apologize if a simple way to this programmatically (not by copying/pasting in a browser field and clicking a button to convert) is documented somewhere. In my searches and reading I cannot find it.

I would like to programmatically turn a Markdown and CSS file into what sounds like may be called "inline" CSS.For example:

This Markdown file (file.md)

# Install
Install instructions

## Update
Update instructions

This CSS file (style.css)

h1 {
    font-size: 100px;
}

h2 {
    color: red;
}

Becomes this (file.html)

<h1 style="font-size: 100px;"><a id="install"></a>Install</h1>
<p>Install instructions</p>
<h2 style="color: red;"><a id="update"><a>Update</h2>
<p>Update instructions</p>

I am transforming the Markdown to HTML with Pandoc

pandoc -f markdown -t html file.md -o file.html

When I use

pandoc -f markdown -t html file.md -o file.html --css=style.css --self-contained

(or --standalone)

It returns

    <!DOCTYPE html>
    <html xmlns="http://www.w3.org/1999/xhtml" lang xml:lang>
    <head>
      <meta charset="utf-8" />
      <meta name="generator" content="pandoc" />
      <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
      <title>file</title>
      <style type="text/css">
          code{white-space: pre-wrap;}
          span.smallcaps{font-variant: small-caps;}
          span.underline{text-decoration: underline;}
          div.column{display: inline-block; vertical-align: top; width: 50%;}
      </style>
      <style type="text/css">h1 {font-size: 100px;}h2 {color: red;}</style>
      <!--[if lt IE 9]>
        <script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv-printshiv.min.js"></script>
      <![endif]-->
    </head>
    <body>
      <h1><a id="install"></a>Install</h1>
      <p>Install instructions</p>
      <h2><a id="update"><a>Update</h2>
      <p>Update instructions</p>
    </body>
    </html>

As mentioned above this is not my goal. I would like the CSS to be strictly "inline":

<h1 style="font-size: 100px;"><a id="install"></a>Install</h1>

Is anyone aware of a tool or script already written than can programmatically achieve this? I have searched and come up empty. Ideally I could use Pandoc for this, but I cannot discover a way.

I do not care if the <head> and <style> blocks of the HTML exist or not. This HTML will be sent via cURL to a content-management system that strips out all HTML elements except the contents inside <body> and any "inline" CSS.

Thank you for any thoughts or pointing me in a direction.

Instil answered 21/2, 2019 at 22:0 Comment(3)
Does your CMS also strip out <style> tags within body? The styles don't have to be in the header, placing CSS within <body> still results in valid HTML.Hemeralopia
you should probably reconfigure your CMS... inline styles are really not good practice...Collocate
@Hemeralopia I did not know this. I will try this method. Thank you.Instil
G
4

I had a similar scenario and found premailer. Install with pip install premailer and use as python3 -m premailer -f INPUT.html -o OUT.html.

Credit: https://qiita.com/kimagure/items/6820e2df2a7604047862

Gareri answered 29/1, 2020 at 11:20 Comment(0)
M
22

EDIT 2023/03/24: The --self-contained flag is now depreciated - pandoc will automatically convert it to --embed-resources --standalone, which should be used instead.

In short:

  • -s/--standalone "By default, pandoc produces a document fragment". To produce a standalone document (valid HTML file including and ), use one of those flags.

  • --embed-resources "Produce a standalone HTML file with no external dependencies, using data: URIs to incorporate the contents of linked scripts, stylesheets, images, and videos."


A better option for most people than -H is to use the --self-contained option:

Produce a standalone HTML file with no external dependencies, using data: URIs to incorporate the contents of linked scripts, stylesheets, images, and videos.

Then you can do:

pandoc -f markdown -t html file.md -o file.html --self-contained --css=github-pandoc.css

This way, you don't need to create a special .css file with style tags. Note that -s is no longer necessary as --self-contained implies -s (although it doesn't hurt).

Please note that this will attempt to include any other assets necessary to display the page (downloading them from the net if necessary!) - check the pandoc documentation of --self-contained for details.

Magnus answered 8/1, 2021 at 2:15 Comment(4)
good find, I spent a couple of hours looking for this last year but didn't find this option for some reason ...Caste
--self-contained seems to be deprecated. The flags are now --embed-resources --standaloneLull
unknown option --embed-resources?Catholic
@Catholic Make sure you're outputting a HTML file and not a PDF file. See github.com/mokeyish/obsidian-enhancing-export/issues/26 for details. And I guess make sure you're on the latest pandoc.Magnus
C
7

The way I've done it is to make use of the -H option to include a file in the html header. This means you need to wrap your css file with <style> </style> tags (so it's not really a css file anymore in the strictest sense). Output gets created like this:

pandoc -f markdown -t html file.md -o file.html -H style.css -s
Caste answered 13/5, 2020 at 4:29 Comment(0)
G
4

I had a similar scenario and found premailer. Install with pip install premailer and use as python3 -m premailer -f INPUT.html -o OUT.html.

Credit: https://qiita.com/kimagure/items/6820e2df2a7604047862

Gareri answered 29/1, 2020 at 11:20 Comment(0)
I
1

Another solution I happened to come across since posting this question is the Juice npm package, which also provides a CLI.

It provides the ability to place CSS inline, using a style sheet, with a script like this:

juice --css style.css original.html final.html

Instil answered 1/6, 2020 at 21:47 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.