Last active
October 11, 2018 13:26
-
-
Save henkman/5870bfe0b20c88976395f8ffe3347dae to your computer and use it in GitHub Desktop.
markdown to pdf converter
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"flag" | |
"fmt" | |
"io" | |
"io/ioutil" | |
"os" | |
"github.com/jung-kurt/gofpdf" | |
blackfriday "gopkg.in/russross/blackfriday.v2" | |
) | |
const FONT = "Times" | |
func renderHeading(pdf *gofpdf.Fpdf, node *blackfriday.Node) { | |
text := node.FirstChild | |
if text != nil { | |
switch node.HeadingData.Level { | |
case 1: | |
pdf.SetFont(FONT, "B", 32) | |
case 2: | |
pdf.SetFont(FONT, "B", 24) | |
case 3: | |
pdf.SetFont(FONT, "B", 18.72) | |
case 4: | |
pdf.SetFont(FONT, "B", 18.4) | |
case 5: | |
pdf.SetFont(FONT, "B", 13.28) | |
case 6: | |
fallthrough | |
default: | |
pdf.SetFont(FONT, "B", 10.72) | |
} | |
_, ht := pdf.GetFontSize() | |
pdf.Cell(0, ht, string(text.Literal)) | |
pdf.Ln(16) | |
} | |
} | |
func renderParagraph(pdf *gofpdf.Fpdf, node *blackfriday.Node, margin float64) { | |
cn := node.FirstChild | |
for cn != nil { | |
switch cn.Type { | |
case blackfriday.Text: | |
pdf.SetFont(FONT, "", 12) | |
_, ht := pdf.GetFontSize() | |
pdf.Write(ht, pdf.UnicodeTranslatorFromDescriptor("")(string(cn.Literal))) | |
case blackfriday.Link: | |
pdf.SetFont(FONT, "", 12) | |
_, ht := pdf.GetFontSize() | |
tit := cn.LinkData.Destination | |
if cn.FirstChild != nil { | |
tit = cn.FirstChild.Literal | |
} | |
trans := pdf.UnicodeTranslatorFromDescriptor("") | |
pdf.WriteLinkString(ht, trans(string(tit)), string(cn.LinkData.Destination)) | |
default: | |
fmt.Println("renderParagraph new type:", cn.Type) | |
} | |
cn = cn.Next | |
} | |
pdf.Ln(margin) | |
} | |
func renderList(pdf *gofpdf.Fpdf, node *blackfriday.Node, margin float64) { | |
left, _, _, _ := pdf.GetMargins() | |
pdf.SetLeftMargin(left * 2) | |
item := node.FirstChild | |
for item != nil { | |
c := item.FirstChild | |
for c != nil { | |
switch c.Type { | |
case blackfriday.Paragraph: | |
pdf.SetFont(FONT, "", 12) | |
_, ht := pdf.GetFontSize() | |
pdf.Write(ht, "- ") | |
renderParagraph(pdf, c, 5) | |
case blackfriday.List: | |
renderList(pdf, c, 0) | |
default: | |
fmt.Println("renderParagraph new type:", c.Type) | |
} | |
c = c.Next | |
} | |
item = item.Next | |
} | |
pdf.SetLeftMargin(left) | |
pdf.Ln(margin) | |
} | |
func main() { | |
var opts struct { | |
In string | |
Out string | |
} | |
flag.StringVar(&opts.In, "i", "", "input markdown file, if not supplied use stdin") | |
flag.StringVar(&opts.Out, "o", "", "output pdf file, if not supplied use stdout") | |
flag.Parse() | |
var in io.Reader | |
if opts.In == "" { | |
in = os.Stdin | |
} else { | |
fd, err := os.Open(opts.In) | |
if err != nil { | |
panic(err) | |
} | |
defer fd.Close() | |
in = fd | |
} | |
var out io.Writer | |
if opts.Out == "" { | |
out = os.Stdout | |
} else { | |
fd, err := os.OpenFile(opts.Out, os.O_WRONLY|os.O_TRUNC|os.O_CREATE, 0750) | |
if err != nil { | |
panic(err) | |
} | |
defer fd.Close() | |
out = fd | |
} | |
raw, err := ioutil.ReadAll(in) | |
if err != nil { | |
panic(err) | |
} | |
root := blackfriday.New().Parse(raw) | |
node := root.FirstChild | |
pdf := gofpdf.New("P", "mm", "A4", "") | |
pdf.AddPage() | |
for node != nil { | |
switch node.Type { | |
case blackfriday.Heading: | |
renderHeading(pdf, node) | |
case blackfriday.Paragraph: | |
renderParagraph(pdf, node, 10) | |
case blackfriday.List: | |
renderList(pdf, node, 5) | |
case blackfriday.HorizontalRule: | |
_, y := pdf.GetXY() | |
left, _, right, _ := pdf.GetMargins() | |
w, _ := pdf.GetPageSize() | |
pdf.Line(left, y, w-right, y) | |
pdf.DrawPath("") | |
pdf.Ln(5) | |
} | |
node = node.Next | |
} | |
if err := pdf.Output(out); err != nil { | |
panic(err) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment