kashida/builtin.rs
1//! The built-in pattern sets, compiled on first use.
2
3use crate::pattern::{compile_pattern_text, PatternSet};
4use std::sync::OnceLock;
5
6const ARABIC_SIMPLE_TEXT: &str = include_str!("../data/arabic-simple.pat");
7const ARABIC_NASKH_TEXT: &str = include_str!("../data/arabic-naskh.pat");
8const ARABIC_NASTALIQ_TEXT: &str = include_str!("../data/arabic-nastaliq.pat");
9const SYRIAC_TEXT: &str = include_str!("../data/syriac.pat");
10
11fn arabic_simple_set() -> &'static PatternSet {
12 static SET: OnceLock<PatternSet> = OnceLock::new();
13 SET.get_or_init(|| {
14 compile_pattern_text(ARABIC_SIMPLE_TEXT).expect("built-in \"arabic-simple\" compiles")
15 })
16}
17
18fn arabic_naskh_set() -> &'static PatternSet {
19 static SET: OnceLock<PatternSet> = OnceLock::new();
20 SET.get_or_init(|| {
21 compile_pattern_text(ARABIC_NASKH_TEXT).expect("built-in \"arabic-naskh\" compiles")
22 })
23}
24
25fn arabic_nastaliq_set() -> &'static PatternSet {
26 static SET: OnceLock<PatternSet> = OnceLock::new();
27 SET.get_or_init(|| {
28 compile_pattern_text(ARABIC_NASTALIQ_TEXT).expect("built-in \"arabic-nastaliq\" compiles")
29 })
30}
31
32fn syriac_set() -> &'static PatternSet {
33 static SET: OnceLock<PatternSet> = OnceLock::new();
34 SET.get_or_init(|| compile_pattern_text(SYRIAC_TEXT).expect("built-in \"syriac\" compiles"))
35}
36
37/// The names of the built-in pattern sets:
38///
39/// - `"arabic-naskh"`: Classical Arabic _kashida_ insertion rules suitable for
40/// classical _Naskh_ and _Naskh_-like typefaces (e.g. Thuluth) that follow
41/// the classical rules of Arabic calligraphy and have advanced relations
42/// between letters.
43/// The rules are derived mainly from the publications of [Benatia et al.]
44/// on the subject, but overridden where they disagree with Fawzi Salim
45/// Afifi’s _Taallum al-khatt al-arabi_, part 3 (تعلم الخط العربي، الجزء
46/// الثالث).
47/// - `"arabic-nastaliq"`: Classical Arabic _kashida_ insertion rules suitable
48/// for classical _Nastaliq_ typefaces. Uses the `arabic-naskh` rules with
49/// some tailoring for _Nastaliq_. Currently based on Afifi’s _Silsilat
50/// taalim al-khatt al-arabi_, part 9: _al-khatt al-farisi_ (سلسلة تعليم الخط
51/// العربي، الجزء التاسع: الخط الفارسي).
52/// - `"arabic-simple"`: Arabic _kashida_ rules suitable for _simple_
53/// typefaces, i.e. those where letters have only the basic forms with no or
54/// very limited relations between letters (no or very few ligatures,
55/// contextual alternates, and so on).
56/// It is also suitable for _Kufic_ styles of Arabic in general.
57/// The rules are based on [Microsoft justification rules], which are rooted
58/// in Arabic newspaper typesetting.
59/// - `"syriac"`: Syriac, following the [guidelines proposed for justified
60/// Syriac].
61///
62/// See the `.pat` sources for the rules themselves and their citations.
63///
64/// [Microsoft justification rules]: https://web.archive.org/web/20130308140133/microsoft.com/middleeast/msdn/JustifyingText-CSS.aspx
65/// [Benatia et al.]: https://www.tug.org/tugboat/tb27-2/tb87benatia.pdf
66/// [guidelines proposed for justified Syriac]: https://bugs.documentfoundation.org/show_bug.cgi?id=140767
67pub fn builtin_pattern_set_names() -> &'static [&'static str] {
68 &["arabic-naskh", "arabic-nastaliq", "arabic-simple", "syriac"]
69}
70
71/// Whether `name` refers to a built-in pattern set, without compiling it,
72/// unlike [`builtin_pattern_set`].
73pub fn is_builtin_pattern_set(name: &str) -> bool {
74 builtin_pattern_set_names().contains(&name)
75}
76
77/// The built-in pattern set of that name, compiled on first use, or `None`
78/// if there is none. [`builtin_pattern_set_names`] lists and describes them.
79pub fn builtin_pattern_set(name: &str) -> Option<&'static PatternSet> {
80 match name {
81 "arabic-naskh" => Some(arabic_naskh_set()),
82 "arabic-nastaliq" => Some(arabic_nastaliq_set()),
83 "arabic-simple" => Some(arabic_simple_set()),
84 "syriac" => Some(syriac_set()),
85 _ => None,
86 }
87}