kaushalmodi / ox-hugo

A carefully crafted Org exporter back-end for Hugo
https://ox-hugo.scripter.co
GNU General Public License v3.0
867 stars 130 forks source link

Take LaTeX preview images to export to hugo-md #670

Closed opensource-philosophy closed 1 year ago

opensource-philosophy commented 1 year ago

Hey @kaushalmodi, and thank you very much for this awesome tool!

I have something in between a question and a feature request. I’m trying to be as clear as possible, and am more than happy to provide you with more information if needed!

The General Problem

I am using .svg images to implement LaTeX images into my blog posts. This is mostly working just fine, but there is one drawback: LaTeX needs some code to be compiled twice to produce the desired results. Here is a MWE:

#+startup: latexpreview
#+options: tex:dvisvgm

#+LATEX_HEADER: \usepackage{tikz}
#+LATEX_HEADER: \usetikzlibrary{calc,tikzmark}

\begin{center}

\begin{tabular}{ll}
Here\tikzmark{n1} is a tikzmark. & \\
Here\tikzmark{N1} is another tikzmark. &
\end{tabular}

\begin{tikzpicture}[remember picture, overlay, align=center]
\coordinate(A1) at(pic cs:N1) {};
\coordinate(A2) at(pic cs:n1) {};
\draw[->] ($(A1.north)  +(0.1em,0.4ex)$) to[bend right=46, looseness=1]  ($(A2.south));
\end{tikzpicture}

\end{center}

If you compile it just once, the arrow will not be placed correctly. If you compile it twice, however, it is placed correctly. Thus, simply inserting the code into your org-hugo-file won’t do the trick.

My Solution Attempt

The way I tried to solve this was by writing a function which deletes the preview image at point and replaces it with the result of compiling the code twice:

(defun vitus/get-preview-img-path ()
  "Get the file path of the .svg image overlayed at point."
  (interactive)
  (let* ((forbuffer t)
         (fg
          (let ((color (plist-get org-format-latex-options
                                  :foreground)))
            (if forbuffer
                (cond
                 ((eq color 'auto)
                  (face-attribute face :foreground nil 'default))
                 ((eq color 'default)
                  (face-attribute 'default :foreground nil))
                 (t color))
              color)))
         (bg
          (let ((color (plist-get org-format-latex-options
                                  :background)))
            (if forbuffer
                (cond
                 ((eq color 'auto)
                  (face-attribute face :background nil 'default))
                 ((eq color 'default)
                  (face-attribute 'default :background nil))
                 (t color))
              color)))

         (context (org-element-context))
         (value (org-element-property :value context))
         (hash (sha1 (prin1-to-string
                      (list org-format-latex-header
                            org-latex-default-packages-alist
                            org-latex-packages-alist
                            org-format-latex-options
                            'forbuffer value fg bg))))
         (prefix (concat org-preview-latex-image-directory "org-ltximg"))
         (absprefix (expand-file-name prefix default-directory))
         (imagetype "svg")
         (movefile (format "%s_%s.%s" absprefix hash imagetype)))
    movefile))

(defun vitus/tikz-preview-image ()
  "Compile the image at point three times to make sure the correct LaTeX image is created."
  (interactive)
  (let ((org-preview-latex-process-alist
         '((dvisvgm :programs
                    ("latex" "dvisvgm")
                    :description "dvi > svg" :message "you need to install the programs: latex and dvisvgm." :use-xcolor t :image-input-type "xdv" :image-output-type "svg" :image-size-adjust
                    (3 . 1.5)
                    :latex-compiler
                    ("xelatex -no-pdf -interaction nonstopmode -output-directory %o %f ; xelatex -no-pdf -interaction nonstopmode -output-directory %o %f ; xelatex -no-pdf -interaction nonstopmode -output-directory %o %f")
                    :image-converter
                    ("dvisvgm %f -n -b min -c %S -o %O"))))
        (datum (org-element-context)))
    (if (memq (org-element-type datum) '(latex-environment latex-fragment))
        (let ((beg (org-element-property :begin datum))
              (end (org-element-property :end datum)))
          (org-clear-latex-preview beg end)
          (message "Creating LaTeX preview...")
          (delete-file (vitus/get-preview-img-path))
          (org--latex-preview-region beg end)
          (message "Creating LaTeX preview... done."))
      (error "Point not on a LaTeX-fragment"))))

The way to make xelatex compile three times can be found in the :latex-compiler key: I just iterated the bash command three times to make sure it is working.

The Actual Problem

Now I am able to actually see the correct inline-images, but the images that are exported by ox-hugo are still the wrong ones – those which were compiled once! To stay with the example, the arrow is still not shown correctly. I cannot seem to grasp why and thought you might have an idea why this is happening, or how to resolve this.

As to the feature-request: I do not know too much about your code, but would it be possible to define a variable which stores a list of keywords that are searched for in the LaTeX-fragment at hand, and write an if-statement which compiles the code for those fragments that match at least one of these keywords not once but twice? This would automate the process. Also, is there a way to use src-blocks to produce LaTeX-images which are then exported to hugo-md?

Thanks for the efforts, and all the best!

kaushalmodi commented 1 year ago

Hello, I am not sure if this issue has to do with ox-hugo. I rely on the Org core for the LaTeX parsing.

Also, if you see the issue when using ox-html as well, and if you can get that fixed for that, it will get auto-fixed for ox-hugo too.

Sorry, I don't have much to add.

Also, I won't be able to respond for the next 3 weeks as I will be on vacation.

kaushalmodi commented 1 year ago

Hello, I need to close this issue as I believe that it's out of the scope of ox-hugo development. If I've misunderstood this, and if the same issue is not seen with other Org exporters, please let me know and we can discuss further.