This repository has no description
1#let cut-lines = (
2 starts,
3 ends,
4 content,
5 keep_delimiting: false,
6) => {
7 let lines = content.split(regex("\r?\n"))
8 let predicate = pred => if type(pred) == str {
9 it => it.trim() == str
10 } else if type(pred) == function {
11 pred
12 } else if type(pred) == regex {
13 it => it.find(pred) != none
14 } else {
15 panic("cut-between predicates must be strings or functions")
16 }
17 let start_index = lines.position(predicate(starts))
18
19 if start_index == none {
20 none
21 } else {
22 let lines_from_start = lines.slice(if keep_delimiting {
23 start_index
24 } else {
25 calc.max(start_index + 1, 0)
26 })
27
28 lines_from_start
29 .slice(
30 0,
31 lines_from_start.position(predicate(ends))
32 + if keep_delimiting { 1 } else { 0 },
33 )
34 .join("\n")
35 }
36}
37
38#let cut-between = (starts, ends, content) => cut-lines(
39 starts,
40 ends,
41 content,
42 keep_delimiting: false,
43)
44#let cut-around = (starts, ends, content) => cut-lines(
45 starts,
46 ends,
47 content,
48 keep_delimiting: true,
49)
50
51#let dedent = content => {
52 let lines = content.split(regex("\r?\n"))
53 let min_indent = lines
54 .filter(it => it.trim() != "")
55 .map(it => it.clusters().position(c => c != " "))
56 .fold(99999, (a, b) => calc.min(a, b))
57
58 lines.map(it => it.slice(calc.min(it.len(), min_indent))).join("\n")
59}
60
61
62#let include-function = (
63 filepath,
64 name,
65 lang: none,
66 is_method: false,
67 transform: it => it,
68) => {
69 let start_pattern = if lang == "rust" {
70 if is_method {
71 regex("^ (pub )?fn " + name)
72 } else {
73 regex("^(pub )?fn " + name)
74 }
75 } else if lang == "python" {
76 regex("^def " + name)
77 } else if lang == none {
78 panic("specify a source language")
79 } else {
80 panic(lang + " is not supported for now. Use cut-between directly.")
81 }
82
83 let end_pattern = if lang == "rust" {
84 if is_method {
85 regex("^ \}")
86 } else {
87 regex("^\}")
88 }
89 } else if lang == "python" {
90 regex("^# end") // TODO pass next line to cut-between
91 } else {
92 none
93 }
94
95 let contents = cut-around(
96 start_pattern,
97 end_pattern,
98 read(filepath),
99 )
100
101 if contents == none {
102 [
103 Woops! function #name not in #filepath .\_.
104 Searched for a line beginning with #start_pattern in:
105
106 #raw(lang: lang, read(filepath))
107 ]
108 } else {
109 raw(lang: lang, dedent(transform(contents)))
110 }
111}