pinpoint
#pinpoint(anchor, excerpt: false, parens: true, verb: auto, show-page: true, quotes: false, format: auto, mode: auto, on-empty: auto)pinpoint(<anchor>) searches the manuscript for every passage carrying that anchor and reports where it is — the mechanism behind the real page numbers a response letter cites, since the manuscript and the letter share one bundle.
Page only, by default
#import "../../lib.typ": *
#document("manuscript.png")[
#set page(width: 16.6cm, height: auto, margin: 12pt)
#set text(size: 10.5pt)
#passage(<r1-1>)[The sample size #rep[was not justified][was determined by a power calculation].]
]
#document("response.png")[
#set page(width: 16.6cm, height: auto, margin: 12pt)
#set text(size: 10.5pt)
#reviewer(1)[
#exchange(<r1-1>)[The sample size is not justified.][
We thank the reviewer. #pinpoint(<r1-1>)
]
]
]
Manuscript:
Response:
The same anchor on two passages, on different pages, reports both:
#import "../../lib.typ": *
#document("manuscript.pdf")[
#set page(width: 16.6cm, height: auto, margin: 12pt)
#set text(size: 10.5pt)
#passage(<r1-1>)[This revision responds to a single comment that required changes in two separate sections.]
#pagebreak()
#passage(<r1-1>)[The same comment, addressed a second time here.]
]
#document("response.png")[
#set page(width: 16.6cm, height: auto, margin: 12pt)
#set text(size: 10.5pt)
#reviewer(1)[
#exchange(<r1-1>)[A single comment requiring changes in two places.][
Addressed in both places. #pinpoint(<r1-1>)
]
]
]
Manuscript, page 1:
Manuscript, page 2:
Response:
If the anchor matches no real add/del/rep mark anywhere — a touched passage, cited only to point at text that didn’t change — the verb switches from “modified on” to “see” automatically. Not a style choice: asserting a change that didn’t happen would simply be false, so nothing has to be configured for it.
parens: and verb: — fitting the citation into a sentence
The wired-in parenthetical reads fine as a trailing citation (“We addressed this concern (modified on p. 3).”), but not every sentence ends that way:
#import "../../lib.typ": *
#document("manuscript.png")[
#set page(width: 16.6cm, height: auto, margin: 12pt)
#set text(size: 10.5pt)
#passage(<r1-1>)[The sample size #rep[was not justified][was determined by a power calculation].]
#touched(<r1-2>)[We kept the eligibility criteria exactly as submitted.]
]
#document("response.png")[
#set page(width: 16.6cm, height: auto, margin: 12pt)
#set text(size: 10.5pt)
#reviewer(1)[
#exchange(<r1-1>)[The sample size is not justified.][
See #pinpoint(<r1-1>, parens: false, verb: none) for the updated wording.
]
#exchange(<r1-2>)[Please confirm the eligibility criteria are unchanged.][
Confirmed --- #pinpoint(<r1-2>).
]
]
]
Manuscript:
Response:
parens: false drops the parentheses; verb: none additionally drops “modified on”/“see”, leaving only “p. 3” (or “p. 3 and p. 7” for two pages) — for a sentence, like See #pinpoint(<r>, parens: false, verb: none) for the updated wording., that already supplies its own verb. The two are independent: parens: false alone still says “modified on p. 3” without the parentheses; verb: none alone keeps the parentheses around a bare page number. Neither one alone fits every sentence shape — that’s why both exist rather than a single “compact” switch.
excerpt: true — quoting the real text
Rather than a page number, the actual content of every passage carrying the anchor — exactly as it reads in the manuscript right now, so it can never go stale:
#import "../../lib.typ": *
#document("manuscript.png")[
#set page(width: 16.6cm, height: auto, margin: 12pt)
#set text(size: 10.5pt)
#passage(<r1-1>)[The sample size #rep[was not justified][was determined by a power calculation].]
#deleted(<r1-2>, summary: [an outdated caveat about generalizability])[
An earlier caveat about generalizability, no longer needed.
]
]
#document("response.png")[
#set page(width: 16.6cm, height: auto, margin: 12pt)
#set text(size: 10.5pt)
#reviewer(1)[
#exchange(<r1-1>)[The sample size is not justified.][
Addressed as follows: #pinpoint(<r1-1>, excerpt: true)
]
#exchange(<r1-2>)[This caveat is no longer accurate.][
Agreed: #pinpoint(<r1-2>, excerpt: true)
]
]
]
Manuscript:
Response:
A passage declared with summary: ignores excerpt and always renders “Removed: ‹summary›” instead, as the second comment above shows — there being no meaningful text left to quote in the clean manuscript once the passage is fully removed.
show-page: and quotes: — dropping the page, adding real quotation marks
#import "../../lib.typ": *
#document("manuscript.png")[
#set page(width: 16.6cm, height: auto, margin: 12pt)
#set text(size: 10.5pt)
#passage(<r1-1>)[The sample size #rep[was not justified][was determined by a power calculation].]
]
#document("response.png")[
#set page(width: 16.6cm, height: auto, margin: 12pt)
#set text(size: 10.5pt)
#reviewer(1)[
#exchange(<r1-1>)[The sample size is not justified.][
#pinpoint(<r1-1>, excerpt: true, quotes: true)
On page 1: #pinpoint(<r1-1>, excerpt: true, show-page: false)
]
]
]
Manuscript:
Response:
show-page: false drops the leading *p. 1* — — for a sentence that already states where the excerpt comes from (“On page 1, ‹excerpt›”), or a caller who simply doesn’t want it. quotes: true wraps the excerpt in real, typeset quotation marks via Typst’s native quote().
quotes: true only ever requests quotation marks — a passage whose content is a figure, a table, or a block equation never gets them, regardless of this setting: forcing quotation marks onto a figure produces two stray quote glyphs sitting alone above and below it, not an improvement, so this is detected and declined automatically rather than left for you to remember passage by passage.
mode: — overriding style for one excerpt
An excerpt renders, by default, in whichever mode the current compile is running under — clean text in response.pdf, struck-through/underlined tracked style in response-tracked.pdf (both produced automatically once exchanges is set, see The letter, automatically below). mode: overrides this for one call, in either direction.
mode: "tracked", called from a clean letter, shows the tracked style even though response.pdf itself is otherwise all clean text:
#import "../../lib.typ": *
#document("manuscript.png")[
#set page(width: 16.6cm, height: auto, margin: 12pt)
#set text(size: 10.5pt)
#passage(<r1-1>)[The sample size #rep[was not justified][was determined by a power calculation].]
]
#document("response.png")[
#set page(width: 16.6cm, height: auto, margin: 12pt)
#set text(size: 10.5pt)
#reviewer(1)[
#exchange(<r1-1>)[The sample size is not justified.][
Compare the wording: #pinpoint(<r1-1>, excerpt: true, mode: "tracked")
]
]
]
Manuscript:
Response:
Useful when the point being made is “we removed exactly what you objected to,” which a clean, final-text quote doesn’t convey on its own.
The reverse also works: mode: "clean", called from a letter compiled tracked (--input variant=tracked, exchanges set), shows the final wording for one excerpt even though the rest of that same letter is otherwise quoting tracked style:
#import "../../lib.typ": *
#import "../../../typst-contexture/lib.typ" as contexture
#let my-template(body) = {
set page(width: 16.6cm, height: auto, margin: 12pt)
set text(size: 10.5pt)
body
}
#let exchanges = reviewer(1)[
#exchange(<r1-1>)[This claim needs more support.][
We have expanded this sentence. #pinpoint(<r1-1>, excerpt: true, mode: "clean")
]
]
#show: contexture.bundle.with(
template: my-template,
documents: (letter(exchanges: exchanges, template: my-template),),
)
#passage(<r1-1>)[The treatment #rep[has an effect][has a clinically meaningful effect] on survival.]
Manuscript, tracked:
Response, tracked — the excerpt still reads as accepted, final text, despite the compile being tracked:
on-empty: and format:
#import "../../lib.typ": *
#set page(width: 16.6cm, height: auto, margin: 12pt)
#set text(size: 10.5pt)
#set-revisions(require-exchange: false)
No anchor `<r9-9>` exists anywhere in this document.
Default `on-empty:` warns: #pinpoint(<r9-9>)
#pinpoint(<r9-9>, on-empty: none) shows nothing instead when given `on-empty: none`.
#pinpoint(<r9-9>, on-empty: [not found in this round]) shows custom content instead, given as `on-empty:`.
#passage(<r2-1>)[A change #add[on this page].]
Default wording: #pinpoint(<r2-1>)
Custom `format:`: #pinpoint(<r2-1>, format: (pages, has-marks) => [(see line 1 of p. #pages.first())])
on-empty: controls what happens when no passage anywhere carries the given anchor — auto (the default) warns, none shows nothing, anything else is shown as-is. format: replaces the default page-list wording entirely, with a function (pages-array, has-marks) -> content — has-marks is the same flag that drives the automatic “modified”/“see” switch above, passed through so a fully custom format can make that same distinction without querying the bundle again. For a journal with its own citation convention.
| ← Writing the exchanges | xref → |