1

I have some markdown files and I want to display them on my blog which developed by Laravel.

So I think out such a solution:

Controller

public function display() {
    $pd = new Parsedown();
    $text = Storage::disk('local')->get('x.md');
    $html = $pd->text($text);
    $title = "title";
    return view('x.y', [
        "html" => $html,
        "title" => $title
    ]);
}

Blade

<div class="container-fluid">
    <div class="row">
        <div class="panel panel-default">
            <div class="panel-heading">
                <h3 class="panel-title text-center">{{ $title }}</h3>
            </div>
            <div class="panel-body">
                {!! $html !!}
            </div>
        </div>
    </div>
</div>

It works well except table element:

Parsedown parse table like that:

header 1 | header 2
-------- | --------
cell 1.1 | cell 1.2
cell 2.1 | cell 2.2

into:

<table>
<thead>
<tr>
<th>header 1</th>
<th>header 2</th>
</tr>
</thead>
<tbody>
<tr>
<td>cell 1.1</td>
<td>cell 1.2</td>
</tr>
<tr>
<td>cell 2.1</td>
<td>cell 2.2</td>
</tr>
</tbody>
</table>

Then I got a table with no bootstrap styles, and it looks weird. What I want to get is:

<table class="table">
  ...
</table>

So, could anyone please give me some suggestions about that?

Sayakiss
  • 6,878
  • 8
  • 61
  • 107
  • This might be related to your question https://stackoverflow.com/questions/1058933/can-i-define-a-class-name-on-paragraph-using-markdown – Nima Sep 21 '17 at 13:45
  • 1
    Heve you tried [parsedown-extra](https://github.com/erusev/parsedown-extra)? – PeterM Sep 21 '17 at 14:24

2 Answers2

2

After I read the source code of Parsedown, I find a solution.

In blockTable() method:

change this:

        $Block = array(
            'alignments' => $alignments,
            'identified' => true,
            'element' => array(
                'name' => 'table',
                'handler' => 'elements'
            ),
        );

to:

        $Block = array(
            'alignments' => $alignments,
            'identified' => true,
            'element' => array(
                'name' => 'table',
                'handler' => 'elements',
                'attributes' => [       //+
                    "class" => "table"  //+
                ]                       //+
            ),
        );

And it will output table element with class="table".

Finally, I created a new class which extends Parsedown, and override that blockTable method with my own implementation.

Sayakiss
  • 6,878
  • 8
  • 61
  • 107
1

Parsedown does not support adding class to generated elements. Parsedown also does not support emitting the generated HTML as an XML document. Therefore, you have two choices:

  1. Use preg_replace to replace with regular expressions.
  2. Use SimpleXML (or similar) to parse the HTML tree and replace elements.

Since the HTML Parsedown generates is simple, well-formed, and predictable you can probably get away with preg_replace. The implementation would look something like this:

public function display() {
    $pd = new Parsedown();
    $text = Storage::disk('local')->get('x.md');
    $html = $pd->text($text);
    $html = preg_replace('/^\s*<table>\s*$/', '<table class="table">', $html);
    $title = "title";
    return view('x.y', [
        "html" => $html,
        "title" => $title
    ]);
}
bishop
  • 37,830
  • 11
  • 104
  • 139