Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unwanted newlines in LaTeX export #27

Open
Perangelot opened this issue May 15, 2022 · 4 comments
Open

Unwanted newlines in LaTeX export #27

Perangelot opened this issue May 15, 2022 · 4 comments
Labels
documentation Improvements or additions to documentation

Comments

@Perangelot
Copy link

Perangelot commented May 15, 2022

Consider the following custom block:

#+begin_blockquote :citekey key :pages pages
*This* is a /try/.
#+end_blockquote

which was defined like this

(org-defblock blockquote nil (citekey "" pages "") "This is just an attempt."
(format (if (equal backend 'latex)
"\\blockcquote[%s]{%s}{%s}" nil)
pages citekey contents))

What it should print:

\blockcquote[pages]{key}{\textbf{This} is a \emph{try}.}

What it does print:

\blockcquote[pages]{key}{
\textbf{This} is a \emph{try}.

}

The problem is that, due to the added whitespace, the custom block just shown produces the latter output. If this is exported to LaTeX, instead of "**This** is a _try_", you get " **This** is a _try_ ". regexp-replacement does not work here, adding % only for the first line. Any ideas what to do?

@alhassy
Copy link
Owner

alhassy commented May 25, 2022

Note that org-defblock XXX gives you a function org--XXX that you can play with ---see https://github.com/alhassy/org-special-block-extras/blob/master/org-special-block-extras.el#L647. So in this case, you can press C-h o RET blockquote and see the exact name, and docstring, of the resulting function.

Then you can experiment with this function to see what it is generating; e.g.,

(org--blockquote 'latex  "*This* is a /try/.")

;; Press   C-u C-x C-e   at the end of the closing parens above to get the following:

"#+begin_export latex 
\\blockcquote[]{}{
#+end_export
*This* is a /try/.
#+begin_export latex
}
#+end_export"

This ugly mess is what Org "sees" before producing LaTeX 😨

Hope this helps.

@alhassy alhassy added the documentation Improvements or additions to documentation label May 25, 2022
@Perangelot

This comment was marked as outdated.

@Perangelot
Copy link
Author

Perangelot commented May 27, 2022

After hours of searching, I have finally found the culprit. Your export machinery makes an unncessary move. Let us take

#+begin_blockquote :citekey key :pages pages
*This* is a /try/.
#+end_blockquote

as an example again. The function org-defblock---support-block-type takes the name, the documentation string, content of the code-block as well as the main-argument's name and value and other keywords as an input (leaving out that html feature for a second). In our case, it would look like this:

name: blockcquote
doc-string: "This is just an attempt."
main-arg name: "key"
main-arg: key
kwd: (:pages "pages")
body:  "*This* is a /try/."

It then uses two-functions: : org-export and org-parse. org-parse wraps the body in an export block depending on the backend:

(format "#+begin_export %s \n%s\n#+end_export" backend x)

In our case it produces:

"#+begin_export latex
*This* is a /try/.
#+end_export latex"

org-export now also wraps its argument, but the other way around: end_export first, begin_export last:

(format "\n#+end_export\n%s\n#+begin_export %s\n" x backend)

Also note the newline after #+begin_export latex. I have no idea why it is done like this, it does not make sense to me. It does not actually export the body. This is done by the usual org-export machinery; the function is hooked at org-export-before-processing-hook. it only adds export_ lines. This is why we end up with the undesired result:

blockcquote[key]{page}{
\textbf{This} is a \emph{try}.

}

The empty lines immediately above and below result form the _export lines. The second empty line is produced by the misplaced \n in the org-export function.

The easiest way to go about this is to just not use this weird syntax at all but actually parsing the body to org immediately. That is, we modify org-parse. If we replace

(format "\n#+end_export\n%s\n#+begin_export %s\n" x backend)

by

(s-replace-regexp "\n\\'" "" (org-export-string-as x backend t))))))))

we export the body to the preferred backend and delete any newlines before the string ends. This way, we get what we want:

#+begin_export latex 
\blockcquote[key]{pages}{\textbf{This} is a \emph{try}.}
#+end_export

I have added a merge request, see #30. It would be great if you could check whether this solution works and merge it. It's important for me that this is working.

@alhassy
Copy link
Owner

alhassy commented Jul 21, 2023

@Perangelot Thanks for the investigations! 🔥

I haven't been able to get #30 incorporated, it's out of date and seems to break things on my end. I'm still investigating.

However, it seems the most up to date version of org-defblock solves your initial issue:

With this definition

(org-defblock blockquote (nil nil citekey "" pages "" :backend latex)
 "This is just an attempt."
 (format "\\blockcquote[%s]{%s}{%s}" pages citekey contents))

The LaTeX export does not produce too many unwanted newlines...

(org-export-string-as
 "#+begin_blockquote :citekey key :pages pages
 *This* is a /try/.
 #+end_blockquote" 'latex :body-only)
;;
;; ⇒ ⇒ ⇒
;;
"\\blockcquote[pages]{key}{\\textbf{This} is a \\emph{try}.}
"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation Improvements or additions to documentation
Projects
None yet
Development

No branches or pull requests

2 participants