Skip to content

Commit

Permalink
Merged branch 'dev'
Browse files Browse the repository at this point in the history
  • Loading branch information
Andrew15-5 committed Sep 14, 2023
2 parents c6b8405 + 5d4efaf commit 280c492
Show file tree
Hide file tree
Showing 4 changed files with 122 additions and 76 deletions.
27 changes: 27 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -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
33 changes: 23 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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 <https://github.com/rinmyo/ruby-typ/blob/main/manual.pdf> and `example.typ`.
Expand All @@ -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
<https://www.gnu.org/licenses/agpl-3.0.txt>. There is also a NOTICE file for
3rd party copyright notices.

Copyright (C) 2023 Andrew Voynov
134 changes: 69 additions & 65 deletions rubby.typ
Original file line number Diff line number Diff line change
Expand Up @@ -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")
}
Expand All @@ -11,43 +11,43 @@
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
+ if text.last() != delimiter { delimiter }
)
}

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") {
Expand All @@ -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)
)
4 changes: 3 additions & 1 deletion typst.toml
Original file line number Diff line number Diff line change
@@ -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"]

0 comments on commit 280c492

Please sign in to comment.