mp = MarkdownProcessor()
# Test single backtick
test_str = "Some text `print('hello')`"
test_eq(mp.extract_code(test_str), "print('hello')")Core
MarkdownProcessor
MarkdownProcessor
MarkdownProcessor (output_dir='py')
Handles the processing of markdown files to extract code blocks
# Test triple backtick
test_str = """Some text
```
def hello():
print('world')
```
more text"""
print(test_str)Some text
```
def hello():
print('world')
```
more text
expected = "def hello():\n print('world')\n"
print(expected)def hello():
print('world')
test_eq(mp.extract_code(test_str), expected)# Test multiple code blocks
test_str = """```python
def hello():
print('world')
```
Some text
```
def goodbye():
print('bye')
```"""
expected = "def hello():\n print('world')\n\ndef goodbye():\n print('bye')\n"
test_eq(mp.extract_code(test_str), expected)test_eq(mp.should_process(Path('test.md')), True)
test_eq(mp.should_process(Path('test.py')), False)
test_eq(mp.should_process(Path('test/test.md')), True)
test_eq(mp.should_process(Path('README.md')), False)
test_eq(mp.should_process(Path('readme.md')), False)
test_eq(mp.should_process(Path('ReadMe.md')), False)Let’s check that we are writing the file to disk as expected.
with TemporaryDirectory() as tmp:
# Setup temporary directories
tmpdir = Path(tmp)
out_dir = tmpdir/'py'
# Create test markdown file
md_path = tmpdir/'test.md'
md_path.write_text(test_str)
# Process the file
mp = MarkdownProcessor(output_dir=out_dir)
mp.process_file(md_path)
# Check results
out_file = out_dir/'test.py'
test_eq(out_file.exists(), True)
test_eq(out_file.read_text(), expected)Let’s see if we can process an entire directory as expected.
with TemporaryDirectory() as tmpdir:
tmpdir = Path(tmpdir)
(tmpdir/'test1.md').write_text(test_str)
(tmpdir/'README.md').write_text('# Readme\n' + test_str)
mp = MarkdownProcessor(output_dir=tmpdir/'py')
processed = mp.process_directory(tmpdir)
# Verify results
test_eq(len(processed), 1) # Should process 1 file (excluding README.md)
test_eq((tmpdir/'py'/'test1.py').exists(), True)
# Check content of processed files
test_eq((tmpdir/'py'/'test1.py').read_text(), expected)MarkdownWatcher
MarkdownWatcher
MarkdownWatcher (processor)
Watches for markdown file changes and triggers processing
Now let’s test the markdown watcher, with the file created before and while the watcher is running.
# Setup
input_dir = Path('input_dir')
input_dir.mkdir(exist_ok=True)
output_dir = Path('output_py')
test_before = Path(input_dir / 'test_before.md')
test_before.write_text(test_str)
processor = MarkdownProcessor(output_dir=output_dir)
handler = MarkdownWatcher(processor)
observer = Observer()
observer.schedule(handler, str(input_dir), recursive=False)
observer.start()
test_while = Path(input_dir / 'test_while.md')
test_while.write_text(test_str)
# Give it a moment to process
# By giving it a relatively long time -- 5 seconds! -- we are preventing any intermittent, false failures
time.sleep(5)
# Test and clean up
for stem in ['test_before', 'test_while']:
output_path = output_dir / f'{stem}.py'
test_eq(output_path.exists(), True)
output_path.unlink()
output_dir.rmdir()
observer.stop()
observer.join()
test_before.unlink()
test_while.unlink()
input_dir.rmdir()CLI commands
md_to_py
md_to_py (input_dir:str<Inputdirectorycontainingmarkdownfiles>, output_dir:str<OutputdirectoryforPythonfiles>='py')
Convert markdown files in input_dir to Python files in output_dir
literati
literati (path:str<Directorytomonitor>='.', output_dir:str<OutputdirectoryforPythonfiles>='py')
Monitor markdown files and extract code blocks to Python files
We can easily test the md_to_py however I haven’t found a good way how to test iterati. Falling back to manual testing.
with TemporaryDirectory() as tmpdir:
# Setup
tmpdir = Path(tmpdir)
(tmpdir/'test.md').write_text(test_str)
# Test md_to_py command
try:
md_to_py(str(tmpdir), str(tmpdir/'py'))
test_eq((tmpdir/'py'/'test.py').exists(), True)
test_eq((tmpdir/'py'/'test.py').read_text(), expected)
except Exception as e:
assert False, f"md_to_py raised an exception: {e}"Processed 1 files:
/var/folders/wt/jbbs6xs16r32mfmphb089_2h0000gn/T/tmpvk0tnpe1/py/test.py
# manual solution to testing iterati, uncomment the code for running and terminate using `interrupt kernel`
# make sure to comment it back out before commiting to the library!
# !rm -rf py
# Path('test.md').write_text(test_str)
# literati()
# test_eq(Path('py/test.py').read_text(), expected)
# !ls py
# !rm -rf py