Helper code for software internationalization.
Replace placeholder text in string using the replacements.
Examples:
> (itrans "Hello ~PERSON_A~, I have ~ITEMS~."
;; Replacements.
"Jane"
(list "seeds" "tools"))
(list "Hello " "Jane" ", I have " (list "seeds" "tools") ".")
Procedure specification:
string (string): A string with placeholder text, where placeholder format is arbitrary. For example:
"Hello ~PERSON_A~, I have ~ITEMS~."
regex (regex string pattern): Optional pattern to match the placeholder text in string.
replacements (symbolic expressions) As many symbolic expressions as placeholder text there is in string.
Return value (list of symbolic expressions): For example, using the previous examples:
(list "Hello " "Jane" ", I have " (list "seeds" "tools") ".")
NOTE:
This is a horrible procedure to work around the translation of strings that are separated through s-expressions but that actually belong together in, say, a sentence. Let’s take, for instance, the following sentence:
Please contact Jane Roe from Robotic Bees.
Imagine this sentence is for a website you are writing using SXML. You could write it like this:
(p "Please contact Jane Roe from Robotic Bees.")
But the website should be available in multiple languages, so you have to mark that sentence for translation, which you could do it as follows:
(p ,(_ "Please contact Jane Roe from Robotic Bees."))
Here, the _ is a shortcut procedure for Guile’s gettext
(you define the shortcut in for your project). When the string is
extracted for translation, translators will see the whole sentence in
the translation catalogs:
Please contact Jane Roe from Robotic Bees.
Now, here is the problem. Let’s say you have to convert ’Jane Roe’ and ’Robotic Bees’ into links. You could do as follows:
(p ,(_ "Please contact") " " (a (@@ (href "mailto:jr@@rbees.com")) "Jane Roe") " " ,(_ "from") " " (a (@@ (href "https://rbees.com")) "Robotic Bees") ".")
This is hard to read for the programmer, and what before was a whole sentence that translators could easily read will now be extracted as fragmented strings without context. A translator would see two separate strings:
How can we still mark the whole sentence for translation in a way that
is readable for both programmers and translators? I wished for an
strans procedure, or whatever, that allowed me to mark
s-expressions for translation like this:
(strans
(p "Please contact "
(a (@@ (href "mailto:jr@@rbees.com")) "Jane Roe")
« from »
(a (@@ (href "https://rbees.com")) "Robotic Bees")
"."))
But how would you make it actually work? How would you assemble and
disassemble the sentence when required? I don’t have a clue. So I
decided to work around the issue using the itrans procedure,
which stands for interleaved translation. With this procedure,
you mark whole strings for translation:
(p
,@@(itrans (_ «Please contact ~PERSON~ from ~BUSINESS~.»)
;; Replacements.
'(a (@@ (href «mailto:jr@@rbees.com»)) «Jane Roe»)
'(a (@@ (href «https://rbees.com»)) «Robotic Bees»)))
When the text in this code is extracted for translation, the translators will see:
Please contact ~PERSON~ from ~BUSINESS~.
They need to know they shouldn’t translate the placeholder substrings (the text between ~ marks), but they can move them around if necessary in the target language sentence.
Evaluating the SXML above in an environment set to a Spanish locale would work as follows. First, the sentence is translated to that language:
(p
,@@(itrans "Contacte a ~PERSON~ de ~BUSINESS~."
;; Replacements.
'(a (@@ (href "mailto:jr@@rbees.com")) "Jane Roe")
'(a (@@ (href "https://rbees.com")) "Robotic Bees")))
Then, itrans disassembles the sentence, which results in a list
of parts like this:
(list "Contacte a "
"~PERSON~"
" de "
"~BUSINESS~"
".")
After this, the placeholders are replaced in order with the replacements passed to the procedure:
(list "Contacte a "
'(a (@@ (href "mailto:jr@@rbees.com")) "Jane Roe")
" de "
'(a (@@ (href "https://rbees.com")) "Robotic Bees")
".")
Finally, the list explodes into items, which then become items of the
p expression:
(p "Contacte a " '(a (@@ (href "mailto:jr@@rbees.com")) "Jane Roe") " de " '(a (@@ (href "https://rbees.com")) "Robotic Bees") ".")
At that point, the SXML can be converted into the final HTML.