Skip to content

Commit

Permalink
Support custom themes (by passing a JSON file).
Browse files Browse the repository at this point in the history
  • Loading branch information
jessp01 committed Feb 10, 2025
1 parent 3aa52c0 commit 32edd0c
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 32 deletions.
39 changes: 25 additions & 14 deletions cmd/md2pdf/md2pdf.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ var author = flag.String("author", "", "Author; used if -footer is passed")
var unicodeSupport = flag.String("unicode-encoding", "", "e.g 'cp1251'")
var fontFile = flag.String("font-file", "", "path to font file to use")
var fontName = flag.String("font-name", "", "Font name ID; e.g 'Helvetica-1251'")
var themeArg = flag.String("theme", "light", "[light|dark]")
var themeArg = flag.String("theme", "light", "[light | dark | /path/to/custom/theme.json]")
var hrAsNewPage = flag.Bool("new-page-on-hr", false, "Interpret HR as a new page; useful for presentations")
var printFooter = flag.Bool("with-footer", false, "Print doc footer (author title page number)")
var pageSize = flag.String("page-size", "A4", "[A3 | A4 | A5]")
Expand Down Expand Up @@ -140,38 +140,49 @@ func main() {
}

theme := mdtopdf.LIGHT
textColor := mdtopdf.Colorlookup("black")
fillColor := mdtopdf.Colorlookup("white")
backgroundColor := "white"
themeFile := ""
if *themeArg == "dark" {
theme = mdtopdf.DARK
backgroundColor = "black"
textColor = mdtopdf.Colorlookup("darkgray")
fillColor = mdtopdf.Colorlookup("black")
}else if _, err := os.Stat(*themeArg); err == nil {
theme = mdtopdf.CUSTOM
themeFile = *themeArg
}

pf := mdtopdf.NewPdfRenderer(*orientation, *pageSize, *output, *logFile, opts, theme)
params := mdtopdf.PdfRendererParams{
Orientation: *orientation,
Papersz: *pageSize,
PdfFile: *output,
TracerFile: *logFile,
Opts: opts,
Theme: theme,
CustomThemeFile: themeFile,
FontFile: *fontFile,
FontName: *fontName,
}

pf := mdtopdf.NewPdfRenderer(params)
if inputBaseURL != "" {
pf.InputBaseURL = inputBaseURL
}
pf.Pdf.SetSubject(*title, true)
pf.Pdf.SetTitle(*title, true)
pf.BackgroundColor = mdtopdf.Colorlookup(backgroundColor)
pf.Extensions = parser.NoIntraEmphasis | parser.Tables | parser.FencedCode | parser.Autolink | parser.Strikethrough | parser.SpaceHeadings | parser.HeadingIDs | parser.BackslashLineBreak | parser.DefinitionLists

if *fontFile != "" && *fontName != "" {
pf.Pdf.AddFont(*fontName, "", *fontFile)
pf.Pdf.SetFont(*fontName, "", 12)
pf.Normal = mdtopdf.Styler{Font: *fontName, Style: "",
pf.Normal = mdtopdf.Styler{
Font: *fontName,
Style: "",
Size: 12, Spacing: 2,
FillColor: fillColor,
TextColor: textColor}
TextColor: pf.Normal.TextColor,
}

}

if *printFooter {
pf.Pdf.SetFooterFunc(func() {
color := mdtopdf.Colorlookup(backgroundColor)
pf.Pdf.SetFillColor(color.Red, color.Green, color.Blue)
pf.Pdf.SetFillColor(pf.BackgroundColor.Red, pf.BackgroundColor.Green, pf.BackgroundColor.Blue)
// Position at 1.5 cm from bottom
pf.Pdf.SetY(-15)
// Arial italic 8
Expand Down
72 changes: 54 additions & 18 deletions mdtopdf.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,10 @@ package mdtopdf
import (
"bufio"
"fmt"
"log"
"io"
"os"
"encoding/json"

"strings"

Expand Down Expand Up @@ -60,10 +62,12 @@ type RenderOption func(r *PdfRenderer)
type Theme int

const (
// DARK const
// DARK theme const
DARK Theme = 1
// LIGHT const
// LIGHT theme const
LIGHT Theme = 2
// CUSTOM theme const
CUSTOM Theme = 3
)

// PdfRenderer is the struct to manage conversion of a markdown object
Expand Down Expand Up @@ -229,48 +233,72 @@ func (r *PdfRenderer) SetDarkTheme() {

}

func (r *PdfRenderer) SetCustomTheme(themeJsonFile string) {

Check failure on line 236 in mdtopdf.go

View workflow job for this annotation

GitHub Actions / build

exported method PdfRenderer.SetCustomTheme should have comment or be unexported

Check failure on line 236 in mdtopdf.go

View workflow job for this annotation

GitHub Actions / build

method parameter themeJsonFile should be themeJSONFile

config, err := os.ReadFile(themeJsonFile)
if err != nil {
log.Fatal(err)
}
// Fill the instance from the JSON file content
err = json.Unmarshal(config, &r)
log.Printf("BackgroundColor: %v\n", r.BackgroundColor)
// Check if is there any error while filling the instance
if err != nil {
panic(err)
}
}

type PdfRendererParams struct {

Check failure on line 251 in mdtopdf.go

View workflow job for this annotation

GitHub Actions / build

exported type PdfRendererParams should have comment or be unexported
Orientation, Papersz, PdfFile, TracerFile, FontFile, FontName string
Opts []RenderOption
Theme Theme
CustomThemeFile string
}

// NewPdfRenderer creates and configures an PdfRenderer object,
// which satisfies the Renderer interface.
func NewPdfRenderer(orient, papersz, pdfFile, tracerFile string, opts []RenderOption, theme Theme) *PdfRenderer {
func NewPdfRenderer(params PdfRendererParams) *PdfRenderer {

r := new(PdfRenderer)

// set filenames
r.pdfFile = pdfFile
r.tracerFile = tracerFile
r.pdfFile = params.PdfFile
r.tracerFile = params.TracerFile

// Global things
r.orientation = "portrait"
if orient != "" {
r.orientation = orient
if params.Orientation != "" {
r.orientation = params.Orientation
}

r.units = "pt"
r.papersize = "Letter"
if papersz != "" {
r.papersize = papersz
if params.Papersz != "" {
r.papersize = params.Papersz
}

r.fontdir = "."

r.Theme = theme
if theme == 0 {
r.Theme = LIGHT
}
r.Theme = params.Theme

r.Pdf = fpdf.New(r.orientation, r.units, r.papersize, r.fontdir)

r.Pdf.SetHeaderFunc(func() {
r.SetPageBackground("", r.BackgroundColor)
})

r.Pdf.AddPage()
switch r.Theme {
case DARK:
r.SetDarkTheme()
r.SetDarkTheme()
case LIGHT:
r.SetLightTheme()
r.SetLightTheme()
case CUSTOM:
if params.CustomThemeFile != "" {
log.Printf("Custom: %s\n", params.CustomThemeFile)
r.SetCustomTheme(params.CustomThemeFile)
}
}
r.Pdf.AddPage()
// set default font
r.setStyler(r.Normal)
r.mleft, r.mtop, r.mright, r.mbottom = r.Pdf.GetMargins()
Expand All @@ -283,7 +311,7 @@ func NewPdfRenderer(orient, papersz, pdfFile, tracerFile string, opts []RenderOp
textStyle: r.Normal, leftMargin: r.mleft}
r.cs.push(initcurrent)

for _, o := range opts {
for _, o := range params.Opts {
o(r)
}

Expand All @@ -297,8 +325,16 @@ func NewPdfRendererWithDefaultStyler(orient, papersz, pdfFile, tracerFile string
opts = append(opts, func(r *PdfRenderer) {
r.Normal = defaultStyler
})
params := PdfRendererParams{
Orientation: orient,
Papersz: papersz,
PdfFile: pdfFile,
TracerFile: tracerFile,
Opts: opts,
Theme: theme,
}

return NewPdfRenderer(orient, papersz, pdfFile, tracerFile, opts, theme)
return NewPdfRenderer(params)
}

// Process takes the markdown content, parses it to generate the PDF
Expand Down

0 comments on commit 32edd0c

Please sign in to comment.