Subject: [PATCH] Fix bold or underline of underscores

From: Manuel Giraud <[email-masked]>
Date: Thu, 19 Jun 2025 17:17:21 +0200

Tags: patch

Hi,

Here is a patch for something that was bothering me in the man page
rendering.  How to reproduce it:

            - emacs -Q
            - M-x load-theme <RET> modus-operandi <RET> ;; for a more
                                                        ;; clear distinction
                                                        ;; of faces
            - M-x man <RET> ssh_config <RET>

See that the underscore '_' in "ssh_config" (in the line after NAME) is
rendered with the Man-underline while its surrounding use
Man-overstrike.  This patch tries to fix those discrepancies.

In GNU Emacs 31.0.50 (build 4, x86_64-unknown-openbsd7.7) of 2025-06-18
 built on computer
Repository revision: 27a524602ff9899139e7f45e7607711c96a9b666
Repository branch: master
Windowing system distributor 'The X.Org Foundation', version 11.0.12101016
System Description: OpenBSD computer 7.7 GENERIC.MP#14 amd64

Configured using:
 'configure CC=egcc CPPFLAGS=-I/usr/local/include
 LDFLAGS=-L/usr/local/lib MAKEINFO=gmakeinfo --prefix=/home/manuel/emacs
 --bindir=/home/manuel/bin --with-x-toolkit=no
 --with-toolkit-scroll-bars=no --without-cairo --without-dbus
 --without-gconf --without-gsettings --without-compress-install'

>From 40dabba0b39a93abc64d574895727b59f0d5e253 Mon Sep 17 00:00:00 2001
From: Manuel Giraud <[email-masked]>
Date: Thu, 19 Jun 2025 16:42:57 +0200
Subject: [PATCH] Fix bold or underline of underscores

* lisp/man.el (Man-fontify-manpage): Fix the "_\b_" case.
---
 lisp/man.el | 19 +++++++++++++------
 1 file changed, 13 insertions(+), 6 deletions(-)

diff --git a/lisp/man.el b/lisp/man.el
index 397162a7ad1..9e1d294b1ec 100644
--- a/lisp/man.el
+++ b/lisp/man.el
@@ -1379,17 +1379,24 @@ Man-fontify-manpage
             (put-text-property (1- (point)) (point)
                                'font-lock-face 'Man-underline))))
     (goto-char (point-min))
-    (while (and (search-forward "_\b" nil t) (not (eobp)))
-      (delete-char -2)
-      (put-text-property (point) (1+ (point)) 'font-lock-face 'Man-underline))
+    (while (and (re-search-forward "_\b\\([^_]\\)" nil t) (not (eobp)))
+      (replace-match "\\1")
+      (put-text-property (1- (point)) (point) 'font-lock-face 'Man-underline))
     (goto-char (point-min))
-    (while (search-forward "\b_" nil t)
-      (delete-char -2)
+    (while (re-search-forward "\\([^_]\\)\b_" nil t)
+      (replace-match "\\1")
       (put-text-property (1- (point)) (point) 'font-lock-face 'Man-underline))
     (goto-char (point-min))
-    (while (re-search-forward "\\(.\\)\\(\b+\\1\\)+" nil t)
+    (while (re-search-forward "\\([^_]\\)\\(\b+\\1\\)+" nil t)
       (replace-match "\\1")
       (put-text-property (1- (point)) (point) 'font-lock-face 'Man-overstrike))
+    ;; Special case for "__": is it an underlined underscore or a bold
+    ;; underscore?  Look at the face after it to know.
+    (goto-char (point-min))
+    (while (search-forward "_\b_" nil t)
+      (delete-char -2)
+      (let ((face (get-text-property (point) 'font-lock-face)))
+        (put-text-property (1- (point)) (point) 'font-lock-face face)))
     (goto-char (point-min))
     (while (re-search-forward "o\b\\+\\|\\+\bo" nil t)
       (replace-match "o")
-- 
2.49.0

-- 
Manuel Giraud