Re: Verse block and separations (was: [bug] `org-latex-line-break-safe' breaks the export of verse blocks to LaTeX)

2022-10-19 Thread Max Nikulin

On 16/10/2022 23:33, Juan Manuel Macías wrote:

   (replace-regexp-in-string
"^[ \t]+" (lambda (m) (format "\\hspace*{%dem}" (length m)))
(replace-regexp-in-string
 "\\(\n\\)+\\([ \t]*\\)+" "\n"
 (replace-regexp-in-string
  "\\([ \t]*\\)?[ \t]*\n" "\n"
  (setq contents
(if lin
(replace-regexp-in-string "\\(\n\\)+\\([ \t]*\n\\)+" 
"!\n\n"
  contents)
  contents)) nil t) nil t) nil t) linreset)


I had a hope, it is possible to do it in a single pass of 
`replace-regexp-in-string', but unfortunately the function does not 
allow to make conditional substitution based on (rx (optional (group 
string-start))) (a bug?).


I still prefer to avoid replacement of latex newlines back to empty 
string. Though I am really happy with the following code, I expected a 
more concise snippet. Unit tests may found bugs in it.


(let ((contents "\n\n 0  \n\n\na b\nc d e  \n\n\nf g  \n   h i\n\n"))
  ;; Strip leading newlines.
  (setq contents
(replace-regexp-in-string
 (rx string-start (1+ (0+ blank) ?\n)) ""
 contents 'fixed-case 'literal))
  ;; Add explicit line breaks and strip trailing spaces.
  (setq contents
(replace-regexp-in-string
 (rx (0+ blank) ?\n
 (optional (group (1+ (0+ blank) ?\n)))
 (optional (group (0+ blank) (not (any blank ?\n)
 (lambda (m)
   (let ((par (match-string 1 m))
 (next (match-string 2 m)))
 (if next
 (concat (if par "\n\n" "\n")
 next)
   "")))
 contents 'fixed-case 'literal))
  ;; Indented lines.
  (replace-regexp-in-string
   (rx line-start (1+ blank))
   (lambda (m) (format "\\hspace*{%dem}" (length m)))
   contents 'fixed-case 'literal))

Feel free to use it for inspiration during your work on a patch.




Re: Verse block and separations (was: [bug] `org-latex-line-break-safe' breaks the export of verse blocks to LaTeX)

2022-10-17 Thread Max Nikulin

On 16/10/2022 23:33, Juan Manuel Macías wrote:

Max Nikulin writes:


I am surprised that \vspace is added instead of empty line between
stanzas.


First of all, I'm afraid that in my previous post I mixed up two
different issues: the verse block bug and my personal opinions about the
new added constant. I should have separated these topics, sorry.


It was me who raised issues with verse exporter in discussion of newline 
commands. I was impressed by hard to read elisp code and its result.



I answer here what you comment about the verse blocks and later I will
open a different thread for the other issue.


I am trying to read with enough attention this discussion, for a while I 
have a couple of remarks specific to poetry.



with the stanzaskip \length. I remember that I commented on this anomaly
here on the list, a long time ago, but I can't find the original
message...


https://list.orgmode.org/87k0tjasty@posteo.net/
Juan Manuel Macías. [Small suggestion] on exporting verse blocks to 
LaTeX and vertical spaces. Tue, 15 Dec 2020 18:21:13 +0100


https://list.orgmode.org/?q=verse+vspace


In my init I have redefined the verse block like this, so that there is
a white line between stanzas, not \vspace


Do you still have real problems with current main HEAD state after 
adjusting patterns in your code?



(format "%s\\begin{verse}%s\n%s\\end{verse}%s"
   vwidth


I have not verified it, but since I am not aware of a group wrapping 
this fragment, I suspect that :versewidth may have global effect, not 
limited to the current environment. Org variant of the function is 
rather close at this point.







Re: Verse block and separations (was: [bug] `org-latex-line-break-safe' breaks the export of verse blocks to LaTeX)

2022-10-17 Thread Ihor Radchenko
Juan Manuel Macías  writes:

> Yes, you're right: that \vspace is the normal behavior of the block when
> exporting to LaTeX, and it is certainly not quite correct. In LaTeX,
> both the out-of-the-box verse environment and the one provided by the
> 'verse' package (which, typographically speaking, is the correct way to
> represent verses in LaTeX) do not add a \vspace between stanzas. In the
> LaTeX input the separation between stanzas is expressed by an (at least)
> empty line. In fact, that space can be controlled by the verse package
> with the stanzaskip \length. I remember that I commented on this anomaly
> here on the list, a long time ago, but I can't find the original
> message...

I checked git log and the current approach for verse export dates back
to initial versions of ox-latex. I am pretty sure that it should be
improved.

> In my init I have redefined the verse block like this, so that there is
> a white line between stanzas, not \vspace (I have also added some things
> for the verse package, so that the numbering of verses is not broken).
> So your example would produce a white line under \begin{verse}, not the
> current \vspace, which would be irrelevant to LaTeX. But this is only a
> hack:

Could you provide a patch?

-- 
Ihor Radchenko // yantar92,
Org mode contributor,
Learn more about Org mode at .
Support Org development at ,
or support my work at 



Verse block and separations (was: [bug] `org-latex-line-break-safe' breaks the export of verse blocks to LaTeX)

2022-10-16 Thread Juan Manuel Macías
Max Nikulin writes:

> The following is irrelevant to the recent changes. I have tried
>
>  >8 
> text
>
> #+begin_verse
>
> a b
> c d
>
> e f
> g h
> #+end_verse
>
>  8< 
>
> With the fix Ihor committed today I have got
>
>  >8 
> text
> \begin{verse}
> \vspace*{1em}
> a b\\\empty
> c d\\\empty
> \vspace*{1em}
> e f\\\empty
> g h\\\empty
> \end{verse}
>  8< 
>
> My expectation was
>  >8 
> \begin{verse}
> a b\\\empty
> c d
>
> e f\\\empty
> g h
> \end{verse}
>  8< 
>
> I am surprised that \vspace is added instead of empty line between 
> stanzas. Is there a reason to override LaTeX defaults? If such reason 
> exists would not it better to add
>
>  \parskip=1em plus 0.5em minus 0.25em\relax
>
> before first verse line? Is hard coded rigid vertical space acceptable 
> when high quality output is desired? \vspace before first line looks 
> like a bug. Frankly speaking, nested calls of `replace-regexp-in-string' 
> makes the code hard to read.
>
> P.S. I have not found exact citation, but I noticed a mention: Lamport 
> expected that verse environment would get negative feedback from poets.

First of all, I'm afraid that in my previous post I mixed up two
different issues: the verse block bug and my personal opinions about the
new added constant. I should have separated these topics, sorry.

I answer here what you comment about the verse blocks and later I will
open a different thread for the other issue.

Yes, you're right: that \vspace is the normal behavior of the block when
exporting to LaTeX, and it is certainly not quite correct. In LaTeX,
both the out-of-the-box verse environment and the one provided by the
'verse' package (which, typographically speaking, is the correct way to
represent verses in LaTeX) do not add a \vspace between stanzas. In the
LaTeX input the separation between stanzas is expressed by an (at least)
empty line. In fact, that space can be controlled by the verse package
with the stanzaskip \length. I remember that I commented on this anomaly
here on the list, a long time ago, but I can't find the original
message...

In my init I have redefined the verse block like this, so that there is
a white line between stanzas, not \vspace (I have also added some things
for the verse package, so that the numbering of verses is not broken).
So your example would produce a white line under \begin{verse}, not the
current \vspace, which would be irrelevant to LaTeX. But this is only a
hack:

  (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
  contextual information."
(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))
 (attr (concat
(if cent "[\\versewidth]" "")
(if lin (format "\n\\poemlines{%s}" lin) "")
(if latcode (format "\n%s" latcode) "")))
 (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}" "")))
  (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 space of 1 em.  Also change each blank line with
   ;; a vertical space of 1 em.
   (format "%s\\begin{verse}%s\n%s\\end{verse}%s"
   vwidth
   attr
   (replace-regexp-in-string
"^[ \t]+" (lambda (m) (format "\\hspace*{%dem}" (length m)))
(replace-regexp-in-string
 "\\(\n\\)+\\([ \t]*\\)+" "\n"
 (replace-regexp-in-string
  "\\([ \t]*\\)?[ \t]*\n" "\n"
  (setq contents
(if lin
(replace-regexp-in-string "\\(\n\\)+\\([ 
\t]*\n\\)+" "!\n\n"
  contents)
  contents)) nil t) nil t) nil t) linreset)
   info)))