main
1#import "@preview/bullseye:0.1.0": match-target
2#import "@preview/rubby:0.10.2": get-ruby
3#import "../utils/to-string.typ": to-string
4
5#let ruby-html(rt, rb) = {
6 let rt-str = to-string(rt)
7 let rb-str = to-string(rb)
8 if type(rt-str) != str or type(rb-str) != str {
9 return [#rt (#rb)]
10 }
11 let rt-arr = rt-str.split("|")
12 let rb-arr = rb-str.split("|")
13 if rt-arr.len() != rb-arr.len() {
14 return [#rt (#rb)]
15 }
16 let rt-rb-pairs = rt-arr.zip(rb-arr)
17 return {
18 html.ruby(
19 rt-rb-pairs
20 .map(pair => {
21 let rt = pair.first()
22 let rb = pair.last()
23 rb
24 html.rp("(")
25 html.rt(rt)
26 html.rp(")")
27 })
28 .join(),
29 )
30 }
31}
32
33#let ruby-paged(rt, rb) = {
34 let _ruby = get-ruby(
35 size: 0.5em,
36 dy: 0pt,
37 pos: top,
38 alignment: "center",
39 delimiter: "|",
40 auto-spacing: true,
41 )
42 _ruby(rt, rb)
43}
44
45/// ruby like `<ruby>` in HTML.
46///
47/// == Examples:
48///
49/// ```typst
50/// #kp.ruby("ruby top", "ruby base")
51/// #kp.ruby("rt|and|rb|can|splited|by|bars", "but|must|has|same|number|of|bars")
52/// #kp.ruby([contents], [auto convert to string])
53/// ```
54///
55/// - rt (content,str):
56/// - rb (content,str):
57/// -> content
58#let ruby(rt, rb) = context {
59 match-target(html: ruby-html(rt, rb), paged: ruby-paged(rt, rb))
60}