mandolyte / mdtopdf

Markdown to PDF
MIT License
126 stars 31 forks source link

could not locate "helveticaBB" #18

Closed vladyslav2 closed 2 months ago

vladyslav2 commented 1 year ago

Problem

While working with this library I found an interesting case. If you create this markdown

### **Email:** issuer\_email

and when you try to convert, you will get an error:

➜  go run convert.go -i bad-markdown.md -o result.pdf 
2023/01/20 16:37:07 pdf.OutputFileAndClose() error:Pdf.OutputFileAndClose() error on result.pdf:could not locate "helveticaBB" among embedded core font definition files

Additional info My understanding, gotopdf missing some fonts for italic headers

mandolyte commented 1 year ago

@vladyslav2 Since the gotopdf project is closed, do you have any ideas about how to address this (short of forking it)?

vladyslav2 commented 1 year ago

@mandolyte based on the error, it looks like gotopdf does have some default settings for various fonts (italic, bold, semi-bold and etc) and helveticaBB does not support all of those font variations. My best shot - check gotopdf settings and see if its configurable

FrankStienhans2 commented 2 months ago

Debugged it. The request into the SetFont method is "Arial" with Style "bb". This is being converted to "Hevetica" with style "bb". This is not defined as can be seen here: https://github.com/go-pdf/fpdf/tree/main/font_embed

Screenshot 2024-06-19 at 10 47 30 AM

This proves of course that the issue is either in blackfriday parser or in mdtopdf

FrankStienhans2 commented 2 months ago

Not a fix but a functioning workaround:

func (r *PdfRenderer) processText(node *ast.Text) {
    currentStyle := r.cs.peek().textStyle
    if currentStyle.Style == "bb" { 
        currentStyle.Style = "b"
    }
    r.setStyler(currentStyle)
jessp01 commented 2 months ago

Hi @FrankStienhans2 ,

Thank you for the debugging info.

I'll take a look at it. Please note that a while back, I migrated the project from blackfriday to gomarkdown which is actively maintained (see https://github.com/mandolyte/mdtopdf/pull/40) but the issue is present when using that as well.

If you want a workaround pro tem, I'd suggest applying it in mdtopdf.go:setStyler() rather than in nodeProcessing.go:processText():

func (r *PdfRenderer) setStyler(s Styler) {
        if s.Style == "bb" {
            s.Style = "b"
        }
        r.Pdf.SetFont(s.Font, s.Style, s.Size)
        r.Pdf.SetTextColor(s.TextColor.Red, s.TextColor.Green, s.TextColor.Blue)
        r.Pdf.SetFillColor(s.FillColor.Red, s.FillColor.Green, s.FillColor.Blue)
}
jessp01 commented 2 months ago

So, the problem is here: https://github.com/mandolyte/mdtopdf/blob/master/nodeProcessing.go#L299

This can be easily solved with something like:

if entering {
                if ! strings.Contains(r.cs.peek().textStyle.Style, "b"){
                    r.cs.peek().textStyle.Style += "b"
                }
...

But, because the code (rightly) removes the "b" when entering is false, with this change, the sample MD input (## **Email**: issuer\_email) would result in Email being bold and the remainder of the header ("issuer_email") in "normal" style. I can address this by checking whether the parent element is a header but I suppose the real question is why would one use ** (strong markup) within a header to begin with, considering the fact that headers are typically rendered in bold anyway, as they are (by default) in mdtopdf (see https://github.com/mandolyte/mdtopdf/blob/master/mdtopdf.go#L154). Could you please tell me what your expectation is for such an input?

Cheers,

Xanvial commented 2 months ago

Hello, I encountered similar error, for me the expectation is, it should ignore the strong markup. So will print as a header only.

For now I need to manually remove the ** markdown if it's exist inside a header