Support for Right-To-Left text #217

Open
opened 2026-01-29 14:30:40 +00:00 by claunia · 0 comments
Owner

Originally created by @mhmd-azeez on GitHub (Aug 11, 2018).

Adding support for markdown in achieved by adding dir attribute to the rendered html elements. There are two ways of doing that:

Either you explicitly mark elements as rtl based on their contents, which is not too hard but might slow things down a bit. Or, you mark all of the structural elements with dir="auto" and let the browsers do the heavy lifting.

If you are interested, I am willing to send a PR, but I might need some help in some decisions and specific areas (like getting the first character of a block in a fast way, for example). For more information please take a look at dear-github/dear-github#147. Whichever way we choose, it's better than not supporting it at all.

I played with the second idea a bit, it's very easy to implement it. But not every browser supports it according to my tests and no browser seems to support tables. Here is a simple implementation of the second method:

public class RtlExtension : IMarkdownExtension
{
    public void Setup(MarkdownPipelineBuilder pipeline)
    {
        // Make sure we don't have a delegate twice
        pipeline.DocumentProcessed -= Pipeline_DocumentProcessed;
        pipeline.DocumentProcessed += Pipeline_DocumentProcessed;
    }

    private void Pipeline_DocumentProcessed(MarkdownDocument document)
    {
        foreach (var node in document.Descendants())
        {
            if (node is ParagraphBlock || node is ListBlock ||
                node is HeadingBlock || node is QuoteBlock)
            {
                 node.GetAttributes().AddPropertyIfNotExist("dir", "auto");
            }
        }
    }

    public void Setup(MarkdownPipeline pipeline, IMarkdownRenderer renderer)
    {

    }
}

For the following markdown:

# Fruits
In botany, a [fruit](https://en.wikipedia.org/wiki/Fruit) is the seed-bearing structure in flowering plants (also known as angiosperms) formed from the ovary after flowering.

> Fruits are good for health
-- Anonymous

## Types of fruits
- Berries
  - Strawberry
  - kiwifruit
- Citrus
  - Orange
  - Lemon

## Examples of fruits :yum:
1. Apple
2. Banana
3. Orange

## Grocery List
- [X] Watermelon
- [X] Apricot
- [ ] Fig

Nuitrion |Apple | Oranges
--|-- | --
Calories|52|47
Sugar|10g|9g

# میوە
[میوە](https://ckb.wikipedia.org/wiki/%D9%85%DB%8C%D9%88%DB%95) یان مێوە بەروبوومی ڕوەکیە کە ڕوەکەکان ھەڵیان ئەگرن وەک بەرگێک بۆ تۆوەکانیان، بە زۆری جیادەکرێتەوە بە شیرینی یان ترشی لە تامدا و بە بوونی بڕێکی زۆر ئاو

> میوە بۆ تەندروستی باشە
-- نەزانراو

## نموونەی میوە :yum:
1. سێو
2. مۆز
3. پرتەقاڵ

## جۆرەکانی میوە
- توو
  - فڕاولە
  - کیوی
- مزرەمەنی
  - پڕتەقاڵ
  - لیمۆ

## لیستی کڕین
- [X] شووتی
- [X] قەیسی
- [ ] هەنجیر

 پێکهاتە |سێو | پڕتەقاڵ
--|-- | --
کالۆری|٥٢|٤٧
شەکر| ١٠گ|٩گ

The following html is produced (note, to view the html correctly, you might need to have <meta charset="UTF-8"> in the head of the html document):

<h1 id="fruits" dir="auto">Fruits</h1>
<p dir="auto">In botany, a <a href="https://en.wikipedia.org/wiki/Fruit">fruit</a> is the seed-bearing structure in flowering plants (also known as angiosperms) formed from the ovary after flowering.</p>
<blockquote class="blockquote" dir="auto">
<p dir="auto">Fruits are good for health
-- Anonymous</p>
</blockquote>
<h2 id="types-of-fruits" dir="auto">Types of fruits</h2>
<ul dir="auto">
<li>Berries
<ul dir="auto">
<li>Strawberry</li>
<li>kiwifruit</li>
</ul>
</li>
<li>Citrus
<ul dir="auto">
<li>Orange</li>
<li>Lemon</li>
</ul>
</li>
</ul>
<h2 id="examples-of-fruits" dir="auto">Examples of fruits 😋</h2>
<ol dir="auto">
<li>Apple</li>
<li>Banana</li>
<li>Orange</li>
</ol>
<h2 id="grocery-list" dir="auto">Grocery List</h2>
<ul class="contains-task-list" dir="auto">
<li class="task-list-item"><input disabled="disabled" type="checkbox" checked="checked" /> Watermelon</li>
<li class="task-list-item"><input disabled="disabled" type="checkbox" checked="checked" /> Apricot</li>
<li class="task-list-item"><input disabled="disabled" type="checkbox" /> Fig</li>
</ul>
<table class="table" dir="auto">
<thead>
<tr>
<th dir="auto">Nuitrion</th>
<th dir="auto">Apple</th>
<th dir="auto">Oranges</th>
</tr>
</thead>
<tbody>
<tr>
<td dir="auto">Calories</td>
<td dir="auto">52</td>
<td dir="auto">47</td>
</tr>
<tr>
<td dir="auto">Sugar</td>
<td dir="auto">10g</td>
<td dir="auto">9g</td>
</tr>
</tbody>
</table>
<h1 id="section" dir="auto">میوە</h1>
<p dir="auto"><a href="https://ckb.wikipedia.org/wiki/%D9%85%DB%8C%D9%88%DB%95">میوە</a> یان مێوە بەروبوومی ڕوەکیە کە ڕوەکەکان ھەڵیان ئەگرن وەک بەرگێک بۆ تۆوەکانیان، بە زۆری جیادەکرێتەوە بە شیرینی یان ترشی لە تامدا و بە بوونی بڕێکی زۆر ئاو</p>
<blockquote class="blockquote" dir="auto">
<p dir="auto">میوە بۆ تەندروستی باشە
-- نەزانراو</p>
</blockquote>
<h2 id="section-1" dir="auto">نموونەی میوە 😋</h2>
<ol dir="auto">
<li>سێو</li>
<li>مۆز</li>
<li>پرتەقاڵ</li>
</ol>
<h2 id="section-2" dir="auto">جۆرەکانی میوە</h2>
<ul dir="auto">
<li>توو
<ul dir="auto">
<li>فڕاولە</li>
<li>کیوی</li>
</ul>
</li>
<li>مزرەمەنی
<ul dir="auto">
<li>پڕتەقاڵ</li>
<li>لیمۆ</li>
</ul>
</li>
</ul>
<h2 id="section-3" dir="auto">لیستی کڕین</h2>
<ul class="contains-task-list" dir="auto">
<li class="task-list-item"><input disabled="disabled" type="checkbox" checked="checked" /> شووتی</li>
<li class="task-list-item"><input disabled="disabled" type="checkbox" checked="checked" /> قەیسی</li>
<li class="task-list-item"><input disabled="disabled" type="checkbox" /> هەنجیر</li>
</ul>
<table class="table" dir="auto">
<thead>
<tr>
<th dir="auto">پێکهاتە</th>
<th dir="auto">سێو</th>
<th dir="auto">پڕتەقاڵ</th>
</tr>
</thead>
<tbody>
<tr>
<td dir="auto">کالۆری</td>
<td dir="auto">٥٢</td>
<td dir="auto">٤٧</td>
</tr>
<tr>
<td dir="auto">شەکر</td>
<td dir="auto">١٠گ</td>
<td dir="auto">٩گ</td>
</tr>
</tbody>
</table>

Screenshot (Chrome):
rtl-markdown

In Chrome, Opera and Firefox, all of the elements (except for table) are rendered correctly. Unfortunately, Edge and IE don't respect the direction attribute at all (If its set to "auto").

Originally created by @mhmd-azeez on GitHub (Aug 11, 2018). Adding support for markdown in achieved by adding `dir` attribute to the rendered html elements. There are two ways of doing that: Either you explicitly mark elements as rtl based on their contents, which is not too hard but might slow things down a bit. Or, you mark all of the structural elements with `dir="auto"` and let the browsers do the heavy lifting. If you are interested, I am willing to send a PR, but I might need some help in some decisions and specific areas (like getting the first character of a block in a fast way, for example). For more information please take a look at dear-github/dear-github#147. Whichever way we choose, it's better than not supporting it at all. I played with the second idea a bit, it's very easy to implement it. But not every browser supports it according to my tests and no browser seems to support tables. Here is a simple implementation of the second method: ```csharp public class RtlExtension : IMarkdownExtension { public void Setup(MarkdownPipelineBuilder pipeline) { // Make sure we don't have a delegate twice pipeline.DocumentProcessed -= Pipeline_DocumentProcessed; pipeline.DocumentProcessed += Pipeline_DocumentProcessed; } private void Pipeline_DocumentProcessed(MarkdownDocument document) { foreach (var node in document.Descendants()) { if (node is ParagraphBlock || node is ListBlock || node is HeadingBlock || node is QuoteBlock) { node.GetAttributes().AddPropertyIfNotExist("dir", "auto"); } } } public void Setup(MarkdownPipeline pipeline, IMarkdownRenderer renderer) { } } ``` For the following markdown: ``` # Fruits In botany, a [fruit](https://en.wikipedia.org/wiki/Fruit) is the seed-bearing structure in flowering plants (also known as angiosperms) formed from the ovary after flowering. > Fruits are good for health -- Anonymous ## Types of fruits - Berries - Strawberry - kiwifruit - Citrus - Orange - Lemon ## Examples of fruits :yum: 1. Apple 2. Banana 3. Orange ## Grocery List - [X] Watermelon - [X] Apricot - [ ] Fig Nuitrion |Apple | Oranges --|-- | -- Calories|52|47 Sugar|10g|9g # میوە [میوە](https://ckb.wikipedia.org/wiki/%D9%85%DB%8C%D9%88%DB%95) یان مێوە بەروبوومی ڕوەکیە کە ڕوەکەکان ھەڵیان ئەگرن وەک بەرگێک بۆ تۆوەکانیان، بە زۆری جیادەکرێتەوە بە شیرینی یان ترشی لە تامدا و بە بوونی بڕێکی زۆر ئاو > میوە بۆ تەندروستی باشە -- نەزانراو ## نموونەی میوە :yum: 1. سێو 2. مۆز 3. پرتەقاڵ ## جۆرەکانی میوە - توو - فڕاولە - کیوی - مزرەمەنی - پڕتەقاڵ - لیمۆ ## لیستی کڕین - [X] شووتی - [X] قەیسی - [ ] هەنجیر پێکهاتە |سێو | پڕتەقاڵ --|-- | -- کالۆری|٥٢|٤٧ شەکر| ١٠گ|٩گ ``` The following html is produced (note, to view the html correctly, you might need to have `<meta charset="UTF-8">` in the head of the html document): ``` <h1 id="fruits" dir="auto">Fruits</h1> <p dir="auto">In botany, a <a href="https://en.wikipedia.org/wiki/Fruit">fruit</a> is the seed-bearing structure in flowering plants (also known as angiosperms) formed from the ovary after flowering.</p> <blockquote class="blockquote" dir="auto"> <p dir="auto">Fruits are good for health -- Anonymous</p> </blockquote> <h2 id="types-of-fruits" dir="auto">Types of fruits</h2> <ul dir="auto"> <li>Berries <ul dir="auto"> <li>Strawberry</li> <li>kiwifruit</li> </ul> </li> <li>Citrus <ul dir="auto"> <li>Orange</li> <li>Lemon</li> </ul> </li> </ul> <h2 id="examples-of-fruits" dir="auto">Examples of fruits 😋</h2> <ol dir="auto"> <li>Apple</li> <li>Banana</li> <li>Orange</li> </ol> <h2 id="grocery-list" dir="auto">Grocery List</h2> <ul class="contains-task-list" dir="auto"> <li class="task-list-item"><input disabled="disabled" type="checkbox" checked="checked" /> Watermelon</li> <li class="task-list-item"><input disabled="disabled" type="checkbox" checked="checked" /> Apricot</li> <li class="task-list-item"><input disabled="disabled" type="checkbox" /> Fig</li> </ul> <table class="table" dir="auto"> <thead> <tr> <th dir="auto">Nuitrion</th> <th dir="auto">Apple</th> <th dir="auto">Oranges</th> </tr> </thead> <tbody> <tr> <td dir="auto">Calories</td> <td dir="auto">52</td> <td dir="auto">47</td> </tr> <tr> <td dir="auto">Sugar</td> <td dir="auto">10g</td> <td dir="auto">9g</td> </tr> </tbody> </table> <h1 id="section" dir="auto">میوە</h1> <p dir="auto"><a href="https://ckb.wikipedia.org/wiki/%D9%85%DB%8C%D9%88%DB%95">میوە</a> یان مێوە بەروبوومی ڕوەکیە کە ڕوەکەکان ھەڵیان ئەگرن وەک بەرگێک بۆ تۆوەکانیان، بە زۆری جیادەکرێتەوە بە شیرینی یان ترشی لە تامدا و بە بوونی بڕێکی زۆر ئاو</p> <blockquote class="blockquote" dir="auto"> <p dir="auto">میوە بۆ تەندروستی باشە -- نەزانراو</p> </blockquote> <h2 id="section-1" dir="auto">نموونەی میوە 😋</h2> <ol dir="auto"> <li>سێو</li> <li>مۆز</li> <li>پرتەقاڵ</li> </ol> <h2 id="section-2" dir="auto">جۆرەکانی میوە</h2> <ul dir="auto"> <li>توو <ul dir="auto"> <li>فڕاولە</li> <li>کیوی</li> </ul> </li> <li>مزرەمەنی <ul dir="auto"> <li>پڕتەقاڵ</li> <li>لیمۆ</li> </ul> </li> </ul> <h2 id="section-3" dir="auto">لیستی کڕین</h2> <ul class="contains-task-list" dir="auto"> <li class="task-list-item"><input disabled="disabled" type="checkbox" checked="checked" /> شووتی</li> <li class="task-list-item"><input disabled="disabled" type="checkbox" checked="checked" /> قەیسی</li> <li class="task-list-item"><input disabled="disabled" type="checkbox" /> هەنجیر</li> </ul> <table class="table" dir="auto"> <thead> <tr> <th dir="auto">پێکهاتە</th> <th dir="auto">سێو</th> <th dir="auto">پڕتەقاڵ</th> </tr> </thead> <tbody> <tr> <td dir="auto">کالۆری</td> <td dir="auto">٥٢</td> <td dir="auto">٤٧</td> </tr> <tr> <td dir="auto">شەکر</td> <td dir="auto">١٠گ</td> <td dir="auto">٩گ</td> </tr> </tbody> </table> ``` Screenshot (Chrome): ![rtl-markdown](https://user-images.githubusercontent.com/16880059/43993707-96fb4d26-9d9a-11e8-928f-cac8accfd898.png) In Chrome, Opera and Firefox, all of the elements (except for table) are rendered correctly. Unfortunately, Edge and IE don't respect the direction attribute at all (If its set to "auto").
claunia added the enhancement label 2026-01-29 14:30:40 +00:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/markdig#217