Search code examples
pythonrluaquartoreveal.js

Python output highlighting in Quarto


Continuing on this question about code output highlighting in Quarto: Is it also possible to make this work with Python output?

A minimal working example:

---
title: "Output line highlighting"
format: revealjs
editor: visual
filters:
  - output-line-highlight.lua
---

## Regression Table 

In R:

```{r}
#| class-output: highlight
#| output-line-numbers: "9,10,11,12"
LM <- lm(Sepal.Length ~ Sepal.Width, data = iris)
summary(LM)
```

## Regression Table

In Python:

```{python}
#| class-output: highlight
#| output-line-numbers: "12,13,14,15,16,17"
import pandas as pd
import statsmodels.api as sm

iris = sm.datasets.get_rdataset('iris').data
LM = sm.OLS(iris['Sepal.Length'], sm.add_constant(iris['Sepal.Width'])).fit()
LM.summary2()
```

Rendering this file shows the Lua filter works for the R output, but not for Python.


Solution

  • python code chunk doesn't support the chunk option output-class. Instead, use the option classes and use the class output-highlight. And for r-code chunk, you may use either class-output: highlight or classes: output-highlight.

    And I have updated the filter to support the classes: output-highlight accordingly.

    output-line-highlight.lua

    function highlight(line_number)
      local highlighter = {
        CodeBlock = function(block)
          if block.classes:includes('highlight') then
            block.classes:insert('has-line-highlights')
            block.attributes["code-line-numbers"] = line_number
            return block
          end
      end
      }
      return highlighter
    end
    
    function add_highlight_class()
      return {
        CodeBlock = function(cb)
          if not cb.classes:includes('highlight') then
            cb.classes:insert('highlight')
          end
          return cb
        end
      }
    end
    
    
    function add_class_to_cb()
      return {
        Div = function(el)
          if el.classes:includes('cell-output') then
            return el:walk(add_highlight_class())
          end
        end
      }
    end
    
    function highlight_output_div()
      return {
        Div = function(div)
          if div.classes:includes('output-highlight') then
            return div:walk(add_class_to_cb())
          end
        end  
      }
    end
    
    function add_output_lnum()
      return {
        Div = function(el)
          if el.classes:includes('cell') then
            line_number = tostring(el.attributes["output-line-numbers"])
            return el:walk(highlight(line_number))
          end
        end
      }
    end
    
    function Pandoc(doc)
      if FORMAT == 'revealjs' then
        local doc = doc:walk(highlight_output_div())
        return doc:walk(add_output_lnum())
      end
    end
    

    presentation.qmd

    ---
    title: "Output line highlighting"
    format: revealjs
    filters:
      - output-line-highlight.lua
    ---
    
    ## Regression Table 
    
    In R:
    
    ```{r}
    #| class-output: highlight
    #| output-line-numbers: "9,10,11,12"
    LM <- lm(Sepal.Length ~ Sepal.Width, data = iris)
    summary(LM)
    ```
    
    ## Regression Table
    
    In Python:
    
    ```{python}
    #| classes: output-highlight
    #| output-line-numbers: "2,4"
    
    test = [1, 2, 3, 4]
    
    for i in test:
      if i%2 == 0:
        print("this line is highlighted")
      else:
        print("this line is not highlighted")
    ```
    

    highlighted lines