Marks, Streamlined evolution of a Markdown engine...
Tags: javascript, typescript, markdown
Published: 2020-09-21 17:59:43

### The begining
When I started writing documentation in a web format, I was overwhelmed by the Markdown. This simplicity of writing, allowing on a simple annotated text, to be able to format in a quick but brief way was a real revolution.

But just as every new feature comes with its bunch of good things, it also comes with its frustrating side.

Indeed, can we be more productive in handling emphasis than just *writing this*?

```md
This **will** add *emphasis* to your `text` !
```
and just have this in return ...

This **will** add *emphasis* to your `text` !

***
### Feel the problems coming from miles away
At which point do you realize the limits of something you appreciate? It's when you want to do even more with it... and it's not as simple in reality.

Let's take a simple example. It is very easy to put a piece of text in bold or italics. It is natural to want to add a touch of color to it, isn't it?

And that's where the trouble starts. How do we put our text in red ? The answer ? Mix it with HTML... 

HTML, right in the middle of my text... Ohhh, that sounds slightly insulting to my ears. Why would I want to mix text, with HTML code. Worse yet, how could I convince my colleagues who are not familiar with source code to adopt Markdown... 

Another example, funny, the tables.

What a chance to be able to display data in the form of a table. I saw it as an excellent opportunity to make the documentation pages more relevant.

So go go go go, it was off to try to format my first data in a format that seems super simple :-)

```md
| COL A | COL B   | COL C  |
|-------|:-------:|-------:|
| Left  | Center  |Right   |
```

And then you have this :

| COL A | COL B   | COL C  |
|-------|:-------:|-------:|
| Left  | Center  |Right   |

### The disappointment
I was so cheerful, that I wanted my colleagues to share this enthusiasm, and to adopt this syntax as soon as possible...

And one of my colleague immediately gave me some data to format to see how practical it was... To receive data... in the... CSV format.

What a pain to transform the csv before using it, it is a very common format for data tables. :smile:

I then realized that a user who, by nature, is a bit resistant to change, won't even bother to do the same if he encounters the slightest difficulty with what he had been told.

So I was the only one to use it for a while :-) But that was fair.

***
### The rise of the new era :smile:

Then it became more and more widespread, and during my last project, we decided to keep our documentation up to date, and include this small documentation phase in our Agile cycle.

Just after each Kickoff, before we start coding, we update or create the minimalist documentation related to this feature. And naturally, as everyone has started to learn Markdown, the frustrations are reappearing on a massive scale. :smile: :smile:

As a developer, I decided to extend at least one markdown engine in order to meet the growing needs. But there is the following problem:

How to make an engine simple and extensible, if the format, although simple in appearance, brings problems of streamlining in terms of design?

### The new hope
So I decided to give it a try. To begin with, I had to tackle this heratic side of the parsing.

The syntax of the emphasis is convenient, it should not be changed. But if we want to adopt an extensible approach, we need to streamline the complex blocks, to allow the rendering engine to analyze them more flexibly, without making the syntax more awkward. The notion is fixed by repetition, and from this hypothesis, a single block declaration syntax seems appropriate.

Marks engine, was born :smile:
But what can we do with it ?
***
#### Emphasis
You can keep writing emphasis as in Markdown.
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/dpgpm1jljnrky3jwbolo.png)
Will result as this :

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/eh3u9e6xmgcse4uvwnhy.png)

#### Emoji
You can use Emoji(s) out of the box. Marks includes Twitter emojis.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/2upp8eb7m5r0xxthgdzx.PNG)

The documentation includes a search engine to find all Emoji's name

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/mvvn5uknkfq2pw37yjkc.PNG)

#### Heading

Heading has no reason to be used in another way

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/hb4uw5nv95wyqhxfmrw2.PNG)

#### Blockquote

Same here, syntax is quite the same, but nesting is not allowed the same way for readability purpose.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/rjelb4rrtn8ytrkitjkz.PNG)

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/5c8w1hl7zlxdrcx12ymj.PNG)

#### Unordered list

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/2mb43yfgstwijldjim8o.PNG)

#### Ordered list
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/9uouuxppwtvjl3vjve9i.PNG)

And we added a `neutral` symbol if you don't want to use numbers in your document

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/etd0uj6v1sey7xej6n4l.PNG)

#### The Legacy 
Tables, images, links, code blocks, they all keep the same syntax too.

#### New blocks ?
Yeah, we added a unique way to declare all kind of new blocks.

```md
[NAME OPTIONS] {{
  BODY
}}
```

So for example, the Table syntax becomes ...

```md
[table format:markdown] {{
  | COL A | COL B   | COL C  |
  |-------|---------|--------|
  | AA    | BB      |CC      |
}}
```

But, with this syntax, you can easily change options and brings more flexibility without changing the way you declare it

```md
[table format:csv] {{
COL A,COL B,COL C
AA,BB,CC
}}
```

And for both blocks, the result will be the same 
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/aoxogxomgzqytbu5xh29.PNG)

This allows several things:

* Simplify the work of the parser, and thus keep its speed.
* Prevent users from getting lost in complex syntax
* Simplify the creation of third party plugins.

#### Styles

In Marks, styles are options, but to keep it simple, some option names are dedicated to style. A paragraph, or a block can have styles. The way you declare styles in a block is the same as a paragraph. The difference is where you can set them.

```md
[table format:csv theme:dark variant:bordered,striped] {{
COL A,COL B,COL C
AA,BB,CC
AA,BB,CC
AA,BB,CC
AA,BB,CC
}}
```
In this block, just setting the theme to dark will apply some predifined style to it. So the user can defined easily styles.

Variant are predifined css too, to help streamline the global page templating.

The result with the bootstrap template looks like this :

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/4t0a63hl28tjh6tltzmv.PNG)

#### Options
Even if it is possible to apply styles or other options to a custom block, it is still possible to define the same thing on classic paragraphs

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/hqphyvip2ityzg0yfqja.PNG)

#### Nesting
If you've ever worked with Markdown, you've seen that there are limits to how you can / cannot nest one component into another. 

For example, it is not possible to nest one table into another, the syntax is not flexible enough to allow this.

To allow and simplify this feature, we introduced the `ref` option.

If you add the option ref to a component, it will not be rendered where you declared it. Instead, it will be added where a placeholder exist, with the same ref name.

```md
| Rows id       | A1            | A2    | ::- ref:TAB_1
| ------------- |:-------------:| -----:|
| Row 1         | AA-AA         | AA-AA |

| Rows id       | B1            | B2    |
| ------------- |:-------------:| -----:|
| Row 1         | @@TAB_1@@     | BB-BB |
```

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/8v6rexsht6nrdoemgmje.PNG)

#### Extending it

With this easy block declaration, you can imaging that adding a new plugin will be easy. For example, we provide the Mermaid plugin for Marks.

```md
[mermaid] {{
graph LR
    A[Hard edge] -->|Link text| B(Round edge)
    B --> C{Decision}
    C -->|One| D[Result one]
    C -->|Two| E[Result two]
}}
```
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/yq7z8pd6elmphop5rdds.PNG)

### Conclusion
If you liked this article and want to know more, feel free to follow links

[Website](https://marksjs.com)

[Npm package](https://www.npmjs.com/package/@marks-js/marks)

[Github](https://github.com/NoMoreDeps/marksjs)

Enjoy :smile: