threads / patch / 61351

patch[RESUBMIT 2nd] Consistency for substitution hints (i18n) 0/1]

Subject: [[PATCH] [RESUBMIT 2nd] Consistency for substitution hints (i18n) 0/1]

## tl;dr

16 messages between Apr 21, 2024 and Dec 30, 2024. Diffs are folded; open one to read it.

replies: 15people: 3as markdown or json

Alexander Shopov· Apr 21, 2024, 19:14 UTC · lore
Hopefully this is the 3rd time and I will do it right

i18n: as translators choose substitution hints applicable to their writing system, expose the ones in parse-options for completeness

Alexander Shopov (1):
  parse-options: use localized substitution hints
 parse-options.c | 15 ++++++++++++---
 1 file changed, 12 insertions(+), 3 deletions(-)
-- 
2.44.0
Alexander Shopov· Apr 21, 2024, 19:14 UTC · re: Alexander Shopov · lore

[[PATCH] [RESUBMIT 2nd] Consistency for substitution hints (i18n) 1/1] parse-options: use localized substitution hints

i18n: as translators choose substitution hints applicable to their writing system, expose the ones in parse-options for completeness

Signed-off-by: Alexander Shopov <ash@kambanaria.org>
---
 parse-options.c | 15 ++++++++++++---
 1 file changed, 12 insertions(+), 3 deletions(-)
Show changes to parse-options.c +12 −3
diff --git a/parse-options.c b/parse-options.c
index 63a99dea6e..2362ca83f3 100644
--- a/parse-options.c
+++ b/parse-options.c
@@ -1061,11 +1061,20 @@ static int usage_argh(const struct option *opts, FILE *outfile)
 		!opts->argh || !!strpbrk(opts->argh, "()<>[]|");
 	if (opts->flags & PARSE_OPT_OPTARG)
 		if (opts->long_name)
-			s = literal ? "[=%s]" : "[=<%s>]";
+			s = literal ? "[=%s]" :
+			  /* TRANSLATORS: keep as is unless you use hints for substitution other than `<>'
+			     in which case use those */
+			  _("[=<%s>]");
 		else
-			s = literal ? "[%s]" : "[<%s>]";
+			s = literal ? "[%s]" :
+			  /* TRANSLATORS: keep as is unless you use hints for substitution other than `<>'
+			     in which case use those */
+			  _("[<%s>]");
 	else
-		s = literal ? " %s" : " <%s>";
+		s = literal ? " %s" :
+		  /* TRANSLATORS: keep as is unless you use hints for substitution other than `<>'
+		     in which case use those */
+		  _(" <%s>");
 	return utf8_fprintf(outfile, s, opts->argh ? _(opts->argh) : _("..."));
 }
 
-- 
2.44.0
Junio C Hamano· Apr 21, 2024, 19:33 UTC · re: Alexander Shopov · lore

Re: [[PATCH] [RESUBMIT 2nd] Consistency for substitution hints (i18n) 1/1] parse-options: use localized substitution hints

Alexander Shopov <ash@kambanaria.org> writes:
> i18n: as translators choose substitution hints applicable
> to their writing system, expose the ones in parse-options
> for completeness

Please do not mark a patch whose contents has changed with "RESUBMIT" and the like. The earlier ones you had had unwanted "// Fixme" left in the patch and I am guessing that this version has removed them? Those who have read the earlier one, when the see the RESUBMIT in the title, would probably have ignored the patch and wouldn't have noticed that this one is improved over the previous attempts.

As to what the patch tries to achieve, I do not have a strong opinion, but the title and the explanation of the patch in the proposed log message looked somewhat strange, and the newly added comments looked overly long, all of which you may want to correct when you send out "[PATCH v2]".

Thanks.
Show 32 quoted lines
> Signed-off-by: Alexander Shopov <ash@kambanaria.org>
> ---
>  parse-options.c | 15 ++++++++++++---
>  1 file changed, 12 insertions(+), 3 deletions(-)
>
> diff --git a/parse-options.c b/parse-options.c
> index 63a99dea6e..2362ca83f3 100644
> --- a/parse-options.c
> +++ b/parse-options.c
> @@ -1061,11 +1061,20 @@ static int usage_argh(const struct option *opts, FILE *outfile)
>  		!opts->argh || !!strpbrk(opts->argh, "()<>[]|");
>  	if (opts->flags & PARSE_OPT_OPTARG)
>  		if (opts->long_name)
> -			s = literal ? "[=%s]" : "[=<%s>]";
> +			s = literal ? "[=%s]" :
> +			  /* TRANSLATORS: keep as is unless you use hints for substitution other than `<>'
> +			     in which case use those */
> +			  _("[=<%s>]");
>  		else
> -			s = literal ? "[%s]" : "[<%s>]";
> +			s = literal ? "[%s]" :
> +			  /* TRANSLATORS: keep as is unless you use hints for substitution other than `<>'
> +			     in which case use those */
> +			  _("[<%s>]");
>  	else
> -		s = literal ? " %s" : " <%s>";
> +		s = literal ? " %s" :
> +		  /* TRANSLATORS: keep as is unless you use hints for substitution other than `<>'
> +		     in which case use those */
> +		  _(" <%s>");
>  	return utf8_fprintf(outfile, s, opts->argh ? _(opts->argh) : _("..."));
>  }
Alexander Shopov· May 25, 2024, 12:24 UTC · re: Junio C Hamano · lore

[PATCH 2 0/1] Allowing localized substitution hints in parse-options

I hope this time patch submit is better. Requests for changes from previous review should be handled.

parse-options.c contains functions and macros to print messages with terms optionally enclosed in chars promting substitution to users such as:

  blah-blah-blah <TERM>

Since languages using different alphabets or writing systems can translate the term in an obvious manner to prompt the user to substitute them, I expose these character to the translators so the messages can use the same style as elsewhere in git.

Comments to the translators are shorter than before but hopefully they are not cryptic.

Alexander Shopov (1):
  parse-options: allow localized substitution hints in macros
 parse-options.c | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)

-- 2.45.1

Junio C Hamano· May 27, 2024, 18:14 UTC · re: Alexander Shopov · lore

Re: [PATCH 2 0/1] Allowing localized substitution hints in parse-options

Alexander Shopov <ash@kambanaria.org> writes:
Show 12 quoted lines
> I hope this time patch submit is better.
> Requests for changes from previous review should be handled.
>
> parse-options.c contains functions and macros to print messages with
> terms optionally enclosed in chars promting substitution to users such as:
>
>   blah-blah-blah <TERM>
>
> Since languages using different alphabets or writing systems can translate
> the term in an obvious manner to prompt the user to substitute them, I expose
> these character to the translators so the messages can use the same style as
> elsewhere in git.

Most of the above explanation, starting from "parse-options.c contains... " should replace the proposed log message of the main patch [1/1], I would think. Very clearly written.

The explanation after "such as:" needs improvement, though. Are you trying to highlight that an explanation is spelled with dashes between words format? Are you trying to highlight that the used term is capitalized? Are you trying to highlight that the term comes after explanation? The answer is none of the above, but it is not easy for readers to guess.

One way to make it easier to follow would be to use a more realistic example. The whole proposed log message may become like so:

    parse-options.c API can show help text for an option that takes
    an argument.  For the "--author" option that takes a name, for
    example, the program may define the option like so:
	OPT_STRING(0, "author", &au, N_("author"), N_("override author")),
    When the command is run with "-h" (short help) option, the above
    definition is shown as:
        --[no-]author <author>    override author
    As the program does not accept translated option names, the
    first part of the above, "--[no-]author", is given as-is, but
    the string "author" in a pair of "<>", and the explanation
    "override author" may be translated into user's language.
    The user's language may use a convention to mark a replaceable
    part of the command line (called a "placeholder string")
    differently from enclosing it inside a pair of "<>", but the
    implementation in parse-options.c hardcodes "<%s>".
    Allow translators to specify the presentation of a placeholder
    string for their languages by overriding the "<%s>".
> Comments to the translators are shorter than before but hopefully they are
> not cryptic.

What is cryptic here is what "than before" refers to---compared what?

  ... goes and looks ...
Ah, this is an updated patch for an earlier attempt
  https://lore.kernel.org/git/20240421191458.5411-1-ash@kambanaria.org/
Thanks for sticking with this topic.  Very much appreciated.
Jiang Xin· May 28, 2024, 00:47 UTC · re: Junio C Hamano · lore

Re: [PATCH 2 0/1] Allowing localized substitution hints in parse-options

On Tue, May 28, 2024 at 2:14 AM Junio C Hamano <gitster@pobox.com> wrote:
Show 19 quoted lines
>
> Alexander Shopov <ash@kambanaria.org> writes:
>
> > I hope this time patch submit is better.
> > Requests for changes from previous review should be handled.
> >
> > parse-options.c contains functions and macros to print messages with
> > terms optionally enclosed in chars promting substitution to users such as:
> >
> >   blah-blah-blah <TERM>
> >
> > Since languages using different alphabets or writing systems can translate
> > the term in an obvious manner to prompt the user to substitute them, I expose
> > these character to the translators so the messages can use the same style as
> > elsewhere in git.
>
> Most of the above explanation, starting from "parse-options.c
> contains... " should replace the proposed log message of the main
> patch [1/1], I would think.  Very clearly written.

Typically for a topic with only one commit, it's not necessary to provide a cover letter but provide details in the commit log instead.

Show 31 quoted lines
>
> The explanation after "such as:" needs improvement, though.  Are you
> trying to highlight that an explanation is spelled with dashes
> between words format?  Are you trying to highlight that the used
> term is capitalized?  Are you trying to highlight that the term
> comes after explanation?  The answer is none of the above, but it is
> not easy for readers to guess.
>
> One way to make it easier to follow would be to use a more realistic
> example.  The whole proposed log message may become like so:
>
>     parse-options.c API can show help text for an option that takes
>     an argument.  For the "--author" option that takes a name, for
>     example, the program may define the option like so:
>
>         OPT_STRING(0, "author", &au, N_("author"), N_("override author")),
>
>     When the command is run with "-h" (short help) option, the above
>     definition is shown as:
>
>         --[no-]author <author>    override author
>
>     As the program does not accept translated option names, the
>     first part of the above, "--[no-]author", is given as-is, but
>     the string "author" in a pair of "<>", and the explanation
>     "override author" may be translated into user's language.
>
>     The user's language may use a convention to mark a replaceable
>     part of the command line (called a "placeholder string")
>     differently from enclosing it inside a pair of "<>", but the
>     implementation in parse-options.c hardcodes "<%s>".

I guess the reason some people don't like the markers of placeholders (such as "<" and ">" characters) is that such characters have special meanings (used as IO redirection) in shell programming and they can be replaced with safer characters for languages other than English.

Show 19 quoted lines
>
>     Allow translators to specify the presentation of a placeholder
>     string for their languages by overriding the "<%s>".
>
> > Comments to the translators are shorter than before but hopefully they are
> > not cryptic.
>
> What is cryptic here is what "than before" refers to---compared
> what?
>
>   ... goes and looks ...
>
> Ah, this is an updated patch for an earlier attempt
>
>   https://lore.kernel.org/git/20240421191458.5411-1-ash@kambanaria.org/
>
> Thanks for sticking with this topic.  Very much appreciated.
>
>
Alexander Shopov· May 25, 2024, 12:24 UTC · re: Junio C Hamano · lore

[PATCH 2 1/1] parse-options: allow localized substitution hints in macros

i18n: expose substitution hint chars in functions and macros to translators
Signed-off-by: Alexander Shopov <ash@kambanaria.org>
---
 parse-options.c | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)
Show changes to parse-options.c +9 −3
diff --git a/parse-options.c b/parse-options.c
index 30b9e68f8a..06d962b00e 100644
--- a/parse-options.c
+++ b/parse-options.c
@@ -1070,11 +1070,17 @@ static int usage_argh(const struct option *opts, FILE *outfile)
 		!opts->argh || !!strpbrk(opts->argh, "()<>[]|");
 	if (opts->flags & PARSE_OPT_OPTARG)
 		if (opts->long_name)
-			s = literal ? "[=%s]" : "[=<%s>]";
+			s = literal ? "[=%s]" :
+			  /* TRANSLATORS: change `<>' to other characters or leave as is */
+			  _("[=<%s>]");
 		else
-			s = literal ? "[%s]" : "[<%s>]";
+			s = literal ? "[%s]" :
+			  /* TRANSLATORS: change `<>' to other characters or leave as is */
+			  _("[<%s>]");
 	else
-		s = literal ? " %s" : " <%s>";
+		s = literal ? " %s" :
+		  /* TRANSLATORS: change `<>' to other characters or leave as is */
+		  _(" <%s>");
 	return utf8_fprintf(outfile, s, opts->argh ? _(opts->argh) : _("..."));
 }
 
-- 
2.45.1
Junio C Hamano· May 27, 2024, 18:14 UTC · re: Alexander Shopov · lore

Re: [PATCH 2 1/1] parse-options: allow localized substitution hints in macros

Alexander Shopov <ash@kambanaria.org> writes:
> Subject: Re: [PATCH 2 1/1] parse-options: allow localized substitution hints in macros
These are not "macros", though.  Perhaps
    parse-options: localize marking-up of placeholder text in the short help

or something? As to the body of the proposed log message, I've covered it in my respoinse of the cover letter.

Show 24 quoted lines
> diff --git a/parse-options.c b/parse-options.c
> index 30b9e68f8a..06d962b00e 100644
> --- a/parse-options.c
> +++ b/parse-options.c
> @@ -1070,11 +1070,17 @@ static int usage_argh(const struct option *opts, FILE *outfile)
>  		!opts->argh || !!strpbrk(opts->argh, "()<>[]|");
>  	if (opts->flags & PARSE_OPT_OPTARG)
>  		if (opts->long_name)
> -			s = literal ? "[=%s]" : "[=<%s>]";
> +			s = literal ? "[=%s]" :
> +			  /* TRANSLATORS: change `<>' to other characters or leave as is */
> +			  _("[=<%s>]");
>  		else
> -			s = literal ? "[%s]" : "[<%s>]";
> +			s = literal ? "[%s]" :
> +			  /* TRANSLATORS: change `<>' to other characters or leave as is */
> +			  _("[<%s>]");
>  	else
> -		s = literal ? " %s" : " <%s>";
> +		s = literal ? " %s" :
> +		  /* TRANSLATORS: change `<>' to other characters or leave as is */
> +		  _(" <%s>");
>  	return utf8_fprintf(outfile, s, opts->argh ? _(opts->argh) : _("..."));
>  }

Just like user's language may use a convention different from enclosing it in a pair of <angle brackets> to mark a placeholder text, the use of [square brackets] to mark an optional part may have different per-language counterpart, no?

The above change, on the side that handles PARSE_OPT_OPTARG case, already allows "[=<%s>]" to be translated, but the translator hints can and should clarify that possibility as well, no?

    /* TRANSLATORS: change [] and <> mark-up, if necessary */

The SP that appears before <%s> on the mandatory argument side MUST NOT be translated. To go back to the "--author <author>" example I gave in my response for the cover letter, when the program says:

	OPT_STRING(0, "author", &au, N_("author"), N_("override author")),
in the output of "git commit -h", we give
        --[no-]author <AUTHOR>    OVERRIDE AUTHOR

where I used uppercase letters for the translated string. The SP before <%s> in " <%s>" is what we see after "--[no-]author" in the output.

So, if we were to allow localizing this truly, probably the "else" clause needs a bit more work, e.g.

	if (opts->flags & PARSE_OPT_OPTARG) {
		...
	} else {
		s = literal 
		? "%s"
                : _("<%s>");
		fputc(' ', outfile);
	}

The "=" that appears before %s should NOT be translated for exactly the same reason. If --author were an option that took an optional argument, "git commit -h" would have given

        --[no-]author[=<AUTHOR>]    OVERRIDE AUTHOR

No matter what language the user writes, the user MUST write '=' after "--author" if he or she wants to give an optional argument to the option. So some care must be taken to make sure they keep '=' even if they were to translate _("[=<%s>]"). The easiest way to do so may be to punt and *tell* them (without us having a way to make sure that they followed what we told them to), e.g.

    s = literal 
      ? "[=%s]"
      /*
       * TRANSLATORS: change [] that signals optional-ness, and
       * <> that signal placeholder-ness, of what is enclosed 
       * as necessary to match your locale's convention.  Do not
       * move or change '='; no matter what your language is, the
       * equal sign MUST be the first character in the optional
       * string.
       */
      : _("[=<%s>]");

Other than the above two points on the " " and "=" that must not be changed, the intent of this change looks very good to me.

Thanks.
Alexander Shopov· Jul 7, 2024, 15:35 UTC · re: Junio C Hamano · lore

[PATCH 3 0/1] parse-options: localize mark-up of placeholder text in the short help

Hi Junio & Jiang,
I am submitting the patch taking into account the feedback you gave last time.
Just to quickly remind: this allows translatability of "<>" chars in:
  OPT_STRING(0, "author", &force_author, N_("author"), N_("override author")),
displayed as:
    --[no-]author <author>    override author
@Junio:
> ... above explanation ... should replace ... log message
Done
> The explanation after "such as:" needs improvement...
Improved and closely follows your suggestion
> user's language may use a convention different from ... [square brackets]
> ... to mark an optional part ...
I decided againgst implementing this:
 - None of the translators have indicated such a need and adding it makes
   the whole thing more error prone
 - There is a tiny difference from what I did with the placeholder characters:
   I am actually skipping the characters in the Bulgarian translation (rather than 
   substituting them) which leads to shorter but still clear messages.  Skipping 
   both "[]" and "<>" and will lead to confusion.  "[]" are not as dangerous as
   "<>" for shell
 - If translators actually request it - it can be implemented when the real need
   arises
@Jiang
> ... with only one commit... not necessary to ... provide a cover letter

I agree but I am using the cover letter to remind what this is all about and point what I have done with the code revew. You can't remember all interactions.

> ... people don't like the markers ... "<" and ">" ... have special
> meanings ... in shell programming 
I have added something to this meaning in the log message.

Kind regards: al_shopov

Alexander Shopov (1):
  parse-options: localize mark-up of placeholder text in the short help
 parse-options.c | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)
-- 
2.45.2
Alexander Shopov· Jul 7, 2024, 15:35 UTC · re: Junio C Hamano · lore

[PATCH 3 1/1] parse-options: localize mark-up of placeholder text in the short help

i18n: expose substitution hint chars in functions and macros to translators

For example (based on builtin/commit.c and shortened): the "--author" option takes a name. In source this can be represented as:

  OPT_STRING(0, "author", &force_author, N_("author"), N_("override author")),

When the command is run with "-h" (short help) option (git commit -h), the above definition is displayed as:

  --[no-]author <author>    override author

Git does not use translated option names so the first part of the above, "--[no-]author", is given as-is (it is based on the 2nd argument of OPT_STRING). However the string "author" in the pair of "<>", and the explanation "override author for commit" may be translated into user's language.

The user's language may use a convention to mark a replaceable part of the command line (called a "placeholder string") differently from enclosing it inside a pair of "<>", but the implementation in parse-options.c hardcodes "<%s>".

Allow translators to specify the presentation of a placeholder string for their languages by overriding the "<%s>".

In case the translator's writing system is sufficiently different than Latin the "<>" characters can be substituted by an empty string thus effectively skipping them in the output. For example languages with uppercase versions of characters can use that to deliniate replaceability.

Alternatively a translator can decide to use characters that are visually close to "<>" but are not interpreted by the shell.

Signed-off-by: Alexander Shopov <ash@kambanaria.org>
---
 parse-options.c | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)
Show changes to parse-options.c +9 −3
diff --git a/parse-options.c b/parse-options.c
index 30b9e68f8a..06d962b00e 100644
--- a/parse-options.c
+++ b/parse-options.c
@@ -1070,11 +1070,17 @@ static int usage_argh(const struct option *opts, FILE *outfile)
 		!opts->argh || !!strpbrk(opts->argh, "()<>[]|");
 	if (opts->flags & PARSE_OPT_OPTARG)
 		if (opts->long_name)
-			s = literal ? "[=%s]" : "[=<%s>]";
+			s = literal ? "[=%s]" :
+			  /* TRANSLATORS: change `<>' to other characters or leave as is */
+			  _("[=<%s>]");
 		else
-			s = literal ? "[%s]" : "[<%s>]";
+			s = literal ? "[%s]" :
+			  /* TRANSLATORS: change `<>' to other characters or leave as is */
+			  _("[<%s>]");
 	else
-		s = literal ? " %s" : " <%s>";
+		s = literal ? " %s" :
+		  /* TRANSLATORS: change `<>' to other characters or leave as is */
+		  _(" <%s>");
 	return utf8_fprintf(outfile, s, opts->argh ? _(opts->argh) : _("..."));
 }
 
-- 
2.45.2
Alexander Shopov· Jul 14, 2024, 20:41 UTC · re: Alexander Shopov · lore

Re: [PATCH 3 1/1] parse-options: localize mark-up of placeholder text in the short help

Will the patch for expose substitution hint chars be included in 2.46? Should I do anything more? Kind regards: al_shopov

На нд, 7.07.2024 г. в 17:35 Alexander Shopov <ash@kambanaria.org> написа:
Show 70 quoted lines
>
> i18n: expose substitution hint chars in functions and macros to
> translators
>
> For example (based on builtin/commit.c and shortened): the "--author"
> option takes a name.  In source this can be represented as:
>
>   OPT_STRING(0, "author", &force_author, N_("author"), N_("override author")),
>
> When the command is run with "-h" (short help) option (git commit -h),
> the above definition is displayed as:
>
>   --[no-]author <author>    override author
>
> Git does not use translated option names so the first part of the
> above, "--[no-]author", is given as-is (it is based on the 2nd
> argument of OPT_STRING).  However the string "author" in the pair of
> "<>", and the explanation "override author for commit" may be
> translated into user's language.
>
> The user's language may use a convention to mark a replaceable part of
> the command line (called a "placeholder string") differently from
> enclosing it inside a pair of "<>", but the implementation in
> parse-options.c hardcodes "<%s>".
>
> Allow translators to specify the presentation of a placeholder string
> for their languages by overriding the "<%s>".
>
> In case the translator's writing system is sufficiently different than
> Latin the "<>" characters can be substituted by an empty string thus
> effectively skipping them in the output.  For example languages with
> uppercase versions of characters can use that to deliniate
> replaceability.
>
> Alternatively a translator can decide to use characters that are
> visually close to "<>" but are not interpreted by the shell.
>
> Signed-off-by: Alexander Shopov <ash@kambanaria.org>
> ---
>  parse-options.c | 12 +++++++++---
>  1 file changed, 9 insertions(+), 3 deletions(-)
>
> diff --git a/parse-options.c b/parse-options.c
> index 30b9e68f8a..06d962b00e 100644
> --- a/parse-options.c
> +++ b/parse-options.c
> @@ -1070,11 +1070,17 @@ static int usage_argh(const struct option *opts, FILE *outfile)
>                 !opts->argh || !!strpbrk(opts->argh, "()<>[]|");
>         if (opts->flags & PARSE_OPT_OPTARG)
>                 if (opts->long_name)
> -                       s = literal ? "[=%s]" : "[=<%s>]";
> +                       s = literal ? "[=%s]" :
> +                         /* TRANSLATORS: change `<>' to other characters or leave as is */
> +                         _("[=<%s>]");
>                 else
> -                       s = literal ? "[%s]" : "[<%s>]";
> +                       s = literal ? "[%s]" :
> +                         /* TRANSLATORS: change `<>' to other characters or leave as is */
> +                         _("[<%s>]");
>         else
> -               s = literal ? " %s" : " <%s>";
> +               s = literal ? " %s" :
> +                 /* TRANSLATORS: change `<>' to other characters or leave as is */
> +                 _(" <%s>");
>         return utf8_fprintf(outfile, s, opts->argh ? _(opts->argh) : _("..."));
>  }
>
> --
> 2.45.2
>
Junio C Hamano· Jul 15, 2024, 15:39 UTC · re: Alexander Shopov · lore

Re: [PATCH 3 1/1] parse-options: localize mark-up of placeholder text in the short help

Alexander Shopov <ash@kambanaria.org> writes:
> Will the patch for expose substitution hint chars be included in 2.46?
> Should I do anything more?

Sorry, I lost track. Did we resolve why "<>" is special and but "[]" is OK to leave out of the translatable text? IOW, is there much point in advising the translators that "<>" is something specifically they are allowed to change?

Stepping back a bit, would translators (especially for languages without any need for the ability to replace <> with something else) understand when told

    TRANSLATORS: change `<>' to other characters or leave as is

why anybody would want to change it in the first place? Stepping back even a bit more, probably making it clear to them what these instances of [<%s>], [=<%s>], etc., are doing would be sufficient to help them making the right decision?

If a translator for a hypothetical language that uses say „%s“ reads

	/* TRANSLATORS: <%s> here stands for an command line argument */
	_("<%s>")

in the comment, wouldn't that be sufficient to tell them they are allowed to change "<>" to "„“"?

Similarly, explaining [<%s>] as "optional command line argument", would tell them that it is OK for them to replace not just <> but also [] if their language requires such a change, no?

Thanks for pinging.
Show 28 quoted lines
>> diff --git a/parse-options.c b/parse-options.c
>> index 30b9e68f8a..06d962b00e 100644
>> --- a/parse-options.c
>> +++ b/parse-options.c
>> @@ -1070,11 +1070,17 @@ static int usage_argh(const struct option *opts, FILE *outfile)
>>                 !opts->argh || !!strpbrk(opts->argh, "()<>[]|");
>>         if (opts->flags & PARSE_OPT_OPTARG)
>>                 if (opts->long_name)
>> -                       s = literal ? "[=%s]" : "[=<%s>]";
>> +                       s = literal ? "[=%s]" :
>> +                         /* TRANSLATORS: change `<>' to other characters or leave as is */
>> +                         _("[=<%s>]");
>>                 else
>> -                       s = literal ? "[%s]" : "[<%s>]";
>> +                       s = literal ? "[%s]" :
>> +                         /* TRANSLATORS: change `<>' to other characters or leave as is */
>> +                         _("[<%s>]");
>>         else
>> -               s = literal ? " %s" : " <%s>";
>> +               s = literal ? " %s" :
>> +                 /* TRANSLATORS: change `<>' to other characters or leave as is */
>> +                 _(" <%s>");
>>         return utf8_fprintf(outfile, s, opts->argh ? _(opts->argh) : _("..."));
>>  }
>>
>> --
>> 2.45.2
>>
Alexander Shopov· Dec 28, 2024, 11:42 UTC · re: Junio C Hamano · lore

[PATCH 4 0/1] Localize mark-up of placeholder text in the short help

Hi Junio,

I am resubmitting this patch to make the substitution placeholder text localizable. Fuller explanation and example are given in the commit message.

I have reworked the translator comments to be fuller, clearer and prompt the proper default in case of doubt.

Last time you asked me why I am localizing the `<>' characters for substitution but not the `[]' for optional values.

There are several reasons:
1. No one has asked for such a feature so currently there seems to be
no need for that.  If someone asks - it is easy to provide the feature
then.
2. <> are much more dangerous in the shell than [] when copy-pasted
3. So far Bulgarian translation is the only user of the localizability
of <> and the action there is to omit the characters entirely - they
are not needed as the alphabets are different.  Omitting them makes
messages shorter.  If you omit both <> and [] in messages for
terseness - messages will be ambiguous.

Please indicate whether this is fine. I will iterate on the patch until it is deemed acceptable.

Here are links to previous times I submitted the patch:
3. https://lore.kernel.org/git/20240707153526.97984-1-ash@kambanaria.org/
2. https://lore.kernel.org/git/20240525122514.2608-1-ash@kambanaria.org/
1. https://lore.kernel.org/git/20240421180425.78940-1-ash@kambanaria.org/
0. (check for other teams) https://lore.kernel.org/git/CAP6f5Mmi=f4DPcFwfvEiJMdKMa0BUyZ019mc8uFXyOufgD4NjA@mail.gmail.com/ 

Kind regards: al_shopov

Alexander Shopov (1):
  parse-options: localize mark-up of placeholder text in the short help
 parse-options.c | 18 +++++++++++++++---
 1 file changed, 15 insertions(+), 3 deletions(-)
-- 
2.47.1
Alexander Shopov· Dec 28, 2024, 11:42 UTC · re: Junio C Hamano · lore

[PATCH 4 1/1] parse-options: localize mark-up of placeholder text in the short help

i18n: expose substitution hint chars in functions and macros to translators

For example (based on builtin/commit.c and shortened): the "--author" option takes a name. In source this can be represented as:

  OPT_STRING(0, "author", &force_author, N_("author"), N_("override author")),

When the command is run with "-h" (short help) option (git commit -h), the above definition is displayed as:

  --[no-]author <author>    override author

Git does not use translated option names so the first part of the above, "--[no-]author", is given as-is (it is based on the 2nd argument of OPT_STRING). However the string "author" in the pair of "<>", and the explanation "override author for commit" may be translated into user's language.

The user's language may use a convention to mark a replaceable part of the command line (called a "placeholder string") differently from enclosing it inside a pair of "<>", but the implementation in parse-options.c hardcodes "<%s>".

Allow translators to specify the presentation of a placeholder string for their languages by overriding the "<%s>".

In case the translator's writing system is sufficiently different than Latin the "<>" characters can be substituted by an empty string thus effectively skipping them in the output. For example languages with uppercase versions of characters can use that to deliniate replaceability.

Alternatively a translator can decide to use characters that are visually close to "<>" but are not interpreted by the shell.

Signed-off-by: Alexander Shopov <ash@kambanaria.org>
---
 parse-options.c | 18 +++++++++++++++---
 1 file changed, 15 insertions(+), 3 deletions(-)
Show changes to parse-options.c +15 −3
diff --git a/parse-options.c b/parse-options.c
index 33bfba0ed4..8904345c07 100644
--- a/parse-options.c
+++ b/parse-options.c
@@ -1076,11 +1076,23 @@ static int usage_argh(const struct option *opts, FILE *outfile)
 		!opts->argh || !!strpbrk(opts->argh, "()<>[]|");
 	if (opts->flags & PARSE_OPT_OPTARG)
 		if (opts->long_name)
-			s = literal ? "[=%s]" : "[=<%s>]";
+			s = literal ? "[=%s]" :
+			  /* TRANSLATORS: %s is a command line argument name, `<>' prompt the user to supply a value for it.
+			     Change only the `<>' characters to something else if you use another convention for this.
+			     Most translations leave this message as is. */
+			  _("[=<%s>]");
 		else
-			s = literal ? "[%s]" : "[<%s>]";
+			s = literal ? "[%s]" :
+			  /* TRANSLATORS: %s is a command line argument name, `<>' prompt the user to supply a value for it.
+			     Change only the `<>' characters to something else if you use another convention for this.
+			     Most translations leave this message as is. */
+			  _("[<%s>]");
 	else
-		s = literal ? " %s" : " <%s>";
+		s = literal ? " %s" :
+		  /* TRANSLATORS: %s is a command line argument name, `<>' prompt the user to supply a value for it.
+		     Change only the `<>' characters to something else if you use another convention for this.
+		     Most translations leave this message as is. */
+		  _(" <%s>");
 	return utf8_fprintf(outfile, s, opts->argh ? _(opts->argh) : _("..."));
 }
 
-- 
2.47.1
Junio C Hamano· Dec 28, 2024, 16:55 UTC · re: Alexander Shopov · lore

Re: [PATCH 4 1/1] parse-options: localize mark-up of placeholder text in the short help

Alexander Shopov <ash@kambanaria.org> writes:
> Subject: Re: [PATCH 4 1/1] parse-options: localize mark-up of placeholder text in the short help

It is more common to see "[PATCH v4 1/1]" around here. In fact, I suspect that you have to fight the tool to have them produce "[PATCH 4 1/1]".

Not that it matters to me personally (as "git am" on the receiving end will strip it), but when looking for a specific version of your patch from the mailing list archive, people may find it harder than necessary because of the subtle difference.

Show 11 quoted lines
> i18n: expose substitution hint chars in functions and macros to
> translators
> ...
> In case the translator's writing system is sufficiently different than
> Latin the "<>" characters can be substituted by an empty string thus
> effectively skipping them in the output.  For example languages with
> uppercase versions of characters can use that to deliniate
> replaceability.
>
> Alternatively a translator can decide to use characters that are
> visually close to "<>" but are not interpreted by the shell.
Very well written.
Show 14 quoted lines
> diff --git a/parse-options.c b/parse-options.c
> index 33bfba0ed4..8904345c07 100644
> --- a/parse-options.c
> +++ b/parse-options.c
> @@ -1076,11 +1076,23 @@ static int usage_argh(const struct option *opts, FILE *outfile)
>  		!opts->argh || !!strpbrk(opts->argh, "()<>[]|");
>  	if (opts->flags & PARSE_OPT_OPTARG)
>  		if (opts->long_name)
> -			s = literal ? "[=%s]" : "[=<%s>]";
> +			s = literal ? "[=%s]" :
> +			  /* TRANSLATORS: %s is a command line argument name, `<>' prompt the user to supply a value for it.
> +			     Change only the `<>' characters to something else if you use another convention for this.
> +			     Most translations leave this message as is. */
> +			  _("[=<%s>]");

This is way too wide. Documentation/CodingGuidelines should have something to say on this, but in case it does not, we try to allow those with 80-column terminals to read our code comfortably, and it is even better to allow us to do so after a patch is quoted a few times (i.e. adding a few columns on the left edge), so a practical limit may be around 70-columns.

Also, our multi-line comments have opening slash-asterisk and closing asterisk-slash on their own line.

This part is giving a help for the option value argument for a long option, i.e. for "git subcommand --option[=<value>]", we are talking about the "[=<value>]" part. It is not clear "command line argument name" conveys that. Something along this line, perhaps?

    The "<%s>" part of this string stands for an optional value given to a
    command line option in the long form, and "<>" is there as a
    convention to signal that it is a placeholder (i.e. the user should
    substitute it with the real value).  If your language uses a different
    convention, you can change "<%s>" part to match yours, e.g. it might
    use "|%s|" instead, or if the alphabet is different enough it may use
    "%s" without any placeholder signal.  Most translations leave this
    message as is.
Show 8 quoted lines
> +			  _("[=<%s>]");
>  		else
> -			s = literal ? "[%s]" : "[<%s>]";
> +			s = literal ? "[%s]" :
> +			  /* TRANSLATORS: %s is a command line argument name, `<>' prompt the user to supply a value for it.
> +			     Change only the `<>' characters to something else if you use another convention for this.
> +			     Most translations leave this message as is. */
> +			  _("[<%s>]");
Ditto, except that this is for "the short form".
Show 7 quoted lines
>  	else
> -		s = literal ? " %s" : " <%s>";
> +		s = literal ? " %s" :
> +		  /* TRANSLATORS: %s is a command line argument name, `<>' prompt the user to supply a value for it.
> +		     Change only the `<>' characters to something else if you use another convention for this.
> +		     Most translations leave this message as is. */
> +		  _(" <%s>");

Ditto, except that this is for "a value given to a command line option", not specific to either long or short form.

>  	return utf8_fprintf(outfile, s, opts->argh ? _(opts->argh) : _("..."));
>  }

I'll queue with the following change on top. Thanks.

 parse-options.c | 55 ++++++++++++++++++++++++++++++++++++++++---------------
 1 file changed, 40 insertions(+), 15 deletions(-)
Show changes to diff +40 −15
diff --git c/parse-options.c w/parse-options.c
index 8904345c07..3ff6a5d1fa 100644
--- c/parse-options.c
+++ w/parse-options.c
@@ -1076,23 +1076,48 @@ static int usage_argh(const struct option *opts, FILE *outfile)
 		!opts->argh || !!strpbrk(opts->argh, "()<>[]|");
 	if (opts->flags & PARSE_OPT_OPTARG)
 		if (opts->long_name)
-			s = literal ? "[=%s]" :
-			  /* TRANSLATORS: %s is a command line argument name, `<>' prompt the user to supply a value for it.
-			     Change only the `<>' characters to something else if you use another convention for this.
-			     Most translations leave this message as is. */
-			  _("[=<%s>]");
+			/*
+			 * TRANSLATORS: The "<%s>" part of this string
+			 * stands for an optional value given to a command
+			 * line option in the long form, and "<>" is there
+			 * as a convention to signal that it is a
+			 * placeholder (i.e. the user should substitute it
+			 * with the real value).  If your language uses a
+			 * different convention, you can change "<%s>" part
+			 * to match yours, e.g. it might use "|%s|" instead,
+			 * or if the alphabet is different enough it may use
+			 * "%s" without any placeholder signal.  Most
+			 * translations leave this message as is.
+			 */
+			s = literal ? "[=%s]" : _("[=<%s>]");
 		else
-			s = literal ? "[%s]" :
-			  /* TRANSLATORS: %s is a command line argument name, `<>' prompt the user to supply a value for it.
-			     Change only the `<>' characters to something else if you use another convention for this.
-			     Most translations leave this message as is. */
-			  _("[<%s>]");
+			/*
+			 * TRANSLATORS: The "<%s>" part of this string
+			 * stands for an optional value given to a command
+			 * line option in the short form, and "<>" is there
+			 * as a convention to signal that it is a
+			 * placeholder (i.e. the user should substitute it
+			 * with the real value).  If your language uses a
+			 * different convention, you can change "<%s>" part
+			 * to match yours, e.g. it might use "|%s|" instead,
+			 * or if the alphabet is different enough it may use
+			 * "%s" without any placeholder signal.  Most
+			 * translations leave this message as is.
+			 */
+			s = literal ? "[%s]" : _("[<%s>]");
 	else
-		s = literal ? " %s" :
-		  /* TRANSLATORS: %s is a command line argument name, `<>' prompt the user to supply a value for it.
-		     Change only the `<>' characters to something else if you use another convention for this.
-		     Most translations leave this message as is. */
-		  _(" <%s>");
+		/*
+		 * TRANSLATORS: The "<%s>" part of this string stands for a
+		 * value given to a command line option, and "<>" is there
+		 * as a convention to signal that it is a placeholder
+		 * (i.e. the user should substitute it with the real value).
+		 * If your language uses a different convention, you can
+		 * change "<%s>" part to match yours, e.g. it might use
+		 * "|%s|" instead, or if the alphabet is different enough it
+		 * may use "%s" without any placeholder signal.  Most
+		 * translations leave this message as is.
+		 */
+		s = literal ? " %s" : _(" <%s>");
 	return utf8_fprintf(outfile, s, opts->argh ? _(opts->argh) : _("..."));
 }
 
Jiang Xin· Dec 30, 2024, 03:02 UTC · lore

Re: [PATCH 4 1/1] parse-options: localize mark-up of placeholder text in the short help

On Sun, Dec 29, 2024 at 1:12 AM Alexander Shopov <ash@kambanaria.org> wrote:
Show 7 quoted lines
>
> Thanks a lot for applying and especially for the  feedback.
>
> > you have to fight the tool to have them produce "[PATCH 4 1/1]"
> The command I used was
> git format-patch ... --subject-prefix 'PATCH 4' ...
> I guess I should use --subject-prefix 'PATCH v4' unless there is some other trick I am missing.
You should use "git format-patch --thread -v4" or "--reroll-count=4" instead.

-- Jiang Xin

← back to recent threads