commit 0b7ce40809549aed643165fbb31dcdaa198454c0 Author: G. Branden Robinson Date: Thu Jul 4 01:07:38 2019 +1000 Implement .stringdown and .stringup requests. * src/roff/troff/input.cpp: Add .stringdown and .stringup requests. * doc/groff.texi: Document them, including example. * man/groff_diff.7.man: Document them. * man/groff.7.man: Document them briefly. diff --git a/ChangeLog b/ChangeLog index d44bb276..ca6d65d4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2019-07-04 G. Branden Robinson + + Implement .stringdown and .stringup requests. + + * src/roff/troff/input.cpp: Add .stringdown and .stringup + requests. + * doc/groff.texi: Document them, including example. + * man/groff_diff.7.man: Document them. + * man/groff.7.man: Document them briefly. + 2019-06-28 G. Branden Robinson devlatin1: Map \(oq to ' on output. diff --git a/NEWS b/NEWS index 636804e0..340c0c1a 100644 --- a/NEWS +++ b/NEWS @@ -12,6 +12,13 @@ VERSION 1.22.5 Troff ----- +o New requests 'stringdown' and 'stringup' are implemented. These transform + each letter in their string register argument to the desired case. For + best results, use only the basic Latin alphabet ([A-Za-z]) in your string + values; groff special characters (see the groff_char man page) can be used + and the output will usually transform in the expected way due to the + regular naming convention of the special character escapes. + o On the Latin-1 output device ("groff -T latin1") the output glyph \[oq] (opening quote) is now rendered as code point 0x27 (apostrophe) instead of 0x60 (grave accent). The ECMA-94 Latin character sets do not define any diff --git a/doc/groff.texi b/doc/groff.texi index bcc47cf5..f19b872f 100644 --- a/doc/groff.texi +++ b/doc/groff.texi @@ -10590,6 +10590,31 @@ number register @var{reg}. If @var{reg} doesn't exist, it is created. Rename the request, macro, diversion, or string @var{xx} to @var{yy}. @endDefreq +@DefreqList {stringdown, str} +@DefreqListEndx {stringup, str} +@cindex case-transforming a string (@code{stringdown}, @code{stringup}) +@cindex uppercasing a string (@code{stringup}) +@cindex lowercasing a string (@code{stringdown}) +@cindex up-casing a string (@code{stringup}) +@cindex down-casing a string (@code{stringdown}) +Transform each letter in @var{str} to to lowercase (@code{stringdown}) +or uppercase (@code{stringup}). For best results, use only the basic +Latin alphabet (@code{[A-Za-z]}) in your string values; @code{groff} +special characters (see the @cite{groff_char(7)} man page) can be used +and the output will usually transform in the expected way due to the +regular naming convention of the special character escapes. + +@Example +.ds resume R\['e]sum\['e]\" +\*[resume] +.stringdown resume +\*[resume] +.stringup resume +\*[resume] + @result{} Résumé résumé RÉSUMÉ +@endExample +@endDefreq + @Defreq {rm, xx} @cindex removing request (@code{rm}) @cindex request, removing (@code{rm}) diff --git a/man/groff.7.man b/man/groff.7.man index 24f093fe..f0e02b6c 100644 --- a/man/groff.7.man +++ b/man/groff.7.man @@ -2384,6 +2384,18 @@ and sentence space size set to of the space width in the current font. . .TPx +.REQ .stringdown "stringvar" +Transform each letter in\~\c +.I stringvar +to its lowercase version. +. +.TPx +.REQ .stringup "stringvar" +Transform each letter in\~\c +.I stringvar +to its uppercase version. +. +.TPx .REQ .sty "n style" Associate .I style diff --git a/man/groff_diff.7.man b/man/groff_diff.7.man index ef31a028..bc692df7 100644 --- a/man/groff_diff.7.man +++ b/man/groff_diff.7.man @@ -2168,6 +2168,27 @@ This request is active only if text is justified to both margins (using .BR .ad\ b ). . .TP +.BI .stringdown \~stringvar +.TQ +.BI .stringup \~stringvar +Transform each letter in\~\c +.I stringvar +to lowercase +.RB ( down ) +or uppercase +.RB ( up ). +. +For best results, +use only the basic Latin alphabet (\[lq][A-Za-z]\[rq]) in your string +values; +.I groff +special characters +(see +.IR groff_char (@MAN7EXT@)) +can be used and the output will usually transform in the expected way +due to the regular naming convention of the special character escapes. +. +.TP .BI .sty\ n\ f Associate style\~\c .I f diff --git a/src/roff/troff/input.cpp b/src/roff/troff/input.cpp index a1bd8eaf..e01308b9 100644 --- a/src/roff/troff/input.cpp +++ b/src/roff/troff/input.cpp @@ -4717,6 +4717,59 @@ void chop_macro() skip_line(); } +enum case_xform_mode { STRING_UPCASE, STRING_DOWNCASE }; + +// Case-transform each character of the string argument. +void do_string_case_transform(case_xform_mode mode) +{ + if ((mode != STRING_DOWNCASE) && (mode != STRING_UPCASE)) { + error("impossible string case transformation mode %1!", mode); + return; + } + symbol s = get_name(1); + if (s.is_null()) { + skip_line(); + return; + } + request_or_macro *p = lookup_request(s); + macro *m = p->to_macro(); + if (!m) { + error("cannot apply string case transformation to a request ('%1')", + s.contents()); + skip_line(); + return; + } + string_iterator iter1(*m); + macro *mac = new macro; + for (int l = 0; l < m->macro::length(); l++) { + int nc, c = iter1.get(0); + if (c == PUSH_GROFF_MODE + || c == PUSH_COMP_MODE + || c == POP_GROFFCOMP_MODE) + nc = c; + else if (c == EOF) + break; + else + if (mode == STRING_DOWNCASE) + nc = tolower(c); + else + nc = toupper(c); + mac->append(nc); + } + request_dictionary.define(s, mac); + tok.next(); +} + +// Uppercase-transform each character of the string argument. +void stringdown_request() { + do_string_case_transform(STRING_DOWNCASE); +} + +// Lowercase-transform each character of the string argument. +void stringup_request() { + do_string_case_transform(STRING_UPCASE); +} + void substring_request() { int start; // 0, 1, ..., n-1 or -1, -2, ... @@ -8213,6 +8266,8 @@ void init_input_requests() init_request("shift", shift); init_request("so", source); init_request("spreadwarn", spreadwarn_request); + init_request("stringdown", stringdown_request); + init_request("stringup", stringup_request); init_request("substring", substring_request); init_request("sy", system_request); init_request("tag", tag); commit 46a237cd04b454a134832788992147028c035680 Author: G. Branden Robinson Date: Thu Jul 4 00:12:39 2019 +1000 Regression-test string case transform feature. * src/roff/groff/tests/string_case_xform_errors.sh: New test. * src/roff/groff/tests/string_case_xform_requests.sh: New test. * src/roff/groff/groff.am: Run the tests. diff --git a/src/roff/groff/groff.am b/src/roff/groff/groff.am index b2b30557..954c52f8 100644 --- a/src/roff/groff/groff.am +++ b/src/roff/groff/groff.am @@ -42,7 +42,9 @@ groffopts_DATA = $(GROFF_OPTS_OUTPUT) groff_TESTS = \ src/roff/groff/tests/regression-56555.sh \ - src/roff/groff/tests/on-latin1-device-oq-is-0x27.sh + src/roff/groff/tests/on-latin1-device-oq-is-0x27.sh \ + src/roff/groff/tests/string_case_xform_requests.sh \ + src/roff/groff/tests/string_case_xform_errors.sh TESTS += $(groff_TESTS) MOSTLYCLEANFILES += groff_opts.tmp $(GROFF_OPTS_OUTPUT) diff --git a/src/roff/groff/tests/string_case_xform_errors.sh b/src/roff/groff/tests/string_case_xform_errors.sh new file mode 100755 index 00000000..f65d9dce --- /dev/null +++ b/src/roff/groff/tests/string_case_xform_errors.sh @@ -0,0 +1,31 @@ +#!/usr/bin/env bash +# +# Copyright (C) 2019 Free Software Foundation, Inc. +# +# This file is part of groff. +# +# groff is free software; you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free +# Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# groff is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# + +groff="${abs_top_builddir:-.}/test-groff" + +expected="troff: :1: cannot apply string case transformation to a request ('br')" + +actual=$("$groff" -Tutf8 2>&1 <. +# + +groff="${abs_top_builddir:-.}/test-groff" + +expected="Résumé résumé RÉSUMÉ" + +actual=$("$groff" -Tutf8 <