-
Notifications
You must be signed in to change notification settings - Fork 89
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #111 from luismateoh/spanish-support
Add spanish support
- Loading branch information
Showing
12 changed files
with
636 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
53 changes: 53 additions & 0 deletions
53
...allegro/finance/tradukisto/internal/languages/spanish/SpanishIntegerToWordsConverter.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
package pl.allegro.finance.tradukisto.internal.languages.spanish; | ||
|
||
import pl.allegro.finance.tradukisto.internal.IntegerToStringConverter; | ||
import pl.allegro.finance.tradukisto.internal.MultiFormNumber; | ||
import pl.allegro.finance.tradukisto.internal.NumberProcessor; | ||
|
||
import java.util.Map; | ||
|
||
public class SpanishIntegerToWordsConverter implements IntegerToStringConverter { | ||
|
||
private final IntegerToStringConverter bigNumbersConverter; | ||
private final Map<Integer, MultiFormNumber> exceptions; | ||
private final IntegerToStringConverter smallNumbersConverter; | ||
|
||
public SpanishIntegerToWordsConverter(IntegerToStringConverter bigNumbersConverter, | ||
Map<Integer, MultiFormNumber> exceptions, | ||
IntegerToStringConverter smallNumbersConverter) { | ||
this.bigNumbersConverter = bigNumbersConverter; | ||
this.exceptions = exceptions; | ||
this.smallNumbersConverter = smallNumbersConverter; | ||
} | ||
|
||
@Override | ||
public String asWords(Integer value) { | ||
|
||
if (exceptions.containsKey(value)) { | ||
return exceptions.get(value).getAloneForm(); | ||
} | ||
|
||
Integer bigNumber = value / 1000000; | ||
Integer smallNumber = value % 1000000; | ||
|
||
String numberProcessor = new NumberProcessor(bigNumbersConverter, smallNumbersConverter).process(bigNumber, smallNumber); | ||
|
||
if (value.toString().endsWith("1") && !value.toString().endsWith("11")) { | ||
numberProcessor += "o"; | ||
} | ||
if (value == 1_000_000_000) { | ||
numberProcessor = "mil millones"; | ||
} | ||
if (value > 1_000_000_000) { | ||
numberProcessor = numberProcessor.replace("un mil millones", "mil"); | ||
} | ||
if (value == 2_000_000_000) { | ||
numberProcessor = "dos mil millones"; | ||
} | ||
if (value > 2_000_000_000) { | ||
numberProcessor = numberProcessor.replace("un millón", "un millones") | ||
.replace("dos mil millones", "dos mil"); | ||
} | ||
return numberProcessor; | ||
} | ||
} |
37 changes: 37 additions & 0 deletions
37
.../finance/tradukisto/internal/languages/spanish/SpanishIntegerToWordsConverterAdapter.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
package pl.allegro.finance.tradukisto.internal.languages.spanish; | ||
|
||
import pl.allegro.finance.tradukisto.internal.IntegerToStringConverter; | ||
import pl.allegro.finance.tradukisto.internal.converters.NumberToWordsConverter; | ||
import pl.allegro.finance.tradukisto.internal.languages.GenderType; | ||
import pl.allegro.finance.tradukisto.internal.languages.PluralForms; | ||
|
||
import java.util.ArrayList; | ||
import java.util.Iterator; | ||
import java.util.List; | ||
import java.util.concurrent.atomic.AtomicReference; | ||
|
||
public class SpanishIntegerToWordsConverterAdapter extends NumberToWordsConverter { | ||
|
||
public SpanishIntegerToWordsConverterAdapter(IntegerToStringConverter hundredsToWordsConverter, | ||
List<PluralForms> pluralForms) { | ||
super(hundredsToWordsConverter, pluralForms); | ||
} | ||
|
||
@Override | ||
protected String joinValueChunksWithForms(Iterator<Integer> chunks, Iterator<PluralForms> formsToUse) { | ||
AtomicReference<List<String>> result = new AtomicReference<>(new ArrayList<>()); | ||
|
||
while (chunks.hasNext() && formsToUse.hasNext()) { | ||
Integer currentChunkValue = chunks.next(); | ||
PluralForms currentForms = formsToUse.next(); | ||
|
||
if (currentChunkValue > 0) { | ||
result.get().add(hundredsToWordsConverter.asWords(currentChunkValue, GenderType.NEUTER)); | ||
result.get().add(currentForms.formFor(currentChunkValue)); | ||
} | ||
} | ||
|
||
return joinParts(result.get()); | ||
} | ||
|
||
} |
148 changes: 148 additions & 0 deletions
148
...llegro/finance/tradukisto/internal/languages/spanish/SpanishThousandToWordsConverter.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,148 @@ | ||
package pl.allegro.finance.tradukisto.internal.languages.spanish; | ||
|
||
import pl.allegro.finance.tradukisto.internal.IntegerToStringConverter; | ||
import pl.allegro.finance.tradukisto.internal.MultiFormNumber; | ||
import pl.allegro.finance.tradukisto.internal.languages.GenderForms; | ||
import pl.allegro.finance.tradukisto.internal.languages.GenderType; | ||
import pl.allegro.finance.tradukisto.internal.support.Range; | ||
|
||
import java.util.Map; | ||
|
||
import static java.lang.String.format; | ||
|
||
public class SpanishThousandToWordsConverter implements IntegerToStringConverter { | ||
|
||
private static final String MIL = "%s mil"; | ||
private static final String MIL_UN = "mil %s"; | ||
private static final String S_MIL_S = "%s mil %s"; | ||
private static final String IUN_MIL = "%siún mil"; | ||
private static final String IUN_MIL_WITH_HUNDRED = "%siún mil %s"; | ||
private static final String Y_UN_MIL = "%s y un mil"; | ||
private static final String Y_UN_MIL_WITH_HUNDRED = "%s y un mil %s"; | ||
|
||
private static final boolean HAS_NEXT_VALUE = true; | ||
private static final boolean HAS_NOT_NEXT_VALUE = false; | ||
private static final int HUNDRED = 100; | ||
private static final GenderType genderType = GenderType.NEUTER; | ||
|
||
private final Map<Integer, GenderForms> baseValues; | ||
private final Map<Integer, MultiFormNumber> exceptions; | ||
|
||
public SpanishThousandToWordsConverter(Map<Integer, GenderForms> baseValues, Map<Integer, MultiFormNumber> exceptions) { | ||
this.baseValues = baseValues; | ||
this.exceptions = exceptions; | ||
} | ||
|
||
@Override | ||
public String asWords(Integer value) { | ||
return asWords(value, HAS_NEXT_VALUE); | ||
} | ||
|
||
private String asWords(Integer value, boolean hasNextNumber) { | ||
if (baseValues.containsKey(value)) { | ||
return baseValues.get(value).formFor(genderType); | ||
} | ||
if (exceptions.containsKey(value)) { | ||
if (hasNextNumber) { | ||
return exceptions.get(value).getRegularForm(); | ||
} else { | ||
return exceptions.get(value).getAloneForm(); | ||
} | ||
} | ||
if (Range.closed(31, 99).contains(value)) { | ||
return twoDigitsNumberAsString(value); | ||
} | ||
if (Range.closed(101, 999).contains(value)) { | ||
return threeDigitsNumberAsString(value); | ||
} | ||
if (Range.closed(1000, 999999).contains(value)) { | ||
return thousandsAsString(value); | ||
} | ||
throw new IllegalArgumentException(format("Can't convert %d", value)); | ||
} | ||
|
||
private String twoDigitsNumberAsString(Integer value) { | ||
Integer units = value % 10; | ||
Integer tens = value - units; | ||
return format("%s y %s", asWords(tens), asWords(units)); | ||
} | ||
|
||
private String threeDigitsNumberAsString(Integer value) { | ||
Integer tensWithUnits = value % 100; | ||
Integer hundreds = value - tensWithUnits; | ||
boolean hasNextNumber = tensWithUnits != 0; | ||
return format("%s %s", asWords(hundreds, hasNextNumber), asWords(tensWithUnits)); | ||
} | ||
|
||
private String thousandsAsString(Integer value) { | ||
Integer thousands = value / 1000; | ||
Integer other = value % 1000; | ||
|
||
if (isOneThousand(thousands)) { | ||
return getOneThousandAsWords(other); | ||
} | ||
if (isEndsWithOne(thousands)) { | ||
return getEndWithOneAsWords(thousands, other); | ||
} else { | ||
return getThousandsAsWords(thousands, other); | ||
} | ||
} | ||
|
||
private String getThousandsAsWords(Integer thousands, Integer other) { | ||
if (nothingComesAfter(other)) { | ||
return format(MIL, asWords(thousands)); | ||
} | ||
if (other == HUNDRED) { | ||
return format(S_MIL_S, asWords(thousands, HAS_NOT_NEXT_VALUE), asWords(other, HAS_NOT_NEXT_VALUE)); | ||
} | ||
return format(S_MIL_S, asWords(thousands), asWords(other, HAS_NEXT_VALUE)); | ||
} | ||
|
||
private String getOneThousandAsWords(Integer other) { | ||
if (nothingComesAfter(other)) { | ||
return "mil"; | ||
} | ||
if (other == HUNDRED) { | ||
return format(MIL_UN, asWords(other, HAS_NOT_NEXT_VALUE)); | ||
} | ||
return format(MIL_UN, asWords(other, HAS_NEXT_VALUE)); | ||
} | ||
|
||
private String getEndWithOneAsWords(Integer thousands, Integer other) { | ||
Integer units = thousands % 10; | ||
Integer tens = thousands - units; | ||
if (thousands == 21) { | ||
if (nothingComesAfter(other)) { | ||
return format(IUN_MIL, asWords(tens).substring(0, 5)); | ||
} | ||
if (other == HUNDRED) { | ||
return format(IUN_MIL_WITH_HUNDRED, asWords(tens, HAS_NOT_NEXT_VALUE).substring(0, 5), asWords(other, HAS_NOT_NEXT_VALUE)); | ||
} | ||
return format(IUN_MIL_WITH_HUNDRED, asWords(tens).substring(0, 5), asWords(other, HAS_NEXT_VALUE)); | ||
|
||
} else { | ||
if (nothingComesAfter(other)) { | ||
return format(Y_UN_MIL, asWords(tens)); | ||
} | ||
if (other == HUNDRED) { | ||
return format(Y_UN_MIL_WITH_HUNDRED, asWords(tens, HAS_NOT_NEXT_VALUE), asWords(other, HAS_NOT_NEXT_VALUE)); | ||
} | ||
return format(Y_UN_MIL_WITH_HUNDRED, asWords(tens), asWords(other, HAS_NEXT_VALUE)); | ||
} | ||
} | ||
|
||
private boolean nothingComesAfter(Integer other) { | ||
return other == 0; | ||
} | ||
|
||
private boolean isOneThousand(Integer thousands) { | ||
return thousands == 1; | ||
} | ||
|
||
private boolean isEndsWithOne(Integer number) { | ||
if (number > 20 && number < 100) { | ||
return (Math.abs(number) % 10) == 1; | ||
} | ||
return false; | ||
} | ||
} |
Oops, something went wrong.