Syntax highlighting for code that is printed using code chunks

What I try to do

The file testfile.py has multiple code chunks.
I can use
{python, eval=FALSE, attr.source = ".numberLines", code=xfun::read_utf8('testfile.py')}
and the syntax highlighting works fine.
But I'd like to hide the lines that show the chunk names. These lines start with ## ----

Example

```{python testchunk, comment='', highlight=TRUE, echo=FALSE, attr.output = '.numberLines'}
 with open('testfile.py', 'r') as f:
    for line in f:
      if not line.startswith("## ----"):
        print(line, end='')

```

First question

Do you know a way to enable python syntax highlighting for the contents of testfile.py that is for the python print output?

Second question

I noticed you can't use \@ref{testchunk}or create captions for code chunks. That's limited to figures and tables. Here is a rather difficult solution: https://stackoverflow.com/a/50717459
Maybe you know a better way that works for html and pdf output? Creating figures of printed code just for referencing makes copy and paste impossible.

Hi @adnion, sorry for the delay on this one.

Can you share an example of testfile.py content so that I can try on my side what you want to achieve ?

Would it be related to this ?

If so, I think it could help.

Thank you very much for your response.
Yes exactly. It's related to the cookbook chapter.

A minimal testfile.py

## ---- print-chunk
print("hello")

## ---- add-chunk
def add(a, b):
    return a + b

Thanks!

If you are using this format for your file, the knitr::read_chunk function should be what to used, as in the book's example. It will read the file, and split in code chunks based on the comment, then you can call each of them by there name in later chunks. As you call them with the python engine, them will have the correc language class for the highlighter to work.

Example:

---
title: Python chunks
output: 
  html_document: 
   highlight: tango
---

Read an external script:

```{r, include=FALSE, cache=FALSE}
knitr::read_chunk('test.py')
```

Now we can use the code, e.g.,

```{python, print-chunk}
```

```{python, add-chunk}
```

```{python}
add(2,2)
```

What is not good for what you are trying to do in this example ?

Did I miss something ?

Sorry I wasn't precise enough. The chunks work as intented as you've shown.

I'd like to create a summary of all code filewise. For this I could probably loop over all chunks somehow but I'd prefer to just reread whole files without the chunk names.

The chunk names should be removed but syntax highlighting kept. I could remove lines as shown in the first post but there's no highlighting for python print output.

Thanks for the clarification.

I believe this is something knitr can do with a special option called ref.label. See this

With your example, that would be

---
title: Python chunks
output: 
  html_document: 
   highlight: tango
---

Read an external script:

```{r, include=FALSE, cache=FALSE}
knitr::read_chunk('test.py')
```

Now we can use the code, e.g.,

```{python, print-chunk}
```

```{python, add-chunk}
```

# Summary of code in this doc

```{python, ref.label=c("print-chunk", "add-chunk"), eval = FALSE}

```

Would this be what you are looking for ?

Thank you. It works but it's much work and it's error prone.
Imagine you want to add 10 complete source files in the appendix of a paper.
Although you only used 2 chunks per file in your text now you have to name every part of every file so you can rebuild the file with ref.labelfor the appendix. And you don't want to mix file parts.

Another slow solution could be to write the python print output into separate files without the chunk names.
Later I have to make sure all these separate files are 'in sync', read them into the appendix and delete them.

I hoped for a cleaner way. If only I could apply the syntax highlighting somehow.....

What do you think about my second question about \@ref{testchunk}?

I think I misunderstood your question in the first place. sorry. Syntax highlighting by pandoc is based on the class for the <code> and <pre> html tag. I believe if you add the class yourself, syntax highlighting will apply to the output. You can do that with class.output for example. knitr won't apply a language class on the ouput

---
title: Python chunks
output: 
  html_document: 
   highlight: tango
---

```{python testchunk, comment='', echo=FALSE, class.output = "python"}
with open('test.py', 'r') as f:
  for line in f:
    if not line.startswith("## ----"):
      print(line, end='')
```

About the second question, I am not sure to have understood it well: Do you want to reference some code chunk ?
If so then it is not possible yet

If not, then having the full usecase of what you are trying to do would help me understand.

This is exactly what i need! Thank you very much!

1 Like

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.

If you have a query related to it or one of the replies, start a new topic and refer back with a link.