Skip to content

Commit 087499e

Browse files
authored
Merge pull request #2805 from vibe-d/web_t9n_improvements
Web t9n improvements
2 parents 97960ed + d17211f commit 087499e

File tree

1 file changed

+42
-21
lines changed

1 file changed

+42
-21
lines changed

web/vibe/web/i18n.d

+42-21
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,8 @@ unittest {
3535
import vibe.web.web : registerWebInterface;
3636

3737
struct TranslationContext {
38-
import std.typetuple;
39-
alias languages = TypeTuple!("en_US", "de_DE", "fr_FR");
38+
import std.meta : AliasSeq;
39+
alias languages = AliasSeq!("en_US", "de_DE", "fr_FR");
4040
//mixin translationModule!"app";
4141
//mixin translationModule!"somelib";
4242
}
@@ -62,9 +62,9 @@ unittest {
6262
import vibe.web.web : registerWebInterface;
6363

6464
struct TranslationContext {
65-
import std.typetuple;
65+
import std.meta : AliasSeq;
6666
// A language can be in the form en_US, en-US or en. Put the languages you want to prioritize first.
67-
alias languages = TypeTuple!("en_US", "de_DE", "fr_FR");
67+
alias languages = AliasSeq!("en_US", "de_DE", "fr_FR");
6868
//mixin translationModule!"app";
6969
//mixin translationModule!"somelib";
7070

@@ -97,8 +97,8 @@ unittest {
9797
import vibe.web.web : registerWebInterface;
9898

9999
struct TranslationContext {
100-
import std.typetuple;
101-
alias languages = TypeTuple!("en_US", "de_DE", "fr_FR");
100+
import std.meta : AliasSeq;
101+
alias languages = AliasSeq!("en_US", "de_DE", "fr_FR");
102102
static string determineLanguage(scope HTTPServerRequest req) { return "en_US"; }
103103
}
104104

@@ -143,14 +143,14 @@ html
143143
144144
See_Also: `translationContext`
145145
*/
146-
mixin template translationModule(string FILENAME)
146+
mixin template translationModule(string FILENAME, string language_separator = ".")
147147
{
148-
import std.string : tr;
149-
enum NAME = FILENAME.tr(`/.-\`, "____");
148+
static import std.string;
149+
enum NAME = std.string.tr(FILENAME, `/.\\-`, "____");
150150
private static string file_mixins() {
151151
string ret;
152152
foreach (language; languages)
153-
ret ~= "enum "~language~"_"~NAME~" = extractDeclStrings(import(`"~FILENAME~"."~language~".po`));\n";
153+
ret ~= "enum "~language~"_"~NAME~" = extractDeclStrings(import(`"~FILENAME~language_separator~language~".po`));\n";
154154
return ret;
155155
}
156156

@@ -482,11 +482,15 @@ LangComponents extractDeclStrings(string text)
482482
assert(text.length - i >= 6 && text[i .. i+6] == "msgstr", "Expected 'msgstr', got '"~text[i .. min(i+10, $)]~"'.");
483483
i += 6;
484484

485-
i = skipWhitespace(i, text);
486-
auto ivnext = skipString(i, text);
487-
auto value = dstringUnescape(wrapText(text[i+1 .. ivnext-1]));
488-
i = ivnext;
489-
i = skipToDirective(i, text);
485+
string value;
486+
if (text[i] == '[') i -= 6;
487+
else {
488+
i = skipWhitespace(i, text);
489+
auto ivnext = skipString(i, text);
490+
value = dstringUnescape(wrapText(text[i+1 .. ivnext-1]));
491+
i = ivnext;
492+
i = skipToDirective(i, text);
493+
}
490494

491495
// msgstr[n] is a required field when msgid_plural is not null, and ignored otherwise
492496
string[] value_plural;
@@ -650,9 +654,9 @@ msgstr "Third letter"
650654
enum components = extractDeclStrings(str);
651655

652656
struct TranslationContext {
653-
import std.typetuple;
657+
import std.meta : AliasSeq;
654658
enum enforceExistingKeys = true;
655-
alias languages = TypeTuple!("en_US");
659+
alias languages = AliasSeq!("en_US");
656660

657661
// Note that this is normally handled by mixing in an external file.
658662
enum en_US_unittest = components;
@@ -684,15 +688,20 @@ msgid_plural "Several files were created."
684688
msgstr "One file was created."
685689
msgstr[0] "1 file was created"
686690
msgstr[1] "%d files were created."
691+
692+
msgid "One file was modified."
693+
msgid_plural "Several files were modified."
694+
msgstr[0] "One file was modified."
695+
msgstr[1] "%d files were modified."
687696
`;
688697

689698
import std.stdio;
690699
enum components = extractDeclStrings(str);
691700

692701
struct TranslationContext {
693-
import std.typetuple;
702+
import std.meta : AliasSeq;
694703
enum enforceExistingKeys = true;
695-
alias languages = TypeTuple!("en_US");
704+
alias languages = AliasSeq!("en_US");
696705

697706
// Note that this is normally handled by mixing in an external file.
698707
enum en_US_unittest2 = components;
@@ -738,7 +747,7 @@ private size_t skipLine(size_t i, ref string text)
738747
private size_t skipString(size_t i, ref string text)
739748
{
740749
import std.conv : to;
741-
assert(text[i] == '"', "Expected to encounter the start of a string at position: "~to!string(i));
750+
assert(text[i] == '"', "Expected to encounter the start of a string at position: "~locationString(i, text));
742751
i++;
743752
while (true) {
744753
assert(i < text.length, "Missing closing '\"' for string: "~text[i .. min($, 10)]);
@@ -756,7 +765,7 @@ private size_t skipString(size_t i, ref string text)
756765

757766
private size_t skipIndex(size_t i, ref string text) {
758767
import std.conv : to;
759-
assert(text[i] == '[', "Expected to encounter a plural form of msgstr at position: "~to!string(i));
768+
assert(text[i] == '[', "Expected to encounter a plural form of msgstr at position: "~locationString(i, text));
760769
for (; i<text.length; ++i) {
761770
if (text[i] == ']') {
762771
return i+1;
@@ -865,3 +874,15 @@ private string dstringUnescape(in string str)
865874
}
866875
return ret;
867876
}
877+
878+
private string locationString(size_t i, string text)
879+
{
880+
import std.algorithm.searching : count;
881+
import std.format : format;
882+
import std.string : lastIndexOf;
883+
884+
auto ln = text[0 .. i].count('\n');
885+
auto sep = text[0 .. i].lastIndexOf('\n');
886+
auto col = sep >= 0 ? i - sep - 1 : i;
887+
return format("line %s, column %s", ln+1, col+1);
888+
}

0 commit comments

Comments
 (0)