Skip to content

Commit

Permalink
feat: Allow changing the console width for the execution of code blocks
Browse files Browse the repository at this point in the history
It will set the `COLUMNS` environment variable.

Issue-34: #34
  • Loading branch information
pawamoy committed Jun 13, 2024
1 parent 0db27b2 commit 76d603c
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 1 deletion.
20 changes: 20 additions & 0 deletions docs/usage/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ linking to their related documentation:
- [`session`](#sessions): Execute code blocks within a named session, reusing previously defined variables, etc..
- [`source`](#render-the-source-code-as-well): Render the source as well as the output.
- [`tabs`](#change-the-titles-of-tabs): When rendering the source using tabs, choose the tabs titles.
- [`width`](#change-the-console-width): Change the console width through the `COLUMNS` environment variable.
- [`workdir`](#change-the-working-directory): Change the working directory.
- [`title`](#additional-options): Title is a [Material for MkDocs][material] option.
- [`updatetoc`](#generated-headings-in-table-of-contents): Whether to update the Table of Contents with generated headings.
Expand Down Expand Up @@ -273,6 +274,25 @@ $ cat .git/config
WARNING: **Limitation**
Wrapping the result is not possible when HTML output is enabled.

## Change the console width

To change the console width for the execution of a code block, use the `width` option.
Internally, Markdown Exec will set the `COLUMNS` environment variable accordingly,
and restore its previous value after execution.

If the executed code doesn't support this environment variable,
the default console width will be used (it could be the current width or some arbitrary value).

````md exec="1" source="tabbed-left"
```bash exec="1" width="10"
echo $COLUMNS
```

```bash exec="1" width="1000"
echo $COLUMNS
```
````

## Change the working directory

To change the working directory for the execution of a code block, use the `workdir` option.
Expand Down
2 changes: 2 additions & 0 deletions src/markdown_exec/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ def validator(
tabs_value = inputs.pop("tabs", "|".join(default_tabs))
tabs = tuple(_tabs_re.split(tabs_value, maxsplit=1))
workdir_value = inputs.pop("workdir", None)
width_value = int(inputs.pop("width", "0"))
options["id"] = id_value
options["id_prefix"] = id_prefix_value
options["html"] = html_value
Expand All @@ -89,6 +90,7 @@ def validator(
options["update_toc"] = update_toc_value
options["tabs"] = tabs
options["workdir"] = workdir_value
options["width"] = width_value
options["extra"] = inputs
return True

Expand Down
26 changes: 25 additions & 1 deletion src/markdown_exec/formatters/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,29 @@ def working_directory(path: str | None = None) -> Iterator[None]:
yield


@contextmanager
def console_width(width: int | None = None) -> Iterator[None]:
"""Set the console width for the duration of the context.
The console width is set using the `COLUMNS` environment variable.
Parameters:
width: The width to set the console to.
"""
if width:
old_width = os.environ.get("COLUMNS", None)
os.environ["COLUMNS"] = str(width)
try:
yield
finally:
if old_width is None:
del os.environ["COLUMNS"]
else:
os.environ["COLUMNS"] = old_width
else:
yield


class ExecutionError(Exception):
"""Exception raised for errors during execution of a code block.
Expand Down Expand Up @@ -76,6 +99,7 @@ def base_format(
session: str | None = None,
update_toc: bool = True,
workdir: str | None = None,
width: int | None = None,
**options: Any,
) -> Markup:
"""Execute code and return HTML.
Expand Down Expand Up @@ -114,7 +138,7 @@ def base_format(
source_output = code

try:
with working_directory(workdir):
with working_directory(workdir), console_width(width):
output = run(source_input, returncode=returncode, session=session, id=id, **extra)
except ExecutionError as error:
identifier = id or extra.get("title", "")
Expand Down
17 changes: 17 additions & 0 deletions tests/test_base_formatter.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,3 +91,20 @@ def test_changing_working_directory(md: Markdown) -> None:
workdir="/",
)
assert markup == "<p>/</p>"


def test_console_width(md: Markdown) -> None:
"""Assert we can change the console width with `width`.
Parameters:
md: A Markdown instance (fixture).
"""
for width in (10, 1000):
markup = base_format(
language="bash",
run=lambda code, **_: subprocess.check_output(code, shell=True, text=True), # noqa: S602,
code="echo width: $COLUMNS",
md=md,
width=width,
)
assert f"width: {width}" in markup

0 comments on commit 76d603c

Please sign in to comment.