orthotypo 0.6.0 → 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b41b05766be4f11e6494a7e89823a6ab730910aec4a679d22b764ae96fb05f10
4
- data.tar.gz: 0c2a072f5c3ebd8583b70c7ee4bf0eafe064c827d4e0af250728bcf5762dc5ae
3
+ metadata.gz: 7d98147f241b463ded341c2d422bc85402af278c1dba5c8120fe25de1335addb
4
+ data.tar.gz: aada22cc0374ebd5fdeea55d1d8a0b4ce84734e965f303dec5e34be9edfe82ac
5
5
  SHA512:
6
- metadata.gz: 20ff73ede6bf05d4b2b8842604b09267f36cf2d44fc17c6e4a467e9e703934a20f18616368cc5af88529122166130c8b868612af6caab95ff6f685236b862443
7
- data.tar.gz: 55f9a2023f185176d52de197847f92ee61ea0e8ba20d70c920fec7e31b4d86dbae0ab87594adcd7c406fcdbbc2ef189fa8a113bcfeab9f60786c31dd77771f1e
6
+ metadata.gz: b8a9e8e9d6ecd50bd27eb6309836508d23ed182437487dbf7f1d0130de29705aa2ef81fe7ae516dc976352a8f70d3c05146df1d74432fee615b1d47443118306
7
+ data.tar.gz: bf718bc6f49c667e203b529fad9a565c8f936ff74bd9cd54b56f60f32bd50c72e39f3a838beee66a315a53c6c1dcb13ff93266111ff1f569bbaaa69025923a38
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- orthotypo (0.6.0)
4
+ orthotypo (1.0.1)
5
5
  htmlentities
6
6
  nokogiri
7
7
 
@@ -9,24 +9,23 @@ GEM
9
9
  remote: https://rubygems.org/
10
10
  specs:
11
11
  ast (2.4.2)
12
- base64 (0.1.1)
13
12
  byebug (11.1.3)
14
13
  diff-lcs (1.5.0)
15
14
  htmlentities (4.3.4)
16
- json (2.6.3)
15
+ json (2.7.1)
17
16
  language_server-protocol (3.17.0.3)
18
- nokogiri (1.15.4-arm64-darwin)
17
+ nokogiri (1.16.0-arm64-darwin)
19
18
  racc (~> 1.4)
20
- nokogiri (1.15.4-x86_64-darwin)
19
+ nokogiri (1.16.0-x86_64-darwin)
21
20
  racc (~> 1.4)
22
- parallel (1.23.0)
23
- parser (3.2.2.4)
21
+ parallel (1.24.0)
22
+ parser (3.3.0.2)
24
23
  ast (~> 2.4.1)
25
24
  racc
26
- racc (1.7.1)
25
+ racc (1.7.3)
27
26
  rainbow (3.1.1)
28
- rake (13.0.6)
29
- regexp_parser (2.8.2)
27
+ rake (13.1.0)
28
+ regexp_parser (2.9.0)
30
29
  rexml (3.2.6)
31
30
  rspec (3.12.0)
32
31
  rspec-core (~> 3.12.0)
@@ -44,8 +43,7 @@ GEM
44
43
  rspec (>= 3)
45
44
  terminal-notifier (>= 1.4)
46
45
  rspec-support (3.12.1)
47
- rubocop (1.57.0)
48
- base64 (~> 0.1.1)
46
+ rubocop (1.59.0)
49
47
  json (~> 2.3)
50
48
  language_server-protocol (>= 3.17.0)
51
49
  parallel (~> 1.10)
@@ -53,10 +51,10 @@ GEM
53
51
  rainbow (>= 2.2.2, < 4.0)
54
52
  regexp_parser (>= 1.8, < 3.0)
55
53
  rexml (>= 3.2.5, < 4.0)
56
- rubocop-ast (>= 1.28.1, < 2.0)
54
+ rubocop-ast (>= 1.30.0, < 2.0)
57
55
  ruby-progressbar (~> 1.7)
58
56
  unicode-display_width (>= 2.4.0, < 3.0)
59
- rubocop-ast (1.29.0)
57
+ rubocop-ast (1.30.0)
60
58
  parser (>= 3.2.1.0)
61
59
  ruby-progressbar (1.13.0)
62
60
  terminal-notifier (2.0.0)
data/README.md CHANGED
@@ -28,12 +28,27 @@ Ajout d'espace fine insécable avant les signes doubles en français.
28
28
  ## Roadmap
29
29
 
30
30
  ### v1
31
- 1. S'adapter aux locales (détecter I18n)
32
- 2. Ne pas endommager l'HTML et les HTML entities (&nbsp;)
31
+ Ne pas endommager l'HTML et les HTML entities (&nbsp;)
33
32
 
34
33
  ### v2
34
+ S'adapter aux locales (détecter I18n)
35
35
  Permettre les configs
36
36
 
37
+ ## Tests
38
+
39
+ ```
40
+ rake
41
+ ```
42
+
43
+ ```
44
+ bundle exec rspec
45
+ ```
46
+
47
+ Pour jouer un seul test :
48
+ ```
49
+ bundle exec rspec ./spec/composer/fr_spec.rb:56
50
+ ```
51
+
37
52
  ## Sources
38
53
 
39
54
  - https://fr.wikipedia.org/wiki/Code_typographique
@@ -19,6 +19,12 @@ module Orthotypo
19
19
  []
20
20
  end
21
21
 
22
+ def chars_with_space_before_after_digit
23
+ [
24
+ '%'
25
+ ]
26
+ end
27
+
22
28
  def chars_with_space_after
23
29
  [
24
30
  ',',
@@ -42,6 +48,22 @@ module Orthotypo
42
48
  []
43
49
  end
44
50
 
51
+ def chars_with_no_space_around_between_digits
52
+ [
53
+ '/',
54
+ ':'
55
+ ]
56
+ end
57
+
58
+ def chars_in_numbers
59
+ [
60
+ '.',
61
+ ',',
62
+ '/',
63
+ ':'
64
+ ]
65
+ end
66
+
45
67
  def is_html?
46
68
  # TODO contains tags?
47
69
  @html || contains_html_entities?
@@ -53,13 +75,11 @@ module Orthotypo
53
75
 
54
76
  def prepare_ortho
55
77
  @ortho = string.dup
56
- # @ortho = html_entities.decode(@ortho) if contains_html_entities?
57
78
  @nokogiri = Nokogiri::HTML.fragment @ortho
58
79
  end
59
80
 
60
81
  def clean_ortho
61
82
  @ortho = @nokogiri.to_s
62
- # @ortho = html_entities.encode(@ortho) if contains_html_entities?
63
83
  end
64
84
 
65
85
  def parse
@@ -67,6 +87,7 @@ module Orthotypo
67
87
  preserve_precious_things
68
88
  # Chars
69
89
  parse_chars_with_space_before
90
+ parse_chars_with_space_before_after_digit
70
91
  parse_chars_with_space_after
71
92
  parse_chars_with_space_around
72
93
  parse_chars_with_no_space_around
@@ -74,8 +95,8 @@ module Orthotypo
74
95
  parse_pairs_with_space_around
75
96
  parse_pairs_with_no_space_around
76
97
  # Numbers
77
- parse_numbers
78
- #
98
+ parse_chars_in_numbers
99
+ #
79
100
  clean_ortho
80
101
  restore_precious_things
81
102
  end
@@ -83,20 +104,40 @@ module Orthotypo
83
104
  def preserve_precious_things
84
105
  @precious_things = []
85
106
  @nokogiri.traverse do |node|
86
- next unless node.text?
87
- new_content = node.content.split(SPACE).map { |fragment|
88
- if Analyzer::precious?(fragment)
89
- token = "#{PRECIOUS_TOKEN}#{@precious_things.length}"
90
- @precious_things << fragment
91
- token
92
- else
93
- fragment
107
+ if node.text?
108
+ has_leading_space = node.content.start_with? SPACE
109
+ has_trailing_space = node.content.end_with? SPACE
110
+ node.content = node.content.split(SPACE).map { |fragment|
111
+ store_if_precious(fragment)
112
+ }.join(SPACE)
113
+ node.content = SPACE + node.content if has_leading_space
114
+ node.content = node.content + SPACE if has_trailing_space
115
+ elsif node.element?
116
+ if node.name == 'a'
117
+ node.attributes.each do |key, attribute|
118
+ if attribute.name == 'href'
119
+ attribute.value = store_precious_thing(attribute.value)
120
+ end
121
+ end
94
122
  end
95
- }.join(SPACE)
96
- node.content = new_content
123
+ end
97
124
  end
98
125
  end
99
126
 
127
+ def store_if_precious(string)
128
+ Analyzer::precious?(string) ? store_precious_thing(string)
129
+ : string
130
+ end
131
+
132
+ def store_precious_thing(string)
133
+ # Create token identifier
134
+ token = "#{PRECIOUS_TOKEN}#{@precious_things.length}"
135
+ # Store value
136
+ @precious_things << string
137
+ # Return identifier
138
+ token
139
+ end
140
+
100
141
  def restore_precious_things
101
142
  @precious_things.each_with_index do |value, index|
102
143
  @ortho.gsub! "#{PRECIOUS_TOKEN}#{index}", value
@@ -106,9 +147,15 @@ module Orthotypo
106
147
  def parse_chars_with_space_before
107
148
  chars_with_space_before.each do |char|
108
149
  # Espace normal avant -> espace fine insécable avant
109
- fix(SPACE + '%', NNBSP + '%')
150
+ fix(SPACE + char, NNBSP + char)
110
151
  # Pas d'espace avant -> espace fine insécable avant
111
- fix(/([[:alnum:]])%/, "\\1" + NNBSP + '%')
152
+ fix(/([[:alpha:]])[#{char}]/, "\\1" + NNBSP + char)
153
+ end
154
+ end
155
+
156
+ def parse_chars_with_space_before_after_digit
157
+ chars_with_space_before_after_digit.each do |char|
158
+ fix(/([[:digit:]])[#{char}]/, "\\1" + NNBSP + char)
112
159
  end
113
160
  end
114
161
 
@@ -117,7 +164,7 @@ module Orthotypo
117
164
  # Espace avant -> pas d'espace avant
118
165
  fix(SPACE + char, char)
119
166
  # Pas d'espace après -> espace après
120
- fix(/[#{char}]([[:alnum:]])/, char + SPACE + "\\1")
167
+ fix(/[#{char}]([[:alpha:]])/, char + SPACE + "\\1")
121
168
  end
122
169
  end
123
170
 
@@ -126,7 +173,7 @@ module Orthotypo
126
173
  # Espace normal avant -> espace fine insécable avant
127
174
  fix(SPACE + char, NNBSP + char)
128
175
  # Pas d'espace avant -> espace fine insécable avant
129
- fix(/([[:alnum:]])[#{char}]/, "\\1" + NNBSP + char)
176
+ fix(/([[:alpha:]])[#{char}]/, "\\1" + NNBSP + char)
130
177
  end
131
178
  end
132
179
 
@@ -162,8 +209,10 @@ module Orthotypo
162
209
  end
163
210
  end
164
211
 
165
- def parse_numbers
166
- ['.', ','].each do |char|
212
+ def parse_chars_in_numbers
213
+ chars_in_numbers.each do |char|
214
+ fix(/([[:digit:]])[[:space:]][#{char}]([[:digit:]])/, "\\1" + char + "\\2")
215
+ fix(/([[:digit:]])[[:space:]][#{char}][[:space:]]([[:digit:]])/, "\\1" + char + "\\2")
167
216
  fix(/([[:digit:]])[#{char}][[:space:]]([[:digit:]])/, "\\1" + char + "\\2")
168
217
  end
169
218
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Orthotypo
4
- VERSION = "0.6.0"
4
+ VERSION = "1.0.1"
5
5
  end
@@ -5,7 +5,8 @@ describe Orthotypo::Composer::Fr do
5
5
  it 'adds spaces before double punctuation marks' do
6
6
  expect("mot: suite".ortho).to(eq("mot : suite"))
7
7
  expect("é: suite".ortho).to(eq("é : suite"))
8
- expect("1: suite".ortho).to(eq("1 : suite"))
8
+ # Pas automatisable, parce que 11:20
9
+ # expect("1: suite".ortho).to(eq("1 : suite"))
9
10
  expect("mot; suite".ortho).to(eq("mot ; suite"))
10
11
  expect("mot!".ortho).to(eq("mot !"))
11
12
  expect("mot !".ortho).to(eq("mot !"))
@@ -44,6 +45,18 @@ describe Orthotypo::Composer::Fr do
44
45
  expect("10 %".ortho).to(eq("10 %"))
45
46
  end
46
47
 
48
+ it 'fixes dates/time' do
49
+ expect("10/01/2023 16:00".ortho).to(eq("10/01/2023 16:00"))
50
+ expect("10/01/2023 16:00:00".ortho).to(eq("10/01/2023 16:00:00"))
51
+ expect("10 / 01 / 2023 16:00".ortho).to(eq("10/01/2023 16:00"))
52
+ expect("10 / 01 / 2023 16 : 00".ortho).to(eq("10/01/2023 16:00"))
53
+ expect("10 octobre 2023 16:00".ortho).to(eq("10 octobre 2023 16:00"))
54
+ end
55
+
56
+ it 'does well with HTML' do
57
+ expect("<p><a href=\"https://www.linkedin.com/in/marie-dewet-1397a094/\">Marie Dewet</a>, Co-fondatrice de <a href=\"https://www.linkedin.com/company/maisoncleo/\">MaisonCléo</a> nous apporte ses lumières.</p>".ortho).to(eq("<p><a href=\"https://www.linkedin.com/in/marie-dewet-1397a094/\">Marie Dewet</a>, Co-fondatrice de <a href=\"https://www.linkedin.com/company/maisoncleo/\">MaisonCléo</a> nous apporte ses lumières.</p>"))
58
+ end
59
+
47
60
  # https://www.scribbr.fr/elements-linguistiques/les-espaces/
48
61
  it 'tests de Justine Debret' do
49
62
  expect("Elle a vu son cousin,sa tante et son oncle.Ils allaient tous très bien.".ortho).to(eq("Elle a vu son cousin, sa tante et son oncle. Ils allaient tous très bien."))
@@ -53,6 +66,7 @@ describe Orthotypo::Composer::Fr do
53
66
  expect("Il a dit : «J’arrive ce matin ( ou plus tard ) à Paris [ rue de la République ] pour son anniversaire.»".ortho).to(eq("Il a dit : « J’arrive ce matin (ou plus tard) à Paris [rue de la République] pour son anniversaire. »"))
54
67
  # Le test suivant n'est pas automatisable, parce qu'on ne peut distinguer un Paris-Brest (le gâteau) d'un Paris - Brest (le trajet)
55
68
  # expect("Nous l’avons rencontré à Saint - Martin.".ortho).to(eq("Nous l’avons rencontré à Saint-Martin."))
69
+ expect("Il roule pendant 31, 5 km.".ortho).to(eq("Il roule pendant 31,5 km."))
56
70
  # Le test suivant est-il automatisable ?
57
71
  # expect("Il roule pendant 31, 5km.".ortho).to(eq("Il roule pendant 31,5 km."))
58
72
  # Pas automatisable, rien ne permet de distinguer s'il s'agit d'un rang ou d'un nombre
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: orthotypo
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.0
4
+ version: 1.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Arnaud Levy
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-10-16 00:00:00.000000000 Z
11
+ date: 2024-01-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: htmlentities
@@ -140,7 +140,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
140
140
  - !ruby/object:Gem::Version
141
141
  version: '0'
142
142
  requirements: []
143
- rubygems_version: 3.4.6
143
+ rubygems_version: 3.4.10
144
144
  signing_key:
145
145
  specification_version: 4
146
146
  summary: Pour un texte correctement typographié