From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mp1 ([2001:41d0:2:bcc0::]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) by ms0.migadu.com with LMTPS id 4OQ6FENcN2HLNAEAgWs5BA (envelope-from ) for ; Tue, 07 Sep 2021 14:34:11 +0200 Received: from aspmx1.migadu.com ([2001:41d0:2:bcc0::]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) by mp1 with LMTPS id mCMMEENcN2H5cAAAbx9fmQ (envelope-from ) for ; Tue, 07 Sep 2021 12:34:11 +0000 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 852232D677 for ; Tue, 7 Sep 2021 14:34:10 +0200 (CEST) Received: from localhost ([::1]:56722 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mNaIg-0007BS-Nv for larch@yhetil.org; Tue, 07 Sep 2021 08:34:06 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:42312) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mNa6v-0000nw-Hb for emacs-orgmode@gnu.org; Tue, 07 Sep 2021 08:21:57 -0400 Received: from ciao.gmane.io ([116.202.254.214]:42564) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mNa6t-00071Z-Ik for emacs-orgmode@gnu.org; Tue, 07 Sep 2021 08:21:57 -0400 Received: from list by ciao.gmane.io with local (Exim 4.92) (envelope-from ) id 1mNa6p-0008TB-2f for emacs-orgmode@gnu.org; Tue, 07 Sep 2021 14:21:51 +0200 X-Injected-Via-Gmane: http://gmane.org/ To: emacs-orgmode@gnu.org From: Maxim Nikulin Subject: [PATCH] ox-latex: Allow percent sign in 'src-block' caption Date: Tue, 7 Sep 2021 19:21:42 +0700 Message-ID: References: Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="------------5105C38E7C79F39FD5425BA1" User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Thunderbird/78.13.0 X-Woof-Patch: Confirmed In-Reply-To: Content-Language: en-US Received-SPF: pass client-ip=116.202.254.214; envelope-from=geo-emacs-orgmode@m.gmane-mx.org; helo=ciao.gmane.io X-Spam_score_int: 28 X-Spam_score: 2.8 X-Spam_bar: ++ X-Spam_report: (2.8 / 5.0 requ) BAYES_00=-1.9, DKIM_ADSP_CUSTOM_MED=0.001, FORGED_GMAIL_RCVD=1, FORGED_MUA_MOZILLA=2.309, FREEMAIL_FORGED_FROMDOMAIN=0.25, FREEMAIL_FROM=0.001, HEADER_FROM_DIFFERENT_DOMAINS=0.249, NML_ADSP_CUSTOM_MED=0.9, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: emacs-orgmode@gnu.org X-Mailman-Version: 2.1.23 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" X-Migadu-Flow: FLOW_IN ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=yhetil.org; s=key1; t=1631018050; h=from:from:sender:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to: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; bh=RLkdPnXn2O5viSF5cfyPtdvZ2T/gCe5i0d26P75aTI0=; b=g9AQUxd6bIzMkqeCqkTuDaydMl8rBEYKRQa9QCtxWz1+FNKzGoeoM6wk/qJYjkvfy9q252 dlb1E2Fsl658mFQY0BjlM0hk/wu7mO6N+yr1u77Y9EgMZYJtbp69HE/67OQrYM6bWGXNqh jQOiIPNjnVycofZx+es+f51yqgHkfsvucc5CxjPidZF+yZaBfSuUryqwHriUz7ekgf1jQN RGjfvr859ITK7MV2w8sGM0I41NPjJNPzH3bR1a9dIdySKEzd8wt3NwLlRcid1D79H1Xtej FUhQ5fYi/syXVdidfx2He9KhNH8QGyF8Okc09Ixrnjw8jFi+J7Jg1IEijvScyw== ARC-Seal: i=1; s=key1; d=yhetil.org; t=1631018050; a=rsa-sha256; cv=none; b=UyNGfpqDNNPo8eyJyoSngYdAUe1Vb0oYyYU8B8KPLriecg5J7NkGgdcyy7GNgVJOPnV06n TrsERhtNQ+oRF1V2XzXQqB1G4jHqto1xlDnKyYG4V6sbr1/TDrShBlylDRizMTnhfVXBbw yOZpWfbJJ2ouFMvBhnkaFfyK7GlpLHhXfDgFFeDNIDDiL6Mjz9PjE21E1wIF2h1YqR0kJe 0bf3vADtqwjnecJh+pryj+J/jSVJxXPwjwXKvnhwyv6MG2Z6miQD8OfCNsG+8XhMtbOX54 Bma14ZnExhVuz9Y0W78Nx+So1bVnHq2wWDg5H1/kXPkebnhZUs+3RLGdFrB/nA== ARC-Authentication-Results: i=1; aspmx1.migadu.com; dkim=none; dmarc=fail reason="SPF not aligned (relaxed), No valid DKIM" header.from=gmail.com (policy=none); spf=pass (aspmx1.migadu.com: domain of emacs-orgmode-bounces@gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=emacs-orgmode-bounces@gnu.org X-Migadu-Spam-Score: -0.21 Authentication-Results: aspmx1.migadu.com; dkim=none; dmarc=fail reason="SPF not aligned (relaxed), No valid DKIM" header.from=gmail.com (policy=none); spf=pass (aspmx1.migadu.com: domain of emacs-orgmode-bounces@gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=emacs-orgmode-bounces@gnu.org X-Migadu-Queue-Id: 852232D677 X-Spam-Score: -0.21 X-Migadu-Scanner: scn0.migadu.com X-TUID: n/ENf4/+8ogE This is a multi-part message in MIME format. --------------5105C38E7C79F39FD5425BA1 Content-Type: text/plain; charset=windows-1252 Content-Transfer-Encoding: 7bit On 03/09/2021 19:17, Maxim Nikulin wrote: > On 30/07/2021 22:00, Charest, Luc wrote: >> >> org-latex-src-block: Not enough arguments for format string > > Confirmed > > User input is combined with format string in `org-latex-src-block' > so percent character in caption is treated as a format specifier.> Maybe emacs versions newer than 26 does not throw an error > on extra specifier with missed argument. =:latex-cation-above nil= > might still cause corrupted LaTeX code. I have decided that it is better to provide a partial fix than to leave the problem as is. This patch covers only plain verbatim environment, more advanced formatting using listings or minted should be addressed by another change (Anybody?). Do not close the bug after applying this patch. --------------5105C38E7C79F39FD5425BA1 Content-Type: text/x-patch; charset=UTF-8; name="0001-ox-latex-Allow-percent-sign-in-src-block-caption.patch" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename*0="0001-ox-latex-Allow-percent-sign-in-src-block-caption.patch" >From 5e6930e3c3d30f13e6e33a6fc504b445cacc579d Mon Sep 17 00:00:00 2001 In-Reply-To: References: From: Max Nikulin Date: Tue, 7 Sep 2021 19:01:11 +0700 Subject: [PATCH] ox-latex: Allow percent sign in 'src-block' caption * lisp/ox-latex.el (org-latex-src-block): Prevent leak of percent sign from caption to `format' first argument causing export failure due to insufficient argument number. The fix covers only the case of verbatim environment. * testing/lisp/test-ox.el (test-org-export/latex-src-block-verbatim-caption): New test for src block LaTeX export with cases of various formatting of caption and verbatim environment. Check that percent signs in caption and source block body do not lead to errors. Reported-by: Charest, Luc --- lisp/ox-latex.el | 30 ++++++------- testing/lisp/test-ox.el | 97 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 111 insertions(+), 16 deletions(-) diff --git a/lisp/ox-latex.el b/lisp/ox-latex.el index 99076f8b9..b325b8892 100644 --- a/lisp/ox-latex.el +++ b/lisp/ox-latex.el @@ -2994,22 +2994,20 @@ contextual information." (cond ;; Case 1. No source fontification. ((or (not lang) (not listings)) - (let* ((caption-str (org-latex--caption/label-string src-block info)) - (float-env - (cond ((string= "multicolumn" float) - (format "\\begin{figure*}[%s]\n%s%%s\n%s\\end{figure*}" - (plist-get info :latex-default-figure-position) - (if caption-above-p caption-str "") - (if caption-above-p "" caption-str))) - (caption (concat - (if caption-above-p caption-str "") - "%s" - (if caption-above-p "" (concat "\n" caption-str)))) - (t "%s")))) - (format - float-env - (concat (format "\\begin{verbatim}\n%s\\end{verbatim}" - (org-export-format-code-default src-block info)))))) + (let ((caption-str (org-latex--caption/label-string src-block info)) + (verbatim (format "\\begin{verbatim}\n%s\\end{verbatim}" + (org-export-format-code-default src-block info)))) + (cond ((string= "multicolumn" float) + (format "\\begin{figure*}[%s]\n%s%s\n%s\\end{figure*}" + (plist-get info :latex-default-figure-position) + (if caption-above-p caption-str "") + verbatim + (if caption-above-p "" caption-str))) + (caption (concat + (if caption-above-p caption-str "") + verbatim + (if caption-above-p "" (concat "\n" caption-str)))) + (t verbatim)))) ;; Case 2. Custom environment. (custom-env (let ((caption-str (org-latex--caption/label-string src-block info)) diff --git a/testing/lisp/test-ox.el b/testing/lisp/test-ox.el index 3f39645af..54558041b 100644 --- a/testing/lisp/test-ox.el +++ b/testing/lisp/test-ox.el @@ -3907,6 +3907,103 @@ Another text. (ref:text) (org-export-format-code-default (org-element-map tree 'src-block #'identity info t) info)))))) +(ert-deftest test-org-export/latex-src-block-verbatim-caption () + "Test `org-latex-src-block' caption for verbatim environment. +Check that percent sign does not become a part of format. +This test does not cover listings and custom environments." + (let ((export + (lambda (buffer-text) + (org-test-with-parsed-data + buffer-text + (let* ((backend (org-export-get-backend 'latex)) + (info (org-combine-plists + (org-export--get-export-attributes backend) + (org-export-get-environment backend))) + (result (org-latex-src-block + (org-element-map tree 'src-block #'identity info t) + t info))) + ;; Remove properties to make failure reports more clear. + (set-text-properties 0 (length result) nil result) + result))))) + + (should (equal + "\ +\\begin{verbatim} +\"No float, no listings, 20%S\" +\\end{verbatim} +\\captionof{figure}{Caption of verbatim is below, 20\\%s} +" + (funcall export + "\ +#+CAPTION: Caption of verbatim is below, 20%s +#+BEGIN_SRC emacs-lisp + \"No float, no listings, 20%S\" +#+END_SRC"))) + + ;; `org-latex-caption-above' has no associated property or keyword. + (should (equal + "\ +\\captionof{figure}{Caption of verbatim is above, 40\\%s} +\\begin{verbatim} +\"No float, no listings, 40%S\" +\\end{verbatim}" + (let ((org-latex-caption-above t)) + (funcall export + "\ +#+CAPTION: Caption of verbatim is above, 40%s +#+BEGIN_SRC emacs-lisp + \"No float, no listings, 40%S\" +#+END_SRC")))) + + (should (equal + "\ +\\begin{figure*}[tp] +\\caption{Caption is above, 60\\%s} +\\begin{verbatim} +\"Float, no listings, 60%S\" +\\end{verbatim} +\\end{figure*}" + (let ((org-latex-caption-above t) + (org-latex-default-figure-position "tp")) + (funcall export + "\ +#+CAPTION: Caption is above, 60%s +#+ATTR_LATEX: :float multicolumn +#+BEGIN_SRC emacs-lisp + \"Float, no listings, 60%S\" +#+END_SRC")))) + + (should (equal + "\ +\\begin{figure*}[tp] +\\begin{verbatim} +\"Float, no lang, listings, 80%S\" +\\end{verbatim} +\\caption{Caption is below, 60\\%s} +\\end{figure*}" + (let ((org-latex-listings 'minted) ; inactive due to missing lang + (org-latex-default-figure-position "tp")) + ;; Namely "multicolumn" value to get just figure environment + ;; looks like a bug. + (funcall export + "\ +#+CAPTION: Caption is below, 60%s +#+ATTR_LATEX: :float multicolumn +#+BEGIN_SRC + \"Float, no lang, listings, 80%S\" +#+END_SRC")))) + + (should (equal + "\ +\\begin{verbatim} +\"No caption, no float, no listings, 100%S\" +\\end{verbatim}" + (funcall export + "\ +#+BEGIN_SRC emacs-lisp + \"No caption, no float, no listings, 100%S\" +#+END_SRC"))))) + ;;; Smart Quotes -- 2.25.1 --------------5105C38E7C79F39FD5425BA1--