CSS for Markdown, the basics

This is the first part of some posts on using CSS in and with DT/DTTG. Though I wrote it as a single piece, I broke it up in smaller installments to keep the posts (barely) managable. Please let me know (preferably by a PM) if you find errors of any kind or are missing details. I’ll correct the first ones and try to help with the second ones.

Next post

Why would you care about CSS?

CSS stands for Cascading Style Sheets. It is a text format that allows you to describe the visual appearance of HTML documents. In DEVONthink, CSS is used to determine the visual appearance of Markdown documents when they are rendered as HTML. Whenever you select the preview mode to look at a Markdown document, you’ll see it rendered as HTML in some kind of “style”: Foreground and background colors are set as are the fonts and their sizes, indentation and linespacing and so on. Unless you do anything about it, this will be the style that is built into DEVONthink (and the HTML engine it uses). If you’re happy with that, you can stop reading here.

How can you tell DEVONthink to use your own CSS?

As of the time of this writing (DEVONthink Pro Version 3.8 and DEVONthink To Go 3.5.1), there are four methods to specify your own CSS in DEVONthink:

  1. In the global preferences. In DEVONthink, you’d provide the x-devonthink-item URL to a record stored somewhere in your database(s) and containing your CSS. In DEVONthink To Go, you do the same in the settings for Markdown documents. A globally defined CSS will influence all Markdown documents in DEVONthink.

  2. Add css: URL as the first line of your Markdown document(s). The URL can be any valid URL as well as an x-devonthink-item://... one or an absolute address of a record containing your CSS defintions like /Inbox/myCss.txt.

  3. Add a HTML script element somewhere in your Markdown document, i.e. a piece of code looking like that
    <style> Style definitions go here</style> If you go for this option, make sure that you do not have any empty lines in the style element. Those will break everything.

  4. Add a HTML link element to the top of your Markdown document like so <link rel="steylsheet" href="URL"> Again, the URL parameter can be anything from a usual URL to a x-devonthink-item://... one or an absolute location like /Inbox/myCSS.txt.

The last three methods will add CSS only to those Markdown documents where you insert them. So they’re not really useful if you want to make sure that all your Markdown documents look the same.

Caveat: DEVONthink 3 and DEVONthink To Go currently handle global style sheets (i.e. those set in the preferences) slightly differently. While DEVONthink replaces its own pre-defined styles with those of the style sheet, DEVONthink To Go has your styles always uses its pre-defined styles, only overriding those that you define globally. This behavior may (and should, I think) change in the future so that pre-defined styles are preserved unless overwritten.

13 Likes

I found this series of posts very useful. I’m quite experienced in using CSS, but this is the first time I’ve used it for markdown.

I modified a CSS file based on A CSS to embellish *MultiMarkdown* rendering, created a ‘Global settings’ database, put the CSS file there, and used the x-devonthink-item link in the DTP preferences.

I also put a copy in my ‘~/Global settings’ folder so it is globally available no matter if DTP is running. The reason for this is that I have a quicklook handler installed which displays a markdown file when you quicklook. This handler is available in a number of ways:

If you use macports, type ‘sudo port install QLMarkdown’ in a terminal window.
If you use homebrew, type ‘brew install --cask qlmarkdown’, or copy the zip file from GitHub - toland/qlmarkdown: QuickLook generator for Markdown files. and put the result in /Library/QuickLook (or ~/Library/QuickLook if you want to make this change limited to a single user).

Once it is installed, you can go to /Library/QuickLook/QLMarkdown.qlgenerator/Contents/Resources and replace ‘styles.css’ with a soft link to wherever you put your modified css file (you will have to choose ‘Show package contents’ from the context menu when you get to QLMarkdown.qlgenerator). If you don’t want to use a soft link, you can simply replace styles.css with your new CSS file.

Now getting a quicklook for a markdown file will use your new CSS rules, and the appearance matches what you get in DTP.

4 Likes

Nice! Thanks for sharing your process and the handy tip. :slight_smile:

I have two more comments.

  1. If you expect to print (as in actually making marks on paper) the markdown files, you might want to change the background-color to ‘transparent’. Otherwise the printer will print the background on the entire sheet(s) of paper, which will waste a lot of ink or toner.

  2. This comment is not about CSS, but about using Prism. DTP supports Prism in the markdown file preferences. It does a good job with applying syntax coloring to code sections in the markdown file. Prism also supports numbered lines, but there doesn’t seem to be any way to get that to work in DTP other than getting down in the weeds.

What I’ve come up with is the following boiler plate to put around code snippets:

<pre class=“language-js line-numbers” data-start=“1”><code> // call your favorite function
foobar();
var x = 1;
x += 3;
</code></pre>

To make this more convenient, I’ve made a Keyboard Maestro macro to write the boiler plate and to leave the cursor immediately after the ‘<code>’. Your code should start at that cursor position and not on the next line because otherwise the listing will begin with a blank line 1. The “data-start” attribute defaults to 1, so it can be omitted in most cases. It is useful, though, when your code listing gets broken into separate bits with ordinary text between.

This works well in DTP, but not with most markdown quicklook generators, There you will get the listing without syntax coloring and line numbers. There may be more capable quicklook generators on the net.

When setting the background to white? I would consider that a bug in the driver or some other software layer. Paper is (conventionally) white, no need to apply white to it. Which might be a tad impossible, too, given the colors in current printers: how would you go about printing white with a CMYK set of colors or even with a monochrome printer?
Edit that was a bit sneaky. On can of course “print” white on any background with PDF. In that case, the printer will only print the background and not leave any marks for the foreground pixels. But I still believe that setting the background to white for printing is just fine.

As to the line numbers: while your work around does what it should, I’d prefer DT to support passing on parameters to Prism.

1 Like

I should have been more explicit about my context. I thought I was in a thread which included a css file based on one that is part of Marked 2. That css file contained ‘background-color: ivory’, which in my opinion greatly improves the look of the rendered markdown file. Possibly ivory doesn’t take much toner for a B&W laser printer, but a darker color could be very expensive on a color inkjet printer.

Css does allow for different rules for printing and for rendering on the screen, but I suspect that the css rules are applied before the user decides to print the document. This would be a question for the developers: When a markdown file is printed, is the destination (printer vs screen) known at the time the css rules are applied?

I agree that some scheme to pass options to MathJax and Prism would be nice.

–Barry

Yes

Good. Then the following addition at the end of your css file should do the trick (ymmv. This is what works for a CSS file based on A CSS to embellish MultiMarkdown rendering mentioned above):

@media print {
html, body {
background-color: white;
}
}

Oops! That particular CSS file sets the background directly, so to keep that out of the printed background, you need to delete the ‘background’ and ‘background-size’ rules for ‘html, body’ and change the addition at the bottom to:

@media print {
html, body {
background-color: white;
}
}

@media screen {
html, body {
background: – a jpeg pattern too long for this comment --;
background-size: auto;
}
}

Now I’m slowly getting your point: this other CSS is using a background, not a background-color. Which is a peculiar choice for text, in my opinion. And for different reasons, I’d do neither and stick with white. In which case there’s nothing to change for the print media selector. See here: CSS-for-Markdown/styles.css at master · chrillek/CSS-for-Markdown · GitHub

Also, if you’re printing the HTML from a browser, there might be an option to turn off the background completely.