Terrace/packages/python/docs/reader-api.inc.tce
Joshua Bemenderfer 9d9757e868 Updates.
2025-09-08 16:24:38 -04:00

175 lines
4.1 KiB
Plaintext

Heading 2 Reader API
class mt-12
Markdown
The Reader API provides functions and utilities for creating readers that supply lines to the Document API.
Heading 3 Reader Type
class mt-8 mb-4
Markdown
A `Reader` is a callable that returns the next line in a document or `None` when the end is reached.
CodeBlock python
from typing import Optional, Callable
# Type definition
Reader = Callable[[], Optional[str]]
Heading 3 Built-in Readers
class mt-8 mb-4
Markdown
**String Reader**
Create a reader from a string, splitting on newlines.
CodeBlock python
def create_string_reader(content: str) -> Reader:
"""Create a reader from a string"""
lines = content.split('\n')
# Remove trailing empty line if content ended with newline
if len(lines) > 0 and content.endswith('\n') and lines[-1] == '':
lines = lines[:-1]
index = 0
def reader() -> Optional[str]:
nonlocal index
if index >= len(lines):
return None
line = lines[index]
index += 1
return line
return reader
Markdown
**File Reader**
Create a reader from a file path.
CodeBlock python
def create_file_reader(file_path: str) -> Reader:
"""Create a reader from a file path"""
file_handle = open(file_path, 'r', encoding='utf-8')
def reader() -> Optional[str]:
line = file_handle.readline()
if not line:
file_handle.close()
return None
return line.rstrip('\n\r')
return reader
Markdown
**Lines Reader**
Create a reader from a list of strings.
CodeBlock python
def create_lines_reader(lines: List[str]) -> Reader:
"""Create a reader from a list of lines"""
index = 0
def reader() -> Optional[str]:
nonlocal index
if index >= len(lines):
return None
line = lines[index]
index += 1
return line.rstrip('\n\r')
return reader
Heading 3 Custom Readers
class mt-8 mb-4
Markdown
You can create custom readers for any data source by implementing a function that returns `Optional[str]`.
CodeBlock python
import json
from typing import Iterator
def create_json_lines_reader(file_path: str) -> Reader:
"""Create a reader that processes JSON Lines format"""
def generator() -> Iterator[str]:
with open(file_path, 'r') as f:
for line in f:
try:
data = json.loads(line.strip())
# Convert JSON object to Terrace format
yield f"entry {data.get('name', 'unnamed')}"
for key, value in data.items():
if key != 'name':
yield f" {key} {value}"
except json.JSONDecodeError:
continue
iterator = generator()
def reader() -> Optional[str]:
try:
return next(iterator)
except StopIteration:
return None
return reader
Heading 3 Usage Examples
class mt-8 mb-4
Markdown
**Reading from a string**
CodeBlock python
from terrace import use_document, create_string_reader
content = """
title My Document
author John Doe
date 2023-12-01
"""
reader = create_string_reader(content)
doc = use_document(reader)
for node in doc:
print(f"Level {node.level}: {node.content}")
Markdown
**Reading from a file**
CodeBlock python
from terrace import use_document, create_file_reader
reader = create_file_reader('document.tce')
doc = use_document(reader)
for node in doc:
if node.is_('title'):
print(f"Document: {node.tail}")
Markdown
**Reading from a list of lines**
CodeBlock python
from terrace import use_document, create_lines_reader
lines = [
"config",
" host localhost",
" port 8080",
"routes",
" / home",
" /api api"
]
reader = create_lines_reader(lines)
doc = use_document(reader)
for node in doc:
print(f"{' ' * node.level}{node.head}: {node.tail}")