Skip to content

Rulers: Overview

Steven Chang edited this page Jan 1, 2021 · 6 revisions

Rulers are what dictate the html output of a bbcode tag. The parser will automatically tokenize any content with an opening tag [tag] and a closing tag [/tag], before passing it to the ruler. For anything non-bbcode, read the markdown-it api docs.

Rulers in the markdown-it extension are split into two general types: Inline and Block level. The order of parsing is Block Level > Inline Level. This leaves the engine with the annoying quirks of not being able to put block level tags inside inline level. Overall, these rulers function the same way.

Example of a Ruler

Here is an example of a tag and its ruler, specifically a block level ruler with replace:

[print=line]
text
[/print]
  md.block.bbcode.ruler.push("print", {
    tag: "print",
    replace: function (state, tagInfo, content) {
      let printOption = tagInfo.attrs['_default'];

      let token = state.push("div_open", "div", 1);
      if (!printOption) {
        token.attrs = [["class", "bbcode-print"]];
      } else {
        token.attrs = [["class", "bbcode-print-" + printOption]];
      }

      token = state.push("inline", "", 0);
      token.content = content;
      token.children = [];

      state.push("div_close", "div", -1);

      return true;
    }
  });

It defines the name of the tag, in this case [print], and picks up it's components, the tagInfo and the content.
tagInfo is the arguments given inside the tag, creating a dictionary. In this case [print=line] -> {_default: "line"}.
It passes this, along with content, into a function that determines the html output by pushing attributes into the token.

This is a brief example. The following sections will go into further detail. But first, let us start with the tag itself

Dissection of a Tag

A tag is composed of three parts: tag, tagInfo, content. This comes together like so:

[tag tagInfo]content[/tag]

tag and content are self-explanatory strings (Note: content can be manipulated inside the ruler). tagInfo on the other hand is more interesting, as it is completely optional. tagInfo comes in two types, a single argument, and a multi-argument (see tagInfo).

There certain limitations to these tags that come about as a limitation of markdown-it. As stated above, rulers are divided into inline and block level. Honestly, this deserves its own page, so I'll only discuss what this means for a tag.

Tags must be all in a single line, or have its opening and closing tag be the start and end of a line, respectively. This means that the tag should be designed with either of the following structures in mind.

text [inlineTag]content[/inlineTag] text

[blockTag]
content
[/blockTag]

Structure of a Ruler

Let us discuss the structure of a ruler. Here is the basic outline for creating a ruler:

function setupMarkdownIt(md) {

  md.inline.bbcode.ruler.push("tagname", {
    tag: "tagname",
    method: "method function/value"
  });

  md.block.bbcode.ruler.push("secondtagname", {
    tag: "secondtagname",
    method: "method function/value"
  });
}

All rulers are created inside the setupMarkdownIt(md) function, where an array is pushed into either the block or inline level, containing the name of the tag and the method for handling it. Block and Inline levels will be discussed in a later section. For simplicity in the rest of this discussion, we'll refer to both md.inline.bbcode.ruler and md.block.bbcode.ruler as ruler.

ruler is made up of the tag and the method. tag defines the name of the tag and seems to only allow lowercase, but in use, it is case-insensitive. method determines the html to be outputted.