diff options
| author | Paul Eggert | 2015-06-19 00:35:43 -0700 |
|---|---|---|
| committer | Paul Eggert | 2015-06-19 00:38:45 -0700 |
| commit | c4151ebe15479de4c2e511b068cdf9af6a4576cf (patch) | |
| tree | 14933519830d5da23b6962cdaff705081eb85313 /src/doc.c | |
| parent | aad7ea32c57c7b9673a8d429524e050dac2d210c (diff) | |
| download | emacs-c4151ebe15479de4c2e511b068cdf9af6a4576cf.tar.gz emacs-c4151ebe15479de4c2e511b068cdf9af6a4576cf.zip | |
Improve the optional translation of quotes
Fix several problems with the recently-added custom variable
help-quote-translation where the code would quote inconsistently
in help buffers. Add support for quoting 'like this', which
is common in other GNU programs in ASCII environments. Change
help-quote-translation to use more mnemonic values: values are now the
initial quoting char, e.g., (setq help-quote-translation ?`) gets the
traditional Emacs help-buffer quoting style `like this'. Change the
default behavior of substitute-command-keys to match what's done in
set-locale-environment, i.e., quote ‘like this’ if displayable,
'like this' otherwise.
* doc/lispref/help.texi (Keys in Documentation): Document
new behavior of substitute-command-keys, and document
help-quote-translation.
* doc/lispref/tips.texi (Documentation Tips):
Mention the effect of help-quote-translation.
* etc/NEWS: Mention new behavior of substitute-command-keys,
and merge help-quote-translation news into it.
When talking about doc strings, mention new ways to type quotes.
* lisp/cedet/mode-local.el (overload-docstring-extension):
Revert my recent change to this function, which shouldn't be
needed as the result is a doc string.
* lisp/cedet/mode-local.el (mode-local-print-binding)
(mode-local-describe-bindings-2):
* lisp/cedet/srecode/srt-mode.el (srecode-macro-help):
* lisp/cus-theme.el (describe-theme-1):
* lisp/descr-text.el (describe-text-properties-1, describe-char):
* lisp/emacs-lisp/cl-generic.el (cl--generic-describe):
* lisp/emacs-lisp/eieio-opt.el (eieio-help-class)
(eieio-help-constructor):
* lisp/emacs-lisp/package.el (describe-package-1):
* lisp/faces.el (describe-face):
* lisp/help-fns.el (help-fns--key-bindings)
(help-fns--compiler-macro, help-fns--parent-mode)
(help-fns--obsolete, help-fns--interactive-only)
(describe-function-1, describe-variable):
* lisp/help.el (describe-mode):
Use substitute-command-keys to ensure a more-consistent quoting
style in help buffers.
* lisp/cus-start.el (standard):
Document new help-quote-translation behavior.
* lisp/emacs-lisp/lisp-mode.el (lisp-fdefs):
* lisp/help-mode.el (help-xref-symbol-regexp, help-xref-info-regexp)
(help-xref-url-regexp):
* lisp/international/mule-cmds.el (help-xref-mule-regexp-template):
* lisp/wid-edit.el (widget-documentation-link-regexp):
Also match 'foo', in case we're in a help buffer generated when
help-quote-translation is ?'.
* src/doc.c: Include disptab.h, for DISP_CHAR_VECTOR.
(LEFT_SINGLE_QUOTATION_MARK, uLSQM0, uLSQM1, uLSQM2, uRSQM0)
(uRSQM1, uRSQM2, LSQM, RSQM): New constants.
(Fsubstitute_command_keys): Document and implement new behavior.
(Vhelp_quote_translation): Document new behavior.
Diffstat (limited to 'src/doc.c')
| -rw-r--r-- | src/doc.c | 89 |
1 files changed, 59 insertions, 30 deletions
| @@ -32,6 +32,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 32 | #include "lisp.h" | 32 | #include "lisp.h" |
| 33 | #include "character.h" | 33 | #include "character.h" |
| 34 | #include "buffer.h" | 34 | #include "buffer.h" |
| 35 | #include "disptab.h" | ||
| 35 | #include "keyboard.h" | 36 | #include "keyboard.h" |
| 36 | #include "keymap.h" | 37 | #include "keymap.h" |
| 37 | 38 | ||
| @@ -683,6 +684,18 @@ the same file name is found in the `doc-directory'. */) | |||
| 683 | return unbind_to (count, Qnil); | 684 | return unbind_to (count, Qnil); |
| 684 | } | 685 | } |
| 685 | 686 | ||
| 687 | /* Declare named constants for U+2018 LEFT SINGLE QUOTATION MARK and | ||
| 688 | U+2019 RIGHT SINGLE QUOTATION MARK, which have UTF-8 encodings | ||
| 689 | "\xE2\x80\x98" and "\xE2\x80\x99", respectively. */ | ||
| 690 | enum | ||
| 691 | { | ||
| 692 | LEFT_SINGLE_QUOTATION_MARK = 0x2018, | ||
| 693 | uLSQM0 = 0xE2, uLSQM1 = 0x80, uLSQM2 = 0x98, | ||
| 694 | uRSQM0 = 0xE2, uRSQM1 = 0x80, uRSQM2 = 0x99, | ||
| 695 | }; | ||
| 696 | static unsigned char const LSQM[] = { uLSQM0, uLSQM1, uLSQM2 }; | ||
| 697 | static unsigned char const RSQM[] = { uRSQM0, uRSQM1, uRSQM2 }; | ||
| 698 | |||
| 686 | DEFUN ("substitute-command-keys", Fsubstitute_command_keys, | 699 | DEFUN ("substitute-command-keys", Fsubstitute_command_keys, |
| 687 | Ssubstitute_command_keys, 1, 1, 0, | 700 | Ssubstitute_command_keys, 1, 1, 0, |
| 688 | doc: /* Substitute key descriptions for command names in STRING. | 701 | doc: /* Substitute key descriptions for command names in STRING. |
| @@ -699,8 +712,10 @@ summary). | |||
| 699 | Each substring of the form \\=\\<MAPVAR> specifies the use of MAPVAR | 712 | Each substring of the form \\=\\<MAPVAR> specifies the use of MAPVAR |
| 700 | as the keymap for future \\=\\[COMMAND] substrings. | 713 | as the keymap for future \\=\\[COMMAND] substrings. |
| 701 | 714 | ||
| 702 | Each \\=` is replaced by ‘. Each ' preceded by \\=` and without | 715 | Each \\=‘ and \\=’ are replaced by left and right quote. Each \\=` is |
| 703 | intervening ' is replaced by ’. | 716 | replaced by left quote, and each ' preceded by \\=` and without |
| 717 | intervening ' is replaced by right quote. Left and right quote | ||
| 718 | characters are specified by ‘help-quote-translation’. | ||
| 704 | 719 | ||
| 705 | \\=\\= quotes the following character and is discarded; thus, | 720 | \\=\\= quotes the following character and is discarded; thus, |
| 706 | \\=\\=\\=\\= puts \\=\\= into the output, \\=\\=\\=\\[ puts \\=\\[ into the output, and | 721 | \\=\\=\\=\\= puts \\=\\= into the output, \\=\\=\\=\\[ puts \\=\\[ into the output, and |
| @@ -719,7 +734,7 @@ Otherwise, return a new string. */) | |||
| 719 | ptrdiff_t bsize; | 734 | ptrdiff_t bsize; |
| 720 | Lisp_Object tem; | 735 | Lisp_Object tem; |
| 721 | Lisp_Object keymap; | 736 | Lisp_Object keymap; |
| 722 | unsigned char *start; | 737 | unsigned char const *start; |
| 723 | ptrdiff_t length, length_byte; | 738 | ptrdiff_t length, length_byte; |
| 724 | Lisp_Object name; | 739 | Lisp_Object name; |
| 725 | struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; | 740 | struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; |
| @@ -735,6 +750,21 @@ Otherwise, return a new string. */) | |||
| 735 | name = Qnil; | 750 | name = Qnil; |
| 736 | GCPRO4 (string, tem, keymap, name); | 751 | GCPRO4 (string, tem, keymap, name); |
| 737 | 752 | ||
| 753 | enum { unicode, grave_accent, apostrophe } quote_translation = unicode; | ||
| 754 | if (EQ (Vhelp_quote_translation, make_number ('`'))) | ||
| 755 | quote_translation = grave_accent; | ||
| 756 | else if (EQ (Vhelp_quote_translation, make_number ('\''))) | ||
| 757 | quote_translation = apostrophe; | ||
| 758 | else if (NILP (Vhelp_quote_translation) | ||
| 759 | && DISP_TABLE_P (Vstandard_display_table)) | ||
| 760 | { | ||
| 761 | Lisp_Object dv = DISP_CHAR_VECTOR (XCHAR_TABLE (Vstandard_display_table), | ||
| 762 | LEFT_SINGLE_QUOTATION_MARK); | ||
| 763 | if (VECTORP (dv) && ASIZE (dv) == 1 | ||
| 764 | && EQ (AREF (dv, 0), make_number ('\''))) | ||
| 765 | quote_translation = apostrophe; | ||
| 766 | } | ||
| 767 | |||
| 738 | multibyte = STRING_MULTIBYTE (string); | 768 | multibyte = STRING_MULTIBYTE (string); |
| 739 | nchars = 0; | 769 | nchars = 0; |
| 740 | 770 | ||
| @@ -932,38 +962,39 @@ Otherwise, return a new string. */) | |||
| 932 | strp = SDATA (string) + idx; | 962 | strp = SDATA (string) + idx; |
| 933 | } | 963 | } |
| 934 | } | 964 | } |
| 935 | else if (EQ (Vhelp_quote_translation, Qprefer_unicode) | 965 | else if (strp[0] == '`' && quote_translation == unicode) |
| 936 | && (strp[0] == '`')) | ||
| 937 | { | 966 | { |
| 938 | in_quote = true; | 967 | in_quote = true; |
| 939 | start = (unsigned char *) "\xE2\x80\x98"; /* ‘ */ | 968 | start = LSQM; |
| 940 | subst_quote: | 969 | subst_quote: |
| 941 | length = 1; | 970 | length = 1; |
| 942 | length_byte = 3; | 971 | length_byte = 3; |
| 943 | idx = strp - SDATA (string) + 1; | 972 | idx = strp - SDATA (string) + 1; |
| 944 | goto subst; | 973 | goto subst; |
| 945 | } | 974 | } |
| 946 | else if (EQ (Vhelp_quote_translation, Qprefer_unicode) | 975 | else if (strp[0] == '`' && quote_translation == apostrophe) |
| 947 | && (strp[0] == '\'' && in_quote)) | 976 | { |
| 977 | *bufp++ = '\''; | ||
| 978 | strp++; | ||
| 979 | nchars++; | ||
| 980 | changed = true; | ||
| 981 | } | ||
| 982 | else if (strp[0] == '\'' && in_quote) | ||
| 948 | { | 983 | { |
| 949 | in_quote = false; | 984 | in_quote = false; |
| 950 | start = (unsigned char *) "\xE2\x80\x99"; /* ’ */ | 985 | start = RSQM; |
| 951 | goto subst_quote; | 986 | goto subst_quote; |
| 952 | } | 987 | } |
| 953 | 988 | else if (strp[0] == uLSQM0 && strp[1] == uLSQM1 | |
| 954 | else if (EQ (Vhelp_quote_translation, Qtraditional) | 989 | && (strp[2] == uLSQM2 || strp[2] == uRSQM2) |
| 955 | && (strp[0] == 0xE2) | 990 | && quote_translation != unicode) |
| 956 | && (strp[1] == 0x80) | ||
| 957 | && ((strp[2] == 0x98) /* curly opening quote */ | ||
| 958 | || (strp[2] == 0x99))) /* curly closing quote */ | ||
| 959 | { | 991 | { |
| 960 | start = (strp[2] == 0x98) ? "`" : "'"; | 992 | *bufp++ = (strp[2] == uLSQM2 && quote_translation == grave_accent |
| 961 | length = 1; | 993 | ? '`' : '\''); |
| 962 | length_byte = 1; | 994 | strp += 3; |
| 963 | idx = strp - SDATA (string) + 3; | 995 | nchars++; |
| 964 | goto subst; | 996 | changed = true; |
| 965 | } | 997 | } |
| 966 | |||
| 967 | else if (! multibyte) /* just copy other chars */ | 998 | else if (! multibyte) /* just copy other chars */ |
| 968 | *bufp++ = *strp++, nchars++; | 999 | *bufp++ = *strp++, nchars++; |
| 969 | else | 1000 | else |
| @@ -1005,15 +1036,13 @@ syms_of_doc (void) | |||
| 1005 | Vbuild_files = Qnil; | 1036 | Vbuild_files = Qnil; |
| 1006 | 1037 | ||
| 1007 | DEFVAR_LISP ("help-quote-translation", Vhelp_quote_translation, | 1038 | DEFVAR_LISP ("help-quote-translation", Vhelp_quote_translation, |
| 1008 | doc: /* How to translate quotes for display in *Help*. | 1039 | doc: /* Style to use for single quotes in help. |
| 1009 | If the value is nil (default), no translation is done. | 1040 | The value is a left single quote character of some style. |
| 1010 | If it's the symbol `traditional', any occurrences of the curly quotes | 1041 | Quote \\=‘like this\\=’ if the value is ?\\=‘ (left single quotation mark). |
| 1011 | are translated to their ASCII "equivalents", GRAVE and APOSTROPHE. | 1042 | Quote 'like this' if the value is ?' (apostrophe). |
| 1012 | If it's the symbol `prefer-unicode', any matched pairs of GRAVE and | 1043 | Quote \\=`like this' if the value is ?\\=` (grave accent). |
| 1013 | APOSTROPHE will get translated into the "equivalent" curly quotes. | 1044 | The default value is nil, which means quote with left single quotation mark |
| 1014 | 1045 | if displayable, and with apostrophe otherwise. */); | |
| 1015 | Note that any translation done is done in a fresh copy of the doc | ||
| 1016 | string, and doesn't overwrite the original characters. */); | ||
| 1017 | Vhelp_quote_translation = Qnil; | 1046 | Vhelp_quote_translation = Qnil; |
| 1018 | 1047 | ||
| 1019 | defsubr (&Sdocumentation); | 1048 | defsubr (&Sdocumentation); |