Subject: bug#32281: shr.el align support patch

From: Noam Postavsky <[email-masked]>
Date: Sun, 05 Aug 2018 22:52:35 -0400

severity 32281 wishlist
tags 32281 + patch
quit

Bad Blue Bull <[email-masked]> writes:

> Here's a patch for shr.el that makes it handle "align" attribute for
> headers, paragraphs and lists, works only when monospace font is used
> (becoz of lame implementation of fill-paragraph). Also default value
> of shr-use-fonts set to nil so monospace fonts are used by default.

Seems reasonable overall, but I'm not sure if changing the default is
justified.

> -(defcustom shr-use-fonts t
> +(defcustom shr-use-fonts nil ; set default value to nil because monospace fonts are better for Emacs

Although I do somewhat agree with the "monospace fonts are better for
Emacs" sentiment.

> +(defun shr-fill-paragraph-with-breaks (&optional justify bre-del bre-regexp)
> +  "Fill paragraph at or after point, breaking lines at positions matching regexp argument BRE-REGEXP.
> +If JUSTIFY is non-nil justify as well.
> +Delete matched text if BRE-DEL is non nil
> +BRE-REGEXP must be a regexp that determines positions where to break lines, default value is \\x2028."
> +  (unless bre-regexp (setq bre-regexp "\x2028"))
> +  (setq bre-regexp (concat bre-regexp "\\|\x2029"))
> +  (save-excursion
> +   (let ((line-begin) (paragraph-end))
> +	 (forward-paragraph)
> +	 (insert "\x2029") ; use \x2029 (unicode paragraph separator) to mark end of a paragraph
> +	 (backward-paragraph)
> +	 (setq line-begin (point))
> +	 (while (not paragraph-end)
> +			(re-search-forward bre-regexp)
> +			(if (equal (match-string 0) "\x2029") (setq paragraph-end t)) ; end of paragraph reached
> +			(if (or bre-del paragraph-end) (replace-match ""))
> +			(unless (equal (char-after) ?\n) (insert "\n")) ; I don't know why but two adjacent \n leave an empty line after fill
> +			(fill-region-as-paragraph line-begin (- (point) 1) justify)
> +			(setq line-begin (point)))
> +	 (delete-char -1)
> +	 )))

> +(defun shr-fill-paragraph (dom)
> +  "Fill paragraph"
> +  (when (not shr-use-fonts) ;fill-paragraph is useful only with monospace fonts
> + 	(shr-fill-paragraph-with-breaks
> +	 ((lambda (x)
> +	   (cond
> + 		 ((equal x "right") 'right)
> + 		 ((equal x "center") 'center)
> + 		 ((equal x "left") 'left)
> + 		 ))
> + 	 (cdr (assq 'align (dom-attributes dom)))) ; justify parameter
> +	 t) ; bre-del t
> + 	)
> +  )
> +

>  (defun shr-tag-li (dom)
> @@ -1770,6 +1813,7 @@
>  	(put-text-property start (1+ start) 'shr-prefix-length (length bullet))
>  	(shr-generic dom))))
>    (unless (bolp)
> +	(unless shr-use-fonts (insert "\x2028")) ; insert a line separator
>      (insert "\n")))
>  
>  (defun shr-mark-fill (start)
> @@ -1785,7 +1829,8 @@
>  	     (or (not (bolp))
>  		 (and (> (- (point) 2) (point-min))
>  		      (not (= (char-after (- (point) 2)) ?\n)))))
> -    (insert "\n"))
> +	(unless shr-use-fonts (insert "\x2028")) ; insert a line separator
> +	(insert "\n"))
>    (shr-generic dom))

The indentation in your patch looks kind of off, are you not using
Emacs' builtin auto-indentation?  (also, don't leave hanging parens.)