-
Notifications
You must be signed in to change notification settings - Fork 9
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Restate a theorem, or restate all theorems, elsewhere in document? #8
Comments
Here is a half-baked solution to your second question, using states: #import "@preview/ctheorems:1.1.0": *
#let state-theorems = state("state-theorems", [])
#let theorem = thmbox(
"thm-counter",
"Theorem",
namefmt: name => {
state-theorems.update(x => [#x (#name)])
(name)
},
bodyfmt: body => {
state-theorems.update(x => [#x #body
])
body
},
)
= Theorems
#theorem[Here we state the first theorem.]
Other content
#theorem("Euler")[This is the second statement.]
Yet more content
#theorem[This is the third.]
= Summary
#state-theorems.display() |
This feature is also very important for my use case. Specifically, I use the apxproof LaTeX package, which can automatically send proofs to the appendix and restate the theorem. https://ctan.math.illinois.edu/macros/latex/contrib/apxproof/apxproof.pdf |
There is probably some hacky way of doing this using states. On the other hand, @StarlightScribe Thank you for the reference to |
Update: Here's a very verbose way of achieving this; it uses states like @lumi-a suggested. The #import "@preview/ctheorems:1.1.2": *
#show: thmrules
#set page(width: 6in, height: auto, margin: 1cm)
#let theorems = state("theorems", ())
#let thmfmt(name, number, body, restate: false) = {
// Formatting
if name != none {
block[*Theorem #number* (#name)*.*#h(0.2em) #body]
} else {
block[*Theorem #number.*#h(0.2em) #body]
}
// Save information in state
if restate {
locate(loc => {
theorems.update(x => {
let thm = (
name: name,
number: number,
body: body,
location: loc
)
if x == none {
return (thm, )
} else {
return x + (thm, )
}
})
})
}
}
#let theorem = thmenv(
"theorem",
none,
none,
thmfmt
).with(
supplement: "Theorem"
)
#let proof = thmproof("proof", "Proof", inset: 0em)
//////
#theorem(restate: true)[
This theorem will be restated.
]
#theorem[
This theorem will _not_ be restated.
]
#theorem("Euler", restate: true)[
This theorem will also be restated!
]
#proof[
#lorem(30)
]
= Restated Theorems
#v(1em)
// #theorems.display()
#theorems.display(x => {
for thm in x {
// Extract number at correct location!
let number = thmcounters.at(thm.location).at("latest")
number = numbering("1.1", ..number)
// Show theorem
thmfmt(thm.name, number, thm.body)
}
}) |
I am planning on implementing this feature in v2.0.0, by adding |
Hi @sahasatvik, thank you for having considered, and implemented the ability for users to restate and defer theorems, corollaries, proofs, etc. 🎆 🥳 Having read the pdf and typ files shared in your comment, I'd be inclined to say that things are looking pretty good for a "version 1" of this feature. 😄 I noticed the clever implementation of (what I think are) custom keys 🔑 that could be used to label individual blocks (by "block" I mean a typst-theorem block): #corollary(restate: true,
restate-keys: ("Corollary", "Result") // Custom keys?
)
[
There are infinitely many composite numbers.
] ... and the ability to select which keys to filter in a restate call: = Only Theorems and Corollaries
#thm-restate("Theorem", "Corollary")
= Only 'Results'
#thm-restate("Result") The logic in Do you think that it'd be useful to offer users the ability to perform More generally, having the ability to involve logic in the filter seems helpful when working with lengthy documents containing a varied block types. For instance: = Section A
#corollary(restate: true,
restate-keys: ("A", "Important")
)
[ ... ]
= Section B
[...]
= Section C
[...]
= Section D
[...]
= List of Important Results
#thm-restate( ("A" and "Important") or ("C" and "Important) )
Due to the possible difficulty of letting users specify logic in the key filter, it might be worth considering delaying implementing this to a future version of this feature. 😃 |
That certainly makes a lot of sense, I should probably let Update: The example (output) now features custom filtering functions (a filtering function tests a Thanks for the feedback on this feature, I'll continue taking more suggestions for improvement! |
That was fast 😆. Thanks to your effort, in this implementation, from what I can tell, users are offered the ability to specify custom filters in DNF (disjunctive normal form), i.e., specify a filter in a form that's a disjunction of conjunctions: #thm-restate(("Theorem", "Result"), "Definition")
// Filter for blocks labelled: (Theorem ⋀ Result) ⋁ Definition . ... and also specify a filter based on the existence of a substring across keys: #thm-restate(keys => keys.any(x => x.contains("fi")))
// Blocks labelled with the "Definition" key will be
// restated in this call because the string "fi" is a substring
// in the key "Definition". Once again, thank you @sahasatvik 🙏🏻 . I believe this feature will benefit authors of textbooks when creating a summary of results, say for an end-of-chapter recall/review, and students who desire to distill particular results from their Typst notes into helpsheets for use in exams, or into an abridged version of their notes. |
I was mulling about how convenient it would be for someone writing a summary to have the ability to restate (i.e. re-print/ repeat) a theorem, or restate all theorems, elsewhere in the document, for example to restate theorems under a "List of Results" section.
Might someone know how to ...
... restate a theorem elsewhere in the document?
... restate all theorems elsewhere in the document? (maybe a script to traverse all theorems and print each one?)
... restate a selection of theorems elsewhere in the document? (This might be useful for generating a "List of Results" section at the end of each chapter)
The text was updated successfully, but these errors were encountered: