chdemko / pandoc-latex-environment

Pandoc filter for adding LaTeX environement on specific div
https://pandoc-latex-environment.readthedocs.io/
BSD 3-Clause "New" or "Revised" License
33 stars 9 forks source link

Environments containing lists cause error #9

Closed jefelino closed 3 years ago

jefelino commented 4 years ago

A div containing an enumerated list at the beginning or the end causes pandoc-latex-environment to crash.

MWE:

pandoc -F pandoc-latex-environment --to=latex
---
pandoc-latex-environment:
    theorem: [Theorem]
---

::: Theorem

(a) Test.

:::
Error running filter pandoc-latex-environment:
Error in $.blocks[0].c[1][0].c: cannot unpack array of length 4 into a tuple of length 2

pandoc version 2.9.2.1, pandoc-latex-environment version 1.1.4, freshly installed yesterday. Python 2.7.

My guess is there has been some change to pandoc's internal representation causing this.

ctaaronsan commented 4 years ago

It appears that this bug only occurs when the list is the first or last block in the div. So e.g.

::: Theorem
1. test

xyz
:::

and

::: Theorem
abc

1. test
:::

both cause error, but this:

::: Theorem
abc

1. test

xyz
:::

works fine.

It seems that the bug is caused by these lines of code in pandoc_latex_environment.py

if pos == 1:
    replacement = [RawInline('tex', '\\begin{' + environment + '}' + title + '\n' + label)] + replacement
if pos == last:
    replacement = replacement + [RawInline('tex', '\n\\end{' + environment + '}')]

at lines 44 ~ 47. When the list is the first (pos == 1) or last (pos == last) block inside div, the RawInline was added incorrectly.

chdemko commented 4 years ago

Is it possible for you to propose a PR?

gengor-git commented 3 years ago

I'v had the same problem and played around with the code today.

I endet up with this fix. I placed and whole paragraph bevor and after the entire content. This leaves the original json objects untouched.

                for node in content:
                    node_content = node['c']
                    pos += 1
                    if pos == 1:
                        begin = [RawInline('tex', '\\begin{' + environment + '}' + title + '\n' + label)]
                        # Add the beginning Latex as a new paragraph to avoid conflict with bulletlists.
                        newconts.append(
                            {
                                't': 'Para',
                                'c': begin
                            }
                        )
                        # Now start adding the original content
                        newconts.append(
                            {
                                't': node['t'],
                                'c': node_content
                            }
                        )
                    elif pos == last:
                        end = [RawInline('tex', '\n\\end{' + environment + '}')]
                        # First add the original content.
                        newconts.append(
                            {
                                't': node['t'],
                                'c': node_content
                            }
                        )
                        # Then add the ending Latex as a new paragraph to avoid conflict with bulletlists.
                        newconts.append(
                            {
                                't': 'Para',
                                'c': end
                            }
                        )
                    else:
                        newconts.append(
                            {
                                't': node['t'],
                                'c': node_content
                            }
                        )

There's probably a more elegant way to get the same result. But for what it's worth, the bullet lists at beginning and end work now.

chdemko commented 3 years ago

Fix in code.

tmonjalo commented 3 years ago

The fix for the issue #9 made the issue #7 appears again.