From mboxrd@z Thu Jan 1 00:00:00 1970 From: Roland Kaufmann Subject: [PATCH] Markup on same line as text Date: Thu, 06 Jan 2011 23:12:11 +0100 Message-ID: <4D263E3B.5030407@gmail.com> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="------------090308070205090602030000" Return-path: Received: from [140.186.70.92] (port=45917 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1Pay4B-0004iI-2C for emacs-orgmode@gnu.org; Thu, 06 Jan 2011 17:12:20 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Pay49-0002nW-75 for emacs-orgmode@gnu.org; Thu, 06 Jan 2011 17:12:18 -0500 Received: from mail-ey0-f169.google.com ([209.85.215.169]:39789) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Pay48-0002n8-NW for emacs-orgmode@gnu.org; Thu, 06 Jan 2011 17:12:17 -0500 Received: by eyh6 with SMTP id 6so4336400eyh.0 for ; Thu, 06 Jan 2011 14:12:12 -0800 (PST) List-Id: "General discussions about Org-mode." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: emacs-orgmode-bounces+geo-emacs-orgmode=m.gmane.org@gnu.org Errors-To: emacs-orgmode-bounces+geo-emacs-orgmode=m.gmane.org@gnu.org To: hniksic@xemacs.org Cc: emacs-orgmode@gnu.org This is a multi-part message in MIME format. --------------090308070205090602030000 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit I just discovered a problem with colorization and references in code snippets due to the way org-mode and htmlize interact. Consider the org-mode fragment: #+BEGIN_SRC emacs-lisp (let ((x 42)) ; meaning of l.u.e. (print x)) ; (ref:2) #+END_SRC Without the reference on line 2, doing an org-export-as-html would generate markup like this: (let ((x 42)) ; meaning of l.u.e. (print x)) Note that htmlize put the newline character on the end of the first line together with the text of the comment, both which is put inside the span. The closing tag of the span to colorize the comment thus ends up on the next line. When a reference is put on the next line, org-mode will subsequently add markup to highlight each line, so the markup ends up like this: (let ((x 42)) ; meaning of l.u.e. (print x)) ^^^^^^^ The first closing tag is really the end of the comment which is spilled to the next line, but it erraneously closes the id span. The color of the comment then proceeds to the end of the second line, where the id span was to close. To remedy this, I wrote a patch which postpone writing the newline to the html buffer until after the closing tag has been emitted. The patch is attached and should be applicable to the current Git repository. It should be applicable to version 1.37 of htmlize.el as well, with the command `patch -p3 < 0001-Markup-on-same-line-as-text.patch`. I refactored the insert-text functions so that they return the markup that should be applied instead of doing the insertion itself, and then let this go through a new function add-markup which puts the tags around the text, putting any trailing newline in the text at the very end, before the main htmlize-buffer-1 does the actual insertion in the buffer. I have tested this with all three kinds of htmlize-output-type, and it seems to give the expected result. -- Roland. --------------090308070205090602030000 Content-Type: text/plain; name="0001-Markup-on-same-line-as-text.patch" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="0001-Markup-on-same-line-as-text.patch" >From 86f1508f58dd304471d768481944d34e220e24f1 Mon Sep 17 00:00:00 2001 From: Roland Kaufmann Date: Thu, 6 Jan 2011 11:22:49 +0100 Subject: [PATCH] Markup on same line as text MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="------------1.7.3.1.msysgit.0" This is a multi-part message in MIME format. --------------1.7.3.1.msysgit.0 Content-Type: text/plain; charset=UTF-8; format=fixed Content-Transfer-Encoding: 8bit * contrib/lisp/htmlize.el: Markup on same line as text Newline was considered to be a part of the text to be marked up; thus the closing tag was put on the next line. Since org-mode does line processing on the result, the line number span was closed prematurely by this tag and the formatting erraneously extended through the next line. This fix replaces the insert-text functions with new get-markup variants which return a pair (start-tag end-tag) for the appropriate formatting. The newline is then removed from the text with `split-trailing-newline` and appended again after the close tag in `add-markup`. The text is sent to the buffer after this processing instead of in each behavioral insert-text function. The names of the functions are changed so reflect that the signatures are different. --- contrib/lisp/htmlize.el | 67 ++++++++++++++++++++++++++--------------------- 1 files changed, 37 insertions(+), 30 deletions(-) --------------1.7.3.1.msysgit.0 Content-Type: text/x-patch; name="0001-Markup-on-same-line-as-text.patch" Content-Transfer-Encoding: 8bit Content-Disposition: attachment; filename="0001-Markup-on-same-line-as-text.patch" diff --git a/contrib/lisp/htmlize.el b/contrib/lisp/htmlize.el index 5f4cb5b..f952b80 100644 --- a/contrib/lisp/htmlize.el +++ b/contrib/lisp/htmlize.el @@ -1209,7 +1209,7 @@ property and by buffer overlays that specify `face'." ;; `htmlize-buffer-1' calls a number of "methods", which indirect to ;; the functions that depend on `htmlize-output-type'. The currently ;; used methods are `doctype', `insert-head', `body-tag', and -;; `insert-text'. Not all output types define all methods. +;; `get-markup'. Not all output types define all methods. ;; ;; Methods are called either with (htmlize-method METHOD ARGS...) ;; special form, or by accessing the function with @@ -1347,18 +1347,18 @@ it's called with the same value of KEY. All other times, the cached (insert htmlize-hyperlink-style " -->\n \n")) -(defun htmlize-css-insert-text (text fstruct-list buffer) - ;; Insert TEXT colored with FACES into BUFFER. In CSS mode, this is - ;; easy: just nest the text in one tag for each - ;; face in FSTRUCT-LIST. - (dolist (fstruct fstruct-list) - (princ "" buffer)) - (princ text buffer) - (dolist (fstruct fstruct-list) - (ignore fstruct) ; shut up the byte-compiler - (princ "" buffer))) +(defun htmlize-css-get-markup (fstruct-list) + ;; Get markup for FACES. In CSS mode, this is easy; just create one + ;; tag for each face in FSTRUCT-LIST. + (cons + (mapconcat + (lambda (fs) (concat "")) + fstruct-list "") + (mapconcat + (lambda (fs) (ignore fs) "") + fstruct-list ""))) ;; `inline-css' output support. @@ -1367,20 +1367,16 @@ it's called with the same value of KEY. All other times, the cached (mapconcat #'identity (htmlize-css-specs (gethash 'default face-map)) " "))) -(defun htmlize-inline-css-insert-text (text fstruct-list buffer) +(defun htmlize-inline-css-get-markup (fstruct-list) (let* ((merged (htmlize-merge-faces fstruct-list)) (style (htmlize-memoize merged (let ((specs (htmlize-css-specs merged))) (and specs (mapconcat #'identity (htmlize-css-specs merged) " ")))))) - (when style - (princ "" buffer)) - (princ text buffer) - (when style - (princ "" buffer)))) + (if style + (cons (concat "") "") + (cons "" "")))) ;;; `font' tag based output support. @@ -1390,12 +1386,12 @@ it's called with the same value of KEY. All other times, the cached (htmlize-fstruct-foreground fstruct) (htmlize-fstruct-background fstruct)))) -(defun htmlize-font-insert-text (text fstruct-list buffer) +(defun htmlize-font-get-markup (fstruct-list) ;; In `font' mode, we use the traditional HTML means of altering ;; presentation: tag for colors, for bold, for ;; underline, and for strike-through. - (let* ((merged (htmlize-merge-faces fstruct-list)) - (markup (htmlize-memoize + (let ((merged (htmlize-merge-faces fstruct-list))) + (htmlize-memoize merged (cons (concat (and (htmlize-fstruct-foreground merged) @@ -1410,10 +1406,19 @@ it's called with the same value of KEY. All other times, the cached (and (htmlize-fstruct-italicp merged) "") (and (htmlize-fstruct-boldp merged) "") (and (htmlize-fstruct-foreground merged) "")))))) - (princ (car markup) buffer) - (princ text buffer) - (princ (cdr markup) buffer))) +(defun split-trailing-newline (text) + "Split a trailing newline from the text" + (let ((length-minus-one (- (length text) 1))) + (if (and (>= length-minus-one 0) (char-equal (aref text length-minus-one) ?\n)) + (cons (substring text 0 length-minus-one) "\n") + (cons text "")))) + +(defun add-markup (markup text) + "Interpose head and tail of markup on each side of text" + (let ((text-and-newline (split-trailing-newline text))) + (concat (car markup) (car text-and-newline) (cdr markup) (cdr text-and-newline)))) + (defun htmlize-buffer-1 () ;; Internal function; don't call it from outside this file. Htmlize ;; current buffer, writing the resulting HTML to a new buffer, and @@ -1468,11 +1473,11 @@ it's called with the same value of KEY. All other times, the cached "\n ") (plist-put places 'content-start (point-marker)) (insert "
\n"))
-      (let ((insert-text-method
+      (let ((get-markup-method
 	     ;; Get the inserter method, so we can funcall it inside
 	     ;; the loop.  Not calling `htmlize-method' in the loop
 	     ;; body yields a measurable speed increase.
-	     (htmlize-method-function 'insert-text))
+	     (htmlize-method-function 'get-markup))
 	    ;; Declare variables used in loop body outside the loop
 	    ;; because it's faster to establish `let' bindings only
 	    ;; once.
@@ -1510,7 +1515,9 @@ it's called with the same value of KEY.  All other times, the cached
 	  (when (> (length text) 0)
 	    ;; Insert the text, along with the necessary markup to
 	    ;; represent faces in FSTRUCT-LIST.
-	    (funcall insert-text-method text fstruct-list htmlbuf))
+		(let* ((markup (funcall get-markup-method fstruct-list))
+			   (markedup-text (add-markup markup text)))
+		  (princ markedup-text htmlbuf)))
 	  (goto-char next-change)))
 
       ;; Insert the epilog and post-process the buffer.

--------------1.7.3.1.msysgit.0--



--------------090308070205090602030000
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: inline

_______________________________________________
Emacs-orgmode mailing list
Please use `Reply All' to send replies to the list.
Emacs-orgmode@gnu.org
http://lists.gnu.org/mailman/listinfo/emacs-orgmode

--------------090308070205090602030000--