diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..2a145ae --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,27 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a +Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to +[Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [Unreleased] + +## [0.9.0] - 2023-09-14 + +### Changed + +Now kebab case is used instead of snake case. + +- Renamed function `get_ruby` to `get-ruby` (**breaking change**). +- Renamed `get-ruby`'s argument `auto_spacing` to `auto-spacing` (**breaking + change**). + +## [0.8.0] - 2023-07-03 + +Initial release. + +[0.9.0]: https://github.com/Andrew15-5/rubby/releases/tag/v0.9.0 + +[0.8.0]: https://github.com/Andrew15-5/rubby/releases/tag/v0.8.0 diff --git a/README.md b/README.md index 9199b0e..98e306d 100644 --- a/README.md +++ b/README.md @@ -2,16 +2,16 @@ ## Usage -```typst -#import "@preview/rubby:0.8.0": get_ruby +```typ +#import "@preview/rubby:0.9.0": get-ruby -#let ruby = get_ruby( +#let ruby = get-ruby( size: 0.5em, // Ruby font size dy: 0pt, // Vertical offset of the ruby pos: top, // Ruby position (top or bottom) alignment: "center", // Ruby alignment ("center", "start", "between", "around") delimiter: "|", // The delimiter between words - auto_spacing: true, // Automatically add necessary space around words + auto-spacing: true, // Automatically add necessary space around words ) // Ruby goes first, base text - second. @@ -23,8 +23,8 @@ Treat each kanji as a separate word: If you don't want automatically wrap text with delimiter: -```typst -#let ruby = get_ruby(auto_spacing: false) +```typ +#let ruby = get-ruby(auto-spacing: false) ``` See also and `example.typ`. @@ -36,18 +36,31 @@ based on [the post](https://zenn.dev/saito_atsushi/articles/ff9490458570e1) of 齊藤敦志 (Saito Atsushi). This project is a modified version of [this commit](https://github.com/rinmyo/ruby-typ/commit/23ca86180757cf70f2b9f5851abb5ea5a3b4c6a1). -`auto_spacing` adds missing delimiter around the `content`/`string` which +`auto-spacing` adds missing delimiter around the `content`/`string` which then adds space around base text if ruby is wider than the base text. -Problems appear only if ruby is wider than its base text and `auto_spacing` is +Problems appear only if ruby is wider than its base text and `auto-spacing` is not set to `true` (default is `true`). You can always use a one-letter function (variable) name to shorten the -function call length (if you have to use it a lot), e.g., `#let r = get_ruby()` +function call length (if you have to use it a lot), e.g., `#let r = get-ruby()` (or `f` — short for furigana). But be careful as there are functions with names `v` and `h` and there could be a new built-in function with a name `r` or `f` -which will break your document (Typst right now is in beta, so breaking changes +which may break your document (Typst right now is in beta, so breaking changes are possible). Although you can open issues or send PRs, I won't be able to always reply quickly (sometimes I'm very busy). + +## Changelog + +You can view the change log in the CHANGELOG.md file in the root of the project. + +## License + +This Typst package is licensed under AGPL v3.0. You can view the license in the +LICENSE file in the root of the project or at +. There is also a NOTICE file for +3rd party copyright notices. + +Copyright (C) 2023 Andrew Voynov diff --git a/rubby.typ b/rubby.typ index 33ba81c..388cf04 100644 --- a/rubby.typ +++ b/rubby.typ @@ -2,7 +2,7 @@ // AGPL-3.0-only license is in the LICENSE file in the root of the project // or at https://www.gnu.org/licenses/agpl-3.0.txt -#let _ruby(rt, rb, size, pos, dy, alignment, delimiter, auto_spacing) = { +#let _ruby(rt, rb, size, pos, dy, alignment, delimiter, auto-spacing) = { if not ("center", "start", "between", "around").contains(alignment) { panic("'" + repr(alignment) + "' is not a valid ruby alignment") } @@ -11,17 +11,17 @@ panic("pos can be either top or bottom but '" + repr(pos) + "'") } - let extract_content(content, fn: it => it) = { + let extract-content(content, fn: it => it) = { let func = content.func() return if func == text or func == raw { (content.text, fn) } else { - extract_content(content.body, fn: it => func(fn(it))) + extract-content(content.body, fn: it => func(fn(it))) } } - let add_spacing_if_enabled(text) = { - if auto_spacing != true { return text } + let add-spacing-if-enabled(text) = { + if auto-spacing != true { return text } return ( if text.first() != delimiter { delimiter } + text @@ -29,25 +29,25 @@ ) } - let rt_array = if type(rt) == "content" { - let (inner, func) = extract_content(rt) - add_spacing_if_enabled(inner).split(delimiter).map(func) + let rt-array = if type(rt) == "content" { + let (inner, func) = extract-content(rt) + add-spacing-if-enabled(inner).split(delimiter).map(func) } else if type(rt) == "string" { - add_spacing_if_enabled(rt).split(delimiter) + add-spacing-if-enabled(rt).split(delimiter) } else {(rt,)} - assert(type(rt_array) == "array") + assert(type(rt-array) == "array") - let rb_array = if type(rb) == "content" { - let (inner, func) = extract_content(rb) - add_spacing_if_enabled(inner).split(delimiter).map(func) + let rb-array = if type(rb) == "content" { + let (inner, func) = extract-content(rb) + add-spacing-if-enabled(inner).split(delimiter).map(func) } else if type(rb) == "string" { - add_spacing_if_enabled(rb).split(delimiter) + add-spacing-if-enabled(rb).split(delimiter) } else {(rb,)} - assert(type(rb_array) == "array") + assert(type(rb-array) == "array") - if rt_array.len() != rb_array.len() { - rt_array = (rt,) - rb_array = (rb,) + if rt-array.len() != rb-array.len() { + rt-array = (rt,) + rb-array = (rb,) } let gutter = if (alignment == "center" or alignment == "start") { @@ -57,61 +57,65 @@ } box(style(st => { - let sum_body = [] - let sum_width = 0pt - let i = 0 - while i < rb_array.len() { - let (body, ruby) = (rb_array.at(i), rt_array.at(i)) - let bodysize = measure(body, st) - let rt_plain_width = measure(text(size: size, ruby), st).width - let width = if rt_plain_width > bodysize.width { rt_plain_width } else { bodysize.width } - let chars = if(alignment == "around") { - h(0.5fr) + ruby.clusters().join(gutter) + h(0.5fr) - } else { - ruby.clusters().join(gutter) - } - let rubytext = box( - width: width, - align( - if (alignment == "start") { left } else { center }, - text(size: size, chars) - ) - ) - let textsize = measure(rubytext, st) - let dx = textsize.width - bodysize.width - let (t_dx, l_dx, r_dx) = if (alignment == "start") { - (0pt, 0pt, dx) - } else { - (-dx/2, dx/2, dx/2) - } - let (l, r) = (i != 0, i != rb_array.len() - 1) - sum_width += if l { 0pt } else { t_dx } - let dy = if pos == top { - -1.5 * textsize.height - dy - } else { - bodysize.height + textsize.height/2 + dy - } - place( - top + left, - dx: sum_width, - dy: dy, - rubytext - ) - sum_width += width - sum_body += if l { h(l_dx) } + body + if r { h(r_dx) } - i += 1 + let sum-body = [] + let sum-width = 0pt + let i = 0 + while i < rb-array.len() { + let (body, ruby) = (rb-array.at(i), rt-array.at(i)) + let bodysize = measure(body, st) + let rt-plain-width = measure(text(size: size, ruby), st).width + let width = if rt-plain-width > bodysize.width { + rt-plain-width + } else { + bodysize.width } - sum_body + let chars = if(alignment == "around") { + h(0.5fr) + ruby.clusters().join(gutter) + h(0.5fr) + } else { + ruby.clusters().join(gutter) + } + let rubytext = box( + width: width, + align( + if (alignment == "start") { left } else { center }, + text(size: size, chars) + ) + ) + let textsize = measure(rubytext, st) + let dx = textsize.width - bodysize.width + let (t-dx, l-dx, r-dx) = if (alignment == "start") { + (0pt, 0pt, dx) + } else { + (-dx/2, dx/2, dx/2) + } + let (l, r) = (i != 0, i != rb-array.len() - 1) + sum-width += if l { 0pt } else { t-dx } + let dy = if pos == top { + -1.5 * textsize.height - dy + } else { + bodysize.height + textsize.height/2 + dy + } + place( + top + left, + dx: sum-width, + dy: dy, + rubytext + ) + sum-width += width + sum-body += if l { h(l-dx) } + body + if r { h(r-dx) } + i += 1 + } + sum-body })) } -#let get_ruby( +#let get-ruby( size: 0.5em, dy: 0pt, pos: top, alignment: "center", delimiter: "|", - auto_spacing: true + auto-spacing: true ) = (rt, rb, alignment: alignment) => ( - _ruby(rt, rb, size, pos, dy, alignment, delimiter, auto_spacing) + _ruby(rt, rb, size, pos, dy, alignment, delimiter, auto-spacing) ) diff --git a/typst.toml b/typst.toml index 3a1f7c9..001f005 100644 --- a/typst.toml +++ b/typst.toml @@ -1,8 +1,10 @@ [package] name = "rubby" -version = "0.8.0" +version = "0.9.0" entrypoint = "rubby.typ" authors = ["Andrew Voynov"] license = "AGPL-3.0-only" description = "Add ruby (furigana) next to base text." repository = "https://github.com/Andrew15-5/rubby" +keywords = ["ruby", "furigana", "CJK", "Chinese", "Japanese", "Korean"] +exclude = ["example.typ"]