Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Markdown rendering error (nested partial, code block) #82

Closed
lukasschlueter opened this issue Dec 8, 2018 · 2 comments
Closed

Markdown rendering error (nested partial, code block) #82

lukasschlueter opened this issue Dec 8, 2018 · 2 comments
Assignees
Labels
wontfix This will not be worked on

Comments

@lukasschlueter
Copy link
Contributor

So, this is some very specific issue that the gobuffalo repo ran into.

The problem

Text explanation

In fact, I'm even having some difficulties describing it in an easy way:
If a markdown partial starting with code (```...```, ignoring white-space in the beginning) inside of a markdown partial is directly preceded by an html tag displaying some text (didn't happen with div for example), the code will get parsed incorrectly.

Code sample

Here's some code, hopefully that's more clear:

// main.md
<%= partial("outer_partial.md" %>

// _outer_partial.md
<span>Some text</span>
<%= partial("inner_partial.md" %>

// _inner_partial.md
```go
if true {
    fmt.Println()
}
``` // Some text to prevent misinterpretation from github (not needed)

This should result in the following html code:

<p><span>Some Text</span>
<div class="highlight highlight-go"><pre>if true {
    fmt.Println()
}
</pre></div>
</p>

The actual output is the following:

<p><span>Some text</span>
<div class="highlight highlight-go"><pre>if true {</p>

<pre><code>fmt.Println()
</code></pre>

<p>}
</pre></div></p>

This actually only happens with partials in partials.

Why does this happen?

The markdown parser interprets the indentation of fmt.Println() as a new code block (see https://guides.github.com/features/mastering-markdown/).
I don't know why it does that though. I also don't know why it does that for inside of partials only.

Workarounds

There are multiple ways to prevent this from happening:

1. Don't use partials in partials

The following is working correctly - please don't ask me why.

// main.md
<span>Some text</span>
<%= partial("code_partial.md") %>

// _code_partial.md
```go
if true {
    fmt.Println()
}
``` // Some text to prevent misinterpretation from github (not needed)

2. Add an empty line between html and partial

If the span (or similar) is separated from the partial by an empty line, this also doesn't appear:

// main.md
<%= partial("outer_partial.md" %>

// _outer_partial.md
<span>Some text</span> 

<%= partial("inner_partial.md" %> // Works!

// _inner_partial.md
```go
if true {
    fmt.Println()
}
``` // Some text to prevent misinterpretation from github (not needed)

3. Don't start partials with code

If the inner partial doesn't directly start with the code, this issue also doesn't happen.
Please note that adding white-space does not work, but adding <div></div> does.

// main.md
<%= partial("outer_partial.md" %>

// _outer_partial.md
<span>Some text</span>
<%= partial("inner_partial.md" %>

// _inner_partial.md
Some text
```go
if true {
    fmt.Println()
}
``` // Some text to prevent misinterpretation from github (not needed)
@lukasschlueter
Copy link
Contributor Author

In case someone wants to work on this, here's a tests case to reproduce:

func Test_PartialHelpers_Markdown_With_Text_Before_Partial_In_Partial(t *testing.T) {
	r := require.New(t)

	main := `<%= partial("outer.md") %>`
	outer := `<span>Some text</span>
<%= partial("inner.md") %>
`
	inner := "```go\n" + `if true {
    fmt.Println()
}` + "\n```"

	ctx := NewContext()
	ctx.Set("partialFeeder", func(name string) (string, error) {
		if name == "outer.md" {
			return outer, nil
		}
		return inner, nil
	})

	html, err := Render(main, ctx)
	r.NoError(err)
	r.Equal(`<p><span>Some text</span>
<div class="highlight highlight-go"><pre>if true {
    fmt.Println()
}
</pre></div>
</p>`, string(html))
}

lukasschlueter added a commit to gobuffalo/docs that referenced this issue Dec 8, 2018
stanislas-m pushed a commit to gobuffalo/docs that referenced this issue Dec 10, 2018
* Add empty line as a workaround for gobuffalo/plush#82

* Update plush
@sio4 sio4 self-assigned this Sep 5, 2022
@sio4
Copy link
Member

sio4 commented Sep 5, 2022

This is intended behavior, not of nested partials but of markdown.

In your code the main.md includes outer.md partial and the outer also includes inner.md partial. Inner is fine, but let's see what is included by the main.

First, the inner partial will be translated as (in html)

<div class="highlight highlight-go"><pre>if true {
    fmt.Println()
}
</pre></div>

The above is the expected result. So let's write the outer.md manually with this content (in markdown):

<span>Some text</span>
<div class="highlight highlight-go"><pre>if true {
    fmt.Println()
}
</pre></div>

As you can see, the div block is just next to the span so markdown will treat it as a single paragraph. Markdown spec is clear to this:

The only restrictions are that block-level HTML elements — e.g. <div>, <table>, <pre>, <p>, etc. — must be separated from surrounding content by blank lines, and the start and end tags of the block should not be indented with tabs or spaces. Markdown is smart enough not to add extra (unwanted) <p> tags around HTML block-level tags.

The reason that adding a line after resolves this issue is that it made the content correct.

from https://daringfireball.net/projects/markdown/syntax#html

@sio4 sio4 closed this as completed Sep 5, 2022
@sio4 sio4 changed the title Markdown rendering error Markdown rendering error (nested partial, code block) Sep 5, 2022
@sio4 sio4 added the wontfix This will not be worked on label Sep 5, 2022
sio4 added a commit that referenced this issue Sep 5, 2022
sio4 added a commit that referenced this issue Sep 5, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
wontfix This will not be worked on
Projects
None yet
Development

No branches or pull requests

2 participants