mirror of
https://github.com/Dadido3/go-typst.git
synced 2025-04-11 12:13:16 +00:00
Rework passing-values example
This changes the example to use the template pattern; we now have a single Typst file containing a template function. Instead of loading and rendering the template, we will now generate temporary Typst markup that will import the template function and call it with custom data. This also means that it's pretty easy to test, preview and debug the template.typ outside of go-typst. All that is needed is another Typst file which will call the template with mock data. Also, we now use Compile instead of CompileWithVariables and inject encoded Go values into our temporary markup.
This commit is contained in:
parent
69bd0ed5b5
commit
9268a6691e
13
examples/passing-values/README.md
Normal file
13
examples/passing-values/README.md
Normal file
@ -0,0 +1,13 @@
|
||||
# Passing values example
|
||||
|
||||
This example demonstrates how to pass values to Typst, which can be useful in rendering custom documents such as reports, invoices, and more.
|
||||
|
||||
## How it works
|
||||
|
||||
This example follows the [template pattern](https://typst.app/docs/tutorial/making-a-template/) described in the Typst documentation.
|
||||
Here is a short overview of the files:
|
||||
|
||||
- [template.typ](template.typ) defines a Typst template function that constructs a document based on parameters.
|
||||
- [main.go](main.go) shows how to convert/encode Go values into Typst markup, and how to call/render the template with these converted values.
|
||||
- [template-preview.typ](template-preview.typ) also invokes the template while providing mock data.
|
||||
This is useful when you want to preview, update or debug the template.
|
@ -1,6 +1,7 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"log"
|
||||
"os"
|
||||
"time"
|
||||
@ -8,7 +9,7 @@ import (
|
||||
"github.com/Dadido3/go-typst"
|
||||
)
|
||||
|
||||
// DataEntry contains fake data to be passed to typst.
|
||||
// DataEntry contains data to be passed to Typst.
|
||||
type DataEntry struct {
|
||||
Name string
|
||||
Size struct{ X, Y, Z float64 }
|
||||
@ -25,21 +26,28 @@ var TestData = []DataEntry{
|
||||
}
|
||||
|
||||
func main() {
|
||||
typstCLI := typst.CLI{}
|
||||
var markup bytes.Buffer
|
||||
|
||||
r, err := os.Open("template.typ")
|
||||
if err != nil {
|
||||
log.Panicf("Failed to open template file for reading: %v.", err)
|
||||
// Inject Go values as Typst markup.
|
||||
if err := typst.InjectValues(&markup, map[string]any{"data": TestData, "customText": "This data is coming from a Go application."}); err != nil {
|
||||
log.Panicf("Failed to inject values into Typst markup: %v.", err)
|
||||
}
|
||||
defer r.Close()
|
||||
|
||||
// Import the template and invoke the template function with the custom data.
|
||||
// Show is used to replace the current document with whatever content the template function in `template.typ` returns.
|
||||
markup.WriteString(`
|
||||
#import "template.typ": template
|
||||
#show: doc => template(data, customText)`)
|
||||
|
||||
// Compile the prepared markup with Typst and write the result it into `output.pdf`.
|
||||
f, err := os.Create("output.pdf")
|
||||
if err != nil {
|
||||
log.Panicf("Failed to create output file: %v.", err)
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
if err := typstCLI.CompileWithVariables(r, f, nil, map[string]any{"Data": TestData}); err != nil {
|
||||
typstCLI := typst.CLI{}
|
||||
if err := typstCLI.Compile(&markup, f, nil); err != nil {
|
||||
log.Panicf("Failed to compile document: %v.", err)
|
||||
}
|
||||
}
|
||||
|
16
examples/passing-values/main_test.go
Normal file
16
examples/passing-values/main_test.go
Normal file
@ -0,0 +1,16 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
// Run the example as a test.
|
||||
func TestMain(t *testing.T) {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
t.Error(r)
|
||||
}
|
||||
}()
|
||||
|
||||
main()
|
||||
}
|
Binary file not shown.
@ -1,5 +1,12 @@
|
||||
#let Data = (
|
||||
// Prepare data that will be used as preview.
|
||||
#let data = (
|
||||
(Name: "Bell", Size: (X: 80, Y: 40, Z: 40), Created: datetime(year: 2010, month: 12, day: 1, hour: 12, minute: 13, second: 14), Numbers: (1, 2, 3)),
|
||||
(Name: "Bell", Size: (X: 80, Y: 40, Z: 40), Created: datetime(year: 2010, month: 12, day: 1, hour: 12, minute: 13, second: 14), Numbers: (10, 12, 15)),
|
||||
(Name: "Bell", Size: (X: 80, Y: 40, Z: 40), Created: datetime(year: 2010, month: 12, day: 1, hour: 12, minute: 13, second: 14), Numbers: (100, 109, 199, 200)),
|
||||
)
|
||||
)
|
||||
|
||||
#let customText = "Hey, this is example data to test the template."
|
||||
|
||||
// Invoke the template with the preview data and replace this whole document with the result.
|
||||
#import "template.typ": template
|
||||
#show: doc => template(data, customText)
|
@ -1,33 +1,36 @@
|
||||
#set page(paper: "a4")
|
||||
#let template(data, customText) = {
|
||||
set page(paper: "a4")
|
||||
|
||||
// Uncomment to use test data.
|
||||
//#import "template-test-data.typ": Data
|
||||
[= Example]
|
||||
|
||||
= List of items
|
||||
customText
|
||||
|
||||
#show table.cell.where(y: 0): strong
|
||||
#set table(
|
||||
stroke: (x, y) => if y == 0 {
|
||||
(bottom: 0.7pt + black)
|
||||
},
|
||||
)
|
||||
[== List of items]
|
||||
|
||||
#table(
|
||||
columns: 5,
|
||||
table.header(
|
||||
[Name],
|
||||
[Size],
|
||||
[Example box],
|
||||
[Created],
|
||||
[Numbers],
|
||||
),
|
||||
..for value in Data {
|
||||
(
|
||||
[#value.Name],
|
||||
[#value.Size],
|
||||
box(fill: black, width: 0.1mm * value.Size.X, height: 0.1mm * value.Size.Y),
|
||||
value.Created.display(),
|
||||
[#list(..for num in value.Numbers {([#num],)})],
|
||||
)
|
||||
}
|
||||
)
|
||||
show table.cell.where(y: 0): strong
|
||||
set table(
|
||||
stroke: (x, y) => if y == 0 {
|
||||
(bottom: 0.7pt + black)
|
||||
},
|
||||
)
|
||||
|
||||
table(
|
||||
columns: 5,
|
||||
table.header(
|
||||
[Name],
|
||||
[Size],
|
||||
[Example box],
|
||||
[Created],
|
||||
[Numbers],
|
||||
),
|
||||
..for value in data {
|
||||
(
|
||||
[#value.Name],
|
||||
[#value.Size],
|
||||
box(fill: black, width: 0.1mm * value.Size.X, height: 0.1mm * value.Size.Y),
|
||||
value.Created.display(),
|
||||
[#list(..for num in value.Numbers {([#num],)})],
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user