emacs-orgmode@gnu.org archives
 help / color / mirror / code / Atom feed
From: Rasmus <rasmus@gmx.us>
To: n.goaziou@gmail.com
Cc: emacs-orgmode@gnu.org
Subject: Re: [patch][ox-latex] context-aware subscript
Date: Sat, 31 Aug 2013 15:59:38 +0200	[thread overview]
Message-ID: <87ioymj705.fsf@gmx.us> (raw)
In-Reply-To: <87k3j2nusy.fsf@gmail.com> (Nicolas Goaziou's message of "Sat, 31 Aug 2013 10:11:57 +0200")

[-- Attachment #1: Type: text/plain, Size: 4484 bytes --]

Hi,

> Thanks for the patch. Here are a few comments.

Thanks for the comments.

>> filter replace all   & $\beta_{\text{}}$   & \texttimes{}$_{\text{}}$   \\
>
> We might be able to handle it more nicely, i.e. by skipping \text when
> contents are empty.

Right, these should be removed due to spacing issues, it seems.
However, in this case the change is induced by a filter.  As such, Ox
doesn't know the final output when in the subscript function.  It's
not easy to predict the outcome of a filter before it's been applied.

What I do in the patch is that I apply the filters within the
function.  I don't like this approach as the doc says that filters are
applied ex post so it seems like cheating...  Also, filters using a
regexp with "\text{whatever}" wouldn't work.

So I'm not too optimistic about this particular apporach.

>> +	(prev (org-export-get-previous-element entity info))
>> +	(next (org-export-get-next-element entity info))
>> +	(no-post-blanks-p (= (or (org-element-property :post-blank entity) 1) 0))
>> +	(no-pre-blanks-p (= (or (org-element-property :post-blank
>> +						   (org-export-get-previous-element
>> +						    entity info)) 1) 0))
>
> A nil :post-blank property means 0, not 1. Also, you don't re-use PREV
> in NO-PRE-BLANKS-P.

Right.  I wanted to check for the case where there is no next/previous
element.  But I was wrong.  Thanks.

>> +	(scripts '(subscript superscript)))
>> +    (if (not (org-element-property :latex-math-p entity)) ent
>> +      (concat
>> +       (if (and no-pre-blanks-p
>> +		(memq (org-element-type prev) scripts)
>> +		(not (eq (org-export-data prev info) "")))
>> +	   "" "$")
>> +       ent
>> +       (if (and no-post-blanks-p
>> +		(memq (org-element-type next) scripts)
>> +		(not (eq (org-export-data next info) "")))
>> +	   "" "$")))))
>
> I think this is problematic: if an entity needs to export both the
> previous and the next object, what happens when we have two consecutive
> entities? An infloop?

I agree, but I haven't been able to cause any nasty behavior. I've
probably neglected some case.  These works fine

  1. \alpha\beta_t : \alpha is not a subscript
  2. \alpha\beta_\xi\nu : runs OK recursively. 

On 2.: on my system I've tried with many entities (around 500).  It
works, but obviously it's slow due to the recursiveness.  This is very
nasty.  I don't know if some other mechanism can be derived, tho. . .


>> +		    (not (org-element-property :latex-math-p prev))
>
> Sure, but I'd rather make a stricter check and also test PREV's type.

OK.

–Rasmus


Test file

#+BEGIN_SRC Org
* filters                                                          :noexport:

#+begin_src emacs-lisp
  (defun test-filter (script backend info)
    (when (org-export-derived-backend-p backend 'latex)
      (if  (string-match "a" script) "" script)))

  (defun test-filter2 (script backend info)
    (when (org-export-derived-backend-p backend 'latex)
      (replace-regexp-in-string "zz" "" script)))

  (add-to-list 'org-export-filter-subscript-functions
                 'test-filter)
  (add-to-list 'org-export-filter-subscript-functions
                 'test-filter2)

#+end_src

#+RESULTS:
| test-filter2 | test-filter |

* test 1

|                      | mathp             | text               |
|----------------------+-------------------+--------------------|
| merge maybe          | \alpha\beta_t     | \alpha\times_t     |
| long merge maybe     | \alpha\beta_tv\xi | \alpha\times_tv\xi |
| filter drop          | \alpha\beta_abc   | \alpha\times_abc   |
| filter replace all   | \alpha\beta_zz    | \alpha\times_zz    |
| filter replace parts | \alpha\beta_zz\xi | \alpha\times_zz\xi |
#+END_SRC

Approximate output

                     & mathp                           & text                              
=============================================================================================
merge maybe          & $\alpha$$\beta_{\text{t}}$      & $\alpha$\texttimes{}$_{\text{t}}$ 
long merge maybe     & $\alpha$$\beta_{\text{tv}\xi}$  & $\alpha$\texttimes{}$_{\text{tv}\xi}$
filter drop          & $\alpha$$\beta$                 & $\alpha$\texttimes{}              
filter replace all   & $\alpha$$\beta$                 & $\alpha$\texttimes{}              
filter replace parts & $\alpha$$\beta_{\xi}$           & $\alpha$\texttimes{}$_{\xi}$      


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-maybe-merge-subscript-and-mathp-entity-with-some-che.patch --]
[-- Type: text/x-diff, Size: 3440 bytes --]

From ebb7eb32b8ff18b9ff2c9d8686df1cdc6ed28bfb Mon Sep 17 00:00:00 2001
From: rasmus <rasmus@gmx.us>
Date: Thu, 29 Aug 2013 12:18:00 +0200
Subject: [PATCH] maybe merge subscript and mathp entity with some checks

---
 lisp/ox-latex.el | 51 +++++++++++++++++++++++++++++++++++++++------------
 1 file changed, 39 insertions(+), 12 deletions(-)

diff --git a/lisp/ox-latex.el b/lisp/ox-latex.el
index 1fe918a..cc8ac80 100644
--- a/lisp/ox-latex.el
+++ b/lisp/ox-latex.el
@@ -1234,9 +1234,26 @@ holding contextual information.  See `org-export-data'."
   "Transcode an ENTITY object from Org to LaTeX.
 CONTENTS are the definition itself.  INFO is a plist holding
 contextual information."
-  (let ((ent (org-element-property :latex entity)))
-    (if (org-element-property :latex-math-p entity) (format "$%s$" ent) ent)))
-
+  (let* ((ent (org-element-property :latex entity))
+	 (prev (org-export-get-previous-element entity info))
+	 (next (org-export-get-next-element entity info))
+	 (no-post-blanks-p (= (or (org-element-property :post-blank entity) 0) 0))
+	 (no-pre-blanks-p (= (or (org-element-property :post-blank prev) 0) 0))
+	 (scripts '(subscript superscript)))
+
+    (if (not (org-element-property :latex-math-p entity)) ent
+      (concat
+       (if (and no-pre-blanks-p
+		(memq (org-element-type prev) scripts)
+		;; check if nil
+		(org-export-data prev info))
+	   "" "$")
+       ent
+       (if (and no-post-blanks-p
+		(memq (org-element-type next) scripts)
+		;; check if nil
+		(org-export-data next info))
+	   "" "$")))))
 
 ;;;; Example Block
 
@@ -2217,8 +2234,14 @@ channel."
 			   (let ((blank (org-element-property :post-blank obj)))
 			     (and blank (> blank 0) "\\ "))))))
 	  (plain-text
-	   (setq output
-		 (format "%s\\text{%s}" output (org-export-data obj info))))
+	   (let ((out (or (org-export-filter-apply-functions
+			   org-export-filter-subscript-functions
+			   (org-export-data obj info)
+			   info) "")))
+	     (setq output
+		   (if (not (eq out ""))
+		       (format "%s\\text{%s}" output out)
+		     output))))
 	  (otherwise
 	   (setq output
 		 (concat output
@@ -2230,14 +2253,18 @@ channel."
     ;; or superscript.  Do not wrap into curly brackets if OUTPUT is
     ;; a single character.  Also merge consecutive subscript and
     ;; superscript into the same math snippet.
+    (if (not (eq output ""))
     (concat (and (not in-script-p)
 		 (let ((prev (org-export-get-previous-element object info)))
-		   (or (not prev)
-		       (not (eq (org-element-type prev)
-				(if (eq type 'subscript) 'superscript
-				  'subscript)))
-		       (let ((blank (org-element-property :post-blank prev)))
-			 (and blank (> blank 0)))))
+		   (and
+		    (not (and (eq (org-element-type prev) 'entity)
+			      (org-element-property :latex-math-p prev)))
+		    (or (not prev)
+			(not (eq (org-element-type prev)
+				 (if (eq type 'subscript) 'superscript
+				   'subscript)))
+			(let ((blank (org-element-property :post-blank prev)))
+			  (and blank (> blank 0))))))
 		 "$")
 	    (if (eq (org-element-type object) 'subscript) "_" "^")
 	    (and (> (length output) 1) "{")
@@ -2250,7 +2277,7 @@ channel."
 			       (org-export-get-next-element object info))
 			      (if (eq type 'subscript) 'superscript
 				'subscript))))
-		 "$"))))
+		 "$")))))
 
 (defun org-latex-subscript (subscript contents info)
   "Transcode a SUBSCRIPT object from Org to LaTeX.
-- 
1.8.4


[-- Attachment #3: Type: text/plain, Size: 27 bytes --]



--
Need more coffee. . .

  reply	other threads:[~2013-08-31 13:59 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-08-18  1:29 [patch][ox-latex] context-aware subscript Rasmus
2013-08-19  8:26 ` Nicolas Goaziou
2013-08-28 11:55   ` Rasmus
2013-08-28 13:38     ` Nicolas Goaziou
2013-08-28 13:46       ` Rasmus
2013-08-28 19:21         ` Nicolas Goaziou
2013-08-29 10:50           ` Rasmus
2013-08-31  8:11             ` Nicolas Goaziou
2013-08-31 13:59               ` Rasmus [this message]
2013-08-31 14:46                 ` Nicolas Goaziou

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.orgmode.org/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87ioymj705.fsf@gmx.us \
    --to=rasmus@gmx.us \
    --cc=emacs-orgmode@gnu.org \
    --cc=n.goaziou@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).