├── README.md └── _extensions └── code-visibility ├── _extension.yml └── code-visibility.lua /README.md: -------------------------------------------------------------------------------- 1 | # Code Visibility Extension 2 | 3 | This extension implements some directives for filtering code and stream 4 | output included within a document. 5 | 6 | Use this extension within a Quarto project by first installing it from within the project working directory: 7 | 8 | ``` bash 9 | quarto install extension jjallaire/code-visibility 10 | ``` 11 | 12 | Then add the `code-visibility` filter to your project: 13 | 14 | ```yaml 15 | filters: 16 | - code-visibility 17 | ``` 18 | 19 | ## `#| hide_line` 20 | 21 | The `hide_line` directive hides a specific line of code in an input 22 | cell. For example, this code: 23 | 24 | ```` python 25 | ```{python} 26 | def _secret(): ... 27 | 28 | for i in range(3): 29 | _secret() #| hide_line 30 | print(i) 31 | ``` 32 | ```` 33 | 34 | Becomes this: 35 | 36 | ``` python 37 | def _secret(): ... 38 | 39 | for i in range(3): 40 | print(i) 41 | ``` 42 | 43 | ## `#| filter_stream: ...` 44 | 45 | The `filter_stream` directive filters lines containing specific keywords 46 | in cell outputs. For example, the following code: 47 | 48 | ```` python 49 | ```{python} 50 | #| filter_stream: FutureWarning MultiIndex 51 | print('\n'.join(['A line', 'Foobar baz FutureWarning blah', 52 | 'zig zagMultiIndex zoom', 'Another line.'])) 53 | ``` 54 | ```` 55 | 56 | Produces this output: 57 | 58 | A line 59 | Another line. 60 | -------------------------------------------------------------------------------- /_extensions/code-visibility/_extension.yml: -------------------------------------------------------------------------------- 1 | title: Code Visibility 2 | author: fast.ai 3 | version: 1.0.0 4 | contributes: 5 | filters: 6 | - code-visibility.lua 7 | -------------------------------------------------------------------------------- /_extensions/code-visibility/code-visibility.lua: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -- remove any lines with the hide_line directive. 5 | function CodeBlock(el) 6 | if el.classes:includes('cell-code') then 7 | el.text = filter_lines(el.text, function(line) 8 | return not line:match("#| ?hide_line%s*$") 9 | end) 10 | return el 11 | end 12 | end 13 | 14 | -- apply filter_stream directive to cells 15 | function Div(el) 16 | if el.classes:includes("cell") then 17 | local filters = el.attributes["filter_stream"] 18 | if filters then 19 | -- process cell-code 20 | return pandoc.walk_block(el, { 21 | CodeBlock = function(el) 22 | -- CodeBlock that isn't `cell-code` is output 23 | if not el.classes:includes("cell-code") then 24 | for filter in filters:gmatch("[^%s,]+") do 25 | el.text = filter_lines(el.text, function(line) 26 | return not line:find(filter, 1, true) 27 | end) 28 | end 29 | return el 30 | end 31 | end 32 | }) 33 | 34 | end 35 | 36 | end 37 | 38 | end 39 | 40 | function filter_lines(text, filter) 41 | local lines = pandoc.List() 42 | local code = text .. "\n" 43 | for line in code:gmatch("([^\r\n]*)[\r\n]") do 44 | if filter(line) then 45 | lines:insert(line) 46 | end 47 | end 48 | return table.concat(lines, "\n") 49 | end 50 | 51 | 52 | --------------------------------------------------------------------------------