In articles it is sometimes helpful to have unnumbered equations appear interlaced with numbered ones, the latter being referenced in the document.
How might I write the #set math.equation(numbering: (params) => output) rule so that only equations with reference tags are numbered? Is this something that would need language support to implement?
I figured out a solution. Create the following function
#let equ(eq, id: none) = {
let body = if type(id) == none {eq} else if type(id) == label [#eq #id] else [#eq <#id>]
let numbering = if type(id) != none { "(1)" } else { none }
set math.equation(numbering: numbering)
body
}
Then you can control the showing of labels by setting the argument id. For example,
#lorem(50) As shown in @eq:eq1,
#equ($
y = a x + b
$, id: <eq:eq1>)
#lorem(100)
#equ($
E = m c^2
$)
#lorem(50)
Later I will try to figure out how to achieve this without using a custom function. But such a function is helpful. You can avoid the math equation breaking paragraphs with this
#let equ(eq, id: none) = {
let body = if id == none {eq} else if type(id) == label [#eq #id] else [#eq #label(id)]
let numbering = if id != none { "(1)" } else { none }
set math.equation(numbering: numbering)
linebreak()
box(body, width: 1fr)
linebreak()
}
In this case, display equations are really “in” the paragraph, not “between” two paragraphs.
And here is another solution without the help of a equ function. Put the following code before your document’s main body.
#show: body => {
for elem in body.children {
if elem.func() == math.equation and elem.block {
let numbering = if "label" in elem.fields().keys() { "(1)" } else { none }
set math.equation(numbering: numbering)
elem
} else {
elem
}
}
}
And you can also append some other settings like this comment.
In this case, the following script
#lorem(30)
$ y = a x + b $ <eq:eq2>
#lorem(19)
@eq:eq2 #lorem(20)
$ E = m c^2 $
#lorem(10)
Hey @Aegon, quick tip! The syntax <#id> produces a label literally containing #id (that is, a hash, the letter “i”, and the letter “d”), not a label with the contents of the variable named id. Rather, you should write label(id) (use the label constructor) if you’d like to construct a label from a dynamic string. Hope this helps in the future!
@Christopher_Marcotte Unfortunately, this solution cannot work on equations in lists, enums, etc. To solve this, it is still necessary to define a function which applies the for-loop to its body argument.
#set math.equation(numbering: "(1)")
#show math.equation: it => {
if not it.has("label") {
let fields = it.fields()
fields.remove("body")
fields.numbering = none
return [#counter(math.equation).update(v => v - 1)#math.equation(..fields, it.body)<math-equation-without-label>]
}
return it
}
$ x + y $
$ x + y + z $ <with-label>