Skip to content

Commit bea34e9

Browse files
committed
Fix all RuboCop offenses
- Use push() instead of concat([]) for ARABIC_MARKS - Rename cp parameter to codepoint (min 3 chars) - Use Array#include? instead of || comparison - Use .positive? instead of > 0 - Fix spec: use all() matcher, to_not, single quotes, parentheses - Add trailing commas for multiline arrays
1 parent e8b49c3 commit bea34e9

2 files changed

Lines changed: 62 additions & 69 deletions

File tree

lib/prawn/text/arabic_shaping.rb

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -124,13 +124,13 @@ module ArabicShaping
124124
}.freeze
125125

126126
# Arabic diacritical marks (tashkeel) - transparent to joining
127-
ARABIC_MARKS = (0x064B..0x065F).to_a.concat(
128-
[0x0610, 0x0611, 0x0612, 0x0613, 0x0614, 0x0615,
129-
0x0616, 0x0617, 0x0618, 0x0619, 0x061A,
130-
0x06D6, 0x06D7, 0x06D8, 0x06D9, 0x06DA, 0x06DB,
131-
0x06DC, 0x06DF, 0x06E0, 0x06E1, 0x06E2, 0x06E3,
132-
0x06E4, 0x06E7, 0x06E8, 0x06EA, 0x06EB, 0x06EC, 0x06ED,
133-
0x0670]
127+
ARABIC_MARKS = (0x064B..0x065F).to_a.push(
128+
0x0610, 0x0611, 0x0612, 0x0613, 0x0614, 0x0615,
129+
0x0616, 0x0617, 0x0618, 0x0619, 0x061A,
130+
0x06D6, 0x06D7, 0x06D8, 0x06D9, 0x06DA, 0x06DB,
131+
0x06DC, 0x06DF, 0x06E0, 0x06E1, 0x06E2, 0x06E3,
132+
0x06E4, 0x06E7, 0x06E8, 0x06EA, 0x06EB, 0x06EC, 0x06ED,
133+
0x0670,
134134
).freeze
135135

136136
ARABIC_MARKS_SET = ARABIC_MARKS.to_set.freeze
@@ -178,34 +178,34 @@ def shape(text)
178178

179179
private
180180

181-
def arabic_letter?(cp)
182-
ARABIC_FORMS.key?(cp)
181+
def arabic_letter?(codepoint)
182+
ARABIC_FORMS.key?(codepoint)
183183
end
184184

185-
def arabic_mark?(cp)
186-
ARABIC_MARKS_SET.include?(cp)
185+
def arabic_mark?(codepoint)
186+
ARABIC_MARKS_SET.include?(codepoint)
187187
end
188188

189-
def dual_joining?(cp)
190-
forms = ARABIC_FORMS[cp]
189+
def dual_joining?(codepoint)
190+
forms = ARABIC_FORMS[codepoint]
191191
forms && forms[2] && forms[3]
192192
end
193193

194-
def right_joining?(cp)
195-
forms = ARABIC_FORMS[cp]
194+
def right_joining?(codepoint)
195+
forms = ARABIC_FORMS[codepoint]
196196
forms && forms[1] && !forms[2]
197197
end
198198

199-
def join_causing?(cp)
200-
cp == 0x0640 || cp == 0x200D
199+
def join_causing?(codepoint)
200+
[0x0640, 0x200D].include?(codepoint)
201201
end
202202

203-
def can_join_right?(cp)
204-
dual_joining?(cp) || right_joining?(cp) || join_causing?(cp)
203+
def can_join_right?(codepoint)
204+
dual_joining?(codepoint) || right_joining?(codepoint) || join_causing?(codepoint)
205205
end
206206

207-
def can_join_left?(cp)
208-
dual_joining?(cp) || join_causing?(cp)
207+
def can_join_left?(codepoint)
208+
dual_joining?(codepoint) || join_causing?(codepoint)
209209
end
210210

211211
def shape_run(run)
@@ -232,7 +232,7 @@ def shape_run(run)
232232
else
233233
forms = ARABIC_FORMS[entry]
234234
if forms
235-
prev_joins = idx > 0 && prev_can_join_left?(shaped_bases, idx)
235+
prev_joins = idx.positive? && prev_can_join_left?(shaped_bases, idx)
236236
next_joins = idx < shaped_bases.length - 1 && next_can_join_right?(shaped_bases, idx)
237237
result << select_form(forms, prev_joins, next_joins)
238238
else
@@ -254,7 +254,7 @@ def apply_lam_alef_ligatures(bases)
254254
if bases[i] == 0x0644 && i + 1 < bases.length && LAM_ALEF_LIGATURES.key?(bases[i + 1])
255255
alef = bases[i + 1]
256256
ligature_forms = LAM_ALEF_LIGATURES[alef]
257-
prev_joins = i > 0 && can_join_left?(bases[i - 1])
257+
prev_joins = i.positive? && can_join_left?(bases[i - 1])
258258
ligature_cp = prev_joins ? ligature_forms[1] : ligature_forms[0]
259259
result << [ligature_cp, prev_joins ? :final : :isolated]
260260
i += 2

spec/prawn/text/arabic_shaping_spec.rb

Lines changed: 39 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -5,25 +5,28 @@
55
RSpec.describe Prawn::Text::ArabicShaping do
66
describe '.contains_arabic?' do
77
it 'returns true for Arabic text' do
8-
expect(described_class.contains_arabic?('مرحبا')).to be true
8+
expect(described_class.contains_arabic?('مرحبا')).to be(true)
99
end
1010

1111
it 'returns false for Latin text' do
12-
expect(described_class.contains_arabic?('Hello')).to be false
12+
expect(described_class.contains_arabic?('Hello')).to be(false)
1313
end
1414

1515
it 'returns true for mixed Arabic/Latin text' do
16-
expect(described_class.contains_arabic?('Hello مرحبا')).to be true
16+
expect(described_class.contains_arabic?('Hello مرحبا')).to be(true)
1717
end
1818

1919
it 'returns false for empty string' do
20-
expect(described_class.contains_arabic?('')).to be false
20+
expect(described_class.contains_arabic?('')).to be(false)
2121
end
2222
end
2323

2424
describe '.shape' do
25-
it 'returns nil/empty unchanged' do
25+
it 'returns nil unchanged' do
2626
expect(described_class.shape(nil)).to be_nil
27+
end
28+
29+
it 'returns empty string unchanged' do
2730
expect(described_class.shape('')).to eq('')
2831
end
2932

@@ -33,67 +36,59 @@
3336

3437
it 'converts Arabic characters to presentation forms' do
3538
shaped = described_class.shape('مرحبا')
36-
# All characters should be in the Arabic Presentation Forms range
37-
shaped.codepoints.each do |cp|
38-
expect(cp).to be_between(0xFE70, 0xFEFF)
39-
.or be_between(0xFB50, 0xFDFF)
40-
end
39+
expect(shaped.codepoints).to all(
40+
be_between(0xFE70, 0xFEFF).or(be_between(0xFB50, 0xFDFF)),
41+
)
4142
end
4243

4344
it 'shapes initial form correctly' do
44-
# م at the start of مرحبا should be initial form (FEE3)
4545
shaped = described_class.shape('مرحبا')
46-
expect(shaped.codepoints.first).to eq(0xFEE3) # MEEM INITIAL
46+
expect(shaped.codepoints.first).to eq(0xFEE3)
4747
end
4848

4949
it 'shapes final form correctly' do
50-
# ا at the end of مرحبا should be final form (FE8E)
5150
shaped = described_class.shape('مرحبا')
52-
expect(shaped.codepoints.last).to eq(0xFE8E) # ALEF FINAL (via ALEF MAKSURA)
51+
expect(shaped.codepoints.last).to eq(0xFE8E)
5352
end
5453

5554
it 'shapes medial form correctly' do
56-
# ح in مرحبا should be medial form (FEA4)
5755
shaped = described_class.shape('مرحبا')
58-
expect(shaped.codepoints[2]).to eq(0xFEA3) # HAH MEDIAL
56+
expect(shaped.codepoints[2]).to eq(0xFEA3)
5957
end
6058

6159
it 'shapes isolated characters correctly' do
62-
shaped = described_class.shape('ء') # HAMZA - always isolated
60+
shaped = described_class.shape('ء')
6361
expect(shaped.codepoints.first).to eq(0xFE80)
6462
end
6563

66-
it 'handles right-joining characters (Alef, Dal, etc.)' do
67-
# Alef only joins to the right
68-
shaped = described_class.shape('با') # BEH + ALEF
64+
it 'handles right-joining characters' do
65+
shaped = described_class.shape('با')
6966
cps = shaped.codepoints
70-
expect(cps[0]).to eq(0xFE91) # BEH INITIAL
71-
expect(cps[1]).to eq(0xFE8E) # ALEF FINAL
67+
expect(cps[0]).to eq(0xFE91)
68+
expect(cps[1]).to eq(0xFE8E)
7269
end
7370

7471
it 'creates Lam-Alef ligatures' do
7572
shaped = described_class.shape('لا')
76-
expect(shaped.codepoints).to eq([0xFEFB]) # LAM-ALEF ISOLATED
73+
expect(shaped.codepoints).to eq([0xFEFB])
7774
end
7875

7976
it 'creates Lam-Alef ligature in final form when preceded' do
80-
shaped = described_class.shape('بلا') # BEH + LAM + ALEF
77+
shaped = described_class.shape('بلا')
8178
cps = shaped.codepoints
82-
expect(cps[0]).to eq(0xFE91) # BEH INITIAL
83-
expect(cps[1]).to eq(0xFEFC) # LAM-ALEF FINAL
79+
expect(cps[0]).to eq(0xFE91)
80+
expect(cps[1]).to eq(0xFEFC)
8481
end
8582

8683
it 'creates Lam-Alef with Madda ligature' do
87-
shaped = described_class.shape("ل\u0622") # LAM + ALEF WITH MADDA
84+
shaped = described_class.shape("\u0644\u0622")
8885
expect(shaped.codepoints).to eq([0xFEF5])
8986
end
9087

9188
it 'preserves diacritical marks' do
92-
text = "بِسْمِ" # with kasra and sukun
93-
shaped = described_class.shape(text)
94-
# Marks should still be present
95-
marks = shaped.codepoints.select { |cp| (0x064B..0x065F).cover?(cp) }
96-
expect(marks).not_to be_empty
89+
shaped = described_class.shape("\u0628\u0650\u0633\u0652\u0645\u0650")
90+
marks = shaped.codepoints.select { |codepoint| (0x064B..0x065F).cover?(codepoint) }
91+
expect(marks).to_not be_empty
9792
end
9893

9994
it 'preserves spaces between words' do
@@ -105,29 +100,27 @@
105100
shaped = described_class.shape('Hello مرحبا World')
106101
expect(shaped).to include('Hello')
107102
expect(shaped).to include('World')
108-
# Arabic part should be shaped
109-
expect(shaped).not_to include('م') # original meem should be replaced
103+
expect(shaped).to_not include('م')
110104
end
111105

112-
it 'handles Tatweel (kashida)' do
113-
shaped = described_class.shape("بـا") # BEH + TATWEEL + ALEF
114-
cps = shaped.codepoints
115-
expect(cps).to include(0x0640) # TATWEEL preserved
106+
it 'handles Tatweel' do
107+
shaped = described_class.shape("\u0628\u0640\u0627")
108+
expect(shaped.codepoints).to include(0x0640)
116109
end
117110

118111
it 'shapes Farsi Yeh correctly' do
119-
shaped = described_class.shape("\u06CC") # FARSI YEH isolated
120-
expect(shaped.codepoints.first).to eq(0xFBFC) # FARSI YEH ISOLATED
112+
shaped = described_class.shape("\u06CC")
113+
expect(shaped.codepoints.first).to eq(0xFBFC)
121114
end
122115

123-
it 'shapes Peh correctly (Urdu/Farsi)' do
124-
shaped = described_class.shape("\u067E") # PEH isolated
125-
expect(shaped.codepoints.first).to eq(0xFB56) # PEH ISOLATED
116+
it 'shapes Peh correctly' do
117+
shaped = described_class.shape("\u067E")
118+
expect(shaped.codepoints.first).to eq(0xFB56)
126119
end
127120

128-
it 'shapes Gaf correctly (Farsi)' do
129-
shaped = described_class.shape("\u06AF") # GAF isolated
130-
expect(shaped.codepoints.first).to eq(0xFB92) # GAF ISOLATED
121+
it 'shapes Gaf correctly' do
122+
shaped = described_class.shape("\u06AF")
123+
expect(shaped.codepoints.first).to eq(0xFB92)
131124
end
132125
end
133126
end

0 commit comments

Comments
 (0)