emacs-orgmode@gnu.org archives
 help / color / mirror / code / Atom feed
* caption width in LateX export
@ 2021-12-27  1:22 Seb
  2021-12-27  7:41 ` Juan Manuel Macías
  2021-12-28 14:58 ` Eric S Fraga
  0 siblings, 2 replies; 10+ messages in thread
From: Seb @ 2021-12-27  1:22 UTC (permalink / raw)
  To: emacs-orgmode

Hello,

When exporting to LaTeX, is there a mechanism to make the figure
captions as wide as the figure?  In pure LaTeX, this can be easily
accomplished by placing the figure inside a minipage environment.
Using a special block, as in:

\begin{minipage}{0.7\textwidth}
#+CAPTION: looooooong caption.
[[file_path]]
\end{minipage}

fails, as it seems impossible to pass arguments to the special block.
Any tips welcome.


--
Seb



^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: caption width in LateX export
  2021-12-27  1:22 caption width in LateX export Seb
@ 2021-12-27  7:41 ` Juan Manuel Macías
  2021-12-27  9:09   ` Juan Manuel Macías
  2021-12-27 12:53   ` Sebastian P. Luque
  2021-12-28 14:58 ` Eric S Fraga
  1 sibling, 2 replies; 10+ messages in thread
From: Juan Manuel Macías @ 2021-12-27  7:41 UTC (permalink / raw)
  To: Seb; +Cc: orgmode

Hi Seb

Seb writes:

> When exporting to LaTeX, is there a mechanism to make the figure
> captions as wide as the figure?  In pure LaTeX, this can be easily
> accomplished by placing the figure inside a minipage environment.
> Using a special block, as in:
>
> \begin{minipage}{0.7\textwidth}
>
> #+CAPTION: looooooong caption.
> [[file_path]]
>
> \end{minipage}
>
> fails, as it seems impossible to pass arguments to the special block.
> Any tips welcome.

If you use the caption package (https://www.ctan.org/pkg/caption), you
can indicate in each figure the width of the caption. In this case, you
would have to introduce the code using raw latex via the `:caption'
property:

#+LaTeX_Header: \usepackage{caption}

#+ATTR_LaTeX: :caption \captionsetup{width=.3\linewidth}\caption{Lorem ipsum dolor sit amet, consectetuer adipiscing elit}
#+ATTR_LaTeX: :width .3\linewidth
[[file_path]]

Best regards,

Juan Manuel 


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: caption width in LateX export
  2021-12-27  7:41 ` Juan Manuel Macías
@ 2021-12-27  9:09   ` Juan Manuel Macías
  2021-12-27 12:53   ` Sebastian P. Luque
  1 sibling, 0 replies; 10+ messages in thread
From: Juan Manuel Macías @ 2021-12-27  9:09 UTC (permalink / raw)
  To: Seb; +Cc: orgmode

P.S.: I have come up with another possibility, more automatic, on the
LaTeX side, if you compile with LuaTeX. This thread
(https://tex.stackexchange.com/questions/202046/width-of-the-caption-of-a-figure),
where someone proposes to use a \savebox for concrete images, gave me
the idea. We can automate that through a simple function in Lua, and add
it to the `process_input_buffer' callback, in order to the caption
*always* has the width of each image:

You can put this in your Org document:

#+NAME: luacode
#+begin_src latex :exports none
\usepackage{luacode}

\begin{luacode*}
  function caption_width ( text )
  text = string.gsub ( text, "(\\includegraphics.+)", "\\sbox0{%1}")
  text = string.gsub ( text, "(\\caption{.+})", "\\begin{minipage}{\\wd0}\\usebox0%1\\end{minipage}")
  return text
  end
\end{luacode*}

\newcommand\CaptionAutoWidth{\directlua{luatexbase.add_to_callback
( "process_input_buffer" , caption_width , "caption_width" )}}

\AtBeginDocument{\CaptionAutoWidth}
#+end_src

#+begin_src latex :noweb yes :results raw
,#+LaTeX_HEADER: <<luacode>>
#+end_src

And then:

#+CAPTION: Lorem ipsum dolor sit amet, consectetuer adipiscing elit
#+ATTR_LaTeX: :width .3\linewidth
[[img]]

Best regards,

Juan Manuel 

Juan Manuel Macías writes:

> If you use the caption package (https://www.ctan.org/pkg/caption), you
> can indicate in each figure the width of the caption. In this case, you
> would have to introduce the code using raw latex via the `:caption'
> property:
>
> #+LaTeX_Header: \usepackage{caption}
>
> #+ATTR_LaTeX: :caption \captionsetup{width=.3\linewidth}\caption{Lorem ipsum dolor sit amet, consectetuer adipiscing elit}
> #+ATTR_LaTeX: :width .3\linewidth
> [[file_path]]


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: caption width in LateX export
  2021-12-27  7:41 ` Juan Manuel Macías
  2021-12-27  9:09   ` Juan Manuel Macías
@ 2021-12-27 12:53   ` Sebastian P. Luque
  2021-12-27 13:28     ` Juan Manuel Macías
  1 sibling, 1 reply; 10+ messages in thread
From: Sebastian P. Luque @ 2021-12-27 12:53 UTC (permalink / raw)
  To: emacs-orgmode

On Mon, 27 Dec 2021 07:41:59 +0000,
Juan Manuel Macías <maciaschain@posteo.net> wrote:

[...]

> If you use the caption package (https://www.ctan.org/pkg/caption), you
> can indicate in each figure the width of the caption. In this case,
> you would have to introduce the code using raw latex via the
> `:caption' property:

> #+LaTeX_Header: \usepackage{caption}

> #+ATTR_LaTeX: :caption \captionsetup{width=.3\linewidth}\caption{Lorem
> ipsum dolor sit amet, consectetuer adipiscing elit} #+ATTR_LaTeX:
> :width .3\linewidth [[file_path]]

Thank you, Juan.  Unfortunately, there is a price for this solution as
it is now impossible to name and refer to this segment as usual:

#+LATEX_HEADER: \usepackage{caption}

See [[fig1]].

#+NAME: fig1
#+ATTR_LATEX: :caption \captionsetup{width=0.5\textwidth}\caption{Lorem ipsum dolor sit amet, consectetuer adipiscing elit}
[[file_path]]

leads to this (I compile with latexmk):

Latexmk: Summary of warnings from last run of *latex:
  Latex failed to resolve 1 reference(s)


-- 
Seb



^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: caption width in LateX export
  2021-12-27 12:53   ` Sebastian P. Luque
@ 2021-12-27 13:28     ` Juan Manuel Macías
  2021-12-27 17:16       ` Sebastian P. Luque
  0 siblings, 1 reply; 10+ messages in thread
From: Juan Manuel Macías @ 2021-12-27 13:28 UTC (permalink / raw)
  To: Sebastian P. Luque; +Cc: orgmode

Sebastian P. Luque writes:

> Thank you, Juan.  Unfortunately, there is a price for this solution as
> it is now impossible to name and refer to this segment as usual:

I see. Have you tried the option with LuaTeX that I put in my other
message? You can compile with LuaTeX also using latexmk:

(setq org-latex-pdf-process
      '("latexmk -lualatex -e '$lualatex=q/lualatex %%O -shell-escape %%S/' %f"))

In any case, since this is a simple substitution, you can use also a
function in Elisp as a final output filter[1]:

#+BIND: org-export-filter-final-output-functions (caption-auto-width)
#+begin_src emacs-lisp :exports results :results none
  (defun caption-auto-width (text backend info)
    (when (org-export-derived-backend-p backend 'latex)
      (with-temp-buffer
	(insert text)
	(save-excursion
	  (goto-char (point-min))
	  (while (re-search-forward "\\(\\\\includegraphics.+\\)" nil t)
	    (replace-match "\\\\sbox0{\\1}" t nil)))
	(save-excursion
	  (goto-char (point-min))
	  (while (re-search-forward "\\(\\\\caption.+\\)" nil t)
	    (replace-match "\\\\begin{minipage}{\\\\wd0}\\\\usebox0\\1\\\\end{minipage}" t nil)))
	(setq text (buffer-string)))))
#+end_src

Vid. [[fig:1]] 

#+NAME: fig:1
#+CAPTION: Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Donec hendrerit tempor tellus. Donec pretium posuere tellus
#+ATTR_LaTeX: :width .3\linewidth
[[my-image.jpg]]

[1] You need to set this variable as non-nil, in order to use bind
keywords: (setq org-export-allow-bind-keywords t)

Hope this works,

Best regards,

Juan Manuel 


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: caption width in LateX export
  2021-12-27 13:28     ` Juan Manuel Macías
@ 2021-12-27 17:16       ` Sebastian P. Luque
  2021-12-27 19:28         ` Juan Manuel Macías
  0 siblings, 1 reply; 10+ messages in thread
From: Sebastian P. Luque @ 2021-12-27 17:16 UTC (permalink / raw)
  To: emacs-orgmode

On Mon, 27 Dec 2021 13:28:08 +0000,
Juan Manuel Macías <maciaschain@posteo.net> wrote:

> Sebastian P. Luque writes:
>> Thank you, Juan.  Unfortunately, there is a price for this solution
>> as it is now impossible to name and refer to this segment as usual:

> I see. Have you tried the option with LuaTeX that I put in my other
> message? You can compile with LuaTeX also using latexmk:

> (setq org-latex-pdf-process '("latexmk -lualatex -e
> '$lualatex=q/lualatex %%O -shell-escape %%S/' %f"))

I haven't tried this yet, but it's great to know latexmk can use LuaTex.


> In any case, since this is a simple substitution, you can use also a
> function in Elisp as a final output filter[1]:

> #+BIND: org-export-filter-final-output-functions (caption-auto-width)
> #+begin_src emacs-lisp :exports results :results none

>   (defun caption-auto-width (text backend info) (when
> (org-export-derived-backend-p backend 'latex) (with-temp-buffer
> (insert text) (save-excursion (goto-char (point-min)) (while
> (re-search-forward "\\(\\\\includegraphics.+\\)" nil t) (replace-match
> "\\\\sbox0{\\1}" t nil))) (save-excursion (goto-char (point-min))
> (while (re-search-forward "\\(\\\\caption.+\\)" nil t) (replace-match
> "\\\\begin{minipage}{\\\\wd0}\\\\usebox0\\1\\\\end{minipage}" t nil)))
> (setq text (buffer-string))))) #+end_src

> Vid. [[fig:1]]

> #+NAME: fig:1 #+CAPTION: Lorem ipsum dolor sit amet, consectetuer
> adipiscing elit. Donec hendrerit tempor tellus. Donec pretium posuere
> tellus

> #+ATTR_LaTeX: :width .3\linewidth [[my-image.jpg]]

> [1] You need to set this variable as non-nil, in order to use bind
> keywords: (setq org-export-allow-bind-keywords t)

> Hope this works,

This is great, and very interesting to learn about the BIND keyword.

Thank you,
-- 
Seb



^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: caption width in LateX export
  2021-12-27 17:16       ` Sebastian P. Luque
@ 2021-12-27 19:28         ` Juan Manuel Macías
  0 siblings, 0 replies; 10+ messages in thread
From: Juan Manuel Macías @ 2021-12-27 19:28 UTC (permalink / raw)
  To: orgmode

Sebastian P. Luque writes:

> This is great, and very interesting to learn about the BIND keyword.
>
> Thank you,

You're welcome. Of course, if you use the filter very often, it is not
necessary to include it in a document or use the bind keyword. It
would be enough to add the function to your init and the line:

(add-to-list 'org-export-filter-final-output-functions #'caption-auto-width)

In a case like this, however, I would prefer to use the other function
in Lua within LuaTeX, since two commands could be defined: one to enable
the automatic caption width and one to disable it, throughout the
document. E.g.:

#+begin_src latex
  \usepackage{luacode}

  \begin{luacode*}
    function caption_width ( text )
      text = string.gsub ( text, "(\\includegraphics.+)", "\\sbox0{%1}")
      text = string.gsub ( text, "(\\caption.+)", "\\begin{minipage}{\\wd0}\\usebox0%1\\end{minipage}")
      return text
    end
  \end{luacode*}

\newcommand\CaptionAutoWidthOn{\directlua{luatexbase.add_to_callback
  ( "process_input_buffer" , caption_width , "caption_width" )}}

\newcommand\CaptionAutoWidthOff{\directlua{luatexbase.remove_from_callback
  ( "process_input_buffer" , "caption_width" )}}
#+end_src

\CaptionAutoWidthOn

#+CAPTION: Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Donec hendrerit tempor tellus 
#+ATTR_LaTeX: :width .3\linewidth
[[img.jpg]]

\CaptionAutoWidthOff

#+CAPTION: Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Donec hendrerit tempor tellus
#+ATTR_LaTeX: :width .1\linewidth
[[img.jpg]]


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: caption width in LateX export
  2021-12-27  1:22 caption width in LateX export Seb
  2021-12-27  7:41 ` Juan Manuel Macías
@ 2021-12-28 14:58 ` Eric S Fraga
  2021-12-28 15:59   ` Seb
  1 sibling, 1 reply; 10+ messages in thread
From: Eric S Fraga @ 2021-12-28 14:58 UTC (permalink / raw)
  To: Seb; +Cc: emacs-orgmode

On Sunday, 26 Dec 2021 at 19:22, Seb wrote:
> Using a special block, as in:

[...]

> fails, as it seems impossible to pass arguments to the special block.

Not true.  The following seems to create the LaTeX code you wanted:

--8<---------------cut here---------------start------------->8---
#+attr_latex: :options {0.7\textwidth}
#+begin_minipage

#+CAPTION: looooooong caption.
[[file_path]]

#+end_minipage
--8<---------------cut here---------------end--------------->8---

HTH,
eric

-- 
: Eric S Fraga, with org release_9.5.1-279-g8908fb in Emacs 29.0.50
: Latest paper written in org: https://arxiv.org/abs/2106.05096


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: caption width in LateX export
  2021-12-28 14:58 ` Eric S Fraga
@ 2021-12-28 15:59   ` Seb
  2021-12-28 16:26     ` Eric S Fraga
  0 siblings, 1 reply; 10+ messages in thread
From: Seb @ 2021-12-28 15:59 UTC (permalink / raw)
  To: emacs-orgmode

On Tue, 28 Dec 2021 14:58:35 +0000,
Eric S Fraga <e.fraga@ucl.ac.uk> wrote:

> On Sunday, 26 Dec 2021 at 19:22, Seb wrote:
>> Using a special block, as in:

> [...]

>> fails, as it seems impossible to pass arguments to the special block.

> Not true.  The following seems to create the LaTeX code you wanted:

> #+attr_latex: :options {0.7\textwidth} #+begin_minipage

> #+CAPTION: looooooong caption.  [[file_path]]

> #+end_minipage

That is strange, as it actually should not work (it still doesn't for me
with your code).  However, I had made a mistake in my original post as I
meant to have the minipage environment inside the floating figure
environment in the output, as in:

---<--------------------cut here---------------start------------------->---
\begin{figure}[htbp]
  \centering
  \begin{minipage}{0.5\textwidth}
    \includegraphics[width=\textwidth]{FILE_PATH}
    \caption{\label{ORG_LABEL}Lorem ipsum dolor sit amet, consectetuer
      adipiscing elit.}
  \end{minipage}
\end{figure}
---<--------------------cut here---------------end--------------------->---

which does compile fine.  Apologies for the confusion this may have
caused.

The previous post by Juan Manuel did provide a neat solution, which I'll
be tweaking to implement this as I never need captions running across
the whole page for figures using much less.

-- 
Seb



^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: caption width in LateX export
  2021-12-28 15:59   ` Seb
@ 2021-12-28 16:26     ` Eric S Fraga
  0 siblings, 0 replies; 10+ messages in thread
From: Eric S Fraga @ 2021-12-28 16:26 UTC (permalink / raw)
  To: Seb; +Cc: emacs-orgmode

On Tuesday, 28 Dec 2021 at 09:59, Seb wrote:
> That is strange, as it actually should not work (it still doesn't for me
> with your code).  

Well, it won't work if the figure is to float but will if you ask org to
not float the figure.

> However, I had made a mistake in my original post as I meant to have
> the minipage environment inside the floating figure environment in the
> output, as in:

That makes more sense and, for this case, special blocks cannot work
unfortunately.

I'm glad you did find a working solution but I simply wanted to clarify
that you can indeed pass options to special blocks which your original
post seemed to state was not possible.  I use special blocks all the
time, including minipages but others as well for custom LaTeX
environments.
-- 
: Eric S Fraga, with org release_9.5.1-279-g8908fb in Emacs 29.0.50
: Latest paper written in org: https://arxiv.org/abs/2106.05096


^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2021-12-28 16:27 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-12-27  1:22 caption width in LateX export Seb
2021-12-27  7:41 ` Juan Manuel Macías
2021-12-27  9:09   ` Juan Manuel Macías
2021-12-27 12:53   ` Sebastian P. Luque
2021-12-27 13:28     ` Juan Manuel Macías
2021-12-27 17:16       ` Sebastian P. Luque
2021-12-27 19:28         ` Juan Manuel Macías
2021-12-28 14:58 ` Eric S Fraga
2021-12-28 15:59   ` Seb
2021-12-28 16:26     ` Eric S Fraga

Code repositories for project(s) associated with this 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).