russross / blackfriday

Blackfriday: a markdown processor for Go
Other
5.45k stars 602 forks source link

May it not work properly with \n line terminators ? #522

Open qiuker521 opened 5 years ago

qiuker521 commented 5 years ago

here are two types of code:

package main

import (
    "gopkg.in/russross/blackfriday.v2"
    "log"
    "web/utils"
)

func Markdown2Html(content string) string {
    output := blackfriday.Run([]byte(content), blackfriday.WithNoExtensions())
    return string(output)
}

func main() {
    a := utils.Get("https://raw.githubusercontent.com/Zuozuohao/Zuozuohao.github.io/master/_posts/2016-06-16-Object-Oriented-Inheritance-in-Go.md")
    //a = strings.Replace(a, "\n", "\r\n", -1)

    log.Println(Markdown2Html(string(a)))
}

returns


<p>` ` ` (does not contains the spaces)
package main</p>

<p>import (
    &quot;fmt&quot;
)</p>

<p>type Pet interface {
    Name() string
    Speak() string
    Play()
}</p>

<p>type pet struct {
    speaker func() string
    name    string
}</p>

<p>type Dog interface {
    Pet
    Breed() string
}</p>

<p>type dog struct {
    pet
    breed string
}</p>

<p>func NewPet(name string) *pet {
    p := &amp;pet{
        name: name,
    }
    p.speaker = p.speak
    return p
}</p>

<p>func (p *pet) Play() {
    fmt.Println(p.Speak())
}</p>

<p>func (p *pet) Speak() string {
    return p.speaker()
}</p>

<p>func (p *pet) speak() string {
    return fmt.Sprintf(&quot;my name is %v&quot;, p.name)
}</p>

<p>func (p *pet) Name() string {
    return p.name
}</p>

<p>func NewDog(name, breed string) *dog {
    d := &amp;dog{
        pet:   pet{name: name},
        breed: breed,
    }
    d.speaker = d.speak
    return d
}</p>

<p>func (d *dog) speak() string {
    return fmt.Sprintf(&quot;%v and I am a %v&quot;, d.pet.speak(), d.breed)
}</p>

<p>func Play(p Pet) {
    p.Play()
}</p>

<p>func main() {
    d := NewDog(&quot;spot&quot;, &quot;pointer&quot;)
    fmt.Println(d.Name())
    fmt.Println(d.Speak())
    Play(d)
}
` ` ` (does not contains the spaces)</p>

……
……
……

however, the code:

package main

import (
    "gopkg.in/russross/blackfriday.v2"
    "log"
    "strings"
    "web/utils"
)

func Markdown2Html(content string) string {
    output := blackfriday.Run([]byte(content), blackfriday.WithNoExtensions())
    return string(output)
}

func main() {
    a := utils.Get("https://raw.githubusercontent.com/Zuozuohao/Zuozuohao.github.io/master/_posts/2016-06-16-Object-Oriented-Inheritance-in-Go.md")
    a = strings.Replace(a, "\n", "\r\n", -1)

    log.Println(Markdown2Html(string(a)))
}

returns the good format:

<code>
package main

import (
    &quot;fmt&quot;
)

type Pet interface {
    Name() string
    Speak() string
    Play()
}

type pet struct {
    speaker func() string
    name    string
}

type Dog interface {
    Pet
    Breed() string
}

type dog struct {
    pet
    breed string
}

func NewPet(name string) *pet {
    p := &amp;pet{
        name: name,
    }
    p.speaker = p.speak
    return p
}

func (p *pet) Play() {
    fmt.Println(p.Speak())
}

func (p *pet) Speak() string {
    return p.speaker()
}

func (p *pet) speak() string {
    return fmt.Sprintf(&quot;my name is %v&quot;, p.name)
}

func (p *pet) Name() string {
    return p.name
}

func NewDog(name, breed string) *dog {
    d := &amp;dog{
        pet:   pet{name: name},
        breed: breed,
    }
    d.speaker = d.speak
    return d
}

func (d *dog) speak() string {
    return fmt.Sprintf(&quot;%v and I am a %v&quot;, d.pet.speak(), d.breed)
}

func Play(p Pet) {
    p.Play()
}

func main() {
    d := NewDog(&quot;spot&quot;, &quot;pointer&quot;)
    fmt.Println(d.Name())
    fmt.Println(d.Speak())
    Play(d)
}
</code>

……
……
……
qiuker521 commented 5 years ago

Here is the minimal runnable code:

package main

import (
    "gopkg.in/russross/blackfriday.v2"
    "io/ioutil"
    "log"
    "net/http"
)

func Markdown2Html(content string) string {
    output := blackfriday.Run([]byte(content), blackfriday.WithNoExtensions())
    return string(output)
}

func main() {
    a := Get("https://raw.githubusercontent.com/Zuozuohao/Zuozuohao.github.io/master/_posts/2016-06-16-Object-Oriented-Inheritance-in-Go.md")
        //comment this and this issue happens
    //a = strings.Replace(a, "\n", "\r\n", -1)

    log.Println(Markdown2Html(string(a)))
}

func Get(urls string) string {
    resp, err := http.Get(urls)
    if err != nil {
        panic(err)
    }

    defer resp.Body.Close()
    body, _ := ioutil.ReadAll(resp.Body)
    return string(body)

}
ivucica commented 5 years ago

Interestingly, I have almost the exact opposite situation.

I'm dealing with some data stored with Windows/DOS-style EOL (\r\n) and paragraphs were not being created until I strings.Replace(content, "\r\n", "\n", -1).

I0315 15:29:23.876900   14327 serve.go:388] INPUT: A

B

Please ignore
I0315 15:29:23.877727   14327 serve.go:389] INPUT HEX: 410d0a0d0a420d0a0d0a506c656173652069676e6f7265
I0315 15:29:23.877960   14327 serve.go:390] OUTPUT: <p>A

B

Please ignore</p>

After the swap:

I0315 15:31:18.472258   15069 serve.go:388] INPUT: A

B

Please ignore
I0315 15:31:18.475149   15069 serve.go:389] INPUT HEX: 410a0a420a0a506c656173652069676e6f7265
I0315 15:31:18.475919   15069 serve.go:390] OUTPUT: <p>A</p>
<p>B</p>

<p>Please ignore</p>

Observe how the paragraphs only exist with the 0x0a 0x0a sequence, but not with the 0x0d 0x0a 0x0d 0x0a.

Relevant chunk:

// post.ContentFiltered contains raw markdown.
input := []byte(strings.Replace(post.ContentFiltered, "\r\n", "\n", -1))
output := blackfriday.Run(input)

glog.Infof("INPUT: %s", string(input))
glog.Infof("INPUT HEX: %s", hex.EncodeToString(output))
glog.Infof("OUTPUT: %s", string(output))