aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBasil L. Contovounesios2020-05-28 00:53:42 +0100
committerBasil L. Contovounesios2020-06-02 14:58:25 +0100
commitb07e3b1d97e73c5cf0cd60edf4838b555530bbf0 (patch)
tree6d0265225716fe97e25a2483e763236cce842238
parent0260d2d2dbb2607e7310bdb518b7b6c0f58f5f98 (diff)
downloademacs-b07e3b1d97e73c5cf0cd60edf4838b555530bbf0.tar.gz
emacs-b07e3b1d97e73c5cf0cd60edf4838b555530bbf0.zip
Improve format-spec documentation (bug#41571)
* doc/lispref/text.texi (Interpolated Strings): Move from here... * doc/lispref/strings.texi (Custom Format Strings): ...to here, renaming the node and clarifying the documentation. (Formatting Strings): End node with sentence referring to the next one. * lisp/format-spec.el (format-spec): Clarify docstring.
-rw-r--r--doc/lispref/strings.texi176
-rw-r--r--doc/lispref/text.texi64
-rw-r--r--lisp/format-spec.el49
3 files changed, 206 insertions, 83 deletions
diff --git a/doc/lispref/strings.texi b/doc/lispref/strings.texi
index 70c3b3cf4be..4a7bda57c4e 100644
--- a/doc/lispref/strings.texi
+++ b/doc/lispref/strings.texi
@@ -28,6 +28,7 @@ keyboard character events.
28* Text Comparison:: Comparing characters or strings. 28* Text Comparison:: Comparing characters or strings.
29* String Conversion:: Converting to and from characters and strings. 29* String Conversion:: Converting to and from characters and strings.
30* Formatting Strings:: @code{format}: Emacs's analogue of @code{printf}. 30* Formatting Strings:: @code{format}: Emacs's analogue of @code{printf}.
31* Custom Format Strings:: Formatting custom @code{format} specifications.
31* Case Conversion:: Case conversion functions. 32* Case Conversion:: Case conversion functions.
32* Case Tables:: Customizing case conversion. 33* Case Tables:: Customizing case conversion.
33@end menu 34@end menu
@@ -1122,6 +1123,181 @@ may be problematic; for example, @samp{%d} and @samp{%g} can mishandle
1122NaNs and can lose precision and type, and @samp{#x%x} and @samp{#o%o} 1123NaNs and can lose precision and type, and @samp{#x%x} and @samp{#o%o}
1123can mishandle negative integers. @xref{Input Functions}. 1124can mishandle negative integers. @xref{Input Functions}.
1124 1125
1126The functions described in this section accept a fixed set of
1127specification characters. The next section describes a function
1128@code{format-spec} which can accept custom specification characters,
1129such as @samp{%a} or @samp{%z}.
1130
1131@node Custom Format Strings
1132@section Custom Format Strings
1133@cindex custom format string
1134@cindex custom @samp{%}-sequence in format
1135
1136Sometimes it is useful to allow users and Lisp programs alike to
1137control how certain text is generated via custom format control
1138strings. For example, a format string could control how to display
1139someone's forename, surname, and email address. Using the function
1140@code{format} described in the previous section, the format string
1141could be something like @w{@code{"%s %s <%s>"}}. This approach
1142quickly becomes impractical, however, as it can be unclear which
1143specification character corresponds to which piece of information.
1144
1145A more convenient format string for such cases would be something like
1146@w{@code{"%f %l <%e>"}}, where each specification character carries
1147more semantic information and can easily be rearranged relative to
1148other specification characters, making such format strings more easily
1149customizable by the user.
1150
1151The function @code{format-spec} described in this section performs a
1152similar function to @code{format}, except it operates on format
1153control strings that use arbitrary specification characters.
1154
1155@defun format-spec template spec-alist &optional only-present
1156This function returns a string produced from the format string
1157@var{template} according to conversions specified in @var{spec-alist},
1158which is an alist (@pxref{Association Lists}) of the form
1159@w{@code{(@var{letter} . @var{replacement})}}. Each specification
1160@code{%@var{letter}} in @var{template} will be replaced by
1161@var{replacement} when formatting the resulting string.
1162
1163The characters in @var{template}, other than the format
1164specifications, are copied directly into the output, including their
1165text properties, if any. Any text properties of the format
1166specifications are copied to their replacements.
1167
1168Using an alist to specify conversions gives rise to some useful
1169properties:
1170
1171@itemize @bullet
1172@item
1173If @var{spec-alist} contains more unique @var{letter} keys than there
1174are unique specification characters in @var{template}, the unused keys
1175are simply ignored.
1176@item
1177If @var{spec-alist} contains more than one association with the same
1178@var{letter}, the closest one to the start of the list is used.
1179@item
1180If @var{template} contains the same specification character more than
1181once, then the same @var{replacement} found in @var{spec-alist} is
1182used as a basis for all of that character's substitutions.
1183@item
1184The order of specifications in @var{template} need not correspond to
1185the order of associations in @var{spec-alist}.
1186@end itemize
1187
1188The optional argument @var{only-present} indicates how to handle
1189specification characters in @var{template} that are not found in
1190@var{spec-alist}. If it is @code{nil} or omitted, the function
1191signals an error. Otherwise, those format specifications and any
1192occurrences of @samp{%%} in @var{template} are left verbatim in the
1193output, including their text properties, if any.
1194@end defun
1195
1196The syntax of format specifications accepted by @code{format-spec} is
1197similar, but not identical, to that accepted by @code{format}. In
1198both cases, a format specification is a sequence of characters
1199beginning with @samp{%} and ending with an alphabetic letter such as
1200@samp{s}.
1201
1202Unlike @code{format}, which assigns specific meanings to a fixed set
1203of specification characters, @code{format-spec} accepts arbitrary
1204specification characters and treats them all equally. For example:
1205
1206@example
1207@group
1208(setq my-site-info
1209 (list (cons ?s system-name)
1210 (cons ?t (symbol-name system-type))
1211 (cons ?c system-configuration)
1212 (cons ?v emacs-version)
1213 (cons ?e invocation-name)
1214 (cons ?p (number-to-string (emacs-pid)))
1215 (cons ?a user-mail-address)
1216 (cons ?n user-full-name)))
1217
1218(format-spec "%e %v (%c)" my-site-info)
1219 @result{} "emacs 27.1 (x86_64-pc-linux-gnu)"
1220
1221(format-spec "%n <%a>" my-site-info)
1222 @result{} "Emacs Developers <emacs-devel@@gnu.org>"
1223@end group
1224@end example
1225
1226A format specification can include any number of the following flag
1227characters immediately after the @samp{%} to modify aspects of the
1228substitution.
1229
1230@table @samp
1231@item 0
1232This flag causes any padding specified by the width to consist of
1233@samp{0} characters instead of spaces.
1234
1235@item -
1236This flag causes any padding specified by the width to be inserted on
1237the right rather than the left.
1238
1239@item <
1240This flag causes the substitution to be truncated on the left to the
1241given width, if specified.
1242
1243@item >
1244This flag causes the substitution to be truncated on the right to the
1245given width, if specified.
1246
1247@item ^
1248This flag converts the substituted text to upper case (@pxref{Case
1249Conversion}).
1250
1251@item _
1252This flag converts the substituted text to lower case (@pxref{Case
1253Conversion}).
1254@end table
1255
1256The result of using contradictory flags (for instance, both upper and
1257lower case) is undefined.
1258
1259As is the case with @code{format}, a format specification can include
1260a width, which is a decimal number that appears after any flags. If a
1261substitution contains fewer characters than its specified width, it is
1262padded on the left:
1263
1264@example
1265@group
1266(format-spec "%8a is padded on the left with spaces"
1267 '((?a . "alpha")))
1268 @result{} " alpha is padded on the left with spaces"
1269@end group
1270@end example
1271
1272Here is a more complicated example that combines several
1273aforementioned features:
1274
1275@example
1276@group
1277(setq my-battery-info
1278 (list (cons ?p "73") ; Percentage
1279 (cons ?L "Battery") ; Status
1280 (cons ?t "2:23") ; Remaining time
1281 (cons ?c "24330") ; Capacity
1282 (cons ?r "10.6"))) ; Rate of discharge
1283
1284(format-spec "%>^-3L : %3p%% (%05t left)" my-battery-info)
1285 @result{} "BAT : 73% (02:23 left)"
1286
1287(format-spec "%>^-3L : %3p%% (%05t left)"
1288 (cons (cons ?L "AC")
1289 my-battery-info))
1290 @result{} "AC : 73% (02:23 left)"
1291@end group
1292@end example
1293
1294As the examples in this section illustrate, @code{format-spec} is
1295often used for selectively formatting an assortment of different
1296pieces of information. This is useful in programs that provide
1297user-customizable format strings, as the user can choose to format
1298with a regular syntax and in any desired order only a subset of the
1299information that the program makes available.
1300
1125@node Case Conversion 1301@node Case Conversion
1126@section Case Conversion in Lisp 1302@section Case Conversion in Lisp
1127@cindex upper case 1303@cindex upper case
diff --git a/doc/lispref/text.texi b/doc/lispref/text.texi
index de436fa9e61..a14867e1d1a 100644
--- a/doc/lispref/text.texi
+++ b/doc/lispref/text.texi
@@ -58,7 +58,6 @@ the character after point.
58 of another buffer. 58 of another buffer.
59* Decompression:: Dealing with compressed data. 59* Decompression:: Dealing with compressed data.
60* Base 64:: Conversion to or from base 64 encoding. 60* Base 64:: Conversion to or from base 64 encoding.
61* Interpolated Strings:: Formatting Customizable Strings.
62* Checksum/Hash:: Computing cryptographic hashes. 61* Checksum/Hash:: Computing cryptographic hashes.
63* GnuTLS Cryptography:: Cryptographic algorithms imported from GnuTLS. 62* GnuTLS Cryptography:: Cryptographic algorithms imported from GnuTLS.
64* Parsing HTML/XML:: Parsing HTML and XML. 63* Parsing HTML/XML:: Parsing HTML and XML.
@@ -4662,69 +4661,6 @@ If optional argument @var{base64url} is non-@code{nil}, then padding
4662is optional, and the URL variant of base 64 encoding is used. 4661is optional, and the URL variant of base 64 encoding is used.
4663@end defun 4662@end defun
4664 4663
4665
4666@node Interpolated Strings
4667@section Formatting Customizable Strings
4668
4669It is, in some circumstances, useful to present users with a string to
4670be customized that can then be expanded programmatically. For
4671instance, @code{erc-header-line-format} is @code{"%n on %t (%m,%l)
4672%o"}, and each of those characters after the percent signs are
4673expanded when the header line is computed. To do this, the
4674@code{format-spec} function is used:
4675
4676@defun format-spec format specification &optional only-present
4677@var{format} is the format specification string as in the example
4678above. @var{specification} is an alist that has elements where the
4679@code{car} is a character and the @code{cdr} is the substitution.
4680
4681If @var{only-present} is @code{nil}, errors will be signaled if a
4682format character has been used that's not present in
4683@var{specification}. If it's non-@code{nil}, that format
4684specification is left verbatim in the result.
4685@end defun
4686
4687Here's a trivial example:
4688
4689@example
4690(format-spec "su - %u %l"
4691 `((?u . ,(user-login-name))
4692 (?l . "ls")))
4693 @result{} "su - foo ls"
4694@end example
4695
4696In addition to allowing padding/limiting to a certain length, the
4697following modifiers can be used:
4698
4699@table @asis
4700@item @samp{0}
4701Pad with zeros instead of the default spaces.
4702
4703@item @samp{-}
4704Pad to the right.
4705
4706@item @samp{^}
4707Use upper case.
4708
4709@item @samp{_}
4710Use lower case.
4711
4712@item @samp{<}
4713If the length needs to be limited, remove characters from the left.
4714
4715@item @samp{>}
4716Same as previous, but remove characters from the right.
4717@end table
4718
4719If contradictory modifiers are used (for instance, both upper and
4720lower case), then what happens is undefined.
4721
4722As an example, @samp{"%<010b"} means ``insert the @samp{b} expansion,
4723but pad with leading zeros if it's less than ten characters, and if
4724it's more than ten characters, shorten by removing characters from the
4725left.''
4726
4727
4728@node Checksum/Hash 4664@node Checksum/Hash
4729@section Checksum/Hash 4665@section Checksum/Hash
4730@cindex MD5 checksum 4666@cindex MD5 checksum
diff --git a/lisp/format-spec.el b/lisp/format-spec.el
index f418cea4259..9278bd74c42 100644
--- a/lisp/format-spec.el
+++ b/lisp/format-spec.el
@@ -29,35 +29,46 @@
29 29
30(defun format-spec (format specification &optional only-present) 30(defun format-spec (format specification &optional only-present)
31 "Return a string based on FORMAT and SPECIFICATION. 31 "Return a string based on FORMAT and SPECIFICATION.
32FORMAT is a string containing `format'-like specs like \"su - %u %k\", 32FORMAT is a string containing `format'-like specs like \"su - %u %k\".
33while SPECIFICATION is an alist mapping from format spec characters 33SPECIFICATION is an alist mapping format specification characters
34to values. 34to their substitutions.
35 35
36For instance: 36For instance:
37 37
38 (format-spec \"su - %u %l\" 38 (format-spec \"su - %u %l\"
39 `((?u . ,(user-login-name)) 39 \\=`((?u . ,(user-login-name))
40 (?l . \"ls\"))) 40 (?l . \"ls\")))
41 41
42Each format spec can have modifiers, where \"%<010b\" means \"if 42Each %-spec may contain optional flag and width modifiers, as
43the expansion is shorter than ten characters, zero-pad it, and if 43follows:
44it's longer, chop off characters from the left side\".
45 44
46The following modifiers are allowed: 45 %<flags><width>character
47 46
48* 0: Use zero-padding. 47The following flags are allowed:
49* -: Pad to the right.
50* ^: Upper-case the expansion.
51* _: Lower-case the expansion.
52* <: Limit the length by removing chars from the left.
53* >: Limit the length by removing chars from the right.
54 48
55Any text properties on a %-spec itself are propagated to the text 49* 0: Pad to the width, if given, with zeros instead of spaces.
56that it generates. 50* -: Pad to the width, if given, on the right instead of the left.
51* <: Truncate to the width, if given, on the left.
52* >: Truncate to the width, if given, on the right.
53* ^: Convert to upper case.
54* _: Convert to lower case.
57 55
58If ONLY-PRESENT, format spec characters not present in 56The width modifier behaves like the corresponding one in `format'
59SPECIFICATION are ignored, and the \"%\" characters are left 57when applied to %s.
60where they are, including \"%%\" strings." 58
59For example, \"%<010b\" means \"substitute into the output the
60value associated with ?b in SPECIFICATION, either padding it with
61leading zeros or truncating leading characters until it's ten
62characters wide\".
63
64Any text properties of FORMAT are copied to the result, with any
65text properties of a %-spec itself copied to its substitution.
66
67ONLY-PRESENT indicates how to handle %-spec characters not
68present in SPECIFICATION. If it is nil or omitted, emit an
69error; otherwise leave those %-specs and any occurrences of
70\"%%\" in FORMAT verbatim in the result, including their text
71properties, if any."
61 (with-temp-buffer 72 (with-temp-buffer
62 (insert format) 73 (insert format)
63 (goto-char (point-min)) 74 (goto-char (point-min))