Skip to content

Commit

Permalink
synthesize
Browse files Browse the repository at this point in the history
  • Loading branch information
PgBiel committed Jan 7, 2025
1 parent f965fba commit 21e4933
Show file tree
Hide file tree
Showing 4 changed files with 83 additions and 3 deletions.
45 changes: 42 additions & 3 deletions src/element.typ
Original file line number Diff line number Diff line change
Expand Up @@ -993,12 +993,21 @@
prefix: "",
typecheck: true,
allow-unknown-fields: false,
synthesize: none,
contextual: auto,
) = {
assert(type(display) == function, message: "element: please specify a show rule in 'display:' to determine how your element is displayed.")
assert(type(fields) == array, message: "element: please specify an array of fields, creating each field with the 'field' function.")
assert(type(prefix) == str, message: "element: the prefix must be a string.")
assert(type(typecheck) == bool, message: "element: the 'typecheck' argument must be a boolean (true to enable typechecking, false to disable).")
assert(type(allow-unknown-fields) == bool, message: "element: the 'allow-unknown-fields' argument must be a boolean.")
assert(synthesize == none or type(synthesize) == function, message: "element: 'synthesize' must be 'none' or a function element fields => element fields.")
assert(contextual == auto or type(contextual) == bool, message: "element: 'contextual' must be 'auto' (true if using a contextual feature) or a boolean (true to wrap the output in a 'context { ... }', false to not).")

if contextual == auto {
// Provide separate context for synthesize.
contextual = synthesize != none
}

let eid = base.unique-id(prefix, name)
let lbl-show = label(lbl-show-head + eid)
Expand Down Expand Up @@ -1227,9 +1236,39 @@
finalized-chain
}

let body = display(constructed-fields)
let tag = [#metadata((kind: "instance", body: body, fields: constructed-fields, func: modified-constructor, eid: eid, fields-known: true, valid: true))]
let shown = [#[#body#tag]#lbl-show]
let shown = {
let tag = (kind: "instance", body: none, fields: constructed-fields, func: modified-constructor, eid: eid, fields-known: true, valid: true)

if contextual {
// Use context for synthesize as well
context {
let synthesized-fields = if synthesize == none {
constructed-fields
} else {
synthesize(constructed-fields)
}
let body = display(synthesized-fields)

let tag = tag
tag.fields = synthesized-fields
tag.body = body

[#[#body#metadata(tag)]#lbl-show]
}
} else {
let synthesized-fields = if synthesize == none {
constructed-fields
} else {
synthesize(constructed-fields)
}
let body = display(synthesized-fields)

tag.fields = synthesized-fields
tag.body = body

[#[#body#metadata(tag)]#lbl-show]
}
}

if data-changed {
show lbl-get: set bibliography(title: [#metadata(global-data)#lbl-get])
Expand Down
1 change: 1 addition & 0 deletions test/unit/elements/synthesize/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# added by typst-test
Binary file added test/unit/elements/synthesize/ref/1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
40 changes: 40 additions & 0 deletions test/unit/elements/synthesize/test.typ
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#import "/test/unit/base.typ": empty
#show: empty

#import "/src/lib.typ" as e: element, field

#let count = counter("adb")

#let (wock, wock-e) = element(
"wock",
display: it => {
assert.eq(it.color, red)
assert.eq(it.inner, [Hello!])
(it.test)()
},
fields: (
field("color", color, default: red),
field("inner", content, default: [Hello!]),
field("test", function, default: () => {})
),
synthesize: it => {
it.resolved-value = count.get().first()
it
}
)

#show wock-e.sel: it => {
count.step()
it
}

#wock(test: () => count.get().first() == 0)
#wock(test: () => count.get().first() == 1)
#wock(test: () => count.get().first() == 2)

#show wock-e.sel: it => {
assert.eq(e.data(it).fields.resolved-value, 3)
it
}

#wock()

0 comments on commit 21e4933

Please sign in to comment.