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

From: Junio C Hamano <[email-masked]>
Date: Mon, 27 May 2024 11:14:55 -0700

Alexander Shopov <[email-masked]> 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.

> 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.