Repository navigation
Expand file tree
/
Copy pathdoc_structure.py
More file actions
111 lines (81 loc) · 3.35 KB
/
Copy pathdoc_structure.py
File metadata and controls
111 lines (81 loc) · 3.35 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
"""
Show flexdoc's document-structure features: the section hierarchy with rolled-up
size stats, the flat table of contents, and exact source spans / offset lookups.
Run from the repository checkout with: `uv run python examples/doc_structure.py`
"""
from collections.abc import Sequence
from textwrap import dedent
from flexdoc import BlockType, FlexDoc, SpanRef, TextUnit
from flexdoc.docs import Block
_SAMPLE = dedent(
"""
# Introduction
Flexdoc parses text into paragraphs and sentences. It tracks exact offsets.
## Goals
Be fast. Be accurate. Stay dependency-light. See the [docs](https://example.com/docs).
## Non-goals
We do not render Markdown here.
# Usage
Parse a document, then iterate or measure its blocks.
"""
).strip()
_BLOCK_SAMPLE = dedent(
"""
# Setup
Install, then configure.
- clone the repo
- install deps
- runtime
- dev
- run the tests
```bash
uv sync
uv run pytest
```
"""
).strip()
def main() -> None:
doc = FlexDoc.from_text(_SAMPLE)
print("--- Section size tree (words + sentences, rolled up) ---")
print(doc.section_size_tree(units=(TextUnit.words, TextUnit.sentences)))
print("\n--- Table of contents (level, title, span) ---")
for level, title, span in doc.toc():
print(f" {' ' * (level - 1)}{title} @{span}")
print("\n--- Per-section rolled-up word counts (logical) ---")
for section in doc.sections():
own = section.size(TextUnit.words, subtree=False)
whole = section.size(TextUnit.words, subtree=True)
print(f" {section.title}: {own} words own, {whole} words including subsections")
print("\n--- Exact spans and offset lookup ---")
offset = _SAMPLE.index("dependency-light")
para = doc.paragraph_at_offset(offset)
sent_index = doc.sentence_at_offset(offset)
assert para is not None and sent_index is not None
print(f" offset {offset} is in paragraph {para.original_text[:30]!r}...")
print(f" and in sentence {doc.get_sent(sent_index).text!r}")
ref = SpanRef.from_span(doc.source_text, *para.span).to_persisted()
print(f" durable paragraph reference resolves to {ref.resolve(doc.source_text)}")
print("\n--- Total words across paragraph blocks only (logical) ---")
paragraphs_only = doc.filtered(include={BlockType.paragraph})
print(
f" {paragraphs_only.size(TextUnit.words)} words in "
f"{len(paragraphs_only.paragraphs)} paragraphs"
)
print("\n--- Structural block tree (whole-document view) ---")
block_doc = FlexDoc.from_text(_BLOCK_SAMPLE)
def show_blocks(blocks: Sequence[Block], depth: int = 0) -> None:
for block in blocks:
preview = _BLOCK_SAMPLE[block.span[0] : block.span[1]].splitlines()[0]
print(f" {' ' * depth}{block.type.value}: {preview!r}")
show_blocks(block.children, depth + 1)
show_blocks(block_doc.blocks())
print("\n--- Links (text, url, span) and the sentence each is in ---")
for link in doc.links():
where = ""
if link.span is not None:
sent_index = doc.sentence_at_offset(link.span[0])
if sent_index is not None:
where = f" — in sentence {doc.get_sent(sent_index).text!r}"
print(f" [{link.text}]({link.url}) @{link.span}{where}")
if __name__ == "__main__":
main()