From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mp2.migadu.com ([2001:41d0:403:58f0::]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) by ms13.migadu.com with LMTPS id oGPfF2nOa2fN3wAAe85BDQ:P1 (envelope-from ) for ; Wed, 25 Dec 2024 09:20:41 +0000 Received: from aspmx1.migadu.com ([2001:41d0:403:58f0::]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) by mp2.migadu.com with LMTPS id oGPfF2nOa2fN3wAAe85BDQ (envelope-from ) for ; Wed, 25 Dec 2024 10:20:41 +0100 X-Envelope-To: larch@yhetil.org Authentication-Results: aspmx1.migadu.com; dkim=pass header.d=posteo.net header.s=2017 header.b=VTK7iS9r; spf=pass (aspmx1.migadu.com: domain of "emacs-orgmode-bounces+larch=yhetil.org@gnu.org" designates 209.51.188.17 as permitted sender) smtp.mailfrom="emacs-orgmode-bounces+larch=yhetil.org@gnu.org"; dmarc=pass (policy=none) header.from=posteo.net ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=yhetil.org; s=key1; t=1735118441; h=from:from:sender:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type:in-reply-to:in-reply-to: references:references:list-id:list-help:list-unsubscribe: list-subscribe:list-post:dkim-signature; bh=4LSTxBFz6BTdRNmqs4hhAUYy07QSGQe7UtoyrwCkUWU=; b=VKt1g+CRx/1rFn92pV4NA5ndjoLEQgach09JGrmelFi4mrPGFVJheMK2Fx2yEw5i9f9AjW UkA/BFFpqywwwAF2y1Y08KSnDOB5fTQdp6Vb3F+e0px4XGXpS7MdGZKmWbfbK9mrk0LAAi mR5zq556vPo/rXyKSqX6hqEm+5viCayCj/ryLdvMB/u1rsNMuvA5hpYLuwmW4VOjiIP5u+ JkPTen0m/0EKEVhqiZ2I9NFfJTfQtW4swy865PmG36tJKvN0WIfhqMZX1qEJThgsrlRIdq 21BE7rPhAR1k/UZ7tfQam60C1SxI92YQjwvfotN0iO5i3lrYCm0FdcYFNf2QAw== ARC-Authentication-Results: i=1; aspmx1.migadu.com; dkim=pass header.d=posteo.net header.s=2017 header.b=VTK7iS9r; spf=pass (aspmx1.migadu.com: domain of "emacs-orgmode-bounces+larch=yhetil.org@gnu.org" designates 209.51.188.17 as permitted sender) smtp.mailfrom="emacs-orgmode-bounces+larch=yhetil.org@gnu.org"; dmarc=pass (policy=none) header.from=posteo.net ARC-Seal: i=1; s=key1; d=yhetil.org; t=1735118441; a=rsa-sha256; cv=none; b=p3l7odmLk+7ODW3J6gvPJLRiqOyugiFuq1nRoVHJRYmVVXvGy3AB3n0sxjHZYSIkcpTwWU RGCWDA1Rjj2+AmQ3n8yuT64323GQjbh5t9VEYe2xdScEJb35PE3C1+DCbgC/jTbbna3sbz AS65YoB/UR8ku/Y4Hv+wVhDmgi42YOJBnP4cF+/6hTRLqGJTvaWaQ9G5rFGViKQ00Lx0GZ 8m6A1RUhZpRbbxc7qW6I9aWShEq1Oe3k2ku523tPQlplbWwuT2rxEiU2+AYWYUCAlPBD0X 4+FkGR1/1ngEWD5wcUnFB9f2mMNSxnLnxOPcNyPTtFBH6KIDy7G97VB6J+Ucaw== Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by aspmx1.migadu.com (Postfix) with ESMTPS id DF90283C88 for ; Wed, 25 Dec 2024 10:20:40 +0100 (CET) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tQNYN-00029H-38; Wed, 25 Dec 2024 04:19:43 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tQNYL-000296-Dy for emacs-orgmode@gnu.org; Wed, 25 Dec 2024 04:19:41 -0500 Received: from mout01.posteo.de ([185.67.36.65]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tQNYI-0007g0-H8 for emacs-orgmode@gnu.org; Wed, 25 Dec 2024 04:19:40 -0500 Received: from submission (posteo.de [185.67.36.169]) by mout01.posteo.de (Postfix) with ESMTPS id A480F240027 for ; Wed, 25 Dec 2024 10:19:34 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=posteo.net; s=2017; t=1735118374; bh=0FA2vKOmtFMcjXlIoUH3UZgrnDNLPwX8SH4tBGaJlMs=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version:Content-Type: From; b=VTK7iS9rcD/2fJ98gs5ynUYBVv3vw95nHB1vor1ma5fBjmBxGgP0WlZdkIsmB8Vet DQqJER1uFA8nAHGlJkrAEp45N7YCSTNmQr/E2AaXBFOnJCSrDWKImGnrN2w5jt6XWx zqLLNb+v5XGCLHemvjdjtepvMjQWwoyg6UQwyksJe3Dr8Tcm1Zd3cs3iqaRu625C4V B2w/HpCgteJt2ZYFV8f69ksDYYDN2qMB/BQQ2OItZ741CMXhdSWhRbgRCn6pXOHb1a wvRfu65ESEcOxrHXQ0JY+pA/acBkOPCOo753+r36wmWgMcONQWJPIC0oOCVrh7y+S1 Panvbt3q2H9nA== Received: from customer (localhost [127.0.0.1]) by submission (posteo.de) with ESMTPSA id 4YJ5n155Wbz6tw8; Wed, 25 Dec 2024 10:19:33 +0100 (CET) From: Ihor Radchenko To: Juan Manuel =?utf-8?Q?Mac=C3=ADas?= Cc: 8dcc <8dcc.git@gmail.com>, emacs-orgmode@gnu.org Subject: Re: Customize list of blocks that use "\footnotemark" in `org-latex-footnote-reference' In-Reply-To: <87r09p89a7.fsf@posteo.net> References: <87bk0u9k6l.fsf@gmail.com> <87r09p89a7.fsf@posteo.net> Date: Wed, 25 Dec 2024 09:21:04 +0000 Message-ID: <87o71015kv.fsf@localhost> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" Received-SPF: pass client-ip=185.67.36.65; envelope-from=yantar92@posteo.net; helo=mout01.posteo.de X-Spam_score_int: -43 X-Spam_score: -4.4 X-Spam_bar: ---- X-Spam_report: (-4.4 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_MED=-2.3, RCVD_IN_MSPIKE_H3=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: emacs-orgmode@gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: "General discussions about Org-mode." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-orgmode-bounces+larch=yhetil.org@gnu.org Sender: emacs-orgmode-bounces+larch=yhetil.org@gnu.org X-Migadu-Flow: FLOW_IN X-Migadu-Country: US X-Migadu-Scanner: mx11.migadu.com X-Migadu-Spam-Score: -5.08 X-Spam-Score: -5.08 X-Migadu-Queue-Id: DF90283C88 X-TUID: TsicoAMEVzgz --=-=-= Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable Juan Manuel Mac=C3=ADas writes: > 8dcc writes: > >> I am exporting an Org file that contains a large verse block to >> LaTeX. This verse block contains footnotes, but they appear in the page >> where the LaTeX verse environment ends. I looked at the exported .tex >> file and I noticed that it was using "\footnotemark" and >> "\footnotetext[N]{...}", instead of "\footnote{...}". > ... > I seem to remember that the problem you describe goes back to how Org > understood the footnote text. When exporting to LaTeX, each line of a > footnote was understood as if it were a verse, and Org added \\ at the > end. Hence the use of \footnotemark and the > =E2=80=98org-latex--delayed-footnotes-definitions=E2=80=99 function. Please try the attached tentative fix. I limited special verse contents processing to plain-text directly inside verse blocks (as in Org AST), except plain text inside inline footnote definitions. --=-=-= Content-Type: text/x-patch Content-Disposition: inline; filename=0001-ox-latex-Put-footnotes-near-their-first-reference-in.patch >From 5c50a75c9014d8712a239bd48293114d6520384a Mon Sep 17 00:00:00 2001 Message-ID: <5c50a75c9014d8712a239bd48293114d6520384a.1735118328.git.yantar92@posteo.net> From: Ihor Radchenko Date: Wed, 25 Dec 2024 10:15:39 +0100 Subject: [PATCH] ox-latex: Put footnotes near their first reference in verses * lisp/ox-latex.el (org-latex-footnote-reference): Do not push footnote definition to the end of the verse. When verse spans multiple pages, this makes all the footnotes appear at the last page rather than near the page where a footnote is defined/references. (org-latex--plain-text-verse-block): New helper function preserving special verse formatting. Extracted from `org-latex-verse-block'. (org-latex-plain-text): Limit special formatting of verse block contents to plain text only, and only for plain text nodes that are inside verse block, but not inside (inline) footnote rereferences. (org-latex-verse-block): Rely upon CONTENTS being properly formatted already via plain-text transcoder. Except trailing and leading blank lines that may not be reliably detected before we assemble to full CONTENTS. This implements an alternative fix to https://list.orgmode.org/orgmode/87sg8prant.fsf@posteo.net/ that does not have a downside of putting all the references to the last page of the verse. Reported-by: 8dcc <8dcc.git@gmail.com> Link: https://orgmode.org/list/87bk0u9k6l.fsf@gmail.com --- lisp/ox-latex.el | 115 +++++++++++++++++++--------------- testing/lisp/test-ox-latex.el | 27 ++++++++ 2 files changed, 91 insertions(+), 51 deletions(-) diff --git a/lisp/ox-latex.el b/lisp/ox-latex.el index 4b2e797d08..743c6340d4 100644 --- a/lisp/ox-latex.el +++ b/lisp/ox-latex.el @@ -2237,11 +2237,10 @@ (defun org-latex-footnote-reference (footnote-reference _contents info) (org-export-get-footnote-definition footnote-reference info) info t))) ;; Use \footnotemark if reference is within another footnote - ;; reference, footnote definition, table cell, verse block, or - ;; item's tag. + ;; reference, footnote definition, table cell, or item's tag. ((or (org-element-lineage footnote-reference - '(footnote-reference footnote-definition - table-cell verse-block)) + '( footnote-reference footnote-definition + table-cell)) (org-element-type-p (org-element-parent-element footnote-reference) 'item)) "\\footnotemark") @@ -3119,6 +3118,8 @@ (defun org-latex-plain-text (text info) "{[}" output nil nil 1)) + ;; When inside verse block, use special rules. + (setq output (org-latex--plain-text-verse-block output text)) ;; Return value. output)) @@ -4188,6 +4189,48 @@ (defun org-latex-verbatim (verbatim _contents info) ;;;; Verse Block +(defun org-latex--plain-text-verse-block (contents plain-text) + "Format CONTENTS if PLAIN-TEXT is inside verse environment. +INFO is the communication plist. +Return CONTENTS unchanged when TEXT is not inside verse environment or +when TEXT is a part of footnote reference. + +In a verse environment, add a line break to each newline character and +change each white space at beginning of a line into a normal space, +calculated with `\\fontdimen2\\font'. One or more blank lines between +lines are exported as a single blank line. If the `:lines' attribute +is used, the last verse of each stanza ends with the string `\\!', +according to the syntax of the `verse' package. The separation between +stanzas can be controlled with the length `\\stanzaskip', of the +aforementioned package. If the `:literal' attribute is used, all +blank lines are preserved and exported as `\\vspace*{\\baselineskip}', +including the blank lines before or after CONTENTS." + (if-let* ((verse-block (org-element-lineage plain-text 'verse-block)) + ;; VALUEFORM + ((not (org-element-lineage plain-text 'footnote-reference)))) + (let* ((lin (org-export-read-attribute :attr_latex verse-block :lines)) + (lit (org-export-read-attribute :attr_latex verse-block :literal))) + (replace-regexp-in-string + "^[ \t]+" (lambda (m) (format "\\hspace*{%d\\fontdimen2\\font}" (length m))) + (replace-regexp-in-string + (if (not lit) + (rx-to-string + `(seq (group "\\\\\n") + (1+ (group line-start (0+ space) "\\\\\n")))) + "^[ \t]*\\\\$") + (if (not lit) + (if lin "\\\\!\n\n" "\n\n") + "\\vspace*{\\baselineskip}") + (replace-regexp-in-string + "\\([ \t]*\\\\\\\\\\)?[ \t]*\n" + "\\\\\n" + contents + nil t) + nil t) + nil t)) + ;; Not in verse block, return CONTENTS unchanged. + contents)) + (defun org-latex-verse-block (verse-block contents info) "Transcode a VERSE-BLOCK element from Org to LaTeX. CONTENTS is verse block contents. INFO is a plist holding @@ -4195,57 +4238,27 @@ (defun org-latex-verse-block (verse-block contents info) (let* ((lin (org-export-read-attribute :attr_latex verse-block :lines)) (latcode (org-export-read-attribute :attr_latex verse-block :latexcode)) (cent (org-export-read-attribute :attr_latex verse-block :center)) - (lit (org-export-read-attribute :attr_latex verse-block :literal)) (attr (concat - (if cent "[\\versewidth]" "") - (if lin (format "\n\\poemlines{%s}" lin) "") - (if latcode (format "\n%s" latcode) ""))) + (if cent "[\\versewidth]" "") + (if lin (format "\n\\poemlines{%s}" lin) "") + (if latcode (format "\n%s" latcode) ""))) + (lit (org-export-read-attribute :attr_latex verse-block :literal)) (versewidth (org-export-read-attribute :attr_latex verse-block :versewidth)) (vwidth (if versewidth (format "\\settowidth{\\versewidth}{%s}\n" versewidth) "")) (linreset (if lin "\n\\poemlines{0}" ""))) - (concat - (org-latex--wrap-label - verse-block - ;; In a verse environment, add a line break to each newline - ;; character and change each white space at beginning of a line - ;; into a normal space, calculated with `\fontdimen2\font'. One - ;; or more blank lines between lines are exported as a single - ;; blank line. If the `:lines' attribute is used, the last - ;; verse of each stanza ends with the string `\\!', according to - ;; the syntax of the `verse' package. The separation between - ;; stanzas can be controlled with the length `\stanzaskip', of - ;; the aforementioned package. If the `:literal' attribute is - ;; used, all blank lines are preserved and exported as - ;; `\vspace*{\baselineskip}', including the blank lines before - ;; or after CONTENTS. - (format "%s\\begin{verse}%s\n%s\\end{verse}%s" - vwidth - attr - (replace-regexp-in-string - "^[ \t]+" (lambda (m) (format "\\hspace*{%d\\fontdimen2\\font}" (length m))) - (replace-regexp-in-string - (if (not lit) - (rx-to-string - `(seq (group "\\\\\n") - (1+ (group line-start (0+ space) "\\\\\n")))) - "^[ \t]*\\\\$") - (if (not lit) - (if lin "\\\\!\n\n" "\n\n") - "\\vspace*{\\baselineskip}") - (replace-regexp-in-string - "\\([ \t]*\\\\\\\\\\)?[ \t]*\n" - "\\\\\n" - (if (not lit) - (concat (org-trim contents t) "\n") - contents) - nil t) - nil t) - nil t) - linreset) - info) - ;; Insert footnote definitions, if any, after the environment, so - ;; the special formatting above is not applied to them. - (org-latex--delayed-footnotes-definitions verse-block info)))) + (org-latex--wrap-label + verse-block + (format "%s\\begin{verse}%s\n%s\\end{verse}%s" + vwidth attr + ;; If the `:literal' attribute is used, all blank lines + ;; are preserved and exported as + ;; `\\vspace*{\\baselineskip}', including the blank lines + ;; before or after CONTENTS. + (if (not lit) + (concat (org-trim contents t) "\n") + contents) + linreset) + info))) ;;; End-user functions diff --git a/testing/lisp/test-ox-latex.el b/testing/lisp/test-ox-latex.el index 892ac44374..b75921ae78 100644 --- a/testing/lisp/test-ox-latex.el +++ b/testing/lisp/test-ox-latex.el @@ -79,6 +79,33 @@ (ert-deftest test-ox-latex/verse () lorem ipsum dolor\\\\ lorem ipsum dolor\\\\ +\\end{verse}"))) + ;; Footnotes inside verse blocks + (org-test-with-exported-text + 'latex + "#+begin_verse +lorem +ipsum[fn::Foo + +bar] +dolor +#+end_verse + +[fn:1] Lorem ipsum dolor sit amet, consectetuer adipiscing elit. +Donec hendrerit tempor. + +Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Donec +hendrerit tempor tellus. +" + (goto-char (point-min)) + (should + (search-forward + "\\begin{verse} +lorem\\\\ +ipsum\\footnote{Foo + +bar}\\\\ +dolor\\\\ \\end{verse}")))) (ert-deftest test-ox-latex/longtable () -- 2.47.1 --=-=-= Content-Type: text/plain -- Ihor Radchenko // yantar92, Org mode maintainer, Learn more about Org mode at . Support Org development at , or support my work at --=-=-=--