Skip to content

Commit

Permalink
0.14 (#15)
Browse files Browse the repository at this point in the history
  • Loading branch information
spacemanspiff2007 authored Nov 15, 2024
1 parent 1c46b7c commit 03eb760
Show file tree
Hide file tree
Showing 9 changed files with 238 additions and 149 deletions.
2 changes: 1 addition & 1 deletion doc/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@

# -- Project information -----------------------------------------------------
project = 'sphinx-exec-code'
copyright = '2021, spacemanspiff2007'
copyright = '2024, spacemanspiff2007'
author = 'spacemanspiff2007'

# The full version, including alpha/beta/rc tags
Expand Down
64 changes: 61 additions & 3 deletions doc/description.rst
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,21 @@ Generated view
Options
------------------------------
It's possible to further configure both the code block and the output block with the following options:
`See sphinx docs <https://www.sphinx-doc.org/en/master/usage/restructuredtext/directives.html#directive-code>`_
for a detailed description


hide_code/hide_output:
hide/hide_output:
Will hide the corresponding block
name/name_output
Define implicit target name that can be referenced by using ref
caption/caption_output
Will add a caption above the block
linenos/linenos_output
Will add line numbers
lineno-start/lineno-start_output
Set the first line number of the block. Linenos is also automatically activated
emphasize-lines/emphasize-lines_output
Emphasize particular lines of the block
language/language_output:
| Will add syntax highlighting for the specified language
| The default for the code block is python, the default for the output block is plain text
Expand All @@ -56,7 +63,7 @@ Generated view
:hide_output:
:caption: This is an important caption

print('Easy!')
print('Easy!')

----

Expand Down Expand Up @@ -171,3 +178,54 @@ Generated view
----

With the combination of ``skip`` and ``hide`` it's possible to "simulate" every code.


Further Examples
------------------------------

This is an example with captions, highlights and name.


.. code-block:: python
.. exec_code::
:lineno-start: 5
:emphasize-lines: 1, 4
:caption: This is an important caption
:caption_output: This is an important output caption
:name: my_example_1
:name_output: my_output_1
print('My')
# This is a comment
print('Output!')
Generated view

----

.. exec_code::
:lineno-start: 5
:emphasize-lines: 1, 4
:caption: This is an important caption
:caption_output: This is an important output caption
:name: my_example_1
:name_output: my_output_1

print('My')
# This is a comment

print('Output!')

----

Create a link using to the blocks by using the name:

.. code-block:: text
See :ref:`this code snippet <my_example_1>` for an example
See :ref:`this code snippet <my_output_1>` for an example output
See :ref:`this code snippet <my_example_1>` for an example
See :ref:`this code snippet <my_output_1>` for an example output
7 changes: 7 additions & 0 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,13 @@ This code will be executed
```

# Changelog
#### 0.14 (2024-11-15)
- Add support for all options from code block
- Reworked how blocks and options are processed

#### 0.13 (2024-10-15)
- Add support for python 3.13

#### 0.12 (2024-01-09)
- Error when providing invalid options

Expand Down
2 changes: 1 addition & 1 deletion src/sphinx_exec_code/__version__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = '0.13'
__version__ = '0.14'
15 changes: 6 additions & 9 deletions src/sphinx_exec_code/code_format.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
from typing import Iterable, List, Tuple
from textwrap import dedent
from typing import List, Tuple

from docutils.statemachine import StringList


class VisibilityMarkerError(Exception):
Expand Down Expand Up @@ -61,7 +64,7 @@ def get_lines(self) -> List[str]:
return code_lines


def get_show_exec_code(code_lines: Iterable[str]) -> Tuple[str, str]:
def get_show_exec_code(code_lines: StringList) -> Tuple[str, str]:
shown = CodeMarker('hide')
executed = CodeMarker('skip')

Expand All @@ -77,13 +80,7 @@ def get_show_exec_code(code_lines: Iterable[str]) -> Tuple[str, str]:

shown_lines = shown.get_lines()

# check if the shown code block is indented as a whole -> strip
leading_spaces = [len(line) - len(line.lstrip()) for line in shown_lines]
if strip_spaces := min(leading_spaces, default=0):
for i, line in enumerate(shown_lines):
shown_lines[i] = line[strip_spaces:]

shown_code = '\n'.join(shown_lines)
executed_code = '\n'.join(executed.get_lines())

return shown_code, executed_code.strip()
return dedent(shown_code), dedent(executed_code.strip())
45 changes: 22 additions & 23 deletions src/sphinx_exec_code/sphinx_exec.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import traceback
from pathlib import Path
from typing import List

from docutils import nodes
from docutils.statemachine import StringList
from sphinx.directives.code import CodeBlock
from sphinx.errors import ExtensionError
from sphinx.util.docutils import SphinxDirective

Expand All @@ -13,24 +13,6 @@
from sphinx_exec_code.sphinx_spec import SphinxSpecBase, build_spec, get_specs


def create_literal_block(objs: list, code: str, spec: SphinxSpecBase) -> None:
if spec.hide or not code:
return None

# generate header if specified
if spec.caption:
objs.append(nodes.caption(text=spec.caption))

# generate code block
block = nodes.literal_block(code, code)
objs.append(block)

# set linenos
block['linenos'] = spec.linenos
block['language'] = spec.language
return None


class ExecCode(SphinxDirective):
""" Sphinx class for execute_code directive
"""
Expand All @@ -57,7 +39,7 @@ def run(self) -> list:
msg = f'Error while running {name}!'
raise ExtensionError(msg, orig_exc=e) from None

def _get_code_line(self, line_no: int, content: List[str]) -> int:
def _get_code_line(self, line_no: int, content: StringList) -> int:
"""Get the first line number of the code"""
if not content:
return line_no
Expand Down Expand Up @@ -99,7 +81,7 @@ def _run(self) -> list:
raise ExtensionError(msg, orig_exc=e) from None

# Show the code from the user
create_literal_block(output, code_show, spec=code_spec)
self.create_literal_block(output, code_show, code_spec, line)

try:
code_results = execute_code(code_exec, file, line)
Expand All @@ -115,5 +97,22 @@ def _run(self) -> list:
raise ExtensionError(msg) from None

# Show the output from the code execution
create_literal_block(output, code_results, spec=output_spec)
self.create_literal_block(output, code_results, output_spec, line)
return output

def create_literal_block(self, objs: list, code: str, spec: SphinxSpecBase, line: int) -> None:
if spec.hide or not code:
return None

c = CodeBlock(
'code-block', [spec.language], spec.spec,
StringList(code.splitlines()),
line,
# I'm not sure what these two do
self.content_offset, '',
# Let's hope these are just for producing error messages and not for anything else
self.state, self.state_machine
)

objs.extend(c.run())
return None
Loading

0 comments on commit 03eb760

Please sign in to comment.