From: Gdobbins <gdobbins@protonmail.com>
To: Paul Eggert <eggert@cs.ucla.edu>
Cc: emacs-devel@gnu.org
Subject: Re: RFC: locale-sensitive Emacs functions
Date: Tue, 28 Mar 2017 07:59:25 -0400 [thread overview]
Message-ID: <DUkEbNKVK1611uZJHQLMjX4QQRzby0Sg5dlDxNIC9xN1Xp_3ujOAi5g4L6azht5tKDB1qpql6BokG-QJoixg_VYpVFXX3HTa6fwTV3orFeI=@protonmail.com> (raw)
In-Reply-To: <721338e4-fad3-e33c-2a77-59107fbe1ff2@cs.ucla.edu>
[-- Attachment #1.1: Type: text/plain, Size: 1350 bytes --]
>I remember concluding that I was glad I didn't have to write code to support the '
>flag, as it would require messing with the LC_NUMERIC locale setting (currently
>hardwired to "C" for other good reasons) and would make for some work redoing
>carefully-calculated output buffer sizes internal to 'format', not to mention
>the character set conversion that would be required.
The way I've proposed should obviate those problems. Since the variables governing the behavior are set by the user, LC_NUMERIC need not be consulted. If it is deemed necessary a function like set-locale-dependent-vars could be created to set these (and potentially other) variables, and the user could put it in their init if they so choose.
>For what it's worth, the Common Lisp approach cannot handle the Indian numbering
>system, which has a comma every two digits except that the last grouping
>contains three digits (e.g., "12,34,56,789").
The literal CL approach can't handle it, but it can be adapted to do so. The attached patch makes it so the format-digit-grouping variable can be a list. The first element of the list controls the grouping size of the least significant figures etc. until the last element controls all remaining groups. Using your example:
(let ((format-digit-grouping '(3 2)))
(format "%'d" 123456789)) => "12,34,56,789"
-- Graham Dobbins
[-- Attachment #1.2: Type: text/html, Size: 1823 bytes --]
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-src-editfns.c-styled_format-Add-d-format-specifier.patch --]
[-- Type: text/x-patch; name="0001-src-editfns.c-styled_format-Add-d-format-specifier.patch", Size: 4933 bytes --]
From b4a7b52f3044ebc51b4529cfcd46682815f69545 Mon Sep 17 00:00:00 2001
From: Graham Dobbins <gdobbins@protonmail.com>
Date: Tue, 28 Mar 2017 07:48:58 -0400
Subject: [PATCH] * src/editfns.c (styled_format): Add %'d format specifier
---
etc/NEWS | 5 +++++
src/editfns.c | 67 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
2 files changed, 70 insertions(+), 2 deletions(-)
diff --git a/etc/NEWS b/etc/NEWS
index cd98f53399..da593b81d8 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -1055,6 +1055,11 @@ its window gets deleted by 'delete-other-windows'.
*** New command 'window-swap-states' swaps the states of two live
windows.
+---
+*** 'format' now accepts the specifier "%'d" to format integers into
+groups of size 'format-digit-grouping' with separator
+'format-digit-separator' which default to 3 and comma respectively.
+
\f
* Changes in Emacs 26.1 on Non-Free Operating Systems
diff --git a/src/editfns.c b/src/editfns.c
index 65c0c721d1..b6e8c489c0 100644
--- a/src/editfns.c
+++ b/src/editfns.c
@@ -3884,7 +3884,7 @@ specifiers, as follows:
%<flags><width><precision>character
-where flags is [+ #-0]+, width is [0-9]+, and precision is a literal
+where flags is [+ #-0\\=']+, width is [0-9]+, and precision is a literal
period "." followed by [0-9]+
The + flag character inserts a + before any positive number, while a
@@ -3900,6 +3900,10 @@ the precision is zero; for %g, it causes a decimal point to be
included even if the the precision is zero, and also forces trailing
zeros after the decimal point to be left in place.
+The \\=' flag is ignored for all arguments except %d. If the argument
+is an integer it is printed in groupings whose size is dictated by
+`format-digit-grouping' and are separated by `format-digit-separator'.
+
The width specifier supplies a lower limit for the length of the
printed representation. The padding, if any, normally goes on the
left, but it goes on the right if the - flag is present. The padding
@@ -4059,6 +4063,7 @@ styled_format (ptrdiff_t nargs, Lisp_Object *args, bool message)
bool space_flag = false;
bool sharp_flag = false;
bool zero_flag = false;
+ bool apos_flag = false;
for (; ; format++)
{
@@ -4069,6 +4074,7 @@ styled_format (ptrdiff_t nargs, Lisp_Object *args, bool message)
case ' ': space_flag = true; continue;
case '#': sharp_flag = true; continue;
case '0': zero_flag = true; continue;
+ case '\'': apos_flag = true; continue;
}
break;
}
@@ -4381,6 +4387,49 @@ styled_format (ptrdiff_t nargs, Lisp_Object *args, bool message)
}
}
sprintf_bytes = sprintf (sprintf_buf, convspec, prec, x);
+
+ if (apos_flag && INTEGERP (args[n]))
+ {
+ Lisp_Object real_grouping = Vformat_digit_grouping;
+ EMACS_INT grouping;
+ if (CONSP (real_grouping))
+ {
+ CHECK_RANGED_INTEGER (XCAR (real_grouping), \
+ 1, MOST_POSITIVE_FIXNUM);
+ grouping = XINT (XCAR (real_grouping));
+ }
+ else
+ {
+ CHECK_RANGED_INTEGER (real_grouping, \
+ 1, MOST_POSITIVE_FIXNUM);
+ grouping = XINT (real_grouping);
+ }
+
+ CHECK_CHARACTER (Vformat_digit_separator);
+
+ char last_char;
+ char temp_char;
+ for (ptrdiff_t i = sprintf_bytes - grouping; \
+ i > 0; i -= grouping)
+ {
+ last_char = XFASTINT (Vformat_digit_separator);
+ for (ptrdiff_t j = i; j <= sprintf_bytes; j++)
+ {
+ temp_char = sprintf_buf[j];
+ sprintf_buf[j] = last_char;
+ last_char = temp_char;
+ }
+ sprintf_bytes++;
+ if (CONSP (real_grouping) \
+ && !NILP (XCDR (real_grouping)))
+ {
+ real_grouping = XCDR (real_grouping);
+ CHECK_RANGED_INTEGER (XCAR (real_grouping), \
+ 1, MOST_POSITIVE_FIXNUM);
+ grouping = XINT (XCAR (real_grouping));
+ }
+ }
+ }
}
else
{
@@ -5171,7 +5220,21 @@ functions if all the text being accessed has this property. */);
DEFVAR_LISP ("operating-system-release", Voperating_system_release,
doc: /* The release of the operating system Emacs is running on. */);
- defsubr (&Spropertize);
+ DEFVAR_LISP ("format-digit-grouping",
+ Vformat_digit_grouping,
+ doc: /* Number of digits in each group of a formatted
+number in `format'. If a list, the first number applies to the least
+significant grouping and so on, with the last number applying to all
+remaining groupings. */);
+ Vformat_digit_grouping = make_number (3);
+
+ DEFVAR_LISP ("format-digit-separator",
+ Vformat_digit_separator,
+ doc: /* Character to use as grouping separator for
+formatted numbers in `format'. */);
+ Vformat_digit_separator = make_number (',');
+
+ defsubr (&Spropertize);
defsubr (&Schar_equal);
defsubr (&Sgoto_char);
defsubr (&Sstring_to_char);
--
2.12.1
next prev parent reply other threads:[~2017-03-28 11:59 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-03-28 3:06 RFC: locale-sensitive Emacs functions Ted Zlatanov
2017-03-28 4:10 ` Gdobbins
2017-03-28 4:37 ` Paul Eggert
2017-03-28 11:59 ` Gdobbins [this message]
2017-03-28 12:45 ` Ted Zlatanov
2017-03-30 18:27 ` Ted Zlatanov
2017-03-31 4:27 ` Gdobbins
2017-03-31 17:59 ` Davis Herring
2017-03-28 19:37 ` Paul Eggert
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://www.gnu.org/software/emacs/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to='DUkEbNKVK1611uZJHQLMjX4QQRzby0Sg5dlDxNIC9xN1Xp_3ujOAi5g4L6azht5tKDB1qpql6BokG-QJoixg_VYpVFXX3HTa6fwTV3orFeI=@protonmail.com' \
--to=gdobbins@protonmail.com \
--cc=eggert@cs.ucla.edu \
--cc=emacs-devel@gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://git.savannah.gnu.org/cgit/emacs.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).