nbsync 0.1.1__tar.gz → 0.1.3__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. {nbsync-0.1.1 → nbsync-0.1.3}/PKG-INFO +1 -9
  2. {nbsync-0.1.1 → nbsync-0.1.3}/README.md +0 -8
  3. {nbsync-0.1.1 → nbsync-0.1.3}/docs/getting-started/first-steps.md +1 -9
  4. {nbsync-0.1.1 → nbsync-0.1.3}/docs/index.md +19 -0
  5. {nbsync-0.1.1 → nbsync-0.1.3}/mkdocs.yaml +0 -3
  6. {nbsync-0.1.1 → nbsync-0.1.3}/pyproject.toml +1 -1
  7. {nbsync-0.1.1 → nbsync-0.1.3}/src/nbsync/markdown.py +43 -18
  8. {nbsync-0.1.1 → nbsync-0.1.3}/src/nbsync/sync.py +2 -2
  9. {nbsync-0.1.1 → nbsync-0.1.3}/tests/test_cell.py +5 -0
  10. {nbsync-0.1.1 → nbsync-0.1.3}/tests/test_markdown.py +35 -0
  11. {nbsync-0.1.1 → nbsync-0.1.3}/.devcontainer/devcontainer.json +0 -0
  12. {nbsync-0.1.1 → nbsync-0.1.3}/.devcontainer/postCreate.sh +0 -0
  13. {nbsync-0.1.1 → nbsync-0.1.3}/.devcontainer/starship.toml +0 -0
  14. {nbsync-0.1.1 → nbsync-0.1.3}/.gitattributes +0 -0
  15. {nbsync-0.1.1 → nbsync-0.1.3}/.github/workflows/ci.yaml +0 -0
  16. {nbsync-0.1.1 → nbsync-0.1.3}/.github/workflows/docs.yaml +0 -0
  17. {nbsync-0.1.1 → nbsync-0.1.3}/.github/workflows/publish.yaml +0 -0
  18. {nbsync-0.1.1 → nbsync-0.1.3}/.gitignore +0 -0
  19. {nbsync-0.1.1 → nbsync-0.1.3}/LICENSE +0 -0
  20. {nbsync-0.1.1 → nbsync-0.1.3}/docs/getting-started/configuration.md +0 -0
  21. {nbsync-0.1.1 → nbsync-0.1.3}/docs/getting-started/installation.md +0 -0
  22. {nbsync-0.1.1 → nbsync-0.1.3}/notebooks/analysis.ipynb +0 -0
  23. {nbsync-0.1.1 → nbsync-0.1.3}/scripts/__init__.py +0 -0
  24. {nbsync-0.1.1 → nbsync-0.1.3}/scripts/plot.py +0 -0
  25. {nbsync-0.1.1 → nbsync-0.1.3}/scripts/plotting.py +0 -0
  26. {nbsync-0.1.1 → nbsync-0.1.3}/src/nbsync/__init__.py +0 -0
  27. {nbsync-0.1.1 → nbsync-0.1.3}/src/nbsync/cell.py +0 -0
  28. {nbsync-0.1.1 → nbsync-0.1.3}/src/nbsync/logger.py +0 -0
  29. {nbsync-0.1.1 → nbsync-0.1.3}/src/nbsync/notebook.py +0 -0
  30. {nbsync-0.1.1 → nbsync-0.1.3}/src/nbsync/plugin.py +0 -0
  31. {nbsync-0.1.1 → nbsync-0.1.3}/src/nbsync/py.typed +0 -0
  32. {nbsync-0.1.1 → nbsync-0.1.3}/tests/__init__.py +0 -0
  33. {nbsync-0.1.1 → nbsync-0.1.3}/tests/conftest.py +0 -0
  34. {nbsync-0.1.1 → nbsync-0.1.3}/tests/test_notebook.py +0 -0
  35. {nbsync-0.1.1 → nbsync-0.1.3}/tests/test_plugin.py +0 -0
  36. {nbsync-0.1.1 → nbsync-0.1.3}/tests/test_sync.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: nbsync
3
- Version: 0.1.1
3
+ Version: 0.1.3
4
4
  Summary: MkDocs plugin treating Jupyter notebooks, Python scripts and Markdown files as first-class citizens for documentation with dynamic execution and real-time synchronization
5
5
  Project-URL: Documentation, https://daizutabi.github.io/nbsync/
6
6
  Project-URL: Source, https://github.com/daizutabi/nbsync
@@ -134,14 +134,6 @@ Use standard Markdown image syntax with the figure identifier:
134
134
  ![Chart description](my-notebook.ipynb){#my-figure}
135
135
  ```
136
136
 
137
- ## Advanced Usage
138
-
139
- For more detailed information on how to use nbsync, see:
140
-
141
- - [Notebook Configuration](usage/notebook.md) - Setting up notebook directories
142
- - [Class Options](usage/class.md) - Control how notebook content is displayed
143
- <!-- - [Workflow Tips](usage/workflow.md) - Best practices for documentation -->
144
-
145
137
  ## The Power of Separation
146
138
 
147
139
  Creating documentation and developing visualizations involve different
@@ -89,14 +89,6 @@ Use standard Markdown image syntax with the figure identifier:
89
89
  ![Chart description](my-notebook.ipynb){#my-figure}
90
90
  ```
91
91
 
92
- ## Advanced Usage
93
-
94
- For more detailed information on how to use nbsync, see:
95
-
96
- - [Notebook Configuration](usage/notebook.md) - Setting up notebook directories
97
- - [Class Options](usage/class.md) - Control how notebook content is displayed
98
- <!-- - [Workflow Tips](usage/workflow.md) - Best practices for documentation -->
99
-
100
92
  ## The Power of Separation
101
93
 
102
94
  Creating documentation and developing visualizations involve different
@@ -159,7 +159,7 @@ plt.title('Scatter Plot by Group')
159
159
 
160
160
  ![Scatter plot](){#scatter}
161
161
 
162
- ## 6. Run Your Documentation
162
+ ### 7. Run Your Documentation
163
163
 
164
164
  Start the MkDocs development server:
165
165
 
@@ -167,14 +167,6 @@ Start the MkDocs development server:
167
167
  mkdocs serve --open
168
168
  ```
169
169
 
170
- ## Next Steps
171
-
172
- Now that you have the basics working, you can:
173
-
174
- 1. [Explore advanced notebook features](../usage/notebook.md)
175
- 2. [Learn about Python file integration](../usage/python-files.md)
176
- 3. [Discover markdown-based notebooks](../usage/markdown-files.md)
177
-
178
170
  ## Troubleshooting
179
171
 
180
172
  ### Common Issues
@@ -104,6 +104,25 @@ layouts.
104
104
  | ![](){`plot(np.sin)`} | ![](){`plot(np.cos)`} |
105
105
  ```
106
106
 
107
+ ### Code Execution with markdown-exec Style Syntax
108
+
109
+ nbsync supports the markdown-exec style code blocks with the `exec="1"`
110
+ attribute as a compatible approach to code execution. While this syntax
111
+ is familiar to markdown-exec users, nbsync executes it through the
112
+ Jupyter Notebook engine instead, providing the ability to render diverse
113
+ MIME content types (HTML, SVG, images, etc.) directly in your
114
+ documentation. This enables richer and more complex outputs than
115
+ traditional execution methods.
116
+
117
+ ````markdown source="tabbed-nbsync"
118
+ ```python exec="1" source="tabbed-left"
119
+ import numpy as np
120
+ from PIL import Image
121
+ x = np.random.randint(0, 255, (100, 100), dtype=np.uint8)
122
+ Image.fromarray(x)
123
+ ```
124
+ ````
125
+
107
126
  ### Dynamic Updates and Execution
108
127
 
109
128
  Automatic synchronization between notebooks and documentation ensures code
@@ -58,9 +58,6 @@ markdown_extensions:
58
58
  - pymdownx.superfences
59
59
  - pymdownx.tabbed:
60
60
  alternate_style: true
61
- - tables
62
- - toc:
63
- permalink: true
64
61
  nav:
65
62
  - Home: index.md
66
63
  - Getting Started:
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "nbsync"
7
- version = "0.1.1"
7
+ version = "0.1.3"
8
8
  description = "MkDocs plugin treating Jupyter notebooks, Python scripts and Markdown files as first-class citizens for documentation with dynamic execution and real-time synchronization"
9
9
  readme = "README.md"
10
10
  license = { file = "LICENSE" }
@@ -12,6 +12,49 @@ if TYPE_CHECKING:
12
12
  Element: TypeAlias = str | CodeBlock | Image
13
13
 
14
14
 
15
+ def convert_code_block(code_block: CodeBlock) -> Iterator[Element]:
16
+ for elem in _convert_code_block_tabbed(code_block):
17
+ if isinstance(elem, CodeBlock):
18
+ yield _convert_code_block_exec(elem)
19
+ else:
20
+ yield elem
21
+
22
+
23
+ def _convert_code_block_tabbed(code_block: CodeBlock) -> Iterator[Element]:
24
+ source = code_block.attributes.get("source", None)
25
+ if source != "tabbed-nbsync":
26
+ yield code_block
27
+ return
28
+
29
+ markdown = code_block.text.replace('source="tabbed-nbsync"', "")
30
+ markdown = textwrap.indent(markdown, " ")
31
+ yield f'===! "Markdown"\n\n{markdown}\n\n'
32
+
33
+ text = textwrap.indent(code_block.source, " ")
34
+ text = f'=== "Rendered"\n\n{text}'
35
+ yield from nbstore.markdown.parse(text)
36
+
37
+
38
+ def _convert_code_block_exec(code_block: CodeBlock) -> CodeBlock | Image:
39
+ exec_ = code_block.attributes.get("exec", None)
40
+ if exec_ != "1" or not code_block.classes:
41
+ return code_block
42
+
43
+ if code_block.classes[0] != "python":
44
+ return code_block
45
+
46
+ del code_block.attributes["exec"]
47
+ return Image(
48
+ code_block.indent,
49
+ "",
50
+ code_block.classes[1:],
51
+ code_block.attributes,
52
+ code_block.source,
53
+ url=".md",
54
+ indent=code_block.indent,
55
+ )
56
+
57
+
15
58
  def convert_image(image: Image, index: int | None = None) -> Iterator[Element]:
16
59
  if image.source:
17
60
  if not image.identifier and index is None:
@@ -29,24 +72,6 @@ def convert_image(image: Image, index: int | None = None) -> Iterator[Element]:
29
72
  yield image.text
30
73
 
31
74
 
32
- def convert_code_block(code_block: CodeBlock) -> Iterator[Element]:
33
- source = code_block.attributes.get("source", None)
34
- if source == "tabbed-nbsync":
35
- yield from _convert_code_block_tabbed(code_block)
36
- else:
37
- yield code_block
38
-
39
-
40
- def _convert_code_block_tabbed(code_block: CodeBlock) -> Iterator[Element]:
41
- markdown = code_block.text.replace('source="tabbed-nbsync"', "")
42
- markdown = textwrap.indent(markdown, " ")
43
- yield f'===! "Markdown"\n\n{markdown}\n\n'
44
-
45
- text = textwrap.indent(code_block.source, " ")
46
- text = f'=== "Rendered"\n\n{text}'
47
- yield from nbstore.markdown.parse(text)
48
-
49
-
50
75
  SUPPORTED_EXTENSIONS = (".ipynb", ".md", ".py")
51
76
 
52
77
 
@@ -62,8 +62,8 @@ class Synchronizer:
62
62
  if isinstance(elem, Image):
63
63
  nb = self.notebooks[elem.url].nb
64
64
  yield convert_image(elem, nb)
65
- else:
66
- yield convert_code_block(elem)
65
+ elif code_block := convert_code_block(elem):
66
+ yield code_block
67
67
 
68
68
 
69
69
  def update_notebooks(
@@ -101,3 +101,8 @@ def test_tabbed_right_title(convert):
101
101
  def test_unknown(convert):
102
102
  x = convert("![a](a.ipynb){#id source='unknown' tabs='a|b'}")
103
103
  assert x == "2"
104
+
105
+
106
+ def test_code_block_exec(convert):
107
+ x = convert('```python exec="1" source="1"\nprint(1+1)\n```')
108
+ assert x == "```python\nprint(1+1)\n```\n\n2"
@@ -123,6 +123,41 @@ def test_convert_tabbed_code_block_image():
123
123
  assert elems[2].text.startswith(" ![")
124
124
 
125
125
 
126
+ def test_convert_code_block_exec_1():
127
+ from nbsync.markdown import convert_code_block
128
+
129
+ text = '```python exec="1" a\nprint(1+1)\n```'
130
+ elems = nbstore.markdown.parse(text)
131
+ code_block = list(elems)[0]
132
+ assert isinstance(code_block, CodeBlock)
133
+ x = next(convert_code_block(code_block))
134
+ assert isinstance(x, Image)
135
+ assert x.classes == ["a"]
136
+ assert x.url == ".md"
137
+
138
+
139
+ def test_convert_code_block_exec_on():
140
+ from nbsync.markdown import convert_code_block
141
+
142
+ text = '```python exec="on" a\nprint(1+1)\n```'
143
+ elems = nbstore.markdown.parse(text)
144
+ code_block = list(elems)[0]
145
+ assert isinstance(code_block, CodeBlock)
146
+ x = next(convert_code_block(code_block))
147
+ assert isinstance(x, CodeBlock)
148
+
149
+
150
+ def test_convert_code_block_exec_not_python():
151
+ from nbsync.markdown import convert_code_block
152
+
153
+ text = '```bash exec="1" a\nls\n```'
154
+ elems = nbstore.markdown.parse(text)
155
+ code_block = list(elems)[0]
156
+ assert isinstance(code_block, CodeBlock)
157
+ x = next(convert_code_block(code_block))
158
+ assert isinstance(x, CodeBlock)
159
+
160
+
126
161
  def test_set_url():
127
162
  from nbsync.markdown import set_url
128
163
 
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes