hablaba 0.0.4 → 1.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 +5 -5
- data/CHANGELOG.md +59 -0
- data/LICENSE +21 -0
- data/README.md +102 -0
- data/lib/hablaba/version.rb +5 -0
- data/lib/hablaba.rb +133 -117
- metadata +18 -12
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
|
-
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: b3667a098fb9e82c4c24e8f823935488da1f927b39d09b1e3deb342eb309a571
|
|
4
|
+
data.tar.gz: dcbb203fe8f136e9ac1ea467407279d8c0fec7e5f2529e6de0698256ab3138b7
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 3099e4586682a1b997a1237a69d4b85535da9e2c4a9f4149cb1fa8852b6ab5aa409df1dbc3a600703a2c026d6796f945dede4eb78ea5c25f31902506802b12b6
|
|
7
|
+
data.tar.gz: 7a964443876025f04818cf79c3ce426adc4dfc4e0e570f3af39c44e1e645129f9196e25f90db2e79f7140a94bc0db0be0972e3c533a8fda29084e4934f98006f
|
data/CHANGELOG.md
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project are documented here. This project adheres
|
|
4
|
+
to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
5
|
+
|
|
6
|
+
## [1.0.0] - 2026-08-27
|
|
7
|
+
|
|
8
|
+
First release in a decade. The conjugations are unchanged; everything around
|
|
9
|
+
them was rebuilt.
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
|
|
13
|
+
- `Hablaba::Error` and its subclasses `UnknownPronounError`,
|
|
14
|
+
`UnknownVerbError` and `UnknownTenseError`, so bad input fails with a message
|
|
15
|
+
that says what was wrong.
|
|
16
|
+
- Unaccented pronoun spellings (`tu`, `el`) and the feminine plurals
|
|
17
|
+
(`nosotras`, `vosotras`), for callers without a Spanish keyboard.
|
|
18
|
+
- Public `Hablaba::PRONOUNS` and `Hablaba::TENSES` constants.
|
|
19
|
+
- `Hablaba::VERSION`.
|
|
20
|
+
- Input is Unicode-normalized, so a decomposed `e` + combining acute accent is
|
|
21
|
+
accepted wherever `é` is.
|
|
22
|
+
- Surrounding whitespace in arguments is ignored.
|
|
23
|
+
- A GitHub Actions build running the tests on Ruby 3.1 through 3.4 and head.
|
|
24
|
+
- Full conjugation tables for one verb of each conjugation in the test suite:
|
|
25
|
+
every person, in every tense.
|
|
26
|
+
|
|
27
|
+
### Changed
|
|
28
|
+
|
|
29
|
+
- **Breaking:** unrecognized input raises instead of returning `nil` or
|
|
30
|
+
crashing with an internal `TypeError`/`NoMethodError`. An unknown tense used
|
|
31
|
+
to return `nil` silently.
|
|
32
|
+
- **Breaking:** a pronoun must now be an exact match. `"yolanda"` previously
|
|
33
|
+
conjugated as `yo`, and `"él mismo"` crashed.
|
|
34
|
+
- Requires Ruby >= 3.1.
|
|
35
|
+
- The conjugation logic is now a set of lookup tables rather than one method
|
|
36
|
+
per tense per verb ending.
|
|
37
|
+
|
|
38
|
+
### Fixed
|
|
39
|
+
|
|
40
|
+
- User input is no longer interpolated into a regular expression.
|
|
41
|
+
- Arguments are never mutated, and frozen strings are accepted.
|
|
42
|
+
|
|
43
|
+
## [0.0.4] - 2015-12-09
|
|
44
|
+
|
|
45
|
+
- Added the imperfect subjunctive and the accented `nosotros` form.
|
|
46
|
+
|
|
47
|
+
## [0.0.3] - 2015-12-08
|
|
48
|
+
|
|
49
|
+
- Added the present subjunctive, conditional and future tenses.
|
|
50
|
+
|
|
51
|
+
## [0.0.2] - 2014-12-31
|
|
52
|
+
|
|
53
|
+
- Made the pronoun and verb arguments case-insensitive.
|
|
54
|
+
|
|
55
|
+
## [0.0.1] - 2014-12-31
|
|
56
|
+
|
|
57
|
+
- Initial release: present, preterite and imperfect tenses.
|
|
58
|
+
|
|
59
|
+
[1.0.0]: https://github.com/adriand/hablaba/releases/tag/v1.0.0
|
data/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
The MIT License (MIT)
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2014-2026 Adrian Duyzer
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
|
13
|
+
all copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
# Hablaba
|
|
2
|
+
|
|
3
|
+
[](https://github.com/adriand/hablaba/actions/workflows/ci.yml)
|
|
4
|
+
[](https://rubygems.org/gems/hablaba)
|
|
5
|
+
|
|
6
|
+
Hablaba conjugates regular Spanish verbs in seven tenses. Pure Ruby, no runtime
|
|
7
|
+
dependencies.
|
|
8
|
+
|
|
9
|
+
## Installation
|
|
10
|
+
|
|
11
|
+
```sh
|
|
12
|
+
gem install hablaba
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Or in a Gemfile:
|
|
16
|
+
|
|
17
|
+
```ruby
|
|
18
|
+
gem "hablaba"
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Usage
|
|
22
|
+
|
|
23
|
+
```ruby
|
|
24
|
+
require "hablaba"
|
|
25
|
+
|
|
26
|
+
Hablaba.conjugate("yo", "hablar") # => "hablo"
|
|
27
|
+
Hablaba.conjugate("yo", "hablar", :preterite) # => "hablé"
|
|
28
|
+
Hablaba.conjugate("nosotros", "comer", :future) # => "comeremos"
|
|
29
|
+
Hablaba.conjugate("ellas", "vivir", :conditional) # => "vivirían"
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
The tense defaults to `:present`. Arguments are case-insensitive, trimmed of
|
|
33
|
+
surrounding whitespace, and never mutated.
|
|
34
|
+
|
|
35
|
+
### Pronouns
|
|
36
|
+
|
|
37
|
+
yo tú él ella usted nosotros vosotros ellos ellas ustedes
|
|
38
|
+
|
|
39
|
+
Accents are optional (`tu` and `el` work), and the feminine plurals `nosotras`
|
|
40
|
+
and `vosotras` are accepted. The full list is available as
|
|
41
|
+
`Hablaba::PRONOUNS`, a hash of each spelling to its column in a conjugation
|
|
42
|
+
table.
|
|
43
|
+
|
|
44
|
+
### Tenses
|
|
45
|
+
|
|
46
|
+
| Tense | Example |
|
|
47
|
+
| ------------------------ | -------------------------------- |
|
|
48
|
+
| `:present` | I *speak* — *hablo* |
|
|
49
|
+
| `:preterite` | I *spoke* — *hablé* |
|
|
50
|
+
| `:imperfect` | I *used to speak* — *hablaba* |
|
|
51
|
+
| `:present_subjunctive` | I hope *that I speak* — *hable* |
|
|
52
|
+
| `:imperfect_subjunctive` | I hoped *that I spoke* — *hablara* |
|
|
53
|
+
| `:conditional` | I *would speak* — *hablaría* |
|
|
54
|
+
| `:future` | I *will speak* — *hablaré* |
|
|
55
|
+
|
|
56
|
+
Also available as `Hablaba::TENSES`.
|
|
57
|
+
|
|
58
|
+
### Errors
|
|
59
|
+
|
|
60
|
+
Unrecognized input raises, rather than returning something misleading:
|
|
61
|
+
|
|
62
|
+
```ruby
|
|
63
|
+
Hablaba.conjugate("we", "hablar") # Hablaba::UnknownPronounError
|
|
64
|
+
Hablaba.conjugate("yo", "casa") # Hablaba::UnknownVerbError
|
|
65
|
+
Hablaba.conjugate("yo", "hablar", :pluscuamperfecto) # Hablaba::UnknownTenseError
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
All three inherit from `Hablaba::Error`, so a single `rescue` catches them:
|
|
69
|
+
|
|
70
|
+
```ruby
|
|
71
|
+
begin
|
|
72
|
+
Hablaba.conjugate(pronoun, verb, tense)
|
|
73
|
+
rescue Hablaba::Error => e
|
|
74
|
+
warn e.message
|
|
75
|
+
end
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
## Limitations
|
|
79
|
+
|
|
80
|
+
- **Regular verbs only.** Irregular verbs are not detected, so
|
|
81
|
+
`Hablaba.conjugate("yo", "tener")` returns the regular `"teno"`, not
|
|
82
|
+
`"tengo"`. Stem-changing verbs (`pensar` → `pienso`) and orthographic changes
|
|
83
|
+
(`buscar` → `busqué`) are not handled either.
|
|
84
|
+
- The imperfect subjunctive returns the `-ra` form (`hablara`), not the `-se`
|
|
85
|
+
form (`hablase`).
|
|
86
|
+
- Voseo (`vos hablás`) is not supported.
|
|
87
|
+
- Compound tenses, the imperative, and the participles are not supported.
|
|
88
|
+
|
|
89
|
+
## Development
|
|
90
|
+
|
|
91
|
+
```sh
|
|
92
|
+
bundle install
|
|
93
|
+
bundle exec rake test
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
Tests run against Ruby 3.1 through 3.4 in CI. The suite checks the complete
|
|
97
|
+
conjugation table — every person, in every tense — for one verb of each
|
|
98
|
+
conjugation.
|
|
99
|
+
|
|
100
|
+
## License
|
|
101
|
+
|
|
102
|
+
MIT. See [LICENSE](LICENSE).
|
data/lib/hablaba.rb
CHANGED
|
@@ -1,145 +1,161 @@
|
|
|
1
|
-
#
|
|
1
|
+
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require_relative "hablaba/version"
|
|
4
|
+
|
|
5
|
+
# Hablaba conjugates regular Spanish verbs in seven tenses.
|
|
6
|
+
#
|
|
7
|
+
# Hablaba.conjugate("yo", "hablar") # => "hablo"
|
|
8
|
+
# Hablaba.conjugate("nosotros", "comer", :future) # => "comeremos"
|
|
9
|
+
#
|
|
10
|
+
# Only regular verbs are supported. Irregular verbs are not detected, so
|
|
11
|
+
# Hablaba.conjugate("yo", "tener") returns the regular form "teno", not "tengo".
|
|
3
12
|
class Hablaba
|
|
13
|
+
# Base class for every error Hablaba raises.
|
|
14
|
+
class Error < StandardError; end
|
|
15
|
+
|
|
16
|
+
# Raised when the pronoun is not one Hablaba recognizes.
|
|
17
|
+
class UnknownPronounError < Error; end
|
|
18
|
+
|
|
19
|
+
# Raised when the verb is not an infinitive ending in -ar, -er or -ir.
|
|
20
|
+
class UnknownVerbError < Error; end
|
|
21
|
+
|
|
22
|
+
# Raised when the tense is not one Hablaba supports.
|
|
23
|
+
class UnknownTenseError < Error; end
|
|
24
|
+
|
|
25
|
+
# Every accepted pronoun, mapped to its column in a conjugation table
|
|
26
|
+
# (0 = first person singular through 5 = third person plural). Unaccented
|
|
27
|
+
# spellings are accepted so callers do not need a Spanish keyboard.
|
|
28
|
+
PRONOUNS = {
|
|
29
|
+
"yo" => 0,
|
|
30
|
+
"tú" => 1, "tu" => 1,
|
|
31
|
+
"él" => 2, "el" => 2, "ella" => 2, "usted" => 2,
|
|
32
|
+
"nosotros" => 3, "nosotras" => 3,
|
|
33
|
+
"vosotros" => 4, "vosotras" => 4,
|
|
34
|
+
"ellos" => 5, "ellas" => 5, "ustedes" => 5
|
|
35
|
+
}.freeze
|
|
36
|
+
|
|
37
|
+
# Supported tenses, in the order they appear in the README.
|
|
38
|
+
TENSES = %i[
|
|
39
|
+
present preterite imperfect present_subjunctive
|
|
40
|
+
imperfect_subjunctive conditional future
|
|
41
|
+
].freeze
|
|
42
|
+
|
|
43
|
+
# The three regular infinitive endings.
|
|
44
|
+
INFINITIVE_ENDINGS = %w[ar er ir].freeze
|
|
45
|
+
|
|
46
|
+
# Endings that attach to the stem (the infinitive minus -ar/-er/-ir).
|
|
47
|
+
STEM_ENDINGS = {
|
|
48
|
+
present: {
|
|
49
|
+
"ar" => %w[o as a amos áis an],
|
|
50
|
+
"er" => %w[o es e emos éis en],
|
|
51
|
+
"ir" => %w[o es e imos ís en]
|
|
52
|
+
},
|
|
53
|
+
preterite: {
|
|
54
|
+
"ar" => %w[é aste ó amos asteis aron],
|
|
55
|
+
"er" => %w[í iste ió imos isteis ieron],
|
|
56
|
+
"ir" => %w[í iste ió imos isteis ieron]
|
|
57
|
+
},
|
|
58
|
+
imperfect: {
|
|
59
|
+
"ar" => %w[aba abas aba ábamos abais aban],
|
|
60
|
+
"er" => %w[ía ías ía íamos íais ían],
|
|
61
|
+
"ir" => %w[ía ías ía íamos íais ían]
|
|
62
|
+
},
|
|
63
|
+
present_subjunctive: {
|
|
64
|
+
"ar" => %w[e es e emos éis en],
|
|
65
|
+
"er" => %w[a as a amos áis an],
|
|
66
|
+
"ir" => %w[a as a amos áis an]
|
|
67
|
+
}
|
|
68
|
+
}.freeze
|
|
69
|
+
|
|
70
|
+
# Endings that attach to the whole infinitive rather than the stem.
|
|
71
|
+
INFINITIVE_ENDINGS_BY_TENSE = {
|
|
72
|
+
conditional: %w[ía ías ía íamos íais ían],
|
|
73
|
+
future: %w[é ás á emos éis án]
|
|
74
|
+
}.freeze
|
|
75
|
+
|
|
76
|
+
# The imperfect subjunctive is built from the third person plural preterite
|
|
77
|
+
# with its -ron dropped: hablaron -> habla-, comieron -> comie-. Only the
|
|
78
|
+
# nosotros form carries an accent, so each ending has a plain and an
|
|
79
|
+
# accented variant.
|
|
80
|
+
IMPERFECT_SUBJUNCTIVE_LINKS = {
|
|
81
|
+
"ar" => %w[a á],
|
|
82
|
+
"er" => %w[ie ié],
|
|
83
|
+
"ir" => %w[ie ié]
|
|
84
|
+
}.freeze
|
|
85
|
+
private_constant :IMPERFECT_SUBJUNCTIVE_LINKS
|
|
86
|
+
|
|
87
|
+
IMPERFECT_SUBJUNCTIVE_ENDINGS = %w[ra ras ra ramos rais ran].freeze
|
|
88
|
+
private_constant :IMPERFECT_SUBJUNCTIVE_ENDINGS
|
|
89
|
+
|
|
90
|
+
# The one person whose imperfect subjunctive form is accented.
|
|
91
|
+
NOSOTROS = 3
|
|
92
|
+
private_constant :NOSOTROS
|
|
4
93
|
|
|
5
94
|
class << self
|
|
6
|
-
|
|
7
|
-
# Conjugate a Spanish verb
|
|
95
|
+
# Conjugate a regular Spanish verb.
|
|
8
96
|
#
|
|
9
97
|
# Example:
|
|
10
|
-
# >> Hablaba.conjugate(
|
|
11
|
-
# => hablo
|
|
98
|
+
# >> Hablaba.conjugate("yo", "hablar")
|
|
99
|
+
# => "hablo"
|
|
12
100
|
#
|
|
13
101
|
# Arguments:
|
|
14
|
-
# pronoun: (String)
|
|
15
|
-
# verb:
|
|
16
|
-
# tense:
|
|
17
|
-
#
|
|
18
|
-
#
|
|
102
|
+
# pronoun: (String) one of PRONOUNS, in any case, with or without accents
|
|
103
|
+
# verb: (String) an infinitive ending in -ar, -er or -ir
|
|
104
|
+
# tense: (Symbol) one of TENSES, defaults to :present
|
|
105
|
+
#
|
|
106
|
+
# Raises UnknownPronounError, UnknownVerbError or UnknownTenseError when
|
|
107
|
+
# an argument is not recognized.
|
|
19
108
|
def conjugate(pronoun, verb, tense = :present)
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
conjugate_in_the_imperfect_subjunctive(pronoun, verb)
|
|
32
|
-
when :conditional
|
|
33
|
-
conjugate_in_the_conditional(pronoun, verb)
|
|
34
|
-
when :future
|
|
35
|
-
conjugate_in_the_future(pronoun, verb)
|
|
109
|
+
person = person_for(pronoun)
|
|
110
|
+
infinitive = normalize(verb, "verb")
|
|
111
|
+
ending = infinitive_ending(infinitive)
|
|
112
|
+
stem = infinitive[0..-3]
|
|
113
|
+
|
|
114
|
+
if (endings_by_ending = STEM_ENDINGS[tense])
|
|
115
|
+
stem + endings_by_ending.fetch(ending)[person]
|
|
116
|
+
elsif (endings = INFINITIVE_ENDINGS_BY_TENSE[tense])
|
|
117
|
+
infinitive + endings[person]
|
|
118
|
+
elsif tense == :imperfect_subjunctive
|
|
119
|
+
imperfect_subjunctive(person, ending, stem)
|
|
36
120
|
else
|
|
37
|
-
|
|
121
|
+
raise UnknownTenseError,
|
|
122
|
+
"#{tense.inspect} is not a supported tense; expected one of #{TENSES.join(', ')}"
|
|
38
123
|
end
|
|
39
124
|
end
|
|
40
125
|
|
|
41
126
|
private
|
|
42
127
|
|
|
43
|
-
def
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
[/yo/,/tú/,/él\z|ella\z|usted\z/,/nosotros/,/vosotros/,/ellos|ellas|ustedes/].index { |p| p =~ pronoun }
|
|
49
|
-
end
|
|
50
|
-
|
|
51
|
-
def get_verb_ending_and_root(verb)
|
|
52
|
-
verb_ending = /ar\z|er\z|ir\z/.match(verb)[0]
|
|
53
|
-
root = verb.gsub(/#{verb_ending}\z/, '')
|
|
54
|
-
return verb_ending, root
|
|
55
|
-
end
|
|
56
|
-
|
|
57
|
-
def conjugate_in_the_present(pronoun, verb)
|
|
58
|
-
verb_ending, root = get_verb_ending_and_root(verb)
|
|
59
|
-
case verb_ending
|
|
60
|
-
when 'ar' then conjugate_ar_in_the_present(pronoun, root)
|
|
61
|
-
when 'er' then conjugate_er_in_the_present(pronoun, root)
|
|
62
|
-
when 'ir' then conjugate_ir_in_the_present(pronoun, root)
|
|
63
|
-
end
|
|
64
|
-
end
|
|
65
|
-
|
|
66
|
-
def conjugate_ar_in_the_present(pronoun, root_of_verb)
|
|
67
|
-
root_of_verb + %W[o as a amos áis an][pronoun_index(pronoun)]
|
|
68
|
-
end
|
|
69
|
-
|
|
70
|
-
def conjugate_er_in_the_present(pronoun, root_of_verb)
|
|
71
|
-
root_of_verb + %W[o es e emos éis en][pronoun_index(pronoun)]
|
|
72
|
-
end
|
|
73
|
-
|
|
74
|
-
def conjugate_ir_in_the_present(pronoun, root_of_verb)
|
|
75
|
-
root_of_verb + %W[o es e imos ís en][pronoun_index(pronoun)]
|
|
76
|
-
end
|
|
77
|
-
|
|
78
|
-
def conjugate_in_the_preterite(pronoun, verb)
|
|
79
|
-
verb_ending, root = get_verb_ending_and_root(verb)
|
|
80
|
-
if verb_ending == 'ar'
|
|
81
|
-
conjugate_ar_in_the_preterite(pronoun, root)
|
|
82
|
-
else # er and ir are the same
|
|
83
|
-
conjugate_er_ir_in_the_preterite(pronoun, root)
|
|
128
|
+
def person_for(pronoun)
|
|
129
|
+
key = normalize(pronoun, "pronoun")
|
|
130
|
+
PRONOUNS.fetch(key) do
|
|
131
|
+
raise UnknownPronounError,
|
|
132
|
+
"#{pronoun.inspect} is not a supported pronoun; expected one of #{PRONOUNS.keys.join(', ')}"
|
|
84
133
|
end
|
|
85
134
|
end
|
|
86
135
|
|
|
87
|
-
def
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
def conjugate_er_ir_in_the_preterite(pronoun, root_of_verb)
|
|
92
|
-
root_of_verb + %W[í iste ió imos isteis ieron][pronoun_index(pronoun)]
|
|
93
|
-
end
|
|
136
|
+
def infinitive_ending(infinitive)
|
|
137
|
+
ending = infinitive[-2, 2]
|
|
138
|
+
return ending if INFINITIVE_ENDINGS.include?(ending)
|
|
94
139
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
if verb_ending == 'ar'
|
|
98
|
-
conjugate_ar_in_the_imperfect(pronoun, root)
|
|
99
|
-
else # er and ir are the same
|
|
100
|
-
conjugate_er_ir_in_the_imperfect(pronoun, root)
|
|
101
|
-
end
|
|
140
|
+
raise UnknownVerbError,
|
|
141
|
+
"#{infinitive.inspect} is not an infinitive; expected a verb ending in -ar, -er or -ir"
|
|
102
142
|
end
|
|
103
143
|
|
|
104
|
-
def
|
|
105
|
-
|
|
144
|
+
def imperfect_subjunctive(person, ending, stem)
|
|
145
|
+
plain, accented = IMPERFECT_SUBJUNCTIVE_LINKS.fetch(ending)
|
|
146
|
+
link = person == NOSOTROS ? accented : plain
|
|
147
|
+
stem + link + IMPERFECT_SUBJUNCTIVE_ENDINGS[person]
|
|
106
148
|
end
|
|
107
149
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
# with this method
|
|
115
|
-
def conjugate_in_the_present_subjunctive(pronoun, verb)
|
|
116
|
-
verb_ending, root = get_verb_ending_and_root(verb)
|
|
117
|
-
if verb_ending == 'ar'
|
|
118
|
-
root + %W[e es e emos éis en][pronoun_index(pronoun)]
|
|
119
|
-
else # er and ir are the same
|
|
120
|
-
root + %W[a as a amos áis an][pronoun_index(pronoun)]
|
|
121
|
-
end
|
|
122
|
-
end
|
|
123
|
-
|
|
124
|
-
def conjugate_in_the_imperfect_subjunctive(pronoun, verb)
|
|
125
|
-
verb_ending, root = get_verb_ending_and_root(verb)
|
|
126
|
-
# get the third person preterite (e.g. rompieron) and then remove the on (rompier)
|
|
127
|
-
third_person_root = conjugate_in_the_preterite('ellos', verb).gsub(/on\z|an\z/i, '')
|
|
128
|
-
if pronoun == 'nosotros'
|
|
129
|
-
third_person_root.gsub!(/ar\z/i, 'ár')
|
|
130
|
-
third_person_root.gsub!(/er\z/i, 'ér')
|
|
150
|
+
# Downcase, trim, and compose accents so that a decomposed "e" + combining
|
|
151
|
+
# acute (which is what some keyboards and macOS filenames produce) matches
|
|
152
|
+
# the precomposed "é" used in the tables above.
|
|
153
|
+
def normalize(word, label)
|
|
154
|
+
unless word.respond_to?(:to_str)
|
|
155
|
+
raise ArgumentError, "#{label} must be a String, got #{word.class}"
|
|
131
156
|
end
|
|
132
|
-
third_person_root + %W[a as a amos ais an][pronoun_index(pronoun)]
|
|
133
|
-
end
|
|
134
157
|
|
|
135
|
-
|
|
136
|
-
verb + %W[ía ías ía íamos íais ían][pronoun_index(pronoun)]
|
|
158
|
+
word.to_str.unicode_normalize(:nfc).strip.downcase
|
|
137
159
|
end
|
|
138
|
-
|
|
139
|
-
def conjugate_in_the_future(pronoun, verb)
|
|
140
|
-
verb + %W[é ás á emos éis án][pronoun_index(pronoun)]
|
|
141
|
-
end
|
|
142
|
-
|
|
143
160
|
end
|
|
144
|
-
|
|
145
161
|
end
|
metadata
CHANGED
|
@@ -1,27 +1,35 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: hablaba
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.0
|
|
4
|
+
version: 1.0.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Adrian Duyzer
|
|
8
|
-
autorequire:
|
|
9
8
|
bindir: bin
|
|
10
9
|
cert_chain: []
|
|
11
|
-
date:
|
|
10
|
+
date: 2026-08-27 00:00:00.000000000 Z
|
|
12
11
|
dependencies: []
|
|
13
|
-
description: Hablaba conjugates regular Spanish verbs
|
|
14
|
-
|
|
12
|
+
description: Hablaba conjugates regular Spanish verbs across seven tenses. Pure Ruby,
|
|
13
|
+
with no runtime dependencies.
|
|
14
|
+
email:
|
|
15
|
+
- adrianduyzer@gmail.com
|
|
15
16
|
executables: []
|
|
16
17
|
extensions: []
|
|
17
18
|
extra_rdoc_files: []
|
|
18
19
|
files:
|
|
20
|
+
- CHANGELOG.md
|
|
21
|
+
- LICENSE
|
|
22
|
+
- README.md
|
|
19
23
|
- lib/hablaba.rb
|
|
24
|
+
- lib/hablaba/version.rb
|
|
20
25
|
homepage: https://github.com/adriand/hablaba
|
|
21
26
|
licenses:
|
|
22
27
|
- MIT
|
|
23
|
-
metadata:
|
|
24
|
-
|
|
28
|
+
metadata:
|
|
29
|
+
source_code_uri: https://github.com/adriand/hablaba
|
|
30
|
+
bug_tracker_uri: https://github.com/adriand/hablaba/issues
|
|
31
|
+
changelog_uri: https://github.com/adriand/hablaba/blob/master/CHANGELOG.md
|
|
32
|
+
rubygems_mfa_required: 'true'
|
|
25
33
|
rdoc_options: []
|
|
26
34
|
require_paths:
|
|
27
35
|
- lib
|
|
@@ -29,16 +37,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
29
37
|
requirements:
|
|
30
38
|
- - ">="
|
|
31
39
|
- !ruby/object:Gem::Version
|
|
32
|
-
version: '
|
|
40
|
+
version: '3.1'
|
|
33
41
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
34
42
|
requirements:
|
|
35
43
|
- - ">="
|
|
36
44
|
- !ruby/object:Gem::Version
|
|
37
45
|
version: '0'
|
|
38
46
|
requirements: []
|
|
39
|
-
|
|
40
|
-
rubygems_version: 2.2.2
|
|
41
|
-
signing_key:
|
|
47
|
+
rubygems_version: 3.6.1
|
|
42
48
|
specification_version: 4
|
|
43
|
-
summary:
|
|
49
|
+
summary: Spanish verb conjugator
|
|
44
50
|
test_files: []
|