Commit eea0032

HPCesia <me@hpcesia.com>
2026-08-16 09:00:59
Add ruby typst component
1 parent e6a318d
Changed files (3)
src
contents
_lib
components
posts
src/contents/_lib/components/ruby.typ
@@ -0,0 +1,60 @@
+#import "@preview/bullseye:0.1.0": match-target
+#import "@preview/rubby:0.10.2": get-ruby
+#import "../utils/to-string.typ": to-string
+
+#let ruby-html(rt, rb) = {
+  let rt-str = to-string(rt)
+  let rb-str = to-string(rb)
+  if type(rt-str) != str or type(rb-str) != str {
+    return [#rt (#rb)]
+  }
+  let rt-arr = rt-str.split("|")
+  let rb-arr = rb-str.split("|")
+  if rt-arr.len() != rb-arr.len() {
+    return [#rt (#rb)]
+  }
+  let rt-rb-pairs = rt-arr.zip(rb-arr)
+  return {
+    html.ruby(
+      rt-rb-pairs
+        .map(pair => {
+          let rt = pair.first()
+          let rb = pair.last()
+          rb
+          html.rp("(")
+          html.rt(rt)
+          html.rp(")")
+        })
+        .join(),
+    )
+  }
+}
+
+#let ruby-paged(rt, rb) = {
+  let _ruby = get-ruby(
+    size: 0.5em,
+    dy: 0pt,
+    pos: top,
+    alignment: "center",
+    delimiter: "|",
+    auto-spacing: true,
+  )
+  _ruby(rt, rb)
+}
+
+/// ruby like `<ruby>` in HTML.
+///
+/// == Examples:
+///
+/// ```typst
+/// #kp.ruby("ruby top", "ruby base")
+/// #kp.ruby("rt|and|rb|can|splited|by|bars", "but|must|has|same|number|of|bars")
+/// #kp.ruby([contents], [auto convert to string])
+/// ```
+///
+/// - rt (content,str):
+/// - rb (content,str):
+/// -> content
+#let ruby(rt, rb) = context {
+  match-target(html: ruby-html(rt, rb), paged: ruby-paged(rt, rb))
+}
src/contents/_lib/lib.typ
@@ -1,5 +1,6 @@
 #import "@preview/bullseye:0.1.0": match-target
 
+#import "./components/ruby.typ": ruby
 #import "./components/sidenote.typ": sidenote
 
 ///
src/contents/posts/typst-syntax.typ
@@ -140,3 +140,34 @@ Prefer to Markdown tables? A Typst package #link("https://typst.app/universe/pac
   the structure of a document.
 / HTML: #[*H*]yper#[*T*]ext #[*M*]arkup #[*L*]anguage, a standard for structuring web content.
 / URL: #[*U*]niform #[*R*]esource #[*L*]ocator, a text string that specifies where a resource can be found on the Internet.
+
+= Extra Components
+
+These components are added by Kerplunk.
+
+== Ruby
+
+Ruby, also known as #kp.ruby("振り仮名", "furigana"), is a small annotation that appears above or next to a word. It's commonly used in Japanese to show the pronunciation of kanji characters.
+
+```typst
+#kp.ruby("ruby top", "ruby base")
+#kp.ruby("rt|and|rb|can|splited|by|bars", "but|must|has|same|number|of|bars")
+#kp.ruby([contents], [auto convert to string])
+```
+
+== Sidenotes
+
+#kp.sidenote[This is a sidenote. It can be used to add some extra information without interrupting the reading flow.]
+
+Sidenotes is a special footnote that appears in the margin of the page also, but without a marker in the main text.
+You can use it to add some extra information without interrupting the reading flow.
+
+```typst
+// Just like footnote, only one line of content,
+// and no marker in the main text.
+#kp.sidenote[contents]
+// A block margin note, can contain multiple
+// paragraphs and other components.
+#kp.sidenote(block: true)[contents]
+```
+