github.com/xyproto/orbiton/v2@v2.65.12-0.20240516144430-e10a419274ec/pdf.go (about) 1 package main 2 3 import ( 4 "fmt" 5 "strings" 6 "time" 7 8 "github.com/jung-kurt/gofpdf" 9 "github.com/xyproto/files" 10 ) 11 12 // SavePDF can save the text as a PDF document. It's pretty experimental. 13 func (e *Editor) SavePDF(title, filename string) error { 14 // Check if the file exists 15 if files.Exists(filename) { 16 return fmt.Errorf("%s already exists", filename) 17 } 18 19 // Build a large string with the document contents, while expanding tabs. 20 // Also count the maximum line length. 21 var sb strings.Builder 22 maxLineLength := 0 23 for i := 0; i < e.Len(); i++ { 24 line := e.Line(LineIndex(i)) 25 // Expand tabs for each line 26 sb.WriteString(strings.ReplaceAll(line, "\t", strings.Repeat(" ", e.indentation.PerTab)) + "\n") 27 // Count the maximum line length 28 if len(line) > maxLineLength { 29 maxLineLength = len(line) 30 } 31 } 32 contents := sb.String() 33 34 // If the lines are long, make the font smaller 35 var smallFontSize, largeFontSize float64 36 if maxLineLength > 100 { 37 smallFontSize = 8 // the text should never be smaller than 8 38 largeFontSize = 14 39 } else if maxLineLength > 80 { 40 smallFontSize = 9 41 largeFontSize = 14 42 } else { 43 smallFontSize = 10.0 44 largeFontSize = 14 45 } 46 47 // Create a timestamp for the current date, using the "2006-01-02" format 48 timestamp := time.Now().Format("2006-01-02") 49 50 // Use A4 and Unicode 51 pdf := gofpdf.New("P", "mm", "A4", "") 52 tr := pdf.UnicodeTranslatorFromDescriptor("") // "" defaults to "cp1252" 53 54 pdf.SetTopMargin(30) 55 56 // Top text 57 pdf.SetHeaderFunc(func() { 58 pdf.SetY(5) 59 pdf.SetFont("Helvetica", "", 8) 60 // Top right corner 61 pdf.CellFormat(0, 0, timestamp, "", 0, "R", false, 0, "") 62 }) 63 64 // Bottom text 65 pdf.SetFooterFunc(func() { 66 pdf.SetY(-15) 67 pdf.SetFont("Helvetica", "", 8) 68 // Bottom center 69 pdf.CellFormat(0, 10, fmt.Sprintf("%d", pdf.PageNo()), "", 0, "C", false, 0, "") 70 }) 71 72 pdf.AddPage() 73 pdf.SetY(20) 74 ht := pdf.PointConvert(8.0) 75 76 // Header 77 pdf.SetFont("Courier", "B", largeFontSize) 78 pdf.MultiCell(190, ht, tr(title+"\n\n"), "", "L", false) 79 pdf.Ln(ht) 80 81 // Body 82 pdf.SetFont("Courier", "", smallFontSize) 83 pdf.MultiCell(190, ht, tr(contents+"\n"), "", "L", false) 84 pdf.Ln(ht) 85 86 // Save to file 87 return pdf.OutputFileAndClose(filename) 88 }