Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Code environments #7

Open
devmotion opened this issue Sep 11, 2022 · 2 comments
Open

Code environments #7

devmotion opened this issue Sep 11, 2022 · 2 comments

Comments

@devmotion
Copy link
Contributor

The JSS style guide says:

In short, there are two options: a) if no distinction between input and output is necessary, the code is placed between `\begin{Code}` and `\end{Code}`. b) If input and output should be distinguished, this can be done like in the following example.

\begin{CodeChunk}
\begin{CodeInput}
first input first line
first input second line
\end{CodeInput}
\begin{CodeOutput}
output of first input
\end{CodeOutput}
\begin{CodeInput}
second input
\end{CodeInput}
\begin{CodeOutput}
second output
\end{CodeOutput}
\end{CodeChunk}

Currently, these environments are not supported by the Quarto template.

I decided to wrap input-output blocks (or sequences thereof) in a

:::{.codechunk}

...

:::

block and to use the following filter:

return {
  {
    Div = function(el)
      if el.classes:includes("codechunk") then
        if quarto.doc.isFormat("pdf") then
          return el.content:walk {
            CodeBlock = function(el)
              local env = el.classes:includes("cell-code") and "CodeInput" or "CodeOutput"
              return pandoc.RawBlock("tex", "\\begin{" .. env .. "}\n" .. el.text .. "\n\\end{" .. env .. "}")
            end,
          }
        else
          return el.content
        end
      else
        return el
      end
    end,
  },
  {
    Code = function(el)
      if quarto.doc.isFormat("pdf") then
        return pandoc.RawInline("tex", "\\code{" .. el.text .. "}")
      else
        return el
      end
    end,
    CodeBlock = function(el)
      if quarto.doc.isFormat("pdf") and el.classes:includes("cell-code") then
        return pandoc.RawBlock("tex", "\\begin{Code}\n" .. el.text .. "\n\\end{Code}")
      else
        return el
      end
    end,
  }
}

Unfortunately, it seems adding the filter to the extension breaks e.g. multi-column figures with accompanying code.
I assume the problem is that it is applied to early in the pipeline, before Quarto-internal filters are applied that handle that use case.
I had to set the filter in my Quarto file and ensure that it is applied after the Quarto filters:

filters:
  - quarto
  - codes.lua

I wonder if there is a way to include this in the extension, or support these custom code environments in some other way?

@dragonstyle
Copy link
Collaborator

This is a nice addition. Currently we don't have a way for extensions to position their filters in the chain. In the long run we'd rather move towards a model where filters can gain access to more structured Quarto elements (e.g. code cells) and work with those directly before we actually emit the final content.

We're hoping to land some improvements to this in the 1.2 release of Quarto - I think it is worth seeing what solutions this might permit as I can't really think of a great workaround in the meantime.

@dragonstyle
Copy link
Collaborator

Just an update - we are intending to add some improvements in 1.3 that are likely to at least make it possible to improve this (by allowing targeting of code cells, inputs, outputs, and so on more semantically in filters). That is likely a few more weeks away at the soonest...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants