pythoncharmers-meta 0.7.3__tar.gz → 0.7.5__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.
- pythoncharmers_meta-0.7.5/MD_MAGIC.md +189 -0
- {pythoncharmers_meta-0.7.3 → pythoncharmers_meta-0.7.5}/PKG-INFO +1 -1
- {pythoncharmers_meta-0.7.3 → pythoncharmers_meta-0.7.5}/pyproject.toml +1 -1
- pythoncharmers_meta-0.7.5/src/pythoncharmers_meta/.claude/settings.local.json +23 -0
- pythoncharmers_meta-0.7.5/src/pythoncharmers_meta/__init__.py +79 -0
- pythoncharmers_meta-0.7.5/src/pythoncharmers_meta/nb_magic.py +779 -0
- pythoncharmers_meta-0.7.5/src/pythoncharmers_meta/source.ipynb +632 -0
- pythoncharmers_meta-0.7.5/src/pythoncharmers_meta/source2.ipynb +1048 -0
- {pythoncharmers_meta-0.7.3 → pythoncharmers_meta-0.7.5}/uv.lock +1 -1
- pythoncharmers_meta-0.7.3/src/pythoncharmers_meta/__init__.py +0 -58
- pythoncharmers_meta-0.7.3/src/pythoncharmers_meta/nb_magic.py +0 -293
- {pythoncharmers_meta-0.7.3 → pythoncharmers_meta-0.7.5}/.gitignore +0 -0
- {pythoncharmers_meta-0.7.3 → pythoncharmers_meta-0.7.5}/LICENSE +0 -0
- {pythoncharmers_meta-0.7.3 → pythoncharmers_meta-0.7.5}/README.md +0 -0
- {pythoncharmers_meta-0.7.3 → pythoncharmers_meta-0.7.5}/src/pythoncharmers_meta/ai_magic.py +0 -0
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
# Markdown Cell Magic Implementation Design
|
|
2
|
+
|
|
3
|
+
## Problem Statement
|
|
4
|
+
|
|
5
|
+
Training participants need a way to copy Markdown cells from trainer notebooks during live sessions. Unlike code cells which have visible execution counts, Markdown cells lack visible identifiers, making them difficult to reference.
|
|
6
|
+
|
|
7
|
+
## Design Considerations
|
|
8
|
+
|
|
9
|
+
### Current Magic Commands
|
|
10
|
+
- %code (formerly %nb): Handles code cells (identified by execution_count)
|
|
11
|
+
- %md: Handles markdown cells with flexible syntax (by index or relative to code cells)
|
|
12
|
+
- %nb: Kept as alias for %code for backward compatibility
|
|
13
|
+
|
|
14
|
+
### Challenges with Markdown Cells
|
|
15
|
+
1. **No visible numbering**: Markdown cells don't have execution counts
|
|
16
|
+
2. **Cell IDs not user-friendly**: Internal IDs exist but aren't visible in the UI
|
|
17
|
+
3. **Mixed cell types**: Notebooks interleave code and Markdown cells
|
|
18
|
+
4. **Cell type conversion**: Content retrieved needs manual conversion from Code to Markdown
|
|
19
|
+
|
|
20
|
+
## Proposed Solutions
|
|
21
|
+
|
|
22
|
+
### Solution 1: Between Code Cells (Fence Method)
|
|
23
|
+
**Syntax**: `%md 1 2` - Get all Markdown cells between code cells 1 and 2
|
|
24
|
+
|
|
25
|
+
**Pros**:
|
|
26
|
+
- Uses existing visible code cell numbers
|
|
27
|
+
- Intuitive for contiguous Markdown sections
|
|
28
|
+
|
|
29
|
+
**Cons**:
|
|
30
|
+
- Ambiguous for non-contiguous selections
|
|
31
|
+
- Doesn't work for Markdown at notebook start/end
|
|
32
|
+
- May return multiple cells when only one is needed
|
|
33
|
+
|
|
34
|
+
### Solution 2: Position-Based Reference
|
|
35
|
+
**Syntax**: `%md after:3` or `%md before:5` - Get Markdown cell(s) after/before code cell
|
|
36
|
+
|
|
37
|
+
**Pros**:
|
|
38
|
+
- Precise single-cell selection
|
|
39
|
+
- Clear intent
|
|
40
|
+
- Works at notebook boundaries
|
|
41
|
+
|
|
42
|
+
**Cons**:
|
|
43
|
+
- Requires multiple commands for multiple cells
|
|
44
|
+
- User needs to know exact positions
|
|
45
|
+
|
|
46
|
+
### Solution 3: Content Pattern Matching
|
|
47
|
+
**Syntax**: `%md "# Section Title"` - Find Markdown cells containing pattern
|
|
48
|
+
|
|
49
|
+
**Pros**:
|
|
50
|
+
- Natural for users who can see content
|
|
51
|
+
- Works without knowing cell positions
|
|
52
|
+
- Can use distinctive headers/keywords
|
|
53
|
+
|
|
54
|
+
**Cons**:
|
|
55
|
+
- Pattern might not be unique
|
|
56
|
+
- Requires exact string matching or regex
|
|
57
|
+
|
|
58
|
+
### Solution 4: Hybrid Cell Magic (Recommended)
|
|
59
|
+
**Syntax**: `%%md 3` - Cell magic that fetches Markdown after code cell 3
|
|
60
|
+
|
|
61
|
+
**Pros**:
|
|
62
|
+
- Automatically converts cell type to Markdown
|
|
63
|
+
- No manual cleanup needed
|
|
64
|
+
- Clear one-to-one mapping
|
|
65
|
+
- Can extend to support ranges
|
|
66
|
+
|
|
67
|
+
**Cons**:
|
|
68
|
+
- Different from line magic pattern
|
|
69
|
+
- Requires cell magic implementation
|
|
70
|
+
|
|
71
|
+
### Solution 5: Smart Sequential Indexing (Recommended Alternative)
|
|
72
|
+
**Syntax**: `%md 3` or `%md 3-5` - Use sequential index for all Markdown cells
|
|
73
|
+
|
|
74
|
+
**Implementation**:
|
|
75
|
+
- Build index of all Markdown cells in order
|
|
76
|
+
- Reference by position (1st, 2nd, 3rd Markdown cell)
|
|
77
|
+
- Optional: `%md --list` to show available Markdown cells with previews
|
|
78
|
+
|
|
79
|
+
**Pros**:
|
|
80
|
+
- Simple, consistent interface
|
|
81
|
+
- Works like %nb for code cells
|
|
82
|
+
- No ambiguity
|
|
83
|
+
- Can show preview list
|
|
84
|
+
|
|
85
|
+
**Cons**:
|
|
86
|
+
- Users need to count Markdown cells
|
|
87
|
+
- Numbers change if trainer adds cells
|
|
88
|
+
|
|
89
|
+
## Implemented Solution
|
|
90
|
+
|
|
91
|
+
The `%md` command now supports **unified syntax** for both index-based and code-relative selection:
|
|
92
|
+
|
|
93
|
+
### Markdown Index Syntax
|
|
94
|
+
```python
|
|
95
|
+
%md m1 # Get 1st Markdown cell
|
|
96
|
+
%md m3-m5 # Get 3rd through 5th Markdown cells
|
|
97
|
+
%md m7- # Get 7th cell onwards
|
|
98
|
+
%md -m3 # Get cells 1 through 3
|
|
99
|
+
%md --list # List all Markdown cells with m-prefixed numbers
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
### Code-Relative Syntax (uses last occurrence if duplicates exist)
|
|
103
|
+
```python
|
|
104
|
+
%md -3 # All Markdown cells before code cell 3
|
|
105
|
+
%md 5- # All Markdown cells after code cell 5
|
|
106
|
+
%md 3-5 # All Markdown between code cells 3 and 5
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### Combined Usage
|
|
110
|
+
```python
|
|
111
|
+
%md -1 m3 5- # Before code 1, markdown cell 3, after code 5
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
## Implementation Details
|
|
115
|
+
|
|
116
|
+
### Cell Type Handling
|
|
117
|
+
- Unlike %nb, the %md and %mdat magics do NOT add a comment header
|
|
118
|
+
- Content is inserted directly without any prefix
|
|
119
|
+
- Users manually convert cell type (Ctrl+M, M in Jupyter)
|
|
120
|
+
- Future: Investigate IPython API for automatic cell type conversion
|
|
121
|
+
|
|
122
|
+
### Preview Feature
|
|
123
|
+
```python
|
|
124
|
+
%md --list
|
|
125
|
+
# Output:
|
|
126
|
+
# 1: # Introduction
|
|
127
|
+
# This notebook covers...
|
|
128
|
+
# 2: ## Data Loading
|
|
129
|
+
# We'll use pandas to...
|
|
130
|
+
# 3: ### Important Notes
|
|
131
|
+
# Remember to check...
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
### Error Handling
|
|
135
|
+
- Clear messages for invalid ranges
|
|
136
|
+
- Warnings when no Markdown cells found
|
|
137
|
+
- Handle notebooks without code cells gracefully
|
|
138
|
+
|
|
139
|
+
## Alternative Approaches Considered
|
|
140
|
+
|
|
141
|
+
### Invisible Anchors
|
|
142
|
+
Add hidden HTML comments as anchors in Markdown cells:
|
|
143
|
+
```markdown
|
|
144
|
+
<!-- md-anchor: section1 -->
|
|
145
|
+
# Introduction
|
|
146
|
+
```
|
|
147
|
+
**Rejected**: Requires modifying trainer notebooks
|
|
148
|
+
|
|
149
|
+
### Visual Cell Numbers
|
|
150
|
+
Propose Jupyter enhancement to show Markdown cell numbers in UI.
|
|
151
|
+
**Rejected**: Outside our control, long-term solution
|
|
152
|
+
|
|
153
|
+
### Dual Output
|
|
154
|
+
Return both code and Markdown versions, let user choose.
|
|
155
|
+
**Rejected**: Clutters interface, still requires manual work
|
|
156
|
+
|
|
157
|
+
## Migration Path
|
|
158
|
+
|
|
159
|
+
1. Renamed `%nb` to `%code` as the canonical command for code cells
|
|
160
|
+
2. Kept `%nb` as an alias for backward compatibility
|
|
161
|
+
3. Implemented unified `%md` command with both index and position-based syntax
|
|
162
|
+
4. Removed separate `%mdat` command (functionality merged into `%md`)
|
|
163
|
+
5. Updated all documentation and help text
|
|
164
|
+
|
|
165
|
+
## Usage Examples
|
|
166
|
+
|
|
167
|
+
### Trainer notebook structure:
|
|
168
|
+
```
|
|
169
|
+
[Code 1] Import statements
|
|
170
|
+
[Markdown] # Data Analysis Workshop
|
|
171
|
+
[Markdown] ## Prerequisites
|
|
172
|
+
[Code 2] Load data
|
|
173
|
+
[Markdown] ### Understanding the dataset
|
|
174
|
+
[Code 3] Explore data
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
### Participant commands:
|
|
178
|
+
```python
|
|
179
|
+
%code 1 # Get code cell 1 (preferred)
|
|
180
|
+
%nb 1 # Same as %code 1 (backward compatibility)
|
|
181
|
+
%md m1 # Get "# Data Analysis Workshop"
|
|
182
|
+
%md m2-m3 # Get "## Prerequisites" and "### Understanding the dataset"
|
|
183
|
+
%md 1- # Get markdown after code cell 1
|
|
184
|
+
%md -2 # Get markdown before code cell 2
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
## Conclusion
|
|
188
|
+
|
|
189
|
+
The unified `%md` command provides a powerful and flexible interface for selecting markdown cells. By supporting both index-based (`m1`, `m2-m5`) and code-relative (`-1`, `2-`, `3-5`) syntax in a single command, users have maximum flexibility without needing to remember multiple commands. The implementation handles edge cases like duplicate code cell numbers (using the last occurrence) and provides clear error messages for invalid selections.
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
"permissions": {
|
|
3
|
+
"allow": [
|
|
4
|
+
"Bash(python3:*)",
|
|
5
|
+
"Bash(cd:*)",
|
|
6
|
+
"Bash(cd:*)",
|
|
7
|
+
"Bash(rm:*)",
|
|
8
|
+
"Bash(git add:*)",
|
|
9
|
+
"Bash(cd:*)",
|
|
10
|
+
"Bash(cd:*)",
|
|
11
|
+
"Bash(cd:*)",
|
|
12
|
+
"Bash(cd:*)",
|
|
13
|
+
"Bash(cd:*)",
|
|
14
|
+
"Bash(cd:*)",
|
|
15
|
+
"Bash(cd:*)",
|
|
16
|
+
"Bash(cd:*)",
|
|
17
|
+
"Bash(cd:*)",
|
|
18
|
+
"Bash(python test:*)"
|
|
19
|
+
],
|
|
20
|
+
"deny": [],
|
|
21
|
+
"ask": []
|
|
22
|
+
}
|
|
23
|
+
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Python Charmers meta-package.
|
|
3
|
+
|
|
4
|
+
This package is for use in Python Charmers training courses.
|
|
5
|
+
|
|
6
|
+
You can load the IPython extension like so:
|
|
7
|
+
|
|
8
|
+
%load_ext pythoncharmers_meta
|
|
9
|
+
|
|
10
|
+
assuming the pythoncharmers_meta packages has been installed system-wide.
|
|
11
|
+
|
|
12
|
+
This package depends on packages used in Python Charmers training courses. It
|
|
13
|
+
also provides an IPython extension that enables several magic commands:
|
|
14
|
+
|
|
15
|
+
- %code: Grab code cells from a notebook
|
|
16
|
+
- %md: Grab markdown cells (by index or relative to code cells)
|
|
17
|
+
- %nb: Alias for %code (for backward compatibility)
|
|
18
|
+
- %ai: Invoke the `llm` package for quick use of an LLM like gpt-4o-mini
|
|
19
|
+
|
|
20
|
+
The %code and %md magics grab cells from a notebook on the filesystem,
|
|
21
|
+
defaulting to the most recently modified notebook in the latest ~/Trainer_XYZ folder.
|
|
22
|
+
|
|
23
|
+
For help on the magics, add a trailing question mark. For example:
|
|
24
|
+
|
|
25
|
+
%code?
|
|
26
|
+
%md?
|
|
27
|
+
%ai?
|
|
28
|
+
|
|
29
|
+
Two additional magics are available for getting and setting the current
|
|
30
|
+
path and/or file that %code and %md query. To get help on these, run:
|
|
31
|
+
|
|
32
|
+
%nbfile?
|
|
33
|
+
%nbpath?
|
|
34
|
+
|
|
35
|
+
"""
|
|
36
|
+
|
|
37
|
+
# Import version from package metadata (single source of truth)
|
|
38
|
+
try:
|
|
39
|
+
from importlib.metadata import version, PackageNotFoundError
|
|
40
|
+
try:
|
|
41
|
+
__version__ = version("pythoncharmers-meta")
|
|
42
|
+
except PackageNotFoundError:
|
|
43
|
+
# Package is not installed, likely in development mode
|
|
44
|
+
# Fall back to reading from pyproject.toml if needed
|
|
45
|
+
__version__ = "unknown"
|
|
46
|
+
except ImportError:
|
|
47
|
+
# Python < 3.8 fallback
|
|
48
|
+
try:
|
|
49
|
+
import pkg_resources
|
|
50
|
+
__version__ = pkg_resources.get_distribution("pythoncharmers-meta").version
|
|
51
|
+
except Exception:
|
|
52
|
+
__version__ = "unknown"
|
|
53
|
+
|
|
54
|
+
# Public API
|
|
55
|
+
__all__ = ["__version__", "load_ipython_extension", "NotebookMagic"]
|
|
56
|
+
|
|
57
|
+
from .nb_magic import NotebookMagic
|
|
58
|
+
|
|
59
|
+
try:
|
|
60
|
+
from .ai_magic import AIMagic
|
|
61
|
+
__all__.append("AIMagic")
|
|
62
|
+
except Exception as e:
|
|
63
|
+
print(e)
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def load_ipython_extension(ipython):
|
|
67
|
+
"""
|
|
68
|
+
Any module file that defines a function named `load_ipython_extension`
|
|
69
|
+
can be loaded via `%load_ext module.path` or be configured to be
|
|
70
|
+
autoloaded by IPython at startup time.
|
|
71
|
+
"""
|
|
72
|
+
# You can register the class itself without instantiating it. IPython will
|
|
73
|
+
# call the default constructor on it.
|
|
74
|
+
ipython.register_magics(NotebookMagic)
|
|
75
|
+
|
|
76
|
+
try:
|
|
77
|
+
ipython.register_magics(AIMagic)
|
|
78
|
+
except Exception as e:
|
|
79
|
+
print(e)
|