orthotypo 1.0.3 → 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: 818fb1bd3d3eb901d75f4e02210bf77fd7602b1d032003a3dac4f8a74d82f947
4
- data.tar.gz: eef332835ee689969703219a8ddb6807c2f7d4d6d0e066ec71e9b1d68010e3ed
3
+ metadata.gz: 8a4b5c4a5884c04f0db62b3f19eb82e931ccde58da14d5d313c414466dfed31b
4
+ data.tar.gz: 9fd24516a4c7362fc58c1d849a7a3faa0a8503955a1b36ffad18388369391bd6
5
5
  SHA512:
6
- metadata.gz: 6055df7db77d195116bd55015ceecc22c7799991a13cfbd0f7fc01868afe16bf6c1578763a972c4ceee032fb72736388353463468cfd8a1596c8c54b659f854c
7
- data.tar.gz: 6643636a85073aecf213a8c533882fe960d275acead499b91cf92fa7ce987de006d9951b520e6077e234b951c44ff825002f1af692edcfafd1291d072942dcc7
6
+ metadata.gz: 3fe022af3600f9f095c43ec74f3f433f9dae967e84da59b45a1066e6ea8b4357208207f3430a1e73bd760383c3e017adca47966e821d7cea5b401ed7e77d3a91
7
+ data.tar.gz: af7b75573421c39b43ab15bc6f2e96e35afa30b3f07b0352b7daa055380ce6e30a224fd40af2f18823d204e0a7485af4ea729e7d7c4f5d621cd69cafa5a1d4a9
@@ -0,0 +1,18 @@
1
+ version: 2.1
2
+ orbs:
3
+ ruby: circleci/ruby@2.1.1
4
+ jobs:
5
+ test:
6
+ docker:
7
+ - image: cimg/ruby:3.3
8
+ steps:
9
+ - checkout
10
+ - ruby/install-deps
11
+ - run:
12
+ name: Run tests
13
+ command: bundle exec rake
14
+ workflows:
15
+ version: 2
16
+ deploy:
17
+ jobs:
18
+ - test
data/Gemfile CHANGED
@@ -6,5 +6,4 @@ source "https://rubygems.org"
6
6
  gemspec
7
7
 
8
8
  gem "rake", "~> 13.0"
9
-
10
9
  gem "rubocop", "~> 1.21"
data/Gemfile.lock CHANGED
@@ -1,69 +1,70 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- orthotypo (1.0.3)
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
- parallel (1.24.0)
22
- 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)
23
17
  ast (~> 2.4.1)
24
18
  racc
25
- racc (1.7.3)
19
+ prism (1.7.0)
20
+ racc (1.8.1)
26
21
  rainbow (3.1.1)
27
- rake (13.1.0)
28
- regexp_parser (2.9.0)
29
- rexml (3.2.6)
30
- rspec (3.13.0)
22
+ rake (13.3.1)
23
+ regexp_parser (2.11.3)
24
+ rspec (3.13.2)
31
25
  rspec-core (~> 3.13.0)
32
26
  rspec-expectations (~> 3.13.0)
33
27
  rspec-mocks (~> 3.13.0)
34
- rspec-core (3.13.0)
28
+ rspec-core (3.13.6)
35
29
  rspec-support (~> 3.13.0)
36
- rspec-expectations (3.13.0)
30
+ rspec-expectations (3.13.5)
37
31
  diff-lcs (>= 1.2.0, < 2.0)
38
32
  rspec-support (~> 3.13.0)
39
- rspec-mocks (3.13.0)
33
+ rspec-mocks (3.13.7)
40
34
  diff-lcs (>= 1.2.0, < 2.0)
41
35
  rspec-support (~> 3.13.0)
42
36
  rspec-nc (0.3.0)
43
37
  rspec (>= 3)
44
38
  terminal-notifier (>= 1.4)
45
- rspec-support (3.13.0)
46
- rubocop (1.60.2)
39
+ rspec-support (3.13.6)
40
+ rspec_junit_formatter (0.6.0)
41
+ rspec-core (>= 2, < 4, != 2.12.0)
42
+ rubocop (1.82.1)
47
43
  json (~> 2.3)
48
- language_server-protocol (>= 3.17.0)
44
+ language_server-protocol (~> 3.17.0.2)
45
+ lint_roller (~> 1.1.0)
49
46
  parallel (~> 1.10)
50
47
  parser (>= 3.3.0.2)
51
48
  rainbow (>= 2.2.2, < 4.0)
52
- regexp_parser (>= 1.8, < 3.0)
53
- rexml (>= 3.2.5, < 4.0)
54
- rubocop-ast (>= 1.30.0, < 2.0)
49
+ regexp_parser (>= 2.9.3, < 3.0)
50
+ rubocop-ast (>= 1.48.0, < 2.0)
55
51
  ruby-progressbar (~> 1.7)
56
- unicode-display_width (>= 2.4.0, < 3.0)
57
- rubocop-ast (1.30.0)
58
- parser (>= 3.2.1.0)
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)
59
56
  ruby-progressbar (1.13.0)
60
57
  terminal-notifier (2.0.0)
61
- unicode-display_width (2.5.0)
58
+ unicode-display_width (3.2.0)
59
+ unicode-emoji (~> 4.1)
60
+ unicode-emoji (4.2.0)
62
61
 
63
62
  PLATFORMS
64
63
  arm64-darwin-22
65
64
  arm64-darwin-23
66
65
  x86_64-darwin-22
66
+ x86_64-darwin-24
67
+ x86_64-linux
67
68
 
68
69
  DEPENDENCIES
69
70
  byebug
@@ -71,6 +72,7 @@ DEPENDENCIES
71
72
  rake (~> 13.0)
72
73
  rspec
73
74
  rspec-nc
75
+ rspec_junit_formatter
74
76
  rubocop (~> 1.21)
75
77
 
76
78
  BUNDLED WITH
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,250 +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
- token = "#{PRECIOUS_TOKEN}#{@precious_things.length}"
147
- # Store value
148
- @precious_things << string
149
- # Return identifier
150
- token
151
25
  end
152
26
 
153
- def restore_precious_things
154
- @precious_things.each_with_index do |value, index|
155
- @ortho.gsub! "#{PRECIOUS_TOKEN}#{index}", value
156
- end
157
- end
158
-
159
- def parse_chars_with_space_before
160
- chars_with_space_before.each do |char|
27
+ def to_s
28
+ unless @ortho
29
+ @ortho = @string.dup
161
30
  # Espace normal avant -> espace fine insécable avant
162
- fix(SPACE + char, NNBSP + char)
163
- # Pas d'espace avant -> espace fine insécable avant
164
- fix(/([[:alpha:]])#{Regexp.quote(char)}/, "\\1" + NNBSP + char)
165
- end
166
- end
167
-
168
- def parse_chars_with_space_before_after_digit
169
- chars_with_space_before_after_digit.each do |char|
170
- fix(/([[:digit:]])#{Regexp.quote(char)}/, "\\1" + NNBSP + char)
171
- end
172
- end
173
-
174
- def parse_chars_with_space_after
175
- chars_with_space_after.each do |char|
176
- # Espace avant -> pas d'espace avant
177
- fix(SPACE + char, char)
178
- # Pas d'espace après -> espace après
179
- # FIXME
180
- fix(/#{Regexp.quote(char)}([[:alpha:]])/, char + SPACE + "\\1")
181
- end
182
- end
183
-
184
- def parse_chars_with_space_around
185
- chars_with_space_around.each do |char|
186
- # Espace normal avant -> espace fine insécable avant
187
- fix(SPACE + char, NNBSP + char)
188
- # Pas d'espace avant -> espace fine insécable avant
189
- fix(/([[:alpha:]])#{Regexp.quote(char)}/, "\\1" + NNBSP + char)
190
- end
191
- end
192
-
193
- def parse_chars_with_no_space_before
194
- chars_with_no_space_before.each do |char|
195
- # Espace avant -> pas d'espace avant
196
- fix(SPACE + char, char)
197
- end
198
- end
199
-
200
- def parse_chars_with_no_space_around
201
- chars_with_no_space_around.each do |char|
202
- # Espace avant -> pas d'espace avant
203
- fix(SPACE + char, char)
204
- # Espace après -> pas d'espace après
205
- fix(char + SPACE, char)
206
- end
207
- end
208
-
209
- def parse_pairs_with_space_around
210
- pairs_with_space_around.each do |marks|
211
- opening = marks.chars.first
212
- closing = marks.chars.last
213
- # Espace normal -> espace fine insécable
214
- fix(opening + SPACE, opening + NNBSP)
215
- fix(SPACE + closing, NNBSP + closing)
216
- # Pas d'espace -> espace fine insécable
217
- fix(/#{Regexp.quote(opening)}([^[:space:]])/, opening + NNBSP + "\\1")
218
- fix(/([^[:space:]])#{Regexp.quote(closing)}/, "\\1" + NNBSP + closing)
219
- end
220
- end
221
-
222
- def parse_pairs_with_no_space_around
223
- pairs_with_no_space_around.each do |marks|
224
- opening = marks.chars.first
225
- closing = marks.chars.last
226
- # Espace -> pas d'espace
227
- fix(/#{Regexp.quote(opening)}[[:space:]](.+)[[:space:]]#{Regexp.quote(closing)}/, opening + "\\1" + closing)
228
- end
229
- end
230
-
231
- def parse_chars_in_numbers
232
- chars_in_numbers.each do |char|
233
- fix(/([[:digit:]])[[:space:]]#{Regexp.quote(char)}([[:digit:]])/, "\\1" + char + "\\2")
234
- fix(/([[:digit:]])[[:space:]]#{Regexp.quote(char)}[[:space:]]([[:digit:]])/, "\\1" + char + "\\2")
235
- 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
236
38
  end
39
+ @ortho
237
40
  end
238
41
 
239
- def html_entities
240
- @html_entities ||= HTMLEntities.new(:expanded)
241
- end
42
+ protected
242
43
 
243
44
  def fix(bad, good)
244
- @nokogiri.traverse do |node|
245
- next unless node.text?
246
- node.content = node.content.gsub(bad, good)
247
- end
45
+ @ortho.gsub!(bad, good)
248
46
  end
249
47
  end
250
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.3"
4
+ VERSION = "2.0.0"
5
5
  end
data/lib/orthotypo.rb CHANGED
@@ -1,17 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "htmlentities"
4
- require "nokogiri"
5
- require "uri"
6
- require_relative "orthotypo/analyzer"
7
3
  require_relative "orthotypo/composer"
8
- require_relative "orthotypo/composer/fr"
9
- require_relative "orthotypo/composer/fr_fr"
10
- require_relative "orthotypo/composer/fr_ch"
11
- require_relative "orthotypo/composer/en"
12
- require_relative "orthotypo/composer/en_gb"
13
4
  require_relative "orthotypo/core_ext"
14
- require_relative "orthotypo/localizer"
15
5
  require_relative "orthotypo/version"
16
6
 
17
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,10 +20,8 @@ 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"
25
+ spec.add_development_dependency "rspec_junit_formatter"
28
26
  spec.add_development_dependency "byebug"
29
27
  end
@@ -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
data/spec/spec_helper.rb CHANGED
@@ -1,2 +1,2 @@
1
1
  require 'byebug'
2
- require 'Orthotypo'
2
+ require 'orthotypo'
metadata CHANGED
@@ -1,37 +1,23 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: orthotypo
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.3
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-02-15 00:00:00.000000000 Z
11
+ date: 1980-01-02 00:00:00.000000000 Z
12
12
  dependencies:
13
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
14
+ name: rspec
29
15
  requirement: !ruby/object:Gem::Requirement
30
16
  requirements:
31
17
  - - ">="
32
18
  - !ruby/object:Gem::Version
33
19
  version: '0'
34
- type: :runtime
20
+ type: :development
35
21
  prerelease: false
36
22
  version_requirements: !ruby/object:Gem::Requirement
37
23
  requirements:
@@ -39,7 +25,7 @@ dependencies:
39
25
  - !ruby/object:Gem::Version
40
26
  version: '0'
41
27
  - !ruby/object:Gem::Dependency
42
- name: rspec
28
+ name: rspec-nc
43
29
  requirement: !ruby/object:Gem::Requirement
44
30
  requirements:
45
31
  - - ">="
@@ -53,7 +39,7 @@ dependencies:
53
39
  - !ruby/object:Gem::Version
54
40
  version: '0'
55
41
  - !ruby/object:Gem::Dependency
56
- name: rspec-nc
42
+ name: rspec_junit_formatter
57
43
  requirement: !ruby/object:Gem::Requirement
58
44
  requirements:
59
45
  - - ">="
@@ -85,10 +71,12 @@ description: Il y a un corpus riche de règles typographiques, dépendant des la
85
71
  le web, quand cela est possible.
86
72
  email:
87
73
  - arnaud.levy@noesya.coop
74
+ - sebastien.gaya@noesya.coop
88
75
  executables: []
89
76
  extensions: []
90
77
  extra_rdoc_files: []
91
78
  files:
79
+ - ".circleci/config.yml"
92
80
  - ".gitignore"
93
81
  - ".rubocop.yml"
94
82
  - CHANGELOG.md
@@ -101,22 +89,11 @@ files:
101
89
  - bin/console
102
90
  - bin/setup
103
91
  - lib/orthotypo.rb
104
- - lib/orthotypo/analyzer.rb
105
92
  - lib/orthotypo/composer.rb
106
- - lib/orthotypo/composer/en.rb
107
- - lib/orthotypo/composer/en_gb.rb
108
- - lib/orthotypo/composer/fr.rb
109
- - lib/orthotypo/composer/fr_ch.rb
110
- - lib/orthotypo/composer/fr_fr.rb
111
93
  - lib/orthotypo/core_ext.rb
112
- - lib/orthotypo/localizer.rb
113
94
  - lib/orthotypo/version.rb
114
95
  - orthotypo.gemspec
115
96
  - sig/orthotypo.rbs
116
- - spec/analyzer_spec.rb
117
- - spec/composer/en_spec.rb
118
- - spec/composer/fr_spec.rb
119
- - spec/localizer_spec.rb
120
97
  - spec/orthotypo_spec.rb
121
98
  - spec/spec_helper.rb
122
99
  homepage: https://github.com/noesya/orthotypo
@@ -125,7 +102,6 @@ licenses:
125
102
  metadata:
126
103
  homepage_uri: https://github.com/noesya/orthotypo
127
104
  source_code_uri: https://github.com/noesya/orthotypo
128
- post_install_message:
129
105
  rdoc_options: []
130
106
  require_paths:
131
107
  - lib
@@ -140,8 +116,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
140
116
  - !ruby/object:Gem::Version
141
117
  version: '0'
142
118
  requirements: []
143
- rubygems_version: 3.5.5
144
- signing_key:
119
+ rubygems_version: 3.6.9
145
120
  specification_version: 4
146
121
  summary: Pour un texte correctement typographié
147
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,100 +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
- 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