Added object metadata & references
This commit is contained in:
parent
273e503d3f
commit
73d45c38f6
@ -151,34 +151,96 @@
|
|||||||
// MARK: Sections
|
// MARK: Sections
|
||||||
//
|
//
|
||||||
|
|
||||||
#let generic(t) = block(
|
/// Core render code for all objects (problems, theorems, etc)
|
||||||
|
/// This should never be used directly by client code.
|
||||||
|
///
|
||||||
|
/// Args:
|
||||||
|
/// - kind: the kind of object to make ("Problem", "Definition", etc)
|
||||||
|
/// - label_name: a string. If provided, generate metadata for this object
|
||||||
|
/// under the given label. Labels must be unique, and are prefixed with `obj`
|
||||||
|
/// This label can then be used to reference this object.
|
||||||
|
///
|
||||||
|
/// For example:
|
||||||
|
/// ```
|
||||||
|
/// #problem(label: "problem1")
|
||||||
|
/// This is @obj:problem1
|
||||||
|
/// ```
|
||||||
|
#let _obj_base(kind, ..args, label_name: none) = {
|
||||||
|
counter("obj").step()
|
||||||
|
let n = context counter("obj").get().first()
|
||||||
|
|
||||||
|
// The complete title text of this object,
|
||||||
|
// like "Problem 5:" or "Theorem: "
|
||||||
|
let obj_content = if args.pos().len() == 0 {
|
||||||
|
[#kind #n:]
|
||||||
|
} else {
|
||||||
|
[#kind #n: #args.pos().at(0)]
|
||||||
|
}
|
||||||
|
|
||||||
|
// Render the object
|
||||||
|
block(
|
||||||
above: 8mm,
|
above: 8mm,
|
||||||
below: 2mm,
|
below: 2mm,
|
||||||
text(weight: "bold", t),
|
text(weight: "bold", obj_content),
|
||||||
)
|
|
||||||
|
|
||||||
#let _generic_base(kind, ..args) = {
|
|
||||||
counter("obj").step()
|
|
||||||
if args.pos().len() == 0 {
|
|
||||||
generic([
|
|
||||||
#kind
|
|
||||||
#context counter("obj").display():
|
|
||||||
])
|
|
||||||
} else {
|
|
||||||
generic(
|
|
||||||
[
|
|
||||||
#kind
|
|
||||||
#context counter("obj").display():
|
|
||||||
]
|
|
||||||
+ " "
|
|
||||||
+ args.pos().at(0),
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Generate labeled metadata for this object.
|
||||||
|
//
|
||||||
|
// This can be viewed directly with `#context query(<label>).first().value`,
|
||||||
|
// Or referenced with `@label` (we define a custom renderer for this metadata later)
|
||||||
|
if label_name != none {
|
||||||
|
let label_name = "obj:" + label_name
|
||||||
|
let meta = (
|
||||||
|
"obj_meta_ref_kind": kind,
|
||||||
|
// "obj_content": obj_content,
|
||||||
|
"label": label(label_name),
|
||||||
|
"counter": counter("obj"),
|
||||||
|
)
|
||||||
|
[ #metadata(meta) #label(label_name) ]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#let problem(..args) = _generic_base("Problem", ..args)
|
// `ref` implementation for object meta-references,
|
||||||
#let definition(..args) = _generic_base("Definition", ..args)
|
// see `show: ref`.
|
||||||
#let theorem(..args) = _generic_base("Theorem", ..args)
|
#let _ref_obj(it) = {
|
||||||
|
let magic_key = "obj_meta_ref_kind"
|
||||||
|
if not (
|
||||||
|
it.element != none
|
||||||
|
and it.element.has("value")
|
||||||
|
and type(it.element.value) == "dictionary"
|
||||||
|
and it.element.value.keys().contains(magic_key)
|
||||||
|
) {
|
||||||
|
// This label is not attached to object metadata
|
||||||
|
return none
|
||||||
|
}
|
||||||
|
|
||||||
|
let v = it.element.value
|
||||||
|
let obj_type = v.at(magic_key)
|
||||||
|
|
||||||
|
// The value of this object's counter at its label
|
||||||
|
let obj_count = v.counter.at(v.label).first()
|
||||||
|
|
||||||
|
// Produces text like "Problem 2",
|
||||||
|
// which takes you to the referenced object when clicked.
|
||||||
|
link(v.label, [#obj_type #obj_count])
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Factory function for objects.
|
||||||
|
/// Provided for convenience, lets us define objects in one line.
|
||||||
|
#let _mkobj(kind) = {
|
||||||
|
let out(..args, label: none) = _obj_base(
|
||||||
|
kind,
|
||||||
|
..args,
|
||||||
|
label_name: label,
|
||||||
|
)
|
||||||
|
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#let problem = _mkobj("Problem")
|
||||||
|
#let definition = _mkobj("Definition")
|
||||||
|
#let theorem = _mkobj("Theorem")
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
@ -272,6 +334,14 @@
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
show ref: it => {
|
||||||
|
// Custom impl for object references
|
||||||
|
let x = _ref_obj(it)
|
||||||
|
if (x != none) { return x }
|
||||||
|
|
||||||
|
return it // Use default `ref` implementation
|
||||||
|
}
|
||||||
|
|
||||||
make_title(
|
make_title(
|
||||||
group,
|
group,
|
||||||
quarter,
|
quarter,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user