Move lang functionality into par

This commit is contained in:
Laurenz 2021-11-16 00:37:33 +01:00
parent 370802de13
commit 210c4d9373
7 changed files with 43 additions and 55 deletions

View File

@ -458,7 +458,7 @@ impl ParBuilder {
fn new(style: &Style) -> Self {
Self {
align: style.aligns.block,
dir: style.dir,
dir: style.par.dir,
leading: style.leading(),
children: vec![],
last: Last::None,

View File

@ -125,7 +125,7 @@ impl Walk for EnumNode {
fn walk_item(ctx: &mut EvalContext, label: EcoString, body: Template) {
ctx.template += Template::from_block(move |style| {
let label = ParNode {
dir: style.dir,
dir: style.par.dir,
leading: style.leading(),
children: vec![ParChild::Text(
label.clone(),

View File

@ -59,7 +59,6 @@ pub fn new() -> Scope {
// Text.
std.def_func("font", font);
std.def_func("par", par);
std.def_func("lang", lang);
std.def_func("strike", strike);
std.def_func("underline", underline);
std.def_func("overline", overline);

View File

@ -15,16 +15,36 @@ pub fn par(ctx: &mut EvalContext, args: &mut Args) -> TypResult<Value> {
let spacing = args.named("spacing")?;
let leading = args.named("leading")?;
let mut dir = args.named::<EcoString>("lang")?.map(|iso| {
match iso.to_ascii_lowercase().as_str() {
"ar" | "he" | "fa" | "ur" | "ps" | "yi" => Dir::RTL,
"en" | "fr" | "de" => Dir::LTR,
_ => Dir::LTR,
}
});
if let Some(Spanned { v, span }) = args.named::<Spanned<Dir>>("dir")? {
if v.axis() == SpecAxis::Horizontal {
dir = Some(v)
} else {
bail!(span, "must be horizontal");
}
}
ctx.template.modify(move |style| {
let par = style.par_mut();
if let Some(spacing) = spacing {
par.spacing = spacing;
if let Some(dir) = dir {
par.dir = dir;
}
if let Some(leading) = leading {
par.leading = leading;
}
if let Some(spacing) = spacing {
par.spacing = spacing;
}
});
ctx.template.parbreak();
@ -32,37 +52,6 @@ pub fn par(ctx: &mut EvalContext, args: &mut Args) -> TypResult<Value> {
Ok(Value::None)
}
/// `lang`: Configure the language.
pub fn lang(ctx: &mut EvalContext, args: &mut Args) -> TypResult<Value> {
let iso = args.find::<EcoString>();
let dir = if let Some(dir) = args.named::<Spanned<Dir>>("dir")? {
if dir.v.axis() == SpecAxis::Horizontal {
Some(dir.v)
} else {
bail!(dir.span, "must be horizontal");
}
} else {
iso.as_deref().map(lang_dir)
};
if let Some(dir) = dir {
ctx.template.modify(move |style| style.dir = dir);
}
ctx.template.parbreak();
Ok(Value::None)
}
/// The default direction for the language identified by the given `iso` code.
fn lang_dir(iso: &str) -> Dir {
match iso.to_ascii_lowercase().as_str() {
"ar" | "he" | "fa" | "ur" | "ps" | "yi" => Dir::RTL,
"en" | "fr" | "de" => Dir::LTR,
_ => Dir::LTR,
}
}
/// A node that arranges its children into a paragraph.
#[derive(Debug, Hash)]
pub struct ParNode {

View File

@ -16,8 +16,6 @@ use crate::util::EcoString;
/// Defines a set of properties a template can be instantiated with.
#[derive(Debug, Clone, Eq, PartialEq, Hash)]
pub struct Style {
/// The direction for text and other inline objects.
pub dir: Dir,
/// The alignments of layouts in their parents.
pub aligns: Gen<Align>,
/// The page settings.
@ -58,7 +56,6 @@ impl Style {
impl Default for Style {
fn default() -> Self {
Self {
dir: Dir::LTR,
aligns: Gen::splat(Align::Start),
page: Rc::new(PageStyle::default()),
par: Rc::new(ParStyle::default()),
@ -106,17 +103,20 @@ impl Default for PageStyle {
/// Defines style properties of paragraphs.
#[derive(Debug, Clone, Eq, PartialEq, Hash)]
pub struct ParStyle {
/// The spacing between paragraphs (dependent on scaled font size).
pub spacing: Linear,
/// The direction for text and other inline objects.
pub dir: Dir,
/// The spacing between lines (dependent on scaled font size).
pub leading: Linear,
/// The spacing between paragraphs (dependent on scaled font size).
pub spacing: Linear,
}
impl Default for ParStyle {
fn default() -> Self {
Self {
spacing: Relative::new(1.2).into(),
dir: Dir::LTR,
leading: Relative::new(0.65).into(),
spacing: Relative::new(1.2).into(),
}
}
}

View File

@ -4,35 +4,35 @@
// Test reordering with different top-level paragraph directions.
#let text = [Text טֶקסט]
#font(serif, "Noto Serif Hebrew")
#lang("he") {text}
#lang("de") {text}
#par(lang: "he") {text}
#par(lang: "de") {text}
---
// Test that consecutive, embedded LTR runs stay LTR.
// Here, we have two runs: "A" and italic "B".
#let text = [أنت A_B_مطرC]
#font(serif, "Noto Sans Arabic")
#lang("ar") {text}
#lang("de") {text}
#par(lang: "ar") {text}
#par(lang: "de") {text}
---
// Test that consecutive, embedded RTL runs stay RTL.
// Here, we have three runs: "גֶ", bold "שֶׁ", and "ם".
#let text = [Aגֶ*שֶׁ*םB]
#font(serif, "Noto Serif Hebrew")
#lang("he") {text}
#lang("de") {text}
#par(lang: "he") {text}
#par(lang: "de") {text}
---
// Test embedding up to level 4 with isolates.
#font(serif, "Noto Serif Hebrew", "Twitter Color Emoji")
#lang(dir: rtl)
#par(dir: rtl)
א\u{2066}A\u{2067}Bב\u{2069}?
---
// Test hard line break (leads to two paragraphs in unicode-bidi).
#font("Noto Sans Arabic", serif)
#lang("ar")
#par(lang: "ar")
Life المطر هو الحياة \
الحياة تمطر is rain.
@ -45,12 +45,12 @@ Lריווח #h(1cm) R
---
// Test inline object.
#font("Noto Serif Hebrew", serif)
#lang("he")
#par(lang: "he")
קרנפיםRh#image("../../res/rhino.png", height: 11pt)inoחיים
---
// Test the `lang` function.
// Test setting a vertical direction.
// Ref: false
// Error: 12-15 must be horizontal
#lang(dir: ttb)
// Error: 11-14 must be horizontal
#par(dir: ttb)

View File

@ -41,5 +41,5 @@ A🐈中文B
// Test reshaping.
#font("Noto Serif Hebrew")
#lang("he")
#par(lang: "he")
ס \ טֶ