orthotypo 1.0.4 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b39450aef34318976f5708d105828cbc0792ff8d6c81a1f3c3eb51d2ce27713b
4
- data.tar.gz: d2a701e7525d6babcf406c702fc1e181ecae671840344df66f0d3d02538a702a
3
+ metadata.gz: 8a4b5c4a5884c04f0db62b3f19eb82e931ccde58da14d5d313c414466dfed31b
4
+ data.tar.gz: 9fd24516a4c7362fc58c1d849a7a3faa0a8503955a1b36ffad18388369391bd6
5
5
  SHA512:
6
- metadata.gz: 8066e337bf64b472bf9610e5e96c41819c5e0148a8725d22781c3d26a987835cc098745f8f12de4d3f087d745186006f6fe11f8fd7daa64e870d0175e458f3f6
7
- data.tar.gz: b9d9e4398cbc8e7516f6eb475abc0a22ae291b12b38706ed08bbc18e568abb415da8ec45ed7a6a3658a911efe68df0b6d15b0950b1f007d108dadf6de5ab1e0d
6
+ metadata.gz: 3fe022af3600f9f095c43ec74f3f433f9dae967e84da59b45a1066e6ea8b4357208207f3430a1e73bd760383c3e017adca47966e821d7cea5b401ed7e77d3a91
7
+ data.tar.gz: af7b75573421c39b43ab15bc6f2e96e35afa30b3f07b0352b7daa055380ce6e30a224fd40af2f18823d204e0a7485af4ea729e7d7c4f5d621cd69cafa5a1d4a9
data/Gemfile.lock CHANGED
@@ -1,73 +1,69 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- orthotypo (1.0.4)
5
- htmlentities
6
- nokogiri
4
+ orthotypo (2.0.0)
7
5
 
8
6
  GEM
9
7
  remote: https://rubygems.org/
10
8
  specs:
11
- ast (2.4.2)
12
- byebug (11.1.3)
13
- diff-lcs (1.5.1)
14
- htmlentities (4.3.4)
15
- json (2.7.1)
16
- language_server-protocol (3.17.0.3)
17
- nokogiri (1.16.2-arm64-darwin)
18
- racc (~> 1.4)
19
- nokogiri (1.16.2-x86_64-darwin)
20
- racc (~> 1.4)
21
- nokogiri (1.16.2-x86_64-linux)
22
- racc (~> 1.4)
23
- parallel (1.24.0)
24
- parser (3.3.0.5)
9
+ ast (2.4.3)
10
+ byebug (12.0.0)
11
+ diff-lcs (1.6.2)
12
+ json (2.18.0)
13
+ language_server-protocol (3.17.0.5)
14
+ lint_roller (1.1.0)
15
+ parallel (1.27.0)
16
+ parser (3.3.10.0)
25
17
  ast (~> 2.4.1)
26
18
  racc
27
- racc (1.7.3)
19
+ prism (1.7.0)
20
+ racc (1.8.1)
28
21
  rainbow (3.1.1)
29
- rake (13.1.0)
30
- regexp_parser (2.9.0)
31
- rexml (3.2.6)
32
- rspec (3.13.0)
22
+ rake (13.3.1)
23
+ regexp_parser (2.11.3)
24
+ rspec (3.13.2)
33
25
  rspec-core (~> 3.13.0)
34
26
  rspec-expectations (~> 3.13.0)
35
27
  rspec-mocks (~> 3.13.0)
36
- rspec-core (3.13.0)
28
+ rspec-core (3.13.6)
37
29
  rspec-support (~> 3.13.0)
38
- rspec-expectations (3.13.0)
30
+ rspec-expectations (3.13.5)
39
31
  diff-lcs (>= 1.2.0, < 2.0)
40
32
  rspec-support (~> 3.13.0)
41
- rspec-mocks (3.13.0)
33
+ rspec-mocks (3.13.7)
42
34
  diff-lcs (>= 1.2.0, < 2.0)
43
35
  rspec-support (~> 3.13.0)
44
36
  rspec-nc (0.3.0)
45
37
  rspec (>= 3)
46
38
  terminal-notifier (>= 1.4)
47
- rspec-support (3.13.1)
39
+ rspec-support (3.13.6)
48
40
  rspec_junit_formatter (0.6.0)
49
41
  rspec-core (>= 2, < 4, != 2.12.0)
50
- rubocop (1.62.1)
42
+ rubocop (1.82.1)
51
43
  json (~> 2.3)
52
- language_server-protocol (>= 3.17.0)
44
+ language_server-protocol (~> 3.17.0.2)
45
+ lint_roller (~> 1.1.0)
53
46
  parallel (~> 1.10)
54
47
  parser (>= 3.3.0.2)
55
48
  rainbow (>= 2.2.2, < 4.0)
56
- regexp_parser (>= 1.8, < 3.0)
57
- rexml (>= 3.2.5, < 4.0)
58
- rubocop-ast (>= 1.31.1, < 2.0)
49
+ regexp_parser (>= 2.9.3, < 3.0)
50
+ rubocop-ast (>= 1.48.0, < 2.0)
59
51
  ruby-progressbar (~> 1.7)
60
- unicode-display_width (>= 2.4.0, < 3.0)
61
- rubocop-ast (1.31.2)
62
- parser (>= 3.3.0.4)
52
+ unicode-display_width (>= 2.4.0, < 4.0)
53
+ rubocop-ast (1.49.0)
54
+ parser (>= 3.3.7.2)
55
+ prism (~> 1.7)
63
56
  ruby-progressbar (1.13.0)
64
57
  terminal-notifier (2.0.0)
65
- unicode-display_width (2.5.0)
58
+ unicode-display_width (3.2.0)
59
+ unicode-emoji (~> 4.1)
60
+ unicode-emoji (4.2.0)
66
61
 
67
62
  PLATFORMS
68
63
  arm64-darwin-22
69
64
  arm64-darwin-23
70
65
  x86_64-darwin-22
66
+ x86_64-darwin-24
71
67
  x86_64-linux
72
68
 
73
69
  DEPENDENCIES
data/README.md CHANGED
@@ -4,6 +4,8 @@
4
4
 
5
5
  Il y a un corpus riche de règles typographiques, dépendant des langues.
6
6
  Cette gem vise à intégrer ces règles et à automatiser leurs mises en application pour le web, quand cela est possible.
7
+ La version 1 créait des effets de bord, en tentant d'implémenter trop de logiques.
8
+ La version 2 est beaucoup plus modeste.
7
9
 
8
10
  ## Installation
9
11
 
@@ -17,23 +19,13 @@ If bundler is not being used to manage dependencies, install the gem by executin
17
19
 
18
20
  ## Usage
19
21
 
20
- Ajout d'espace fine insécable avant les signes doubles en français.
22
+ Remplacement d'espace par un espace insécable avant les signes doubles.
21
23
 
22
24
  ```
23
- "Un texte avec un signe double: mais il manque l'espace.".ortho
24
- > Un texte avec un signe double: mais il manque l'espace.
25
-
25
+ "Un texte avec un espace devant un signe double : mais il manque l'espace insécable.".ortho
26
+ > Un texte avec un espace devant un signe double : mais il manque l'espace insécable.
26
27
  ```
27
28
 
28
- ## Roadmap
29
-
30
- ### v1
31
- Ne pas endommager l'HTML et les HTML entities (&nbsp;)
32
-
33
- ### v2
34
- S'adapter aux locales (détecter I18n)
35
- Permettre les configs
36
-
37
29
  ## Tests
38
30
 
39
31
  ```
@@ -1,251 +1,48 @@
1
1
  module Orthotypo
2
2
  class Composer
3
- attr_reader :string, :ortho
4
-
5
3
  SPACE = ' '.freeze
6
4
  NBSP = ' '.freeze
7
5
  NNBSP = ' '.freeze
8
- PRECIOUS_TOKEN = 'orthotypopreciousthing'
9
6
 
10
- def initialize(string, html: nil)
7
+ NON_BREAKING_SPACE_BEFORE = [
8
+ ';',
9
+ ':',
10
+ '!',
11
+ '?',
12
+ '”',
13
+ '»',
14
+ '›'
15
+ ].freeze
16
+
17
+ NON_BREAKING_SPACE_AFTER = [
18
+ '“',
19
+ '«',
20
+ '‹'
21
+ ].freeze
22
+
23
+ def initialize(string)
11
24
  @string = string
12
- @html = html
13
- parse
14
- end
15
-
16
- protected
17
-
18
- def chars_with_space_before
19
- []
20
- end
21
-
22
- def chars_with_space_before_after_digit
23
- [
24
- '%'
25
- ]
26
- end
27
-
28
- def chars_with_space_after
29
- [
30
- ',',
31
- '.'
32
- ]
33
- end
34
-
35
- def chars_with_space_around
36
- []
37
- end
38
-
39
- def chars_with_no_space_before
40
- []
41
- end
42
-
43
- def chars_with_no_space_around
44
- []
45
- end
46
-
47
- def pairs_with_space_around
48
- []
49
- end
50
-
51
- def pairs_with_no_space_around
52
- []
53
- end
54
-
55
- def chars_with_no_space_around_between_digits
56
- [
57
- '/',
58
- ':'
59
- ]
60
- end
61
-
62
- def chars_in_numbers
63
- [
64
- '.',
65
- ',',
66
- '/',
67
- ':'
68
- ]
69
- end
70
-
71
- def is_html?
72
- # TODO contains tags?
73
- @html || contains_html_entities?
74
- end
75
-
76
- def contains_html_entities?
77
- @contains_html_entities ||= html_entities.decode(string) != string
78
- end
79
-
80
- def prepare_linebreaks
81
- @string.gsub! "\r\n", "<br>"
82
- @string.gsub! "\r", "<br>"
83
- @string.gsub! "\n", "<br>"
84
- end
85
-
86
- def prepare_ortho
87
- @ortho = string.dup
88
- @nokogiri = Nokogiri::HTML.fragment @ortho
89
- end
90
-
91
- def clean_ortho
92
- @ortho = @nokogiri.to_s
93
- end
94
-
95
- def parse
96
- prepare_linebreaks
97
- prepare_ortho
98
- preserve_precious_things
99
- # Chars
100
- parse_chars_with_space_before
101
- parse_chars_with_space_before_after_digit
102
- parse_chars_with_space_after
103
- parse_chars_with_space_around
104
- parse_chars_with_no_space_before
105
- parse_chars_with_no_space_around
106
- # Pairs
107
- parse_pairs_with_space_around
108
- parse_pairs_with_no_space_around
109
- # Numbers
110
- parse_chars_in_numbers
111
- #
112
- clean_ortho
113
- restore_precious_things
114
- end
115
-
116
- def preserve_precious_things
117
- @precious_things = {}
118
- @nokogiri.traverse do |node|
119
- if node.text?
120
- has_leading_space = node.content.start_with? SPACE
121
- has_trailing_space = node.content.end_with? SPACE
122
- node.content = node.content.split(SPACE).map { |fragment|
123
- store_if_precious(fragment)
124
- }.join(SPACE)
125
- node.content = SPACE + node.content if has_leading_space
126
- node.content = node.content + SPACE if has_trailing_space
127
- elsif node.element?
128
- if node.name == 'a'
129
- node.attributes.each do |key, attribute|
130
- if attribute.name == 'href'
131
- attribute.value = store_precious_thing(attribute.value)
132
- end
133
- end
134
- end
135
- end
136
- end
137
- end
138
-
139
- def store_if_precious(string)
140
- Analyzer::precious?(string) ? store_precious_thing(string)
141
- : string
142
- end
143
-
144
- def store_precious_thing(string)
145
- # Create token identifier
146
- uid = SecureRandom.hex
147
- token = "#{PRECIOUS_TOKEN}-#{uid}"
148
- # Store value
149
- @precious_things[uid] = string
150
- # Return identifier
151
- token
152
25
  end
153
26
 
154
- def restore_precious_things
155
- @precious_things.each do |uid, value|
156
- @ortho.gsub! "#{PRECIOUS_TOKEN}-#{uid}", value
157
- end
158
- end
159
-
160
- def parse_chars_with_space_before
161
- chars_with_space_before.each do |char|
27
+ def to_s
28
+ unless @ortho
29
+ @ortho = @string.dup
162
30
  # Espace normal avant -> espace fine insécable avant
163
- fix(SPACE + char, NNBSP + char)
164
- # Pas d'espace avant -> espace fine insécable avant
165
- fix(/([[:alpha:]])#{Regexp.quote(char)}/, "\\1" + NNBSP + char)
166
- end
167
- end
168
-
169
- def parse_chars_with_space_before_after_digit
170
- chars_with_space_before_after_digit.each do |char|
171
- fix(/([[:digit:]])#{Regexp.quote(char)}/, "\\1" + NNBSP + char)
172
- end
173
- end
174
-
175
- def parse_chars_with_space_after
176
- chars_with_space_after.each do |char|
177
- # Espace avant -> pas d'espace avant
178
- fix(SPACE + char, char)
179
- # Pas d'espace après -> espace après
180
- # FIXME
181
- fix(/#{Regexp.quote(char)}([[:alpha:]])/, char + SPACE + "\\1")
182
- end
183
- end
184
-
185
- def parse_chars_with_space_around
186
- chars_with_space_around.each do |char|
187
- # Espace normal avant -> espace fine insécable avant
188
- fix(SPACE + char, NNBSP + char)
189
- # Pas d'espace avant -> espace fine insécable avant
190
- fix(/([[:alpha:]])#{Regexp.quote(char)}/, "\\1" + NNBSP + char)
191
- end
192
- end
193
-
194
- def parse_chars_with_no_space_before
195
- chars_with_no_space_before.each do |char|
196
- # Espace avant -> pas d'espace avant
197
- fix(SPACE + char, char)
198
- end
199
- end
200
-
201
- def parse_chars_with_no_space_around
202
- chars_with_no_space_around.each do |char|
203
- # Espace avant -> pas d'espace avant
204
- fix(SPACE + char, char)
205
- # Espace après -> pas d'espace après
206
- fix(char + SPACE, char)
207
- end
208
- end
209
-
210
- def parse_pairs_with_space_around
211
- pairs_with_space_around.each do |marks|
212
- opening = marks.chars.first
213
- closing = marks.chars.last
214
- # Espace normal -> espace fine insécable
215
- fix(opening + SPACE, opening + NNBSP)
216
- fix(SPACE + closing, NNBSP + closing)
217
- # Pas d'espace -> espace fine insécable
218
- fix(/#{Regexp.quote(opening)}([^[:space:]])/, opening + NNBSP + "\\1")
219
- fix(/([^[:space:]])#{Regexp.quote(closing)}/, "\\1" + NNBSP + closing)
220
- end
221
- end
222
-
223
- def parse_pairs_with_no_space_around
224
- pairs_with_no_space_around.each do |marks|
225
- opening = marks.chars.first
226
- closing = marks.chars.last
227
- # Espace -> pas d'espace
228
- fix(/#{Regexp.quote(opening)}[[:space:]](.+)[[:space:]]#{Regexp.quote(closing)}/, opening + "\\1" + closing)
229
- end
230
- end
231
-
232
- def parse_chars_in_numbers
233
- chars_in_numbers.each do |char|
234
- fix(/([[:digit:]])[[:space:]]#{Regexp.quote(char)}([[:digit:]])/, "\\1" + char + "\\2")
235
- fix(/([[:digit:]])[[:space:]]#{Regexp.quote(char)}[[:space:]]([[:digit:]])/, "\\1" + char + "\\2")
236
- fix(/([[:digit:]])#{Regexp.quote(char)}[[:space:]]([[:digit:]])/, "\\1" + char + "\\2")
31
+ NON_BREAKING_SPACE_BEFORE.each do |char|
32
+ fix(SPACE + char, NNBSP + char)
33
+ end
34
+ # Espace normal après -> espace fine insécable après
35
+ NON_BREAKING_SPACE_AFTER.each do |char|
36
+ fix(char + SPACE, char + NNBSP)
37
+ end
237
38
  end
39
+ @ortho
238
40
  end
239
41
 
240
- def html_entities
241
- @html_entities ||= HTMLEntities.new(:expanded)
242
- end
42
+ protected
243
43
 
244
44
  def fix(bad, good)
245
- @nokogiri.traverse do |node|
246
- next unless node.text?
247
- node.content = node.content.gsub(bad, good)
248
- end
45
+ @ortho.gsub!(bad, good)
249
46
  end
250
47
  end
251
48
  end
@@ -1,5 +1,5 @@
1
1
  String.class_eval do
2
2
  def ortho(locale: nil, html: nil)
3
- @ortho ||= Orthotypo::Localizer.new(self, locale: locale, html: html).composer.ortho
3
+ @ortho ||= Orthotypo::Composer.new(self).to_s
4
4
  end
5
5
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Orthotypo
4
- VERSION = "1.0.4"
4
+ VERSION = "2.0.0"
5
5
  end
data/lib/orthotypo.rb CHANGED
@@ -1,18 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "htmlentities"
4
- require "nokogiri"
5
- require "securerandom"
6
- require "uri"
7
- require_relative "orthotypo/analyzer"
8
3
  require_relative "orthotypo/composer"
9
- require_relative "orthotypo/composer/fr"
10
- require_relative "orthotypo/composer/fr_fr"
11
- require_relative "orthotypo/composer/fr_ch"
12
- require_relative "orthotypo/composer/en"
13
- require_relative "orthotypo/composer/en_gb"
14
4
  require_relative "orthotypo/core_ext"
15
- require_relative "orthotypo/localizer"
16
5
  require_relative "orthotypo/version"
17
6
 
18
7
  module Orthotypo
data/orthotypo.gemspec CHANGED
@@ -5,8 +5,8 @@ require_relative "lib/orthotypo/version"
5
5
  Gem::Specification.new do |spec|
6
6
  spec.name = "orthotypo"
7
7
  spec.version = Orthotypo::VERSION
8
- spec.authors = ["Arnaud Levy"]
9
- spec.email = ["arnaud.levy@noesya.coop"]
8
+ spec.authors = ["Arnaud Levy", "Sébastien Gaya"]
9
+ spec.email = ["arnaud.levy@noesya.coop", "sebastien.gaya@noesya.coop"]
10
10
 
11
11
  spec.summary = "Pour un texte correctement typographié"
12
12
  spec.description = "Il y a un corpus riche de règles typographiques, dépendant des langues. Cette gem vise à intégrer ces règles et à automatiser leur mise en application pour le web, quand cela est possible."
@@ -20,9 +20,6 @@ Gem::Specification.new do |spec|
20
20
  spec.files = `git ls-files`.split("\n")
21
21
  spec.require_paths = "lib"
22
22
 
23
- spec.add_dependency "htmlentities"
24
- spec.add_dependency "nokogiri"
25
-
26
23
  spec.add_development_dependency "rspec"
27
24
  spec.add_development_dependency "rspec-nc"
28
25
  spec.add_development_dependency "rspec_junit_formatter"
@@ -14,8 +14,34 @@ describe Orthotypo do
14
14
  expect("<a href=\"https://unsplash.com/@lusvardi?utm_source=osuny\">https://unsplash.com/@lusvardi?utm_source=osuny</a>".ortho).to eq "<a href=\"https://unsplash.com/@lusvardi?utm_source=osuny\">https://unsplash.com/@lusvardi?utm_source=osuny</a>"
15
15
  end
16
16
 
17
- it 'leaves URLs untouched' do
17
+ it 'leaves mails untouched' do
18
18
  expect("prenom.nom@example.com".ortho).to eq "prenom.nom@example.com"
19
19
  expect("<a href=\"mailto:prenom.nom@example.com\">prenom.nom@example.com</a>".ortho).to eq "<a href=\"mailto:prenom.nom@example.com\">prenom.nom@example.com</a>"
20
20
  end
21
+
22
+ it 'transforms regular spaces before double punctuation marks' do
23
+ # :;!?
24
+ expect("mot : suite".ortho).to(eq("mot : suite"))
25
+ expect("mot ; suite".ortho).to(eq("mot ; suite"))
26
+ expect("mot ! suite".ortho).to(eq("mot ! suite"))
27
+ expect("mot ? suite".ortho).to(eq("mot ? suite"))
28
+ # No problem with special chars
29
+ expect("é : suite".ortho).to(eq("é : suite"))
30
+ expect("1 : suite".ortho).to(eq("1 : suite"))
31
+ end
32
+
33
+ it 'fixes spaces after and before quotation marks' do
34
+ # «»
35
+ expect("«mot»".ortho).to(eq("«mot»"))
36
+ expect("« mot »".ortho).to(eq("« mot »"))
37
+ expect("« mot »".ortho).to(eq("« mot »"))
38
+ # ‹›
39
+ expect("‹mot›".ortho).to(eq("‹mot›"))
40
+ expect("‹ mot ›".ortho).to(eq("‹ mot ›"))
41
+ expect("‹ mot ›".ortho).to(eq("‹ mot ›"))
42
+ # “”
43
+ expect("“mot”".ortho).to(eq("“mot”"))
44
+ expect("“ mot ”".ortho).to(eq("“ mot ”"))
45
+ expect("“ mot ”".ortho).to(eq("“ mot ”"))
46
+ end
21
47
  end
metadata CHANGED
@@ -1,43 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: orthotypo
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.4
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Arnaud Levy
8
- autorequire:
8
+ - Sébastien Gaya
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-03-15 00:00:00.000000000 Z
11
+ date: 1980-01-02 00:00:00.000000000 Z
12
12
  dependencies:
13
- - !ruby/object:Gem::Dependency
14
- name: htmlentities
15
- requirement: !ruby/object:Gem::Requirement
16
- requirements:
17
- - - ">="
18
- - !ruby/object:Gem::Version
19
- version: '0'
20
- type: :runtime
21
- prerelease: false
22
- version_requirements: !ruby/object:Gem::Requirement
23
- requirements:
24
- - - ">="
25
- - !ruby/object:Gem::Version
26
- version: '0'
27
- - !ruby/object:Gem::Dependency
28
- name: nokogiri
29
- requirement: !ruby/object:Gem::Requirement
30
- requirements:
31
- - - ">="
32
- - !ruby/object:Gem::Version
33
- version: '0'
34
- type: :runtime
35
- prerelease: false
36
- version_requirements: !ruby/object:Gem::Requirement
37
- requirements:
38
- - - ">="
39
- - !ruby/object:Gem::Version
40
- version: '0'
41
13
  - !ruby/object:Gem::Dependency
42
14
  name: rspec
43
15
  requirement: !ruby/object:Gem::Requirement
@@ -99,6 +71,7 @@ description: Il y a un corpus riche de règles typographiques, dépendant des la
99
71
  le web, quand cela est possible.
100
72
  email:
101
73
  - arnaud.levy@noesya.coop
74
+ - sebastien.gaya@noesya.coop
102
75
  executables: []
103
76
  extensions: []
104
77
  extra_rdoc_files: []
@@ -116,22 +89,11 @@ files:
116
89
  - bin/console
117
90
  - bin/setup
118
91
  - lib/orthotypo.rb
119
- - lib/orthotypo/analyzer.rb
120
92
  - lib/orthotypo/composer.rb
121
- - lib/orthotypo/composer/en.rb
122
- - lib/orthotypo/composer/en_gb.rb
123
- - lib/orthotypo/composer/fr.rb
124
- - lib/orthotypo/composer/fr_ch.rb
125
- - lib/orthotypo/composer/fr_fr.rb
126
93
  - lib/orthotypo/core_ext.rb
127
- - lib/orthotypo/localizer.rb
128
94
  - lib/orthotypo/version.rb
129
95
  - orthotypo.gemspec
130
96
  - sig/orthotypo.rbs
131
- - spec/analyzer_spec.rb
132
- - spec/composer/en_spec.rb
133
- - spec/composer/fr_spec.rb
134
- - spec/localizer_spec.rb
135
97
  - spec/orthotypo_spec.rb
136
98
  - spec/spec_helper.rb
137
99
  homepage: https://github.com/noesya/orthotypo
@@ -140,7 +102,6 @@ licenses:
140
102
  metadata:
141
103
  homepage_uri: https://github.com/noesya/orthotypo
142
104
  source_code_uri: https://github.com/noesya/orthotypo
143
- post_install_message:
144
105
  rdoc_options: []
145
106
  require_paths:
146
107
  - lib
@@ -155,8 +116,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
155
116
  - !ruby/object:Gem::Version
156
117
  version: '0'
157
118
  requirements: []
158
- rubygems_version: 3.4.10
159
- signing_key:
119
+ rubygems_version: 3.6.9
160
120
  specification_version: 4
161
121
  summary: Pour un texte correctement typographié
162
122
  test_files: []
@@ -1,20 +0,0 @@
1
- module Orthotypo
2
- class Analyzer
3
-
4
- def self.url?(string)
5
- uri = URI.parse(string)
6
- uri.class != URI::Generic
7
- rescue URI::InvalidURIError
8
- false
9
- end
10
-
11
- def self.email?(string)
12
- string =~ /\A#{URI::MailTo::EMAIL_REGEXP}\z/ ? true : false
13
- end
14
-
15
- def self.precious?(string)
16
- email?(string) || url?(string)
17
- end
18
-
19
- end
20
- end
@@ -1,18 +0,0 @@
1
- module Orthotypo
2
- class Composer::En < Composer
3
-
4
- def chars_with_space_after
5
- [
6
- ',',
7
- '.',
8
- '...',
9
- '…',
10
- ';',
11
- ':',
12
- '!',
13
- '?'
14
- ]
15
- end
16
-
17
- end
18
- end
@@ -1,5 +0,0 @@
1
- module Orthotypo
2
- class Composer::EnGb < Composer::En
3
-
4
- end
5
- end
@@ -1,61 +0,0 @@
1
- module Orthotypo
2
- class Composer::Fr < Composer
3
-
4
- protected
5
-
6
- def chars_with_space_before
7
- [
8
- '%'
9
- ]
10
- end
11
-
12
- def chars_with_space_after
13
- [
14
- ',',
15
- '...',
16
- '…'
17
- ]
18
- end
19
-
20
- def chars_with_space_around
21
- [
22
- ';',
23
- ':',
24
- '!',
25
- '?'
26
- ]
27
- end
28
-
29
- def chars_with_no_space_before
30
- [
31
- '.'
32
- ]
33
- end
34
-
35
- def chars_with_no_space_around
36
- [
37
- "'",
38
- '’',
39
- 'ʼ'
40
- ]
41
- end
42
-
43
- def pairs_with_space_around
44
- [
45
- '«»'
46
- ]
47
- end
48
-
49
- def pairs_with_no_space_around
50
- [
51
- '“”',
52
- '‹›',
53
- '""',
54
- "''",
55
- "()",
56
- "{}",
57
- "[]"
58
- ]
59
- end
60
- end
61
- end
@@ -1,4 +0,0 @@
1
- module Orthotypo
2
- class Composer::FrCh < Composer::Fr
3
- end
4
- end
@@ -1,4 +0,0 @@
1
- module Orthotypo
2
- class Composer::FrFr < Composer::Fr
3
- end
4
- end
@@ -1,32 +0,0 @@
1
- module Orthotypo
2
- class Localizer
3
-
4
- DEFAULT_LOCALE = 'fr'
5
-
6
- def initialize(string, locale: nil, html: nil)
7
- @string = string
8
- @locale = locale
9
- @html = html
10
- end
11
-
12
- def composer
13
- composer_class.new @string, html: @html
14
- end
15
-
16
- protected
17
-
18
- def composer_class
19
- composer_class = composer_class_for(@locale) unless @locale.nil?
20
- composer_class ||= composer_class_for(DEFAULT_LOCALE)
21
- composer_class
22
- end
23
-
24
- def composer_class_for(locale)
25
- formatted_locale = locale.split('-').map(&:capitalize).join
26
- class_name = "::Orthotypo::Composer::#{formatted_locale}"
27
- Object.module_eval(class_name, __FILE__, __LINE__)
28
- rescue
29
- nil
30
- end
31
- end
32
- end
@@ -1,10 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Orthotypo::Analyzer do
4
- it 'find urls' do
5
- expect(Orthotypo::Analyzer.url?("https://unsplash.com/@lusvardi?utm_source=osuny")).to be true
6
- expect(Orthotypo::Analyzer.url?("https://hal.science/hal-02455856")).to be true
7
- expect(Orthotypo::Analyzer.url?("mailto:test@example.com")).to be true
8
- expect(Orthotypo::Analyzer.url?("mot:")).to be false
9
- end
10
- end
@@ -1,17 +0,0 @@
1
-
2
- require 'spec_helper'
3
-
4
- describe Orthotypo::Composer::En do
5
- it 'removes spaces before double punctuation marks' do
6
- expect("mot: suite".ortho(locale: 'en')).to eq "mot: suite"
7
- expect("mot : suite".ortho(locale: 'en')).to eq "mot: suite"
8
- expect("é: suite".ortho(locale: 'en')).to eq "é: suite"
9
- expect("é : suite".ortho(locale: 'en')).to eq "é: suite"
10
- expect("1: suite".ortho(locale: 'en')).to eq "1: suite"
11
- expect("1 : suite".ortho(locale: 'en')).to eq "1: suite"
12
- expect("mot; suite".ortho(locale: 'en')).to eq "mot; suite"
13
- expect("mot ; suite".ortho(locale: 'en')).to eq "mot; suite"
14
- expect("mot!".ortho(locale: 'en')).to eq "mot!"
15
- expect("mot !".ortho(locale: 'en')).to eq "mot!"
16
- end
17
- end
@@ -1,108 +0,0 @@
1
-
2
- require 'spec_helper'
3
-
4
- describe Orthotypo::Composer::Fr do
5
- it 'adds spaces before double punctuation marks' do
6
- expect("mot: suite".ortho).to(eq("mot : suite"))
7
- expect("é: suite".ortho).to(eq("é : suite"))
8
- # Pas automatisable, parce qu'on peut écrire une heure 11:20
9
- # expect("1: suite".ortho).to(eq("1 : suite"))
10
- expect("mot; suite".ortho).to(eq("mot ; suite"))
11
- expect("mot!".ortho).to(eq("mot !"))
12
- expect("mot !".ortho).to(eq("mot !"))
13
- end
14
-
15
- it 'transforms regular spaces before double punctuation marks' do
16
- expect("mot : suite".ortho).to(eq("mot : suite"))
17
- expect("é : suite".ortho).to(eq("é : suite"))
18
- expect("1 : suite".ortho).to(eq("1 : suite"))
19
- end
20
-
21
- it 'fixes space before simple punctuation' do
22
- expect("mot , suite".ortho).to(eq("mot, suite"))
23
- expect("mot . suite".ortho).to(eq("mot. suite"))
24
- expect("l 'approche".ortho).to(eq("l'approche"))
25
- expect("l' approche".ortho).to(eq("l'approche"))
26
- end
27
-
28
- it 'fixes space after simple punctuation' do
29
- expect("mot,suite".ortho).to(eq("mot, suite"))
30
- expect("84.Paris".ortho).to(eq("84.Paris"))
31
- expect("etudiant.gouv.fr".ortho).to(eq("etudiant.gouv.fr"))
32
- expect("4,5".ortho).to(eq("4,5"))
33
- expect("4.5".ortho).to(eq("4.5"))
34
- # Le test suivant, on ne fait rien, on ne peut pas résoudre, car s'apparente au cas précédent (1984.5)
35
- # expect("Il est né en 1984.5 maisons en paille".ortho).to(eq("Il est né en 1984. 5 maisons en paille"))
36
- end
37
-
38
- it 'fixes quotation marks' do
39
- expect("«mot»".ortho).to(eq("« mot »"))
40
- expect("« mot »".ortho).to(eq("« mot »"))
41
- expect("“ mot ”".ortho).to(eq("“mot”"))
42
- expect("‹ mot ›".ortho).to(eq("‹mot›"))
43
- expect("\" mot \"".ortho).to(eq("\"mot\""))
44
- expect("' mot '".ortho).to(eq("'mot'"))
45
- expect("( une phrase entre parenthèses )".ortho).to(eq("(une phrase entre parenthèses)"))
46
- expect('photos "On the Job", stock'.ortho).to(eq('photos "On the Job", stock'))
47
- end
48
-
49
- it 'fixes percent' do
50
- expect("10%".ortho).to(eq("10 %"))
51
- expect("10 %".ortho).to(eq("10 %"))
52
- end
53
-
54
- it 'fixes dates/time' do
55
- expect("10/01/2023 16:00".ortho).to(eq("10/01/2023 16:00"))
56
- expect("10/01/2023 16:00:00".ortho).to(eq("10/01/2023 16:00:00"))
57
- expect("10 / 01 / 2023 16:00".ortho).to(eq("10/01/2023 16:00"))
58
- expect("10 / 01 / 2023 16 : 00".ortho).to(eq("10/01/2023 16:00"))
59
- expect("10 octobre 2023 16:00".ortho).to(eq("10 octobre 2023 16:00"))
60
- end
61
-
62
- it 'does well with HTML' do
63
- 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>"))
64
- expect("<p></p><p>Nous aimons la qualité</p><p></p>".ortho).to(eq("<p></p><p>Nous aimons la qualité</p><p></p>"))
65
- expect('<p>Série de photos "On the Job", Death to the stock</p>'.ortho).to(eq('<p>Série de photos "On the Job", Death to the stock</p>'))
66
- end
67
-
68
- it 'manages linebreaks' do
69
- expect("A parallel between wildlife and urban ensembles.\r\rShot during summer 2014 on our trip from north to south of Portugal.".ortho).to(eq("A parallel between wildlife and urban ensembles.<br><br>Shot during summer 2014 on our trip from north to south of Portugal."))
70
- end
71
-
72
- it 'preserves URLs' do
73
- expect("https://hal.science/hal-02455856".ortho).to(eq("https://hal.science/hal-02455856"))
74
- end
75
-
76
- # https://www.scribbr.fr/elements-linguistiques/les-espaces/
77
- it 'tests de Justine Debret' do
78
- # FIXME
79
- # 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."))
80
- expect("Elle ne disait plus rien…jusqu’au moment du repas.".ortho).to(eq("Elle ne disait plus rien… jusqu’au moment du repas."))
81
-
82
- expect("Elle dit: qui voudrait bien venir voir ce film? Il répond: moi; à moins qu’il ne fasse très beau!".ortho).to(eq("Elle dit : qui voudrait bien venir voir ce film ? Il répond : moi ; à moins qu’il ne fasse très beau !"))
83
-
84
- expect("L’ hiver ne va pas durer toute l’année.".ortho).to(eq("L’hiver ne va pas durer toute l’année."))
85
-
86
- 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. »"))
87
-
88
- # 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)
89
- # expect("Nous l’avons rencontré à Saint - Martin.".ortho).to(eq("Nous l’avons rencontré à Saint-Martin."))
90
-
91
- expect("Il roule pendant 31, 5 km.".ortho).to(eq("Il roule pendant 31,5 km."))
92
-
93
- # Le test suivant est-il automatisable ?
94
- # expect("Il roule pendant 31, 5km.".ortho).to(eq("Il roule pendant 31,5 km."))
95
-
96
- # Pas automatisable, rien ne permet de distinguer s'il s'agit d'un rang ou d'un nombre
97
- # expect("Il en compte 1,000, 10,000, 36,742, 500,000, puis 1,000,000, 25,000,000, etc.".ortho).to(eq("Il en compte 1 000, 10 000, 36 742, 500 000, puis 1 000 000, 25 000 000, etc."))
98
- # expect("Le numéro gagnant est le 3 541 672.".ortho).to(eq("Le numéro gagnant est le 3541672."))
99
- end
100
-
101
- it 'preserves all URLs' do
102
- # Generates '<a href="https://example0.fr\">Example 0</a><a href="https://example1.fr\">Example 1</a><a href="https://example2.fr\">Example 2</a>...'
103
- input = (0..12).map { |n|
104
- "<a href=\"https://example#{n}.fr\">Example #{n}</a>"
105
- }.join
106
- expect(input.ortho).to(eq(input))
107
- end
108
- end
@@ -1,13 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Orthotypo do
4
- it 'selects proper locale' do
5
- expect(Orthotypo::Localizer.new('').composer).to be_a Orthotypo::Composer::Fr
6
- expect(Orthotypo::Localizer.new('', locale: 'fr').composer).to be_a Orthotypo::Composer::Fr
7
- expect(Orthotypo::Localizer.new('', locale: 'fr-FR').composer).to be_a Orthotypo::Composer::FrFr
8
- expect(Orthotypo::Localizer.new('', locale: 'fr-CH').composer).to be_a Orthotypo::Composer::FrCh
9
- expect(Orthotypo::Localizer.new('', locale: 'en').composer).to be_a Orthotypo::Composer::En
10
- expect(Orthotypo::Localizer.new('', locale: 'en-GB').composer).to be_a Orthotypo::Composer::EnGb
11
- expect(Orthotypo::Localizer.new('', locale: 'en-UNKNOWN').composer).to be_a Orthotypo::Composer::Fr
12
- end
13
- end