{"thread":{"id":"29831","subject":"[PATCH] i18n: Not add stripped contents for translation","startedAt":"2012-03-05T01:21:34Z","lastAt":"2012-03-06T06:55:21Z","messageCount":10,"participants":["Jiang Xin","Junio C Hamano","Jens Lehmann"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"186061","messageId":"1330910494-17216-1-git-send-email-worldhello.net@gmail.com","threadId":"29831","inReplyTo":null,"subject":"[PATCH] i18n: Not add stripped contents for translation","fromName":"Jiang Xin","fromEmail":"worldhello.net@gmail.com","sentAt":"2012-03-05T01:21:34Z","receivedAt":"2012-03-05T01:21:34Z","isPatch":true,"sender":{"key":"worldhello.net@gmail.com","avatar":"https://avatars.githubusercontent.com/u/183860?v=4"},"body":"The last two chars of the concatenate str from the i18n marked strings\n(\", \") will be stripped out by strbuf_setlen.\n\n        before: \"new commits, modified content, \"\n        end:    \"new commits, modified content\"\n\nIf the translations won't end with COMMA+SPACE, will break the integrity\nof the concatenate string. As for Chinese, COMMA+SPACE may translated to\n\"，\" -- a 3-byte UTF-8 Chinese comma character.\n\nSigned-off-by: Jiang Xin <worldhello.net@gmail.com>\n---\n wt-status.c |    6 +++---\n 1 个文件被修改，插入 3 行(+)，删除 3 行(-)\n\ndiff --git a/wt-status.c b/wt-status.c\nindex 9ffc535..0042dbc 100644\n--- a/wt-status.c\n+++ b/wt-status.c\n@@ -245,11 +245,11 @@ static void wt_status_print_change_data(struct wt_status *s,\n \t\tif (d->new_submodule_commits || d->dirty_submodule) {\n \t\t\tstrbuf_addstr(&extra, \" (\");\n \t\t\tif (d->new_submodule_commits)\n-\t\t\t\tstrbuf_addf(&extra, _(\"new commits, \"));\n+\t\t\t\tstrbuf_addf(&extra, \"%s, \", _(\"new commits\"));\n \t\t\tif (d->dirty_submodule & DIRTY_SUBMODULE_MODIFIED)\n-\t\t\t\tstrbuf_addf(&extra, _(\"modified content, \"));\n+\t\t\t\tstrbuf_addf(&extra, \"%s, \", _(\"modified content\"));\n \t\t\tif (d->dirty_submodule & DIRTY_SUBMODULE_UNTRACKED)\n-\t\t\t\tstrbuf_addf(&extra, _(\"untracked content, \"));\n+\t\t\t\tstrbuf_addf(&extra, \"%s, \", _(\"untracked content\"));\n \t\t\tstrbuf_setlen(&extra, extra.len - 2);\n \t\t\tstrbuf_addch(&extra, ')');\n \t\t}\n-- \n1.7.9.2.330.g152e4.dirty\n"},{"id":"186063","messageId":"7v7gyz7pei.fsf@alter.siamese.dyndns.org","threadId":"29831","inReplyTo":"1330910494-17216-1-git-send-email-worldhello.net@gmail.com","subject":"Re: [PATCH] i18n: Not add stripped contents for translation","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2012-03-05T02:27:49Z","receivedAt":"2012-03-05T02:27:49Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jiang Xin <worldhello.net@gmail.com> writes:\n\n> The last two chars of the concatenate str from the i18n marked strings\n> (\", \") will be stripped out by strbuf_setlen.\n>\n>         before: \"new commits, modified content, \"\n>         end:    \"new commits, modified content\"\n>\n> If the translations won't end with COMMA+SPACE, will break the integrity\n> of the concatenate string. As for Chinese, COMMA+SPACE may translated to\n> \"，\" -- a 3-byte UTF-8 Chinese comma character.\n\nHmph.  Why would that be a bad thing in the first place?\nFor example, for the diff.c::print_stat_summary() message, you have this\ntranslation:\n\n>  1 个文件被修改，插入 3 行(+)，删除 3 行(-)\n\nwhere the original would be:\n\n   %d file changed, %d insertions(+), %d deletions(-).\n\nand I would imagine that it entirely is plausible if a native reader would\nwish to read a Japanese translation like this:\n\n   1個のファイルを変更、挿入 3 行(+)、削除 3 行(-)\n\nwithout using ASCII comma, but using \"、\" instead.\n\n> diff --git a/wt-status.c b/wt-status.c\n> index 9ffc535..0042dbc 100644\n> --- a/wt-status.c\n> +++ b/wt-status.c\n> @@ -245,11 +245,11 @@ static void wt_status_print_change_data(struct wt_status *s,\n>  \t\tif (d->new_submodule_commits || d->dirty_submodule) {\n>  \t\t\tstrbuf_addstr(&extra, \" (\");\n>  \t\t\tif (d->new_submodule_commits)\n> -\t\t\t\tstrbuf_addf(&extra, _(\"new commits, \"));\n> +\t\t\t\tstrbuf_addf(&extra, \"%s, \", _(\"new commits\"));\n>  \t\t\tif (d->dirty_submodule & DIRTY_SUBMODULE_MODIFIED)\n> -\t\t\t\tstrbuf_addf(&extra, _(\"modified content, \"));\n> +\t\t\t\tstrbuf_addf(&extra, \"%s, \", _(\"modified content\"));\n>  \t\t\tif (d->dirty_submodule & DIRTY_SUBMODULE_UNTRACKED)\n> -\t\t\t\tstrbuf_addf(&extra, _(\"untracked content, \"));\n> +\t\t\t\tstrbuf_addf(&extra, \"%s, \", _(\"untracked content\"));\n>  \t\t\tstrbuf_setlen(&extra, extra.len - 2);\n>  \t\t\tstrbuf_addch(&extra, ')');\n>  \t\t}\n"},{"id":"186066","messageId":"CANYiYbGdJ0yFmPnsK_JdABwmFraVdNi08QgFKRmGzJt-DA9tBw@mail.gmail.com","threadId":"29831","inReplyTo":"7v7gyz7pei.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH] i18n: Not add stripped contents for translation","fromName":"Jiang Xin","fromEmail":"worldhello.net@gmail.com","sentAt":"2012-03-05T03:01:30Z","receivedAt":"2012-03-05T03:01:30Z","isPatch":true,"sender":{"key":"worldhello.net@gmail.com","avatar":"https://avatars.githubusercontent.com/u/183860?v=4"},"body":"2012/3/5 Junio C Hamano <gitster@pobox.com>:\n>> If the translations won't end with COMMA+SPACE, will break the integrity\n>> of the concatenate string. As for Chinese, COMMA+SPACE may translated to\n>> \"，\" -- a 3-byte UTF-8 Chinese comma character.\n>\n> Hmph.  Why would that be a bad thing in the first place?\n\nOrignal source code:\n\n244   case WT_STATUS_CHANGED:\n245     if (d->new_submodule_commits || d->dirty_submodule) {\n246       strbuf_addstr(&extra, \" (\");\n247       if (d->new_submodule_commits)\n248         strbuf_addf(&extra, _(\"new commits, \"));\n249       if (d->dirty_submodule & DIRTY_SUBMODULE_MODIFIED)\n250         strbuf_addf(&extra, _(\"modified content, \"));\n251       if (d->dirty_submodule & DIRTY_SUBMODULE_UNTRACKED)\n252         strbuf_addf(&extra, _(\"untracked content, \"));\n253       strbuf_setlen(&extra, extra.len - 2);\n254       strbuf_addch(&extra, ')');\n255     }\n\nThe bad thing is strbuf_setlen() at line 253. We can not asume the translation\nof \", \" must be 2 characters.\n\nIf we change line 253 like the following, it may work but introduce another\nstring \", \" for translation, and it looks weird.\n\n253       strbuf_setlen(&extra, extra.len - strlen( _(\", \") ));\n\nIt is because I translate the \", \" to \"，\" (chinese comma), the translated\nchinese comma is 3 bytes long, striped two of them cause the output\nlooks weird.\n\nIt is also a bug hard to detect, If a careless translater lost the end space\nin translation.\n\n\n-- \nJiang Xin\n"},{"id":"186068","messageId":"7vobsb67dn.fsf@alter.siamese.dyndns.org","threadId":"29831","inReplyTo":"CANYiYbGdJ0yFmPnsK_JdABwmFraVdNi08QgFKRmGzJt-DA9tBw@mail.gmail.com","subject":"Re: [PATCH] i18n: Not add stripped contents for translation","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2012-03-05T03:42:28Z","receivedAt":"2012-03-05T03:42:28Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jiang Xin <worldhello.net@gmail.com> writes:\n\n> Orignal source code:\n>\n> 244   case WT_STATUS_CHANGED:\n> 245     if (d->new_submodule_commits || d->dirty_submodule) {\n> 246       strbuf_addstr(&extra, \" (\");\n> 247       if (d->new_submodule_commits)\n> 248         strbuf_addf(&extra, _(\"new commits, \"));\n> 249       if (d->dirty_submodule & DIRTY_SUBMODULE_MODIFIED)\n> 250         strbuf_addf(&extra, _(\"modified content, \"));\n> 251       if (d->dirty_submodule & DIRTY_SUBMODULE_UNTRACKED)\n> 252         strbuf_addf(&extra, _(\"untracked content, \"));\n> 253       strbuf_setlen(&extra, extra.len - 2);\n> 254       strbuf_addch(&extra, ')');\n> 255     }\n>\n> The bad thing is strbuf_setlen() at line 253. We can not asume the translation\n> of \", \" must be 2 characters.\n\nIt sounds like you are merely working around a poor style in the original,\nwhich should have been structured more like this in the first place, no?\n\n        /* a helper function elsewhere, possibly inlined */\n        static void add_iwsep_as_needed(struct strbuf *buf, int origlen)\n        {\n                if (buf->len != origlen)\n                        strbuf_addstr(buf, _(\",\"));\n        }\n\n        ...\n        int origlen;\n\n        strbuf_addstr(&extra, \" (\"))\n        origlen = extra.len;\n        if (a)\n                strbuf_addstr(&extra, _(\"msg a\"));\n        if (b) {\n                add_iwsep_as_needed(&extra, origlen);\n                strbuf_addstr(&extra, _(\"msg b\"));\n        }\n        if (c) {\n                add_iwsep_as_needed(&extra, origlen);\n                strbuf_addstr(&extra, _(\"msg c\"));\n        }\n        strbuf_addstr(&extra, \")\");\n\nCc'ing Jens whose 9297f77 (git status: Show detailed dirty status of\nsubmodules in long format, 2010-03-08) introduced the \"two-byte backstep\".\n\n\nThis is a tangent and I am just showing aloud my ignorance, but I wonder\nif there is a reasonably generic and \"best current practice\" way to\nstructure code to show an enumeration in human languages, for example,\n\n\tA, B, C and D.\n\nin an easier-to-translate way.\n\nI suspect that it might be sufficiently generic if we can make it possible\nto allow the first and the last inter-word-separation and the token after\nall the items to be different from other inter-word-separation tokens.\n\nE.g. in English, the first one and all the \"other\" are \", \", the last\ninter-word token is \" and \", and the token at the very end is \".\". In\nJapanese some translators may want to say \"AやBとCとD。\", meaning the\nfirst one is \"や\", \"。\" is used at the very end, and all the others may be\n\"と\".\n"},{"id":"186134","messageId":"4F55155A.3050309@web.de","threadId":"29831","inReplyTo":"7vobsb67dn.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH] i18n: Not add stripped contents for translation","fromName":"Jens Lehmann","fromEmail":"jens.lehmann@web.de","sentAt":"2012-03-05T19:34:50Z","receivedAt":"2012-03-05T19:34:50Z","isPatch":true,"sender":{"key":"jens.lehmann@web.de","avatar":"https://avatars.githubusercontent.com/u/135220?v=4"},"body":"Am 05.03.2012 04:42, schrieb Junio C Hamano:\n> Jiang Xin <worldhello.net@gmail.com> writes:\n> \n>> Orignal source code:\n>>\n>> 244   case WT_STATUS_CHANGED:\n>> 245     if (d->new_submodule_commits || d->dirty_submodule) {\n>> 246       strbuf_addstr(&extra, \" (\");\n>> 247       if (d->new_submodule_commits)\n>> 248         strbuf_addf(&extra, _(\"new commits, \"));\n>> 249       if (d->dirty_submodule & DIRTY_SUBMODULE_MODIFIED)\n>> 250         strbuf_addf(&extra, _(\"modified content, \"));\n>> 251       if (d->dirty_submodule & DIRTY_SUBMODULE_UNTRACKED)\n>> 252         strbuf_addf(&extra, _(\"untracked content, \"));\n>> 253       strbuf_setlen(&extra, extra.len - 2);\n>> 254       strbuf_addch(&extra, ')');\n>> 255     }\n>>\n>> The bad thing is strbuf_setlen() at line 253. We can not asume the translation\n>> of \", \" must be 2 characters.\n> \n> It sounds like you are merely working around a poor style in the original,\n> which should have been structured more like this in the first place, no?\n> \n>         /* a helper function elsewhere, possibly inlined */\n>         static void add_iwsep_as_needed(struct strbuf *buf, int origlen)\n>         {\n>                 if (buf->len != origlen)\n>                         strbuf_addstr(buf, _(\",\"));\n>         }\n> \n>         ...\n>         int origlen;\n> \n>         strbuf_addstr(&extra, \" (\"))\n>         origlen = extra.len;\n>         if (a)\n>                 strbuf_addstr(&extra, _(\"msg a\"));\n>         if (b) {\n>                 add_iwsep_as_needed(&extra, origlen);\n>                 strbuf_addstr(&extra, _(\"msg b\"));\n>         }\n>         if (c) {\n>                 add_iwsep_as_needed(&extra, origlen);\n>                 strbuf_addstr(&extra, _(\"msg c\"));\n>         }\n>         strbuf_addstr(&extra, \")\");\n> \n> Cc'ing Jens whose 9297f77 (git status: Show detailed dirty status of\n> submodules in long format, 2010-03-08) introduced the \"two-byte backstep\".\n\nI have no objections at all against changing the code that way to make it\npossible to translate it in a sane way. This code predates the i18n effort\nby a few months, so it didn't take this kind of problem into account.\n"},{"id":"186139","messageId":"7v62ei24l6.fsf@alter.siamese.dyndns.org","threadId":"29831","inReplyTo":"4F55155A.3050309@web.de","subject":"Re: [PATCH] i18n: Not add stripped contents for translation","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2012-03-05T20:08:37Z","receivedAt":"2012-03-05T20:08:37Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jens Lehmann <Jens.Lehmann@web.de> writes:\n\n> I have no objections at all against changing the code that way to make it\n> possible to translate it in a sane way. This code predates the i18n effort\n> by a few months, so it didn't take this kind of problem into account.\n\nAh, Ok, that explains it.\n"},{"id":"186169","messageId":"CANYiYbHGAG5ijeL3yW5SKYAfMNwtme5ELPeGNPhNyKBPGTONMg@mail.gmail.com","threadId":"29831","inReplyTo":"7vobsb67dn.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH] i18n: Not add stripped contents for translation","fromName":"Jiang Xin","fromEmail":"worldhello.net@gmail.com","sentAt":"2012-03-06T04:16:06Z","receivedAt":"2012-03-06T04:16:06Z","isPatch":true,"sender":{"key":"worldhello.net@gmail.com","avatar":"https://avatars.githubusercontent.com/u/183860?v=4"},"body":"2012/3/5 Junio C Hamano <gitster@pobox.com>:\n> This is a tangent and I am just showing aloud my ignorance, but I wonder\n> if there is a reasonably generic and \"best current practice\" way to\n> structure code to show an enumeration in human languages, for example,\n>\n>        A, B, C and D.\n>\n> in an easier-to-translate way.\n>\n> I suspect that it might be sufficiently generic if we can make it possible\n> to allow the first and the last inter-word-separation and the token after\n> all the items to be different from other inter-word-separation tokens.\n>\n> E.g. in English, the first one and all the \"other\" are \", \", the last\n> inter-word token is \" and \", and the token at the very end is \".\". In\n> Japanese some translators may want to say \"AやBとCとD。\", meaning the\n> first one is \"や\", \"。\" is used at the very end, and all the others may be\n> \"と\".\n\nI write a function for this.\n\n/*\n * Make list of items easy for l10n translation.\n *\n *   1. Input list of items one by one through the 2nd argument,\n *      but leave the 1st argument as NULL.\n *\n *   2. Get the output joint string from the 1st argument.\n *\n * According to the number of items input. The joint string maybe:\n *\n *   a\n *   a and b\n *   a, b and c\n *   a, b, c and d\n *\n */\n#define MAX_L10N_LIST_ITEMS_COUNT  128\nvoid append_l10n_list_items(struct strbuf *ret, const char *item)\n{\n    static const char **itemlist = NULL;\n    static int  count = 0;\n    int i = 0;\n\n    if (itemlist == NULL)\n        itemlist = xmalloc(MAX_L10N_LIST_ITEMS_COUNT * sizeof(char*));\n\n    if(item != NULL && count < MAX_L10N_LIST_ITEMS_COUNT )\n        itemlist[count++] = item;\n\n    if (ret != NULL) {\n        if (count == 1) {\n            strbuf_addstr(ret, itemlist[0]);\n        }\n        else if (count == 2) {\n            strbuf_addf(ret, _(\"%s and %s\"), itemlist[0], itemlist[1]);\n        }\n        else if (count > 2) {\n            strbuf_addf(ret, _(\"%s, \"), itemlist[0]);\n            for (i=1; i<count-2; i++) {\n                strbuf_addstr(ret, itemlist[i]);\n                strbuf_addstr(ret, _(\", \"));\n            }\n            strbuf_addf(ret, _(\"%s and %s\"), itemlist[count-2],\nitemlist[count-1]);\n        }\n        free(itemlist);\n        itemlist = NULL;\n        count = 0;\n    }\n}\n\n\n...\n       strbuf_addstr(&extra, \" (\"))\n       if (a)\n               append_l10n_list_items(NULL, _(\"msg a\"));\n       if (b)\n               append_l10n_list_items(NULL, _(\"msg b\"));\n       if (c)\n               append_l10n_list_items(NULL, _(\"msg c\"));\n\n       append_l10n_list_items(&extra, NULL);\n...\n\n-- \nJiang Xin\n"},{"id":"186170","messageId":"7v399mw7k3.fsf@alter.siamese.dyndns.org","threadId":"29831","inReplyTo":"CANYiYbHGAG5ijeL3yW5SKYAfMNwtme5ELPeGNPhNyKBPGTONMg@mail.gmail.com","subject":"Re: [PATCH] i18n: Not add stripped contents for translation","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2012-03-06T06:46:20Z","receivedAt":"2012-03-06T06:46:20Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jiang Xin <worldhello.net@gmail.com> writes:\n\n>> This is a tangent and I am just showing aloud my ignorance, but I wonder\n>> if there is a reasonably generic and \"best current practice\" way to\n>> structure code to show an enumeration in human languages, for example,\n> ...\n> I write a function for this.\n\nIt is not a very good API design to use static array in a function\nlike your code.\n\nYou will often want to walk list of lists in a nested loop and want\nto have two \"appends\" running in parallel.  Imagine you are merging\nthree branches A, B and C in an octopus merge, and want to say\n\"commits A1 and A2 were merged from A\".  You would want to structure\nthe caller like this:\n\n        clear_list(&list_of_branches);\n        # this walks branches A, B and C\n        foreach branch\n                append_item(&list_of_branches, branch);\n\n                clear_list(&list_of_commits);\n                # this walks commits on the branch\n                foreach commit on branch\n                        append_item(&list_of_commits, commit);\n                # this shows e.g. \"commits A1 and A2\"\n                format_list_as_human_string(&list_of_commits);\n        # this shows e.g. \"branches A, B and C\"\n        format_list_as_human_string(&list_of_branches);\n\nIn any case, I was not asking anybody to come up with an original\nsolution. Rather, I was asking if somebody knew an already widely\nused library-ish implementation we can just reuse.  If there is no\nsuch thing, we may end up designing one ourselves, but we shouldn't\nbe doing so if we don't have to.\n"},{"id":"186171","messageId":"CANYiYbFXP_rB82-_ObnPE7NkKpv8NsA7=yu1VY7nRwkRPY5X_A@mail.gmail.com","threadId":"29831","inReplyTo":"CANYiYbHGAG5ijeL3yW5SKYAfMNwtme5ELPeGNPhNyKBPGTONMg@mail.gmail.com","subject":"Re: [PATCH] i18n: Not add stripped contents for translation","fromName":"Jiang Xin","fromEmail":"worldhello.net@gmail.com","sentAt":"2012-03-06T06:47:40Z","receivedAt":"2012-03-06T06:47:40Z","isPatch":true,"sender":{"key":"worldhello.net@gmail.com","avatar":"https://avatars.githubusercontent.com/u/183860?v=4"},"body":"在 2012年3月6日 下午12:16，Jiang Xin <worldhello.net@gmail.com> 写道：\n>\n> /*\n>  * Make list of items easy for l10n translation.\n>  *\n>  *   1. Input list of items one by one through the 2nd argument,\n>  *      but leave the 1st argument as NULL.\n>  *\n>  *   2. Append the output joint string to strbuf from the 1st argument.\n>  *\n>  * According to the number of items input. The joint string maybe:\n>  *\n>  *   a\n>  *   a and b\n>  *   a, b and c\n>  *   a, b, c and d\n>  *\n>  */\n\n-#define MAX_L10N_LIST_ITEMS_COUNT  128\n+#define MAX_L10N_LIST_ITEMS_COUNT      8\n\n> void append_l10n_list_items(struct strbuf *ret, const char *item)\n> {\n>    static const char **itemlist = NULL;\n>    static int  count = 0;\n>    int i = 0;\n>\n>    if (itemlist == NULL)\n>        itemlist = xmalloc(MAX_L10N_LIST_ITEMS_COUNT * sizeof(char*));\n\n+    else if (count >= MAX_L10N_LIST_ITEMS_COUNT)\n+        itemlist = xrealloc(itemlist, (count +\nMAX_L10N_LIST_ITEMS_COUNT) * sizeof(char*));\n\n-    if(item != NULL && count < MAX_L10N_LIST_ITEMS_COUNT )\n+    if (item != NULL)\n\n>        itemlist[count++] = item;\n>\n>    if (ret != NULL) {\n>        if (count == 1) {\n>            strbuf_addstr(ret, itemlist[0]);\n>        }\n>        else if (count == 2) {\n>            strbuf_addf(ret, _(\"%s and %s\"), itemlist[0], itemlist[1]);\n>        }\n>        else if (count > 2) {\n>            strbuf_addf(ret, _(\"%s, \"), itemlist[0]);\n>            for (i=1; i<count-2; i++) {\n\n-                 strbuf_addstr(ret, itemlist[i]);\n-                 strbuf_addstr(ret, _(\", \"));\n+                 strbuf_addf(ret, _(\"%s, %s\"), itemlist[i], \"\");\n\n>            }\n>            strbuf_addf(ret, _(\"%s and %s\"), itemlist[count-2],\n> itemlist[count-1]);\n>        }\n>        free(itemlist);\n>        itemlist = NULL;\n>        count = 0;\n>    }\n> }\n>\n>\n> ...\n>       strbuf_addstr(&extra, \" (\"))\n>       if (a)\n>               append_l10n_list_items(NULL, _(\"msg a\"));\n>       if (b)\n>               append_l10n_list_items(NULL, _(\"msg b\"));\n>       if (c)\n>               append_l10n_list_items(NULL, _(\"msg c\"));\n>\n>       append_l10n_list_items(&extra, NULL);\n> ...\n"},{"id":"186172","messageId":"CANYiYbGzy7bCpk4NHUq58s9iJ5bW9Uf+MMpmPEd1XME5wi1rNg@mail.gmail.com","threadId":"29831","inReplyTo":"7v399mw7k3.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH] i18n: Not add stripped contents for translation","fromName":"Jiang Xin","fromEmail":"worldhello.net@gmail.com","sentAt":"2012-03-06T06:55:21Z","receivedAt":"2012-03-06T06:55:21Z","isPatch":true,"sender":{"key":"worldhello.net@gmail.com","avatar":"https://avatars.githubusercontent.com/u/183860?v=4"},"body":"> In any case, I was not asking anybody to come up with an original\n> solution. Rather, I was asking if somebody knew an already widely\n> used library-ish implementation we can just reuse.  If there is no\n> such thing, we may end up designing one ourselves, but we shouldn't\n> be doing so if we don't have to.\n\nStill awake? hardwork, admire. ;-)\n\n-- \nJiang Xin\n"}]}