What is the typst-way to achieve this (R-code annotated with math line by line). Is there a way to escape raw-mode, or do I use a table, but then if I use a table to ensure code and math are aligned how do I indent to code snippets etc…?
Hi @Manor_Askenazi, could you maybe try to revise your post’s title to be a complete question as per the question guidelines:
Good titles are questions you would ask your friend about Typst.
Adding tags like layout would be useful too! We hope by adhering to this, we make the information in this forum easy to find in the future. Thanks!
as for your question, yes a table or grid would be the solution here. You can simply use raw and math content as the table cells:
#grid(
columns: (1fr, auto),
align: horizon,
```r
x <- 0
```,
$ x = 0\ a $,
)
and indent like you’re used to.
Edit: a downside is that the width of the code and equations can’t “overlap” if it fits for a particular row. I don’t think there should be any problems if you simply do one grid per row, then that isn’t an issue.
Simply make a function
#let aline(..docs) = {
grid(
columns: (1fr, auto),
align: (left, right),
..docs
)
}
Then the following code should look like this:
#aline[``` t_multiplier = 5; min_rate = 0.1 ; prior = 0.2```][$lambda_i^T = 5 lambda_i^F quad pi_r = 0.2$]
#aline[``` no equaion ok```]
#aline[``` bigger equation also ok```][$max((sum_(i = 1)^oo 1 / i^2) / (product_(i = 1)^oo (1 + 1 / i^2)))$]
``` hybrid of aline and bare raw block```
#aline[```
might not be satisfing for
multiple
lines```]
Here is another, slightly more complex function to keep the code in one raw block (Please excuse any typos in the example):
#let annotate-code(code, annotations) = {
// Map the annotations to a dictionary for easy access
let dict = annotations.map(((row, a)) => (str(row), a)).to-dict()
let numbering = numbering.with("1")
show raw.line: it => context {
let num-width = measure(numbering(it.count)).width // Numbering shenanigens (not really necessary)
set block(spacing: 0em)
grid(
columns: (auto, 1fr, auto),
align: (right + horizon, left + horizon, right + horizon),
box(
width: num-width + 1em,
inset: (right: 1em),
text(fill: gray, numbering(it.number)),
),
it.body,
if str(it.number) in dict {
dict.at(str(it.number))
} else {
[]
},
)
}
code
}
You can then use the function as follows:
#annotate-code(
```R
t_multiplier = 5; min_rate = 0.1; prior = 0.2
replicate_psms <- c(19, 28, 25) # BIRC example from
control_psms <- c( 0, 0, 0) # KRAS4A Pull-Down
lambda <- max(mean(control_psms), min_rate)
rep_scores <- c()
for (x in replicate_psms) {
p_t_x <- prior * dpois(x, t_multiplier * lambda)
p_f_x <- (1 - prior) * dpois(x, lambda)
p_x <- p_t_x + p_f_x
if (p_x > 0 ) {
rep_score <- p_t_x / p_x
} else {
stopifnot(x > t_multiplier * lambda)
rep_score <- 1
}
rep_scores <- c(rep_scores, rep_score)
}
score <- mean(rep_scores)
```,
(
(1, $ lambda_i^tau = 5 lambda_i^F quad pi_tau = 0.2 $),
(
5,
$
hat(lambda_i^F) = max((sum_(c = 1)^(N_italic("controls")) x_c) / N_italic("controls"), 0.1)
$,
),
(8, $ pi_tau P(x; lambda_i^tau) $),
(9, $ (1 - pi_tau) P(x; lambda_i^F) $),
(10, $ pi_tau P(x; lambda_i^tau) + (1 - pi_tau) P(x; lambda_i^F) $),
(
12,
$
P(Z_i = 1 | X_i = x) = (pi_tau P(x; lambda_i^tau)) / (pi_tau P(x; lambda_i^tau) + (1 - pi_tau) P(x; lambda_i^F))
$,
),
(
17,
$
italic("Score")_i = (sum_(r = 1)^(N_italic("replicates") P(Z_i = 1 | X_i = x_r))) / N_italic("replicates")
$,
),
),
)