Skip to content

Commit

Permalink
Add Catalan/Valencian alphabet and fix English ASCII mapping
Browse files Browse the repository at this point in the history
  • Loading branch information
mondeja committed Sep 1, 2021
1 parent 1fdc498 commit 5032a59
Show file tree
Hide file tree
Showing 4 changed files with 202 additions and 120 deletions.
5 changes: 5 additions & 0 deletions NOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@ Uses same implementation as Spanish.

Uses same implementation as Spanish.

## Catalan/Valencian

- Uses same implementation as Spanish except for accent marks which differs.
- The character "L geminate" has not been found in unicode database.

# Other useful resources

- [World Braille Usage][world-braille-usage]
Expand Down
20 changes: 8 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ text-to-Braille converter.
| ------ | ----------- |
| English | [North American Braille ASCII code][en-wiki] |
| Spanish | [Braille español (Grado 1)][es-cbe-guide] by [CBE][cbe-once] |
| Galician | [Braille español (Grado 1)][es-cbe-guide] by [CBE][cbe-once] |
| Euskera | [Braille español (Grado 1)][es-cbe-guide] by [CBE][cbe-once] |
| Catalan/Valencian | [Braille español (Grado 1)][es-cbe-guide] by [CBE][cbe-once] |

> See [`NOTES.md`][notes] to check the limitations of each implementation.
Expand All @@ -20,19 +23,12 @@ text-to-Braille converter.
`Preferences` -> `System` -> `Users extensions`.
1. Run Inkscape and you'll see the extension in `Extensions` -> `Text`.

## How to use
## Usage

Select a text that you want to convert in Braille, open this extension,
choose a locale and press `Apply`.

## TODO

- [x] ~~Spanish Braille conversion for texts not prepared for Braille
translation. Add prefixes before numbers and before uppercased letters.~~
- [ ] Catalán/valenciano
- [x] ~~Gallego~~
- [x] ~~Euskera~~
- [x] ~~Spanish combinations~~
1. Select a text that you want to convert in Braille.
1. Open this extension.
1. Choose an alphabet for character mappings.
1. Press `Apply`.

[notes]: https://github.com/mondeja/inkscape-braille-l18n-ext/blob/master/NOTES.md
[download-repo]: https://github.com/mondeja/inkscape-braille-l18n-ext/archive/refs/heads/master.zip
Expand Down
1 change: 1 addition & 0 deletions text_braille_l18n.inx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
<option value="es">Spanish</option>
<option value="gl">Galician</option>
<option value="eu">Basque</option>
<option value="ca">Catalan/Valencian</option>
</param>

<effect>
Expand Down
296 changes: 188 additions & 108 deletions text_braille_l18n.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,138 +3,218 @@

import inkex

# ---------------------------------

# UTILITIES

# English based locales

EN_ASCII = " A1B'K2L@CIF/MSP\"E3H9O6R^DJG>NTQ,*5<-U8V.%[$+X!&;:4\\0Z7(_?W]#Y)="

# Spanish based locales

ES_NUMBERS = {
"1": 0x2801,
"2": 0x2803,
"3": 0x2809,
"4": 0x2819,
"5": 0x2811,
"6": 0x280B,
"7": 0x281b,
"8": 0x2813,
"9": 0x280a,
"0": 0x281a,
}

ES_LETTERS = {
"A": 0x2801,
"B": 0x2803,
"C": 0x2809,
"D": 0x2819,
"E": 0x2811,
"F": 0x280B,
"G": 0x281b,
"H": 0x2813,
"I": 0x280a,
"J": 0x281a,
"K": 0x2805,
"L": 0x2807,
"M": 0x280d,
"N": 0x281d,
"Ñ": 0x283b,
"O": 0x2815,
"P": 0x280f,
"Q": 0x281f,
"R": 0x2817,
"S": 0x280e,
"T": 0x281e,
"U": 0x2825,
"V": 0x2827,
"W": 0x283a,
"X": 0x282d,
"Y": 0x283d,
"Z": 0x2835,
}

ES_SIGNS = {
"ª": 0x2801, # ordinal (feminine) -> same as A
"º": 0x2815, # ordinal (masculine) -> same as O
"&": 0x282f,
".": 0x2804,
",": 0x2802,
":": 0x2812,
";": 0x2806,
"¿": 0x2822,
"?": 0x2822,
"¡": 0x2816,
"!": 0x2816,
'"': 0x2826,
"(": 0x2823,
")": 0x281c,
"-": 0x2824,
"*": 0x2814,
"=": 0x2836,
"÷": 0x2832,
"+": 0x2816,
"@": 0x2810,
" ": 0x2800, # braille space
}

ES_PREFIXES = {
chr(15): 0x2828, # uppercase prefix: https://codepoints.net/U+000F
}

ES_ACCENT_MARKS = {
"Á": 0x2837,
"É": 0x282e,
"Í": 0x280c,
"Ó": 0x282c,
"Ú": 0x283e,
"Ü": 0x2833,
}

ES_COMBINATIONS = {
# signs
"%": (0x2838, 0x2834),
"‰": (0x2838, 0x2834, 0x2834), # per mile
"©": (0x2823, 0x2828, 0x2809, 0x281c),
"®": (0x2823, 0x2828, 0x2817, 0x281c),
"℗": (0x2823, 0x2828, 0x280f, 0x281c),
"🄯": (0x2823, 0x2828, 0x2807, 0x281c),
"/": (0x2820, 0x2802),
"\\": (0x2810, 0x2804),
"<": (0x2810, 0x2805),
">": (0x2828, 0x2802),
"|": (0x2838, 0x2807),
"{": (0x2810, 0x2807),
"}": (0x2838, 0x2802),
"—": (0x2824, 0x2824),

# currencies
"€": (0x2838, 0x2811),
"$": (0x2838, 0x280e),
"¢": (0x2818, 0x2809),
"£": (0x2810, 0x282e),
"¥": (0x2838, 0x283d),
"¥": (0x2838, 0x283d),
}

CA_ACCENT_MARKS = {
"É": 0x283f,
"Í": 0x280c,
"Ó": 0x282a,
"Ú": 0x283e,
"À": 0x2837,
"È": 0x282e,
"Ò": 0x282c,
"Ï": 0x283b,
"Ü": 0x2833,
"Ç": 0x282f,
}

# END: UTILITIES

# ---------------------------------

# LOCALE FUNCTIONS

def en_char_map(char):
# https://en.wikipedia.org/wiki/Braille_ASCII#Braille_ASCII_values
try:
mapint = ("A1B'K2L@CIF/MSP\"E3H9O6R^DJG>NTQ,"
"*5<-U8V.%[$+X!&;:4\\0Z7(_?W]#Y)=").index(char.upper())
mapint = EN_ASCII.index(char.upper())
except ValueError:
return char
return chr(mapint + 0x2801)
return chr(mapint + 0x2800)

def es_char_map(char):
# https://sid.usal.es/idocs/F8/FDO12069/signografiabasica.pdf
"""Spanish/Galician/Euskera chars mappers.
Source: https://sid.usal.es/idocs/F8/FDO12069/signografiabasica.pdf
"""
if char.isnumeric():
# numeric prefix + number
return "".join([
chr(0x283c),
chr({
"1": 0x2801,
"2": 0x2803,
"3": 0x2809,
"4": 0x2819,
"5": 0x2811,
"6": 0x280B,
"7": 0x281b,
"8": 0x2813,
"9": 0x280a,
"0": 0x281a,
}[char]),
])
return "".join([chr(0x283c), chr(ES_NUMBERS[char])])
try:
bchar = chr({
# letters
"A": 0x2801,
"ª": 0x2801, # ordinal (feminine)
"B": 0x2803,
"C": 0x2809,
"D": 0x2819,
"E": 0x2811,
"F": 0x280B,
"G": 0x281b,
"H": 0x2813,
"I": 0x280a,
"J": 0x281a,
"K": 0x2805,
"L": 0x2807,
"M": 0x280d,
"N": 0x281d,
"Ñ": 0x283b,
"O": 0x2815,
"º": 0x2815, # ordinal (masculine)
"P": 0x280f,
"Q": 0x281f,
"R": 0x2817,
"S": 0x280e,
"T": 0x281e,
"U": 0x2825,
"V": 0x2827,
"W": 0x283a,
"X": 0x282d,
"Y": 0x283d,
"Z": 0x2835,
"Á": 0x2837,
"É": 0x282e,
"Í": 0x280c,
"Ó": 0x282c,
"Ú": 0x283e,
"Ü": 0x2833,

# signs
"&": 0x282f,
".": 0x2804,
",": 0x2802,
":": 0x2812,
";": 0x2806,
"¿": 0x2822,
"?": 0x2822,
"¡": 0x2816,
"!": 0x2816,
'"': 0x2826,
"(": 0x2823,
")": 0x281c,
"-": 0x2824,
"*": 0x2814,
"=": 0x2836,
"÷": 0x2832,
"+": 0x2816,
"@": 0x2810,
" ": 0x2800, # braille space

# prefixes
chr(15): 0x2828, # uppercase prefix: https://codepoints.net/U+000F
"#": 0x283c, # numerical prefix
}[char.upper()])
bcharint = {
**ES_LETTERS,
**ES_ACCENT_MARKS,
**ES_SIGNS,
**ES_PREFIXES,
}[char.upper()]
except KeyError:
try:
# combinations
return {
"%": chr(0x2838) + chr(0x2834),
"‰": chr(0x2838) + chr(0x2834) + chr(0x2834), # per mile
"©": chr(0x2823) + chr(0x2828) + chr(0x2809) + chr(0x281c),
"®": chr(0x2823) + chr(0x2828) + chr(0x2817) + chr(0x281c),
"℗": chr(0x2823) + chr(0x2828) + chr(0x280f) + chr(0x281c),
"🄯": chr(0x2823) + chr(0x2828) + chr(0x2807) + chr(0x281c),
"/": chr(0x2820) + chr(0x2802),
"\\": chr(0x2810) + chr(0x2804),
"<": chr(0x2810) + chr(0x2805),
">": chr(0x2828) + chr(0x2802),
"|": chr(0x2838) + chr(0x2807),
"{": chr(0x2810) + chr(0x2807),
"}": chr(0x2838) + chr(0x2802),
"—": chr(0x2824) + chr(0x2824),

# currencies
"€": chr(0x2838) + chr(0x2811),
"$": chr(0x2838) + chr(0x280e),
"¢": chr(0x2818) + chr(0x2809),
"£": chr(0x2810) + chr(0x282e),
"¥": chr(0x2838) + chr(0x283d),
"¥": chr(0x2838) + chr(0x283d),
}[char]
return "".join([chr(num) for num in ES_COMBINATIONS[char]])
except KeyError:
return char
else:
# if uppercase, add uppercase prefix before letter
return "".join([chr(0x2828) if char.isupper() else '', bchar])
if char.isupper():
return "".join([chr(0x2828), chr(bcharint)])
return chr(bcharint)

def ca_char_map(char):
"""Catalan/Valencian chars mappers. Uses the same implementation as
Spanish but different accent marks.
Source: https://sid.usal.es/idocs/F8/FDO12069/signografiabasica.pdf
"""
if char.isnumeric():
# numeric prefix + number
return "".join([chr(0x283c), chr(ES_NUMBERS[char])])
try:
bcharint = {
**ES_LETTERS,
**CA_ACCENT_MARKS,
**ES_SIGNS,
**ES_PREFIXES,
}[char.upper()]
except KeyError:
try:
# combinations
return "".join([chr(num) for num in ES_COMBINATIONS[char]])
except KeyError:
return char
else:
# if uppercase, add uppercase prefix before letter
if char.isupper():
return "".join([chr(0x2828), chr(bcharint)])
return chr(bcharint)

# END: LOCALE FUNCTIONS

LOCALE_CHARMAPS = {
"en": en_char_map,
"es": es_char_map,
"gl": es_char_map, # Galician uses Spanish alphabet
"eu": es_char_map, # Euskera hasn't accent marks, so use Spanish alphabet
"eu": es_char_map, # Euskera hasn't accent marks but uses Spanish alphabet
"ca": ca_char_map, # Catalan/Valencian
}

# ---------------------------------

# EXTENSION

class BrailleL18n(inkex.TextExtension):
"""Convert to Braille giving a localized map of replacements."""
def add_arguments(self, pars):
Expand Down

0 comments on commit 5032a59

Please sign in to comment.