1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
//! A library for finding _kashida_ (_tatweel_) insertion points and
//! priorities, driven by a small pattern language.
//!
//! Given a text and a compiled pattern set, the crate returns the possible
//! _kashida_ insertion points and their priorities.
//!
//! # Example
//!
//! Here is an example that breaks a text into lines and justifies them by
//! inserting _kashida_. For simplicity, the example assumes a monospaced
//! font where every character has the same width.
//!
//! 1. Break text into lines, greedily
//! 2. For each line, insert the highest priority _kashidas_ first across the
//! line:
//! 1. Only the highest _kashida_ point in any given word
//! 2. Up to `MAX_KASHIDA` _kashidas_ at each point
//! 4. Repeat with the next priority, until the line is filled, or there are no
//! more _kashida_ points to fill.
//!
//! The example is also runnable with
//! `cargo run --example justify`:
//!
//! ```
//! ```
//!
//! Which prints:
//!
//! <pre dir="rtl">
//! unjustified
//! قال أفلاطون: «الخط عقال العقل».
//! وقال إقليدس الإغريقي: «الخط
//! هندسة روحانية وإن ظهرت بآلة
//! جسمانية». وقال أبو دلف رحالة
//! القرن العاشر الميلادي: «الخط
//! رياض العلوم». وقال النظام
//! المعتزلي: «الخط أصيل في الروح
//! وإن ظهر بحواس البدن».
//!
//! justified
//! قال أفلاطون: «الخـط عقال العقل».
//! وقــال إقليـدس الإغريقي: «الخــط
//! هندســة روحانيــة وإن ظهرت بـآلة
//! جسمانيــة». وقــال أبو دلف رحالة
//! القرن العاشــر الميلادي: «الخــط
//! ريــاض العـلوم». وقــال النــظام
//! المعتزلي: «الخــط أصـيل في الروح
//! وإن ظهر بحواس البدن».
//! </pre>
pub use ;
pub use ;
pub use ;
use ;
use resolve_run;
/// A point where a kashida may be inserted.
/// Kashida insertion points for `text` from the pattern set alone.
/// Kashida insertion points for `text` under the given pattern set.
///
/// Any **bare** kashida already in the text is stripped first, unless
/// `remove_existing_kashida` is `false`. A kashida carrying a mark serves as
/// a seat for it, so it is always kept.
///
/// Returns the (possibly stripped) text along with the points, whose
/// indices refer to it.
///
/// # Example
///
/// ```
/// use kashida::{builtin_pattern_set, find_kashida_points};
///
/// let set = builtin_pattern_set("arabic-simple").unwrap();
/// let (cleaned, points) = find_kashida_points("بيت", set, true);
/// for point in points {
/// // Insert a kashida after grapheme cluster `point.index`.
/// println!("{} @ {}", point.priority, point.index);
/// }
/// ```