Working with Urubu is giving me the chance to learn a few things about markdown.
On the Authoring page of the Urubu Manual, Jan Decaluwe writes:
In Urubu, content is entered in Markdown format. This is a lightweight format that feels like a natural way to write content in plain text.
I'm not quite so enthusiastic about markdown. I would never call it "natural"—not if you are at all concerned with the presentation of your content. And it seems to me that many users of markdown share this concern, or there wouldn't be so many ways of managing presentation in markdown, nor so many markdown extensions (including those noted by Jan on the page linked to above).
In fact I would go so far as to say that, in many ways, it's easier to write your content in straight HTML than it is to write in markdown, since writing in markdown invariably means trying to manage HTML through what is essentially a markdown filter. At least, that's my impression so far, in an early stage of the process of redoing my website with Urubu.
In any case, I've learned a few things about managing HTML through the "markdown filter," and on this page I share some of them. It's my sense that many of the issues mentioned are peculiar to Urubu's particular implementation of markdown.
Code & Command-Line Output
My advice: get into the habit of displaying any type of code and command-line output—anything even vaguely computer-ish—in blocks marked by three backticks and the raw
/endraw
keywords. In fact, if your IDE or text editor allows it, turn this into a macro or something that can automatically be invoked, plugged in, or turned on.
Here's what I mean by "three backticks and the raw/endraw keywords":
``` {% raw %} < Put your code or command-line output here. > {% endraw %} ```
Not following this suggestion could result in two kinds of problems:
- A make error.
- A missing line or two in the web page display. This is especially true of HTML embedded in Jinja2 code. You might not even notice the missing HTML lines if the Jinja2 code displays.
Images
Figures & Captions
The Templating constructs in pages page of the Urubu documentation explains how to provide captions for your images using the HTML figure
tag. The solution provided, however, has two limitations: it forces you to put all your web site's images into a single directory, and it doesn't allow control of the image size. Here I show you how I fixed this.
Create util.html
In the _layouts folder, create a new file util.html and put this into the content:
{% macro figure(dirPath, imageName, caption='', width='', height='') %} <figure> <img src="{{ dirPath }}/image/{{imageName}}" class="img-responsive" alt="{{caption}}" width="{{ width }}" height="{{ height }}"> {% if caption %} <figcaption>{{caption}}</figcaption> {% endif %} </figure> {% endmacro %}
The macro takes five parameters instead of the original solution's two, with the new parameters providing a required directory path and two optional parameters for width and height. The macro assumes the image has been placed in an "image" subdirectory of the dirPath directory.
Declare the Macro
Declare the macro from any markdown file that needs it. Here is the first part of my documentation.md file, whose result is the Missing Urubu Documentation page.
--- title: Missing Urubu Documentation layout: page tagline: Jerry Kurlandski pager: true teaser: Information missing from the Urubu documentation. --- {% from 'util.html' import figure %} Here I present some information that I consider helpful but have not found in the Urubu documentation. {.lead}
You see I have declared the macro immediately after the yaml front matter. My guess is that you could declare it anywhere in the markdown page (as long as it occurs before the macro invocation), but it makes more sense to consistently put it at the top. This way you won't waste time trying to see whether you've already declared the macro for any given markdown page.
Invoke the Macro
Here's how the same documentation.md page invokes the macro.
{{ figure(".", 'QuickStart_StartPage.jpeg', "Start page of Urubu Quickstart", "520", "330") }}
Floating Images
I'm a big fan of floating images. I think that having your text wrap around an image can make for a very eye-pleasing web page. When I made the decision to migrate my website to Urubu, I feared that floating images would be very hard to implement in markdown. My fear was unfounded.
Here's how I created a floating image on my Missing Urubu Documentation page.
<img align="right" src="./image/directoryStructure.jpeg" title="Directory structure of the Urubu Quickstart project">
What I haven't figured out—yet—is how to give floating images a caption. When I do, you'll be the first to know.
Creating Links
A link (or hyperlink) is a connection from one web resource to another. It goes in one direction and has two end points, called anchors. The link starts at the source anchor and points to the destination anchor. A destination anchor that is positioned at a particular point on a web page, rather than the web page as a whole, is called a bookmark. (See HTML 4 Spec; W3 Schools)
When it comes to links, it seems to me that there is a lot of ambiguity in the words people use. For example, when writers use the word link, they often mean the source anchor. In this discussion, whenever there is a chance of being misunderstood, I will use the terms as I've just defined them.
Fragments & Slugification
In "normal" HTML hyperlinking, you can append what is called a fragment to a source anchor in order to specify a location on the page you're referencing. For example, the first link in the markdown below takes the web user to the Authoring page of the the Urubu Manual, while the second takes the user to the section of that page called "Reference links".
On the [Authoring Page](http://urubu.jandecaluwe.com/manual/authoring.html), you'll find the [Reference links](http://urubu.jandecaluwe.com/manual/authoring.html#reference-links) section.
In the example above, the fragment is the "#reference-links" part of the second link. This link works because the HTML on the page has a tag with an id
that matches the fragment:
<h2 id="reference-links">Reference links</h2>
The section of the page which you're targeting has to have an id
attribute. You can't link to just any part of the page. (Pre-HTML 5 let you also link to tags with the name
property.)
Notice in the example above that the fragment doesn't use that section's literal title, which is "Reference links"; rather, it uses a slugified version of the title. Thus far, my foray into web development leaves me with the following impressions regarding "slugification":
-
Usually the process refers to the part of the URL that points to a specific page. For example, in the URL
https://stackoverflow.com/questions/5574042/string-slugification-in-python
, the slug is the part after the last forward slash. But the term also seems to be used for targeting section headers on a page. -
The details of slugification are not universally agreed on—but usually it involves removing punctuation from the original, lower-casing all the characters, and replacing spaces with hyphens. For example, the slugified version of the title of this section is "fragments-slugification".
-
To aid cross-site navigation, many websites automatically slugify headers on their pages, thereby assigning every section title a slugified
id
. (In fact, Urubu does this as well.) So, while you can't always count on being able to link to a particular section of a web page, very often you can.
Note that Urubu offers website developers a couple of handy tools for linking to pages, and page sections, within one's own website. See my discussion of Linking to a Bookmark on the Project-Wide Reference IDs page.
Creating Source Anchors
There are three ways to link to other pages in markdown. One way is to use a literal URL in the markdown; the other two ways are referred to as the inline style and the reference style. Each of these three ways leads to HTML that uses the <a>
tag.
Literal URLs
Literal URLs are automatically turned into clickable links. Markdown dialects seem to vary on this point, but in Urubu the URL must be enclosed in angle brackets (< >
) and it must include the so-called scheme of the URL (i.e., the http://
or https://
part).
Just go to <http://www.google.com> and google it.
When this markdown is generated into HTML, the HTML looks like this:
<p>Just go to <a href="http://www.google.com">http://www.google.com</a> and google it.</p>
Finally, in the browser the link is highlighted, like this:
Just go to http://www.google.com and google it.
Inline Style
The inline style of linking uses the syntax [<link text>](<URL>)
, where "link text" refers to the highlighted text that appears on the HTML page. With this approach, the link text and the URL are next to each other in the markdown.
Just go to [Google's home page](http://www.google.com) and google it.
When this markdown is generated into HTML, the web page looks like this:
Just go to Google's home page and google it.
Note that this style does not surround the URL with angle brackets, but the http://
or https://
part of the URL is still required.
Reference Style
Finally, the reference style of linking lets you use a reference to a URL that is defined elsewhere on the page. This definition can appear anywhere on the same page (that is, before or after the reference itself). This syntax of the reference is [<reference name>]
; the syntax of the definition is [<reference name>]: <URL>
. This approach is especially useful if you refer to the same URL multiple times on the same page, or if you want to put all your reference definitions together in the same place on a page, as in footnotes.
[Urubu Manual]: http://urubu.jandecaluwe.com/manual/ ... as mentioned in the [Urubu Manual], which you can find on the [Urubu Home page], ... [Urubu Home page]: http://urubu.jandecaluwe.com
In this example, first the Urubu Manual
reference is defined; then both that reference and a new Urubu Home page
reference are used inside some markdown text; then, finally, the latter reference is defined. This illustrates that references can be defined anywhere on the page.
When this markdown is generated into HTML, the web page looks like this:
... as mentioned in the Urubu Manual, which you can find on the Urubu Home page, ...
You see that the reference definitions don't appear in the HTML.
Urubu supports all three forms of linking. In addition, Urubu implements a new form of reference links called project-wide reference IDs. References of this sort can be used globally, not just on a single page. See my Project-Wide Reference IDs page for a detailed discussion.
Creating Destination Anchors
Here we are talking about bookmarks—destination anchors which let other web pages link to a part of a page rather than just the top of a page. This means that what we're really talking about is making it possible for you, a website designer, to easily link to particular places on your own pages.
This section, first, covers a bug that must be fixed with a CSS solution. Then, using that solution, this section goes on to explain how to create destination anchors (that is, bookmarks) in markdown with raw HTML, then how to do it with attribute lists.
Link Misses Bookmark Issue
I first discovered this little bug when I noticed I couldn't get the Urubu table-of-contents sidebar to work for <h4>
and <h5>
tags. After clicking on the link in the sidebar, the browser would always take me to a point close to, but well below, the header's location on the page. I figured out how to fix the problem and documented it on these pages as a sidebar issue. Then I discovered a similar problem with using the <a>
tag for creating a bookmark. I fixed it the same way, but documented it separately as an <a>
tag problem. I only put two and two together when I noticed that I had the same issue with any destination anchor.
The solution involves CSS.
The Urubu Quickstart project comes with a fix—but only for <h2>
and <h3
tags. It's in site.css.
/* heading scrolling */ h2[id]:before, h3[id]:before{ content: ""; display: block; height: 70px; margin-top:-70px; }
After a little research, I still have only an incomplete sense of exactly what this .css styling is doing. I think it's moving not the content of the header tags, but their id
's, up 70 pixels on the page. The empty content
seems to be there just because that field is required. I don't understand the purpose of the display
and height
fields. Also, I played around with that number 70 in the style sheet. Both numbers must be 70—no other combination will do the job. Most of all, I don't understand why the problem exists in the first place.
Be that as it may, for you to get bookmarks to work, you have to have the same styling fix for the id
attribute of any HTML tag that you are using for a bookmark. This includes <h4>
and <h5>
headers that appear in the sidebar (since those links are implemented as bookmarks, which you can see clearly enough in the HTML which Urubu generates for you). For a reason I don't understand, the amount of pixel correction required seems to vary according to the tag. Here is my CSS solution for the tags I use for bookmarks.
h4[id]::before, h5[id]::before, div[id]::before, p[id]::before { content: ""; display: block; height: 70px; margin-top: -70px; } p a[id]::before { content: ""; display: block; height: 52px; margin-top: -52px; }
(Probably I'm delving too deeply into the topic here, but I want to point out that you do not need to style the <a>
tag by itself, because when used by itself as a destination anchor, Urubu always wraps it up in a <p>
tag. This means that the p a[id]::before
styling above covers that as well as the case where you explicitly wrap the <a>
tag inside of a <p>
tag.)
Now that I've covered this bug and how to resolve it, in the next two sections I show you how to create bookmarks in your markdown in two different ways. The first uses what I call "raw HTML," and the second leverages a markdown-only approach.
Bookmarks with Raw HTML
Markdown was created to let you write web pages without having to worry about the syntax of HTML. Even so, in most dialects of markdown—including Urubu's—you can still use HTML. And this is one way to create a destination anchor in markdown.
Prior to HTML 5, the anchor tag <a>
had an optional name
attribute that could be used to create destination anchors. (See https://www.w3.org/MarkUp/1995-archive/Elements/A.html to refresh your memory.) HTML 5 no longer supports the name
attribute. But it continues to support the href
attribute for source anchors.
While HTML 5 removed the use of the name
attribute for bookmarks, it now lets you use the id
attribute, and this attribute can belong to any tag, not just <a>
.
Since markdown allows raw HTML, you could create bookmarks (aka destination anchors) on your website by inserting any of the following into your markdown, all of which assign the id
attribute the value of 'rosebud':
<h4 id="rosebud">The Significance of Rosebud</h4> <div id="rosebud"></div> <p id="rosebud">The Significance of Rosebud</p> <a id="rosebud"></a> <p><a id="rosebud"></a></p>
The official line: Any of these will work as a bookmark—provided you style them as I showed you in the previous section. Note that, as mentioned above, the <a>
tag of the second-last example will be wrapped in a <p>
tag when Urubu generates the HTML. So the last and the second-last are essentially equivalent.
But speaking as a colleague: If you're a software developer, you probably know what it's like to have a vague, uneasy suspicion that some little thing isn't quite right. Your app or whatever is working, but every once in a while something inexplicable will happen; you hardly believe it yourself, and you'll rebuild or refresh, and the problem will go away; and if you're in a stubborn mood and you want to get to the bottom of whatever you saw, you can't reproduce the problem.... Well, that's how I feel about the last two examples. The fact that they need a different pixel setting in the CSS bugs me, and I have my suspicions that their behavior depends on whether or not they appear in the markdown just before or after another paragraph, with no blank line between them. But I can't reproduce the problems I think I saw. So, if I were you, I would stick to the first two examples above—either that, or use the attribute lists method described below.
Bookmarks with Attribute Lists
Another way to define destination anchors in your markdown is visually simple but uses syntax I can never remember. It looks like this (adapted from markdown for another section of Close to the Machine).
- In the listing above, notice the display of `item.teaser` just after page title and date. I discuss the teaser in a separate section below. {: #TeaserMention }
The curly-braced code must be in the line after the end of the paragraph it is targeting. There can be no blank line between them, though spaces between the start of the line and the left curly brace are allowed, as in the example above.
Careful: if you make a mistake with this approach—for example, unintentionally inserting a blank line between the paragraph and the curly-braded code—the build will not generate an error or warning, but your link won't work.
Urubu generates the corresponding HTML to look like this:
<p id="TeaserMention">In the listing above, notice the display of <code>item.teaser</code> just after page title and date. I discuss the teaser in a separate section below. </p>
The Urubu documentation alludes to this approach as making use of attribute lists at http://urubu.jandecaluwe.com/manual/authoring.html#reference-links; the documentation’s link used to work but as of this writing seems to be dead. The same approach is referred to in Google documentation as using custom attributes (https://developers.google.com/web/resources/markdown-syntax#custom_attributes_and_named_anchors).
This approach is also plagued by the Link Misses Bookmark Issue, discussed in the first part of this section, and is fixed with the styling for p[id]::before
given in that section's CSS example.
NOTE: Perhaps incorporate the next section into this section.
Special Characters
Square Brackets in Markdown
Square brackets are part of the syntax used in markdown when you want to insert a link into your web page. Other uses of square brackets result in a make error. For example, in a separate website I tried to put the string in a markdown file: The gentleman [Mr. WARDWELL] seems to represent this case as a person with gold weights
.
Trying to generate the website led to the following error message:
Undefined reference: 'mr. wardwell' urubu_warn(_warning.undef_ref_md, msg=ref, fn=this['fn'])
The fix is to use backslashes ('\') before the left and right square brackets: The gentleman \[Mr. WARDWELL\] seems to represent this case as a person with gold weights
.
Curly Braces in Urubu Markdown
Jan Decaluwe documents how to use curly braces in markdown. There he also explains why the solution to the problem is so ugly to look at (not to mention hard to remember). I repeat the solution below.
While working on another page, I wanted to put the following into markdown: {% endblock %}
. This led to the following error:
urubu.UrubuError: in urubumigration/firstThingsFirst.md: <class 'jinja2.exceptions.TemplateSyntaxError'>: 'Encountered unknown tag 'endblock'.' make: *** [build] Error 1
As Jan reports, to get {{
you write {{ '{{' }}
. This applies as well to single braces: to get {
you write {{ '{' }}
.