brewdoc-darwin-arm64 0.5.0 → 0.7.0

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.
package/README.md CHANGED
@@ -3,46 +3,50 @@
3
3
  [![PyPI](https://img.shields.io/pypi/v/brewdoc)](https://pypi.org/project/brewdoc/)
4
4
  [![CI](https://github.com/kochetkov-ma/brewdoc/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/kochetkov-ma/brewdoc/actions/workflows/ci.yml)
5
5
  [![Release](https://img.shields.io/github/v/release/kochetkov-ma/brewdoc)](https://github.com/kochetkov-ma/brewdoc/releases/latest)
6
- [![MIT](https://img.shields.io/github/license/kochetkov-ma/brewdoc)](https://github.com/kochetkov-ma/brewdoc/blob/v0.5.0/LICENSE)
6
+ [![MIT](https://img.shields.io/github/license/kochetkov-ma/brewdoc)](https://github.com/kochetkov-ma/brewdoc/blob/v0.7.0/LICENSE)
7
7
 
8
8
  Fast, deterministic document-to-Markdown conversion for agent systems. Easy to install. No model weights, OCR or external services.
9
9
 
10
10
  Local conversion runs offline after installation, with no runtime component downloads.
11
11
  Supported documents become one Markdown file and a JSON receipt describing omissions.
12
- See [formats and limits](https://github.com/kochetkov-ma/brewdoc/blob/v0.5.0/FORMATS.md).
13
- Version 0.4.1 added [selected ZIP/XML reader budgets](https://github.com/kochetkov-ma/brewdoc/blob/v0.5.0/FORMATS.md#zipxml-reader-limits)
12
+ See [formats and limits](https://github.com/kochetkov-ma/brewdoc/blob/v0.7.0/FORMATS.md).
13
+ Version 0.4.1 added [selected ZIP/XML reader budgets](https://github.com/kochetkov-ma/brewdoc/blob/v0.7.0/FORMATS.md#zipxml-reader-limits)
14
14
  for DOCX/PPTX and workbook metadata/artifacts. Excessive work refuses before output
15
15
  writes; native workbook values and total process memory remain outside those bounds.
16
16
 
17
- Version 0.5.0 adds ODT/ODP text and tables, selected MIME email bodies and exact UTF-8
18
- Markdown/text pass-through. It preserves workbook Unicode and exposed datetime precision,
19
- and selects one DOCX compatibility fallback.
20
- It also adds textless PDF page facts and selected caption, table and math-spacing fixes.
21
- See the [format contracts](FORMATS.md).
17
+ Version 0.5.0 added ODT/ODP text and tables, selected MIME email bodies and exact UTF-8
18
+ Markdown/text pass-through. It preserved workbook Unicode and exposed datetime precision,
19
+ and selected one DOCX compatibility fallback.
20
+ It also added textless PDF page facts and selected caption, table and math-spacing fixes.
21
+ Version 0.6.0 writes cleaner Markdown with minimal escaping, adds `--body-only`, accepts
22
+ documents through `--url`, decodes legacy HTML charsets and falls back to the whole page in
23
+ article mode.
24
+ Version 0.7.0 adds `--render-js auto` and HTML `--no-links`, refuses captcha, login and
25
+ JavaScript shell pages with a plain reason, reports HTTP status, redirects and charset in URL
26
+ receipts, decodes mislabelled HTML charsets by fallback and writes code and image links as
27
+ standard Markdown links.
22
28
 
23
29
  ## Install
24
30
 
25
- These examples select 0.5.0. Use a channel listed as available in [that release](https://github.com/kochetkov-ma/brewdoc/releases/tag/v0.5.0). Choose one method:
26
-
27
- Article mode is introduced in 0.4.0. Channel availability is listed in the release.
31
+ These examples select 0.7.0. Use a channel listed as available in [that release](https://github.com/kochetkov-ma/brewdoc/releases/tag/v0.7.0). Choose one method:
28
32
 
29
33
  ```sh
30
- python -m pip install "brewdoc==0.5.0"
31
- uv tool install --python 3.12 "brewdoc==0.5.0"
32
- pipx install --python 3.12 "brewdoc==0.5.0"
34
+ python -m pip install "brewdoc==0.7.0"
35
+ uv tool install --python 3.12 "brewdoc==0.7.0"
36
+ pipx install --python 3.12 "brewdoc==0.7.0"
33
37
  ```
34
38
 
35
- Use a virtual environment for pip. Python 3.12+ is required; HTML/URL need CPython 3.12-3.14.
36
- [INSTALL.md](https://github.com/kochetkov-ma/brewdoc/blob/v0.5.0/INSTALL.md) covers prerequisites, Windows, uvx, PATH, update and removal.
39
+ Use a virtual environment for pip. Python 3.12+ is required; local and URL HTML need CPython 3.12-3.14.
40
+ [INSTALL.md](https://github.com/kochetkov-ma/brewdoc/blob/v0.7.0/INSTALL.md) covers prerequisites, Windows, uvx, PATH, update and removal.
37
41
  [Latest release](https://github.com/kochetkov-ma/brewdoc/releases/latest) lists actual assets and channel availability.
38
42
 
39
43
  ### Standalone downloads
40
44
 
41
- Use downloads listed as available in the release. Python and dependencies are bundled. Verify [SHA256SUMS](https://github.com/kochetkov-ma/brewdoc/releases/download/v0.5.0/SHA256SUMS) and keep the entire extracted directory.
45
+ Use downloads listed as available in the release. Python and dependencies are bundled. Verify [SHA256SUMS](https://github.com/kochetkov-ma/brewdoc/releases/download/v0.7.0/SHA256SUMS) and keep the entire extracted directory.
42
46
 
43
- [![Linux x64 download](https://img.shields.io/badge/Linux_x64-download-blue)](https://github.com/kochetkov-ma/brewdoc/releases/download/v0.5.0/brewdoc-0.5.0-linux-x64.tar.gz)
44
- [![Windows x64 download](https://img.shields.io/badge/Windows_x64-download-blue)](https://github.com/kochetkov-ma/brewdoc/releases/download/v0.5.0/brewdoc-0.5.0-windows-x64.zip)
45
- [![macOS ARM64 download](https://img.shields.io/badge/macOS_ARM64-download-blue)](https://github.com/kochetkov-ma/brewdoc/releases/download/v0.5.0/brewdoc-0.5.0-macos-arm64.tar.gz)
47
+ [![Linux x64 download](https://img.shields.io/badge/Linux_x64-download-blue)](https://github.com/kochetkov-ma/brewdoc/releases/download/v0.7.0/brewdoc-0.7.0-linux-x64.tar.gz)
48
+ [![Windows x64 download](https://img.shields.io/badge/Windows_x64-download-blue)](https://github.com/kochetkov-ma/brewdoc/releases/download/v0.7.0/brewdoc-0.7.0-windows-x64.zip)
49
+ [![macOS ARM64 download](https://img.shields.io/badge/macOS_ARM64-download-blue)](https://github.com/kochetkov-ma/brewdoc/releases/download/v0.7.0/brewdoc-0.7.0-macos-arm64.tar.gz)
46
50
 
47
51
  | Native target | Verification environment | JavaScript |
48
52
  |---|---|---|
@@ -52,26 +56,27 @@ Use downloads listed as available in the release. Python and dependencies are bu
52
56
 
53
57
  Older OSes, Linux musl/ARM64 and macOS Intel are outside this binary set.
54
58
  Windows is unsigned; macOS has an ad hoc signature without Developer ID/notarization.
55
- Linux archives have checksums, without a detached publisher signature. [Download and launch](https://github.com/kochetkov-ma/brewdoc/blob/v0.5.0/INSTALL.md#standalone).
59
+ Linux archives have checksums, without a detached publisher signature. [Download and launch](https://github.com/kochetkov-ma/brewdoc/blob/v0.7.0/INSTALL.md#standalone).
56
60
 
57
61
  ### npm
58
62
 
59
63
  [![npm](https://img.shields.io/npm/v/brewdoc)](https://www.npmjs.com/package/brewdoc)
60
64
 
61
65
  npm targets Linux x64/glibc and macOS ARM64. Windows uses the GitHub native download or Python package.
62
- Use npm/npx only when listed as available in [the release](https://github.com/kochetkov-ma/brewdoc/releases/tag/v0.5.0).
63
- [INSTALL.md](https://github.com/kochetkov-ma/brewdoc/blob/v0.5.0/INSTALL.md#npm-and-npx) contains exact-version installation, update and removal instructions.
66
+ Use npm/npx only when listed as available in [the release](https://github.com/kochetkov-ma/brewdoc/releases/tag/v0.7.0).
67
+ [INSTALL.md](https://github.com/kochetkov-ma/brewdoc/blob/v0.7.0/INSTALL.md#npm-and-npx) contains exact-version installation, update and removal instructions.
64
68
 
65
69
  ### Homebrew
66
70
 
67
71
  Use `kochetkov-ma/brew/brewdoc` only when the release lists it as available.
68
72
  It installs the complete native bundle on macOS 15+ ARM64 or Linux x64 with system
69
- glibc 2.35+. See [installation and lifecycle](INSTALL.md#homebrew).
73
+ glibc 2.35+. See [installation and lifecycle](https://github.com/kochetkov-ma/brewdoc/blob/v0.7.0/INSTALL.md#homebrew).
70
74
 
71
75
  ## Usage
72
76
 
73
77
  ```sh
74
78
  brewdoc file.pdf --out file.md
79
+ brewdoc --body-only paper.pdf --out paper.md
75
80
  brewdoc book.epub --out book.md
76
81
  brewdoc file.xlsx --sheet Calc --sheet Inputs --out book.md
77
82
  brewdoc file.xlsm --artifact formula/sheet/000002=formulas.json
@@ -83,13 +88,16 @@ brewdoc --self-check
83
88
  caller order retains full-workbook ordinals. Artifact keys come from the Markdown artifact table.
84
89
  Requests and output collisions are validated before writes. Paths resolve against the caller's directory;
85
90
  `--out` creates parents. Refusal preserves existing output. Self-check is offline and has its own output.
91
+ `--body-only` drops the title, metadata, omissions, contents and unit anchors; unit headings stay
92
+ only for several units. The receipt is unchanged. See [body-only output](https://github.com/kochetkov-ma/brewdoc/blob/v0.7.0/FORMATS.md#body-only-output).
86
93
 
87
94
  ## Markdown and receipts
88
95
 
89
96
  Parsed document output uses `brewdoc.markdown/2`: quoted source title, Metadata, Artifacts,
90
97
  Known omissions, Contents, then anchored units. PDF uses `page/000001`, workbooks `sheet/000001`,
91
98
  PPTX/ODP `slide/000001`, and DOCX/EPUB/HTML/ODT/EML `chapter/000001`.
92
- Empty declared units remain navigable.
99
+ Empty declared units remain navigable. Escaping is minimal; HTML, EPUB and EML omit form
100
+ controls and write images with alt text as `![alt](src)`. See [Markdown escaping](https://github.com/kochetkov-ma/brewdoc/blob/v0.7.0/FORMATS.md#markdown-escaping).
93
101
  Metadata holds source/selection/content hashes, conversion tallies and artifact capabilities;
94
102
  it excludes paths, timestamps, permissions and host data. EPUB retains declared publication metadata.
95
103
 
@@ -112,7 +120,8 @@ without it, Markdown follows on stdout. Local receipts use `brewdoc.receipt/1`;
112
120
  | `out` | Markdown path, or null for stdout |
113
121
  | `markdown_schema`, `unit_keys`, `artifacts` | Success-only schema, ordered source keys and available/requested artifacts |
114
122
  | `selected_sheets` | Caller-ordered names, only when selected |
115
- | `acquisition` | URL provenance, frozen snapshot and capture status |
123
+ | `article_fallback`, `charset_fallback` | Local HTML whole-page fallback and charset chosen by fallback, only when used |
124
+ | `acquisition` | URL provenance, HTTP status, redirects, challenge, charset, frozen snapshot and capture status |
116
125
 
117
126
  Exit 0 means conversion, 1 refusal and 2 invalid usage. Success does not prove content fidelity or complete JavaScript.
118
127
  PDF/DOCX/PPTX emit ASCII; workbooks/HTML/EPUB/ODT/ODP/EML emit UTF-8 without BOM, with LF newlines.
@@ -130,29 +139,39 @@ refs = brewdoc.list_book_artifacts("book.xlsm", sheets=("Calc",))
130
139
  payload = brewdoc.read_book_artifact("book.xlsm", refs[0].key, sheets=("Calc",))
131
140
  ```
132
141
 
133
- `run` accepts `sheets` and an `artifact_outputs` key-to-path mapping. Renderers include
142
+ `run` accepts `sheets`, an `artifact_outputs` key-to-path mapping, `article`, `body_only` and `links`. Renderers include
134
143
  `render_pdf`, `render_doc`, `render_presentation`, `render_epub`, `render_html` and `render_book`.
135
144
  `read_formulas` provides typed formulas; `self_check` verifies installed routes. Local APIs never acquire URLs.
136
145
 
137
146
  ## Explicit URL acquisition
138
147
 
139
- `--url` deliberately acquires a public HTTP(S) page before local conversion.
148
+ `--url` deliberately acquires a public HTTP(S) page or supported document before local conversion.
149
+ Content-Type and magic bytes pick the route: HTML, PDF, Office, OpenDocument, EPUB, EML or text.
140
150
 
141
151
  ```sh
142
152
  brewdoc --url https://example.com/article --out article.md
153
+ brewdoc --url https://arxiv.org/pdf/1706.03762 --out attention.md
143
154
  brewdoc --url https://example.com/article --render-js --timeout 30 --out article.md
155
+ brewdoc --url "https://hn.algolia.com/?q=rust" --render-js auto --out search.md
156
+ brewdoc --url https://example.com/article --no-links --out article.md
144
157
  ```
145
158
 
159
+ Bare `--render-js` means `always`; `--render-js auto` runs JS only when the static page is a JavaScript shell.
160
+ Prefer `--render-js auto` for unknown pages: `always` runs JS on every page and can hit an engine quota on a
161
+ page that static mode reads. Pages that need more than the bounded engine refuse, such as crates.io.
162
+ Captcha, bot challenge, login and shell pages refuse at stage `challenge` or `javascript_required` with a plain
163
+ reason; the receipt names the challenge and keeps the HTTP status. `--no-links` (HTML only) keeps link text,
164
+ omits destinations and discloses it in the receipt.
146
165
  `--timeout` is one positive finite waiting budget, default 30 seconds; cleanup/conversion can add time.
147
166
  Public destinations, DNS, redirects, TLS, requests and bytes are validated. Ordinary requests use GET;
148
167
  JS admits only the narrow credential-free HN Algolia XHR POST exception. Local HTML never fetches or runs scripts.
149
168
  Optional JS needs installed/bundled prerequisites, refuses unsupported runtimes before HTTP and downloads no engine.
150
- Timing-only expiry can preserve valid partial content; hard failures refuse output. [Full URL/JS limits](https://github.com/kochetkov-ma/brewdoc/blob/v0.5.0/FORMATS.md#url-acquisition).
169
+ Timing-only expiry can preserve valid partial content; hard failures refuse output. [Full URL/JS limits](https://github.com/kochetkov-ma/brewdoc/blob/v0.7.0/FORMATS.md#url-acquisition).
151
170
 
152
171
  ## Article mode
153
172
 
154
173
  Introduced in 0.4.0; use a channel listed as available in the release. For Python JS capture, install
155
- `brewdoc[render-js]==0.5.0`; supported standalone bundles include its prerequisites.
174
+ `brewdoc[render-js]==0.7.0`; supported standalone bundles include its prerequisites.
156
175
 
157
176
  ```sh
158
177
  brewdoc page.html --article --out article.md
@@ -165,17 +184,18 @@ code, receipt, markdown = brewdoc.run("page.html", article=True)
165
184
  markdown, tally = brewdoc.render_html("page.html", article=True)
166
185
  ```
167
186
 
168
- Article mode selects one explicit article or a qualified main subtree. It suits single articles
169
- and documentation pages with those literal HTML elements. Feeds with peer articles, ambiguous
170
- main regions and pages without a qualified subtree refuse. A visible form disqualifies main
171
- fallback; an explicit article can retain forms. There is no full-page fallback or text scoring.
172
- Selection uses the recovered static HTML or frozen JS snapshot,
187
+ Article mode keeps visible `main` (or role main) content, or outer `article` content when no main
188
+ exists; articles outside a main are dropped when one exists. Page-chrome landmarks are skipped, but
189
+ a header inside an article or a nav inside main stays.
190
+ Peer articles and multiple mains render in DOM order. When no candidate renders, the whole clean
191
+ page renders and the receipt adds `article_fallback: true`; selection never refuses for page
192
+ structure. There is no text scoring. Selection uses the recovered static HTML or frozen JS snapshot,
173
193
  without layout or inferred author/date metadata. The source title is unchanged.
174
194
 
175
- The receipt's `not_carried` and successful Markdown's Known omissions declare:
195
+ When content is selected, the receipt's `not_carried` and Markdown's Known omissions declare:
176
196
  `body content outside the selected article or main subtree; complete page coverage is not claimed`.
177
- The [article contract](https://github.com/kochetkov-ma/brewdoc/blob/v0.5.0/FORMATS.md#article-selection)
178
- defines selection, refusals and limits.
197
+ The [article contract](https://github.com/kochetkov-ma/brewdoc/blob/v0.7.0/FORMATS.md#article-selection)
198
+ defines selection, fallback and limits.
179
199
 
180
200
  [Earlier source-package CI](https://github.com/kochetkov-ma/brewdoc/actions/runs/38431645006) passed on
181
201
  Ubuntu 22.04 x64/glibc with CPython 3.13.15, and macOS 15 ARM64/Windows Server 2025 x64
@@ -185,10 +205,10 @@ tested patches, not a claim about newer versions. These results predate the 0.5.
185
205
  CPython 3.12.14 retains the local macOS full-suite baseline and existing CI smoke checks.
186
206
  Package evidence is separate from standalone binaries; other OS/minor combinations, free-threaded CPython and other
187
207
  architectures remain untested here.
188
- See [package compatibility](https://github.com/kochetkov-ma/brewdoc/blob/v0.5.0/FORMATS.md#python-package-compatibility).
208
+ See [package compatibility](https://github.com/kochetkov-ma/brewdoc/blob/v0.7.0/FORMATS.md#python-package-compatibility).
189
209
 
190
- [Format contracts](https://github.com/kochetkov-ma/brewdoc/blob/v0.5.0/FORMATS.md) | [Corpus](https://github.com/kochetkov-ma/brewdoc/blob/v0.5.0/benchmarks/CATALOG.md) | [Measurements](https://github.com/kochetkov-ma/brewdoc/blob/v0.5.0/benchmarks/METHODOLOGY.md) | [Results](https://github.com/kochetkov-ma/brewdoc/blob/v0.5.0/benchmarks/results/README.md)
191
- [Releasing](https://github.com/kochetkov-ma/brewdoc/blob/v0.5.0/RELEASING.md) | [Agent entry point](https://github.com/kochetkov-ma/brewdoc/blob/v0.5.0/llms.txt) | [MIT license](https://github.com/kochetkov-ma/brewdoc/blob/v0.5.0/LICENSE)
210
+ [Format contracts](https://github.com/kochetkov-ma/brewdoc/blob/v0.7.0/FORMATS.md) | [Corpus](https://github.com/kochetkov-ma/brewdoc/blob/v0.7.0/benchmarks/CATALOG.md) | [Measurements](https://github.com/kochetkov-ma/brewdoc/blob/v0.7.0/benchmarks/METHODOLOGY.md) | [Results](https://github.com/kochetkov-ma/brewdoc/blob/v0.7.0/benchmarks/results/README.md)
211
+ [Releasing](https://github.com/kochetkov-ma/brewdoc/blob/v0.7.0/RELEASING.md) | [Agent entry point](https://github.com/kochetkov-ma/brewdoc/blob/v0.7.0/llms.txt) | [MIT license](https://github.com/kochetkov-ma/brewdoc/blob/v0.7.0/LICENSE)
192
212
 
193
213
  ## Related projects
194
214
 
Binary file
@@ -2,6 +2,7 @@
2
2
  const hostGlobal = globalThis;
3
3
  let nextId = 1;
4
4
  let clock = 0;
5
+ let frameTime;
5
6
  let baseURL = '';
6
7
  const requests = [];
7
8
  const pending = new Map();
@@ -439,7 +440,7 @@
439
440
  defineProperty(globalThis, 'localStorage', { configurable: true, get() { touch(); return storage; } });
440
441
  }
441
442
 
442
- function anchorURL(value) {
443
+ function anchorURL(value, baseText) {
443
444
  const raw = String(value);
444
445
  if (raw.length > 8192 || encodeURL(raw).replace(/%[0-9a-f]{2}/gi, '_').length > 8192 ||
445
446
  /[\u0000-\u0020\u007f\\]/.test(raw) || /%(?![0-9a-f]{2})/i.test(raw))
@@ -457,7 +458,7 @@
457
458
  let parsed;
458
459
  if (/^https?:\/\//i.test(raw)) parsed = absolute(raw);
459
460
  else {
460
- const base = absolute(pageDocument.baseURI);
461
+ const base = absolute(baseText ?? pageDocument.baseURI);
461
462
  if (raw.startsWith('//')) parsed = absolute(base.protocol + raw);
462
463
  else {
463
464
  if (/^[a-z][a-z0-9+.-]*:/i.test(raw)) throw new TypeError('anchor URL scheme unsupported');
@@ -480,6 +481,68 @@
480
481
  return parsed;
481
482
  }
482
483
 
484
+ const urlParts = new WeakMap();
485
+ const urlQueries = new WeakMap();
486
+ const queryOwners = new WeakMap();
487
+ const formEncode = text => encodeURL(text).replace(/%20/g, '+')
488
+ .replace(/[!'()~]/g, letter => '%' + letter.charCodeAt(0).toString(16).toUpperCase());
489
+ const formDecode = text => { try { return decodeURIComponent(text.replace(/\+/g, ' ')); } catch { return text; } };
490
+ class URLSearchParams {
491
+ #list = [];
492
+ constructor(init = '') {
493
+ if (init && typeof init === 'object')
494
+ for (const [key, value] of Symbol.iterator in init ? init : entries(init)) this.#list.push([String(key), String(value)]);
495
+ else for (const pair of String(init).replace(/^\?/, '').split('&')) {
496
+ const at = pair.indexOf('=');
497
+ if (pair) this.#list.push(at < 0 ? [formDecode(pair), ''] : [formDecode(pair.slice(0, at)), formDecode(pair.slice(at + 1))]);
498
+ }
499
+ }
500
+ #changed() { queryOwners.get(this)?.(this.toString()); }
501
+ get(name) { return this.#list.find(([key]) => key === String(name))?.[1] ?? null; }
502
+ has(name) { return this.#list.some(([key]) => key === String(name)); }
503
+ append(name, value) { this.#list.push([String(name), String(value)]); this.#changed(); }
504
+ delete(name) { this.#list = this.#list.filter(([key]) => key !== String(name)); this.#changed(); }
505
+ set(name, value) {
506
+ const index = this.#list.findIndex(([key]) => key === String(name));
507
+ this.#list = this.#list.filter(([key]) => key !== String(name));
508
+ this.#list.splice(index < 0 ? this.#list.length : index, 0, [String(name), String(value)]);
509
+ this.#changed();
510
+ }
511
+ entries() { return this.#list.map(([key, value]) => [key, value]).values(); }
512
+ [Symbol.iterator]() { return this.entries(); }
513
+ toString() { return this.#list.map(([key, value]) => formEncode(key) + '=' + formEncode(value)).join('&'); }
514
+ }
515
+ class URL {
516
+ constructor(url, base) {
517
+ if (base === undefined && !/^https?:\/\//i.test(String(url))) throw new TypeError('URL without base must be absolute');
518
+ urlParts.set(this, anchorURL(url, base === undefined ? undefined : new URL(base).href));
519
+ }
520
+ get origin() { return this.protocol + '//' + this.host; }
521
+ get searchParams() {
522
+ if (!urlQueries.has(this)) {
523
+ const query = new URLSearchParams(this.search);
524
+ queryOwners.set(query, text => { this.search = text; urlQueries.set(this, query); });
525
+ urlQueries.set(this, query);
526
+ }
527
+ return urlQueries.get(this);
528
+ }
529
+ toString() { return this.href; }
530
+ toJSON() { return this.href; }
531
+ }
532
+ // Only href, pathname, search and hash are writable; other components stay read-only.
533
+ for (const name of ['href', 'protocol', 'host', 'hostname', 'port', 'pathname', 'search', 'hash']) {
534
+ const prefix = { pathname: '/', search: '?', hash: '#' }[name];
535
+ defineProperty(URL.prototype, name, {
536
+ configurable: true, enumerable: true, get() { return urlParts.get(this)[name]; },
537
+ set: name === 'href' || prefix ? function (value) {
538
+ const parts = { ...urlParts.get(this), [name]: String(value) };
539
+ if (prefix && parts[name] && !parts[name].startsWith(prefix)) parts[name] = prefix + parts[name];
540
+ urlParts.set(this, anchorURL(name === 'href' ? parts.href : parts.protocol + '//' + parts.host + parts.pathname + parts.search + parts.hash));
541
+ urlQueries.delete(this);
542
+ } : undefined
543
+ });
544
+ }
545
+
483
546
  class Headers {
484
547
  constructor(source = {}) {
485
548
  this.values = new Map(Object.entries(source).map(([key, value]) => [key.toLowerCase(), String(value)]));
@@ -567,12 +630,12 @@
567
630
  });
568
631
  }
569
632
 
570
- function setTimer(callback, delay = 0, repeat = false, args = []) {
633
+ function setTimer(callback, delay = 0, repeat = false, args = [], frame = false) {
571
634
  if (typeof callback !== 'function') throw new TypeError('string timers unsupported');
572
635
  if (timers.size >= 200) { violation = true; throw new RangeError('timer count exceeded'); }
573
636
  const id = nextId++;
574
637
  const milliseconds = Math.max(0, Math.min(2147483647, Number(delay) || 0));
575
- timers.set(id, { callback, args, delay: milliseconds, due: clock + milliseconds, repeat });
638
+ timers.set(id, { callback, args, delay: milliseconds, due: clock + milliseconds, repeat, frame });
576
639
  return id;
577
640
  }
578
641
 
@@ -582,8 +645,14 @@
582
645
  parsedView = undefined;
583
646
  baseURL = url;
584
647
  installStorage();
585
- globalThis.window = view;
648
+ globalThis.window = globalThis.self = view;
586
649
  globalThis.document = view.document;
650
+ Object.defineProperty(view.document, 'currentScript', { get: () => currentScript ?? null });
651
+ Object.defineProperty(view.document, 'cookie', { get: () => '', set() {} });
652
+ const silent = () => {};
653
+ globalThis.console = { log: silent, info: silent, warn: silent, error: silent, debug: silent };
654
+ globalThis.URL = URL;
655
+ globalThis.URLSearchParams = URLSearchParams;
587
656
  pageDocument = view.document;
588
657
  pageWindow = view;
589
658
  const htmlConstructor = view.HTMLElement;
@@ -643,7 +712,7 @@
643
712
  globalThis[key] = view[key];
644
713
  Object.defineProperty(document, 'readyState', { value: 'loading', writable: true });
645
714
  Object.defineProperty(document, 'baseURI', { value: url, writable: true });
646
- globalThis.location = parse(locationJSON);
715
+ globalThis.location = { ...parse(locationJSON), toString() { return this.href; } };
647
716
  Object.defineProperty(globalThis, 'history', { value: Object.freeze({ length: 1, state: null }) });
648
717
  const anchorPrototype = view.HTMLAnchorElement.prototype;
649
718
  const href = Object.getOwnPropertyDescriptor(anchorPrototype, 'href');
@@ -680,6 +749,9 @@
680
749
  globalThis.setInterval = (callback, delay, ...args) => setTimer(callback, delay, true, args);
681
750
  globalThis.clearTimeout = id => timers.delete(id);
682
751
  globalThis.clearInterval = globalThis.clearTimeout;
752
+ // Frames are due at once so one always runs on the next pump pass, which never waits for them.
753
+ globalThis.requestAnimationFrame = callback => setTimer(callback, 0, false, [clock], true);
754
+ globalThis.cancelAnimationFrame = globalThis.clearTimeout;
683
755
  globalThis.AbortController = class {
684
756
  constructor() { this.signal = new EventTarget(); this.signal.aborted = false; }
685
757
  abort() { this.signal.aborted = true; this.signal.dispatchEvent(new Event('abort')); }
@@ -807,16 +879,18 @@
807
879
  if (record.error) state.reject(error(record.name || 'TypeError', record.error));
808
880
  else state.resolve(new Response(record));
809
881
  };
810
- globalThis.__smallTimers = () => controlJSON([...timers].map(([id, timer]) => ({ id, due: timer.due })));
882
+ globalThis.__smallTimers = () => controlJSON([...timers].map(([id, timer]) => ({ id, due: timer.due, repeat: timer.repeat, frame: timer.frame })));
811
883
  globalThis.__smallRunTimer = (id, now) => {
812
884
  clock = now;
813
885
  const timer = timers.get(id);
814
886
  if (!timer) return;
815
887
  if (timer.repeat) timer.due = now + Math.max(1, timer.delay);
816
888
  else timers.delete(id);
817
- try { timer.callback(...timer.args); } catch (reason) { errors.push(String(reason)); }
889
+ // One pump pass is one frame: its frames share the earliest request time, keeping output deterministic.
890
+ const args = timer.frame ? [frameTime ??= timer.args[0]] : timer.args;
891
+ try { timer.callback(...args); } catch (reason) { errors.push(String(reason)); }
818
892
  };
819
- globalThis.__smallClock = now => { clock = now; };
893
+ globalThis.__smallClock = now => { clock = now; frameTime = undefined; };
820
894
  globalThis.__smallErrors = () => {
821
895
  const descriptor = ownDescriptor(hostGlobal, 'Promise');
822
896
  if (!descriptor || descriptor.get !== promiseGetter || descriptor.set !== promiseSetter ||
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: brewdoc
3
- Version: 0.5.0
3
+ Version: 0.7.0
4
4
  Summary: Fast, deterministic document-to-Markdown conversion for agent systems. Easy to install. No model weights, OCR or external services.
5
5
  Project-URL: Homepage, https://github.com/kochetkov-ma/brewdoc
6
6
  Project-URL: Repository, https://github.com/kochetkov-ma/brewdoc
@@ -31,46 +31,50 @@ Description-Content-Type: text/markdown
31
31
  [![PyPI](https://img.shields.io/pypi/v/brewdoc)](https://pypi.org/project/brewdoc/)
32
32
  [![CI](https://github.com/kochetkov-ma/brewdoc/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/kochetkov-ma/brewdoc/actions/workflows/ci.yml)
33
33
  [![Release](https://img.shields.io/github/v/release/kochetkov-ma/brewdoc)](https://github.com/kochetkov-ma/brewdoc/releases/latest)
34
- [![MIT](https://img.shields.io/github/license/kochetkov-ma/brewdoc)](https://github.com/kochetkov-ma/brewdoc/blob/v0.5.0/LICENSE)
34
+ [![MIT](https://img.shields.io/github/license/kochetkov-ma/brewdoc)](https://github.com/kochetkov-ma/brewdoc/blob/v0.7.0/LICENSE)
35
35
 
36
36
  Fast, deterministic document-to-Markdown conversion for agent systems. Easy to install. No model weights, OCR or external services.
37
37
 
38
38
  Local conversion runs offline after installation, with no runtime component downloads.
39
39
  Supported documents become one Markdown file and a JSON receipt describing omissions.
40
- See [formats and limits](https://github.com/kochetkov-ma/brewdoc/blob/v0.5.0/FORMATS.md).
41
- Version 0.4.1 added [selected ZIP/XML reader budgets](https://github.com/kochetkov-ma/brewdoc/blob/v0.5.0/FORMATS.md#zipxml-reader-limits)
40
+ See [formats and limits](https://github.com/kochetkov-ma/brewdoc/blob/v0.7.0/FORMATS.md).
41
+ Version 0.4.1 added [selected ZIP/XML reader budgets](https://github.com/kochetkov-ma/brewdoc/blob/v0.7.0/FORMATS.md#zipxml-reader-limits)
42
42
  for DOCX/PPTX and workbook metadata/artifacts. Excessive work refuses before output
43
43
  writes; native workbook values and total process memory remain outside those bounds.
44
44
 
45
- Version 0.5.0 adds ODT/ODP text and tables, selected MIME email bodies and exact UTF-8
46
- Markdown/text pass-through. It preserves workbook Unicode and exposed datetime precision,
47
- and selects one DOCX compatibility fallback.
48
- It also adds textless PDF page facts and selected caption, table and math-spacing fixes.
49
- See the [format contracts](FORMATS.md).
45
+ Version 0.5.0 added ODT/ODP text and tables, selected MIME email bodies and exact UTF-8
46
+ Markdown/text pass-through. It preserved workbook Unicode and exposed datetime precision,
47
+ and selected one DOCX compatibility fallback.
48
+ It also added textless PDF page facts and selected caption, table and math-spacing fixes.
49
+ Version 0.6.0 writes cleaner Markdown with minimal escaping, adds `--body-only`, accepts
50
+ documents through `--url`, decodes legacy HTML charsets and falls back to the whole page in
51
+ article mode.
52
+ Version 0.7.0 adds `--render-js auto` and HTML `--no-links`, refuses captcha, login and
53
+ JavaScript shell pages with a plain reason, reports HTTP status, redirects and charset in URL
54
+ receipts, decodes mislabelled HTML charsets by fallback and writes code and image links as
55
+ standard Markdown links.
50
56
 
51
57
  ## Install
52
58
 
53
- These examples select 0.5.0. Use a channel listed as available in [that release](https://github.com/kochetkov-ma/brewdoc/releases/tag/v0.5.0). Choose one method:
54
-
55
- Article mode is introduced in 0.4.0. Channel availability is listed in the release.
59
+ These examples select 0.7.0. Use a channel listed as available in [that release](https://github.com/kochetkov-ma/brewdoc/releases/tag/v0.7.0). Choose one method:
56
60
 
57
61
  ```sh
58
- python -m pip install "brewdoc==0.5.0"
59
- uv tool install --python 3.12 "brewdoc==0.5.0"
60
- pipx install --python 3.12 "brewdoc==0.5.0"
62
+ python -m pip install "brewdoc==0.7.0"
63
+ uv tool install --python 3.12 "brewdoc==0.7.0"
64
+ pipx install --python 3.12 "brewdoc==0.7.0"
61
65
  ```
62
66
 
63
- Use a virtual environment for pip. Python 3.12+ is required; HTML/URL need CPython 3.12-3.14.
64
- [INSTALL.md](https://github.com/kochetkov-ma/brewdoc/blob/v0.5.0/INSTALL.md) covers prerequisites, Windows, uvx, PATH, update and removal.
67
+ Use a virtual environment for pip. Python 3.12+ is required; local and URL HTML need CPython 3.12-3.14.
68
+ [INSTALL.md](https://github.com/kochetkov-ma/brewdoc/blob/v0.7.0/INSTALL.md) covers prerequisites, Windows, uvx, PATH, update and removal.
65
69
  [Latest release](https://github.com/kochetkov-ma/brewdoc/releases/latest) lists actual assets and channel availability.
66
70
 
67
71
  ### Standalone downloads
68
72
 
69
- Use downloads listed as available in the release. Python and dependencies are bundled. Verify [SHA256SUMS](https://github.com/kochetkov-ma/brewdoc/releases/download/v0.5.0/SHA256SUMS) and keep the entire extracted directory.
73
+ Use downloads listed as available in the release. Python and dependencies are bundled. Verify [SHA256SUMS](https://github.com/kochetkov-ma/brewdoc/releases/download/v0.7.0/SHA256SUMS) and keep the entire extracted directory.
70
74
 
71
- [![Linux x64 download](https://img.shields.io/badge/Linux_x64-download-blue)](https://github.com/kochetkov-ma/brewdoc/releases/download/v0.5.0/brewdoc-0.5.0-linux-x64.tar.gz)
72
- [![Windows x64 download](https://img.shields.io/badge/Windows_x64-download-blue)](https://github.com/kochetkov-ma/brewdoc/releases/download/v0.5.0/brewdoc-0.5.0-windows-x64.zip)
73
- [![macOS ARM64 download](https://img.shields.io/badge/macOS_ARM64-download-blue)](https://github.com/kochetkov-ma/brewdoc/releases/download/v0.5.0/brewdoc-0.5.0-macos-arm64.tar.gz)
75
+ [![Linux x64 download](https://img.shields.io/badge/Linux_x64-download-blue)](https://github.com/kochetkov-ma/brewdoc/releases/download/v0.7.0/brewdoc-0.7.0-linux-x64.tar.gz)
76
+ [![Windows x64 download](https://img.shields.io/badge/Windows_x64-download-blue)](https://github.com/kochetkov-ma/brewdoc/releases/download/v0.7.0/brewdoc-0.7.0-windows-x64.zip)
77
+ [![macOS ARM64 download](https://img.shields.io/badge/macOS_ARM64-download-blue)](https://github.com/kochetkov-ma/brewdoc/releases/download/v0.7.0/brewdoc-0.7.0-macos-arm64.tar.gz)
74
78
 
75
79
  | Native target | Verification environment | JavaScript |
76
80
  |---|---|---|
@@ -80,26 +84,27 @@ Use downloads listed as available in the release. Python and dependencies are bu
80
84
 
81
85
  Older OSes, Linux musl/ARM64 and macOS Intel are outside this binary set.
82
86
  Windows is unsigned; macOS has an ad hoc signature without Developer ID/notarization.
83
- Linux archives have checksums, without a detached publisher signature. [Download and launch](https://github.com/kochetkov-ma/brewdoc/blob/v0.5.0/INSTALL.md#standalone).
87
+ Linux archives have checksums, without a detached publisher signature. [Download and launch](https://github.com/kochetkov-ma/brewdoc/blob/v0.7.0/INSTALL.md#standalone).
84
88
 
85
89
  ### npm
86
90
 
87
91
  [![npm](https://img.shields.io/npm/v/brewdoc)](https://www.npmjs.com/package/brewdoc)
88
92
 
89
93
  npm targets Linux x64/glibc and macOS ARM64. Windows uses the GitHub native download or Python package.
90
- Use npm/npx only when listed as available in [the release](https://github.com/kochetkov-ma/brewdoc/releases/tag/v0.5.0).
91
- [INSTALL.md](https://github.com/kochetkov-ma/brewdoc/blob/v0.5.0/INSTALL.md#npm-and-npx) contains exact-version installation, update and removal instructions.
94
+ Use npm/npx only when listed as available in [the release](https://github.com/kochetkov-ma/brewdoc/releases/tag/v0.7.0).
95
+ [INSTALL.md](https://github.com/kochetkov-ma/brewdoc/blob/v0.7.0/INSTALL.md#npm-and-npx) contains exact-version installation, update and removal instructions.
92
96
 
93
97
  ### Homebrew
94
98
 
95
99
  Use `kochetkov-ma/brew/brewdoc` only when the release lists it as available.
96
100
  It installs the complete native bundle on macOS 15+ ARM64 or Linux x64 with system
97
- glibc 2.35+. See [installation and lifecycle](INSTALL.md#homebrew).
101
+ glibc 2.35+. See [installation and lifecycle](https://github.com/kochetkov-ma/brewdoc/blob/v0.7.0/INSTALL.md#homebrew).
98
102
 
99
103
  ## Usage
100
104
 
101
105
  ```sh
102
106
  brewdoc file.pdf --out file.md
107
+ brewdoc --body-only paper.pdf --out paper.md
103
108
  brewdoc book.epub --out book.md
104
109
  brewdoc file.xlsx --sheet Calc --sheet Inputs --out book.md
105
110
  brewdoc file.xlsm --artifact formula/sheet/000002=formulas.json
@@ -111,13 +116,16 @@ brewdoc --self-check
111
116
  caller order retains full-workbook ordinals. Artifact keys come from the Markdown artifact table.
112
117
  Requests and output collisions are validated before writes. Paths resolve against the caller's directory;
113
118
  `--out` creates parents. Refusal preserves existing output. Self-check is offline and has its own output.
119
+ `--body-only` drops the title, metadata, omissions, contents and unit anchors; unit headings stay
120
+ only for several units. The receipt is unchanged. See [body-only output](https://github.com/kochetkov-ma/brewdoc/blob/v0.7.0/FORMATS.md#body-only-output).
114
121
 
115
122
  ## Markdown and receipts
116
123
 
117
124
  Parsed document output uses `brewdoc.markdown/2`: quoted source title, Metadata, Artifacts,
118
125
  Known omissions, Contents, then anchored units. PDF uses `page/000001`, workbooks `sheet/000001`,
119
126
  PPTX/ODP `slide/000001`, and DOCX/EPUB/HTML/ODT/EML `chapter/000001`.
120
- Empty declared units remain navigable.
127
+ Empty declared units remain navigable. Escaping is minimal; HTML, EPUB and EML omit form
128
+ controls and write images with alt text as `![alt](src)`. See [Markdown escaping](https://github.com/kochetkov-ma/brewdoc/blob/v0.7.0/FORMATS.md#markdown-escaping).
121
129
  Metadata holds source/selection/content hashes, conversion tallies and artifact capabilities;
122
130
  it excludes paths, timestamps, permissions and host data. EPUB retains declared publication metadata.
123
131
 
@@ -140,7 +148,8 @@ without it, Markdown follows on stdout. Local receipts use `brewdoc.receipt/1`;
140
148
  | `out` | Markdown path, or null for stdout |
141
149
  | `markdown_schema`, `unit_keys`, `artifacts` | Success-only schema, ordered source keys and available/requested artifacts |
142
150
  | `selected_sheets` | Caller-ordered names, only when selected |
143
- | `acquisition` | URL provenance, frozen snapshot and capture status |
151
+ | `article_fallback`, `charset_fallback` | Local HTML whole-page fallback and charset chosen by fallback, only when used |
152
+ | `acquisition` | URL provenance, HTTP status, redirects, challenge, charset, frozen snapshot and capture status |
144
153
 
145
154
  Exit 0 means conversion, 1 refusal and 2 invalid usage. Success does not prove content fidelity or complete JavaScript.
146
155
  PDF/DOCX/PPTX emit ASCII; workbooks/HTML/EPUB/ODT/ODP/EML emit UTF-8 without BOM, with LF newlines.
@@ -158,29 +167,39 @@ refs = brewdoc.list_book_artifacts("book.xlsm", sheets=("Calc",))
158
167
  payload = brewdoc.read_book_artifact("book.xlsm", refs[0].key, sheets=("Calc",))
159
168
  ```
160
169
 
161
- `run` accepts `sheets` and an `artifact_outputs` key-to-path mapping. Renderers include
170
+ `run` accepts `sheets`, an `artifact_outputs` key-to-path mapping, `article`, `body_only` and `links`. Renderers include
162
171
  `render_pdf`, `render_doc`, `render_presentation`, `render_epub`, `render_html` and `render_book`.
163
172
  `read_formulas` provides typed formulas; `self_check` verifies installed routes. Local APIs never acquire URLs.
164
173
 
165
174
  ## Explicit URL acquisition
166
175
 
167
- `--url` deliberately acquires a public HTTP(S) page before local conversion.
176
+ `--url` deliberately acquires a public HTTP(S) page or supported document before local conversion.
177
+ Content-Type and magic bytes pick the route: HTML, PDF, Office, OpenDocument, EPUB, EML or text.
168
178
 
169
179
  ```sh
170
180
  brewdoc --url https://example.com/article --out article.md
181
+ brewdoc --url https://arxiv.org/pdf/1706.03762 --out attention.md
171
182
  brewdoc --url https://example.com/article --render-js --timeout 30 --out article.md
183
+ brewdoc --url "https://hn.algolia.com/?q=rust" --render-js auto --out search.md
184
+ brewdoc --url https://example.com/article --no-links --out article.md
172
185
  ```
173
186
 
187
+ Bare `--render-js` means `always`; `--render-js auto` runs JS only when the static page is a JavaScript shell.
188
+ Prefer `--render-js auto` for unknown pages: `always` runs JS on every page and can hit an engine quota on a
189
+ page that static mode reads. Pages that need more than the bounded engine refuse, such as crates.io.
190
+ Captcha, bot challenge, login and shell pages refuse at stage `challenge` or `javascript_required` with a plain
191
+ reason; the receipt names the challenge and keeps the HTTP status. `--no-links` (HTML only) keeps link text,
192
+ omits destinations and discloses it in the receipt.
174
193
  `--timeout` is one positive finite waiting budget, default 30 seconds; cleanup/conversion can add time.
175
194
  Public destinations, DNS, redirects, TLS, requests and bytes are validated. Ordinary requests use GET;
176
195
  JS admits only the narrow credential-free HN Algolia XHR POST exception. Local HTML never fetches or runs scripts.
177
196
  Optional JS needs installed/bundled prerequisites, refuses unsupported runtimes before HTTP and downloads no engine.
178
- Timing-only expiry can preserve valid partial content; hard failures refuse output. [Full URL/JS limits](https://github.com/kochetkov-ma/brewdoc/blob/v0.5.0/FORMATS.md#url-acquisition).
197
+ Timing-only expiry can preserve valid partial content; hard failures refuse output. [Full URL/JS limits](https://github.com/kochetkov-ma/brewdoc/blob/v0.7.0/FORMATS.md#url-acquisition).
179
198
 
180
199
  ## Article mode
181
200
 
182
201
  Introduced in 0.4.0; use a channel listed as available in the release. For Python JS capture, install
183
- `brewdoc[render-js]==0.5.0`; supported standalone bundles include its prerequisites.
202
+ `brewdoc[render-js]==0.7.0`; supported standalone bundles include its prerequisites.
184
203
 
185
204
  ```sh
186
205
  brewdoc page.html --article --out article.md
@@ -193,17 +212,18 @@ code, receipt, markdown = brewdoc.run("page.html", article=True)
193
212
  markdown, tally = brewdoc.render_html("page.html", article=True)
194
213
  ```
195
214
 
196
- Article mode selects one explicit article or a qualified main subtree. It suits single articles
197
- and documentation pages with those literal HTML elements. Feeds with peer articles, ambiguous
198
- main regions and pages without a qualified subtree refuse. A visible form disqualifies main
199
- fallback; an explicit article can retain forms. There is no full-page fallback or text scoring.
200
- Selection uses the recovered static HTML or frozen JS snapshot,
215
+ Article mode keeps visible `main` (or role main) content, or outer `article` content when no main
216
+ exists; articles outside a main are dropped when one exists. Page-chrome landmarks are skipped, but
217
+ a header inside an article or a nav inside main stays.
218
+ Peer articles and multiple mains render in DOM order. When no candidate renders, the whole clean
219
+ page renders and the receipt adds `article_fallback: true`; selection never refuses for page
220
+ structure. There is no text scoring. Selection uses the recovered static HTML or frozen JS snapshot,
201
221
  without layout or inferred author/date metadata. The source title is unchanged.
202
222
 
203
- The receipt's `not_carried` and successful Markdown's Known omissions declare:
223
+ When content is selected, the receipt's `not_carried` and Markdown's Known omissions declare:
204
224
  `body content outside the selected article or main subtree; complete page coverage is not claimed`.
205
- The [article contract](https://github.com/kochetkov-ma/brewdoc/blob/v0.5.0/FORMATS.md#article-selection)
206
- defines selection, refusals and limits.
225
+ The [article contract](https://github.com/kochetkov-ma/brewdoc/blob/v0.7.0/FORMATS.md#article-selection)
226
+ defines selection, fallback and limits.
207
227
 
208
228
  [Earlier source-package CI](https://github.com/kochetkov-ma/brewdoc/actions/runs/38431645006) passed on
209
229
  Ubuntu 22.04 x64/glibc with CPython 3.13.15, and macOS 15 ARM64/Windows Server 2025 x64
@@ -213,10 +233,10 @@ tested patches, not a claim about newer versions. These results predate the 0.5.
213
233
  CPython 3.12.14 retains the local macOS full-suite baseline and existing CI smoke checks.
214
234
  Package evidence is separate from standalone binaries; other OS/minor combinations, free-threaded CPython and other
215
235
  architectures remain untested here.
216
- See [package compatibility](https://github.com/kochetkov-ma/brewdoc/blob/v0.5.0/FORMATS.md#python-package-compatibility).
236
+ See [package compatibility](https://github.com/kochetkov-ma/brewdoc/blob/v0.7.0/FORMATS.md#python-package-compatibility).
217
237
 
218
- [Format contracts](https://github.com/kochetkov-ma/brewdoc/blob/v0.5.0/FORMATS.md) | [Corpus](https://github.com/kochetkov-ma/brewdoc/blob/v0.5.0/benchmarks/CATALOG.md) | [Measurements](https://github.com/kochetkov-ma/brewdoc/blob/v0.5.0/benchmarks/METHODOLOGY.md) | [Results](https://github.com/kochetkov-ma/brewdoc/blob/v0.5.0/benchmarks/results/README.md)
219
- [Releasing](https://github.com/kochetkov-ma/brewdoc/blob/v0.5.0/RELEASING.md) | [Agent entry point](https://github.com/kochetkov-ma/brewdoc/blob/v0.5.0/llms.txt) | [MIT license](https://github.com/kochetkov-ma/brewdoc/blob/v0.5.0/LICENSE)
238
+ [Format contracts](https://github.com/kochetkov-ma/brewdoc/blob/v0.7.0/FORMATS.md) | [Corpus](https://github.com/kochetkov-ma/brewdoc/blob/v0.7.0/benchmarks/CATALOG.md) | [Measurements](https://github.com/kochetkov-ma/brewdoc/blob/v0.7.0/benchmarks/METHODOLOGY.md) | [Results](https://github.com/kochetkov-ma/brewdoc/blob/v0.7.0/benchmarks/results/README.md)
239
+ [Releasing](https://github.com/kochetkov-ma/brewdoc/blob/v0.7.0/RELEASING.md) | [Agent entry point](https://github.com/kochetkov-ma/brewdoc/blob/v0.7.0/llms.txt) | [MIT license](https://github.com/kochetkov-ma/brewdoc/blob/v0.7.0/LICENSE)
220
240
 
221
241
  ## Related projects
222
242
 
@@ -0,0 +1,33 @@
1
+ ../../../bin/brewdoc,sha256=EBcDAz0fm_7gb81W-eoCcf0v2BLUMB1QEU85SQT2Xc0,344
2
+ brewdoc-0.7.0.dist-info/INSTALLER,sha256=5hhM4Q4mYTT9z6QB6PGpUAW81PGNFrYrdXMj4oM_6ak,2
3
+ brewdoc-0.7.0.dist-info/METADATA,sha256=6nkUqXDrXOfaUeJ07-Ah0Wy4bTIponltVQsSOmRVWzE,15969
4
+ brewdoc-0.7.0.dist-info/RECORD,,
5
+ brewdoc-0.7.0.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
+ brewdoc-0.7.0.dist-info/WHEEL,sha256=W3fkpkm7-wf9vBI5Z-7s0eWkeM-spu78I8Neb98DeEg,87
7
+ brewdoc-0.7.0.dist-info/direct_url.json,sha256=c99WXMUoBHljQMwxVUMqEft3mLwSWNmD9hZfjkPjxhc,103
8
+ brewdoc-0.7.0.dist-info/entry_points.txt,sha256=avLrj5Y-MJ1yq0XFkjH5dbZW9QwYQkpn_hz6sNydbA4,45
9
+ brewdoc-0.7.0.dist-info/licenses/LICENSE,sha256=DNUrRveB3NXcyWxUr8csAHYmvrOmAzFDDAKv3iXNYKk,1073
10
+ brewdoc-0.7.0.dist-info/uv_cache.json,sha256=wp-ao_aV0ZLGZq-tfbEEGr44VrfyybSQtwdFEm8REXY,127
11
+ brewdoc/__init__.py,sha256=igTIi1n_7Yxlq0dtnhxjBcl4F_GPD9ju0h4wuCoBxf8,867
12
+ brewdoc/_standalone.py,sha256=-zfCo75E8YlQexHuPoTu1tl1SJGMNftH1JXSt6qilxo,4705
13
+ brewdoc/_urljs/__init__.py,sha256=SrVyNMaD02iahY2zp3kggkW7KGJ1xv-C5d4DK1-JYWw,51
14
+ brewdoc/_urljs/glue.js,sha256=FLE1gUULoiMZNHH_RmwV0pFMx2BOc5tBMRBG8ahklgQ,45856
15
+ brewdoc/_urljs/native.py,sha256=usZXp_nWS5KKXj1T-Qelmkr5lhGxfVkTMt80g0bz0CQ,44464
16
+ brewdoc/_vendor/THIRD_PARTY_NOTICES.txt,sha256=Mg3dxJ1SNPASEu4_ruk2j-7WM0lZmrfulGCUpNoOZak,26003
17
+ brewdoc/_vendor/linkedom-worker.js,sha256=6p8d5psAnSEJaN2PTT9OzxCVvt-A04nsgyRMFxNXgog,411521
18
+ brewdoc/cli.py,sha256=plbn5-iYgBCcIUtXEn5yDq0WUouJmxCXEZ_wGP7FKPo,7113
19
+ brewdoc/common.py,sha256=r4w2_BegIDVU5r89Y9vH-UQAcwKgP5dITMfi5UMPQA4,51045
20
+ brewdoc/docx.py,sha256=w5fzxManQw7E34p70-YOT3-hfE0E4Z9SBHaiIqY3ke0,6154
21
+ brewdoc/eml.py,sha256=KYWPD9K16JMiNtubtnQt8w9k5PejVQdXnEO29Vn5zSY,7433
22
+ brewdoc/epub.py,sha256=j9kcZAclfbGrvxHcvaImsGkUrmUzWrip-pvBzh2Zz5U,49436
23
+ brewdoc/htmljs.py,sha256=UEBVlFZc95gaq0rQtgZVY8WkGQS3LzVVywAggc9nrlk,44581
24
+ brewdoc/htmltext.py,sha256=Dq0OykXbNUXC8Phn4q0PDHF48H3J1POYifinv0D6AiQ,42149
25
+ brewdoc/htmlurl.py,sha256=lYUoruiXs3otqddVDIHlqR700ehiyfvBi-G93QnxKgg,50618
26
+ brewdoc/odf.py,sha256=M5OZwNmZKQx68zpQRf158MUXMTHmnnKmtBam6sPi0YI,15467
27
+ brewdoc/output.py,sha256=aMgDoB5UDbRWYr9pBxlH402jEiUl8OSEqhox31O0ljk,4123
28
+ brewdoc/pdf.py,sha256=6qU5tPMjcAeYgqEVIPR8u8xk-FydNCTuD8onQldkTlU,66444
29
+ brewdoc/pptx.py,sha256=OYE42ZMgifyhWW8uj0M7JHsasaxXkcfLfSKVsp77is0,17844
30
+ brewdoc/selfcheck.py,sha256=4MGa8Jg3sxDW4f7WBOSiB2cwtyFCN_Uzg0QVTXdSW1s,28042
31
+ brewdoc/service.py,sha256=QS-6kDYKV-peTmw-LU6FYnEIM8JmtI2eUqjCbcm8nuM,8161
32
+ brewdoc/sheets.py,sha256=qgvSxj4MnwPELvwzb3oSmffIOO5LIaAcTzC65TkYp6c,17411
33
+ brewdoc/text.py,sha256=OCrVnR3t4_FSn5rpxmQhItKg2oagKNhFhyp8XcJYHNw,602
@@ -0,0 +1 @@
1
+ {"url":"file:///Users/runner/work/_temp/ci-dist/dist/brewdoc-0.7.0-py3-none-any.whl","archive_info":{}}
@@ -0,0 +1 @@
1
+ {"timestamp":{"secs_since_epoch":1792435132,"nanos_since_epoch":804999144},"commit":null,"tags":null,"env":{},"directories":{}}
package/binary/brewdoc CHANGED
Binary file
@@ -1,6 +1,6 @@
1
1
  [
2
2
  {
3
- "path": "licenses/installed/brewdoc/brewdoc-0.5.0.dist-info/licenses/LICENSE",
3
+ "path": "licenses/installed/brewdoc/brewdoc-0.7.0.dist-info/licenses/LICENSE",
4
4
  "bytes": 1073,
5
5
  "sha256": "0cd52b46f781dcd5dcc96c54afc72c007626beb3a60331430c02afde25cd60a9"
6
6
  },
@@ -1,6 +1,6 @@
1
1
  {
2
- "version": "0.5.0",
3
- "source_sha": "1471975a6fbd8a17766278fd5a0738c095f2ec57",
2
+ "version": "0.7.0",
3
+ "source_sha": "6c846e79a188731bef1a6d4aa91cc4c4ed72f515",
4
4
  "python": "3.12.14",
5
5
  "target": "macos-arm64"
6
6
  }
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "archive": {
3
- "bytes": 32919814,
4
- "filename": "brewdoc-0.5.0-macos-arm64.tar.gz",
5
- "sha256": "4ad6b07de2af9a89912a6682c133528a49fab5eb72c5c2dca98d8e099abc9aaf"
3
+ "bytes": 32949059,
4
+ "filename": "brewdoc-0.7.0-macos-arm64.tar.gz",
5
+ "sha256": "f2249c426834fb7c95ab90880bdb4b54fbf246c7b8be965f1e08b8b85fe376dc"
6
6
  },
7
7
  "executable": "brewdoc/brewdoc",
8
8
  "inventory": {
@@ -188,83 +188,83 @@
188
188
  "bytes": 1333490,
189
189
  "kind": "file",
190
190
  "mode": 420,
191
- "sha256": "c01c42f52bea6b2727867ccc7c97910610e6ab72a2adda44d53c1cf875215491"
191
+ "sha256": "985a729be78ffcce48665e075dc63d9982b979e0a48da4edeb5d51984e79af6e"
192
192
  },
193
193
  "brewdoc/_internal/brewdoc": {
194
194
  "kind": "directory",
195
195
  "mode": 493
196
196
  },
197
- "brewdoc/_internal/brewdoc-0.5.0.dist-info": {
197
+ "brewdoc/_internal/brewdoc-0.7.0.dist-info": {
198
198
  "kind": "directory",
199
199
  "mode": 493
200
200
  },
201
- "brewdoc/_internal/brewdoc-0.5.0.dist-info/INSTALLER": {
201
+ "brewdoc/_internal/brewdoc-0.7.0.dist-info/INSTALLER": {
202
202
  "bytes": 2,
203
203
  "kind": "file",
204
204
  "mode": 420,
205
205
  "sha256": "e6184ce10e266134fdcfa401e8f1a95005bcd4f18d16b62b757323e2833fe9a9"
206
206
  },
207
- "brewdoc/_internal/brewdoc-0.5.0.dist-info/METADATA": {
208
- "bytes": 13777,
207
+ "brewdoc/_internal/brewdoc-0.7.0.dist-info/METADATA": {
208
+ "bytes": 15969,
209
209
  "kind": "file",
210
210
  "mode": 420,
211
- "sha256": "6b93f4abb6f9e625d5c48e8ada198e4f01665f283a53d93bdf3791612ff81318"
211
+ "sha256": "ea7914a970eb5ce7da51e274efe021d16cb86d3229a2796d550b123a64555b31"
212
212
  },
213
- "brewdoc/_internal/brewdoc-0.5.0.dist-info/RECORD": {
213
+ "brewdoc/_internal/brewdoc-0.7.0.dist-info/RECORD": {
214
214
  "bytes": 2604,
215
215
  "kind": "file",
216
216
  "mode": 420,
217
- "sha256": "cadfd56423a31625f6cce1ca085cf095e944ceefb100761c4ac975176ad01c34"
217
+ "sha256": "015319b37e4ceb064e8bbb03bab76987a2187b86a759709ba15092fefc11fc59"
218
218
  },
219
- "brewdoc/_internal/brewdoc-0.5.0.dist-info/REQUESTED": {
219
+ "brewdoc/_internal/brewdoc-0.7.0.dist-info/REQUESTED": {
220
220
  "bytes": 0,
221
221
  "kind": "file",
222
222
  "mode": 420,
223
223
  "sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
224
224
  },
225
- "brewdoc/_internal/brewdoc-0.5.0.dist-info/WHEEL": {
225
+ "brewdoc/_internal/brewdoc-0.7.0.dist-info/WHEEL": {
226
226
  "bytes": 87,
227
227
  "kind": "file",
228
228
  "mode": 420,
229
229
  "sha256": "5b77e4a649bbfb07fdbc123967eeecd1e5a478cfaca6eefc23c35e6fdf037848"
230
230
  },
231
- "brewdoc/_internal/brewdoc-0.5.0.dist-info/direct_url.json": {
231
+ "brewdoc/_internal/brewdoc-0.7.0.dist-info/direct_url.json": {
232
232
  "bytes": 103,
233
233
  "kind": "file",
234
234
  "mode": 420,
235
- "sha256": "46afb8fab4b12f43148f47352eacee64e64b337cc18bb01ff1d2337d5e6402f4"
235
+ "sha256": "73df565cc52804796340cc3155432a11fb7798bc1258d983f6165f8e43e3c617"
236
236
  },
237
- "brewdoc/_internal/brewdoc-0.5.0.dist-info/entry_points.txt": {
237
+ "brewdoc/_internal/brewdoc-0.7.0.dist-info/entry_points.txt": {
238
238
  "bytes": 45,
239
239
  "kind": "file",
240
240
  "mode": 420,
241
241
  "sha256": "6af2eb8f963e309d72ab45c59231f975b656f50c18424a67fe1cfab0dc9d6c0e"
242
242
  },
243
- "brewdoc/_internal/brewdoc-0.5.0.dist-info/licenses": {
243
+ "brewdoc/_internal/brewdoc-0.7.0.dist-info/licenses": {
244
244
  "kind": "directory",
245
245
  "mode": 493
246
246
  },
247
- "brewdoc/_internal/brewdoc-0.5.0.dist-info/licenses/LICENSE": {
247
+ "brewdoc/_internal/brewdoc-0.7.0.dist-info/licenses/LICENSE": {
248
248
  "bytes": 1073,
249
249
  "kind": "file",
250
250
  "mode": 420,
251
251
  "sha256": "0cd52b46f781dcd5dcc96c54afc72c007626beb3a60331430c02afde25cd60a9"
252
252
  },
253
- "brewdoc/_internal/brewdoc-0.5.0.dist-info/uv_cache.json": {
253
+ "brewdoc/_internal/brewdoc-0.7.0.dist-info/uv_cache.json": {
254
254
  "bytes": 127,
255
255
  "kind": "file",
256
256
  "mode": 420,
257
- "sha256": "8b748362bbd23d2f7f357af7ed0e42ed6bd5dc7f319b8d9f71dee428e3b48fb5"
257
+ "sha256": "c29f9aa3f695d192c666afad7db1041abe3856b7f2c9b490b70745126f111176"
258
258
  },
259
259
  "brewdoc/_internal/brewdoc/_urljs": {
260
260
  "kind": "directory",
261
261
  "mode": 493
262
262
  },
263
263
  "brewdoc/_internal/brewdoc/_urljs/glue.js": {
264
- "bytes": 41449,
264
+ "bytes": 45856,
265
265
  "kind": "file",
266
266
  "mode": 420,
267
- "sha256": "694ea584c33165c3f165235cb5f51df97f7582457a9a0125585155fd29d45aa3"
267
+ "sha256": "14b13581450ba223193471ff466c15d2914cc7604e739b41311046f1a8649604"
268
268
  },
269
269
  "brewdoc/_internal/brewdoc/_vendor": {
270
270
  "kind": "directory",
@@ -2211,10 +2211,10 @@
2211
2211
  "sha256": "fe0f992e9acf81baafec12ecf9611ef0885b0ddfd04dc7e2af3fcd132475630c"
2212
2212
  },
2213
2213
  "brewdoc/brewdoc": {
2214
- "bytes": 4003600,
2214
+ "bytes": 4029920,
2215
2215
  "kind": "file",
2216
2216
  "mode": 493,
2217
- "sha256": "22315b1e9fc7e332cb3b7c420b02b532e4730f4966a910f201d36cfcbff13309"
2217
+ "sha256": "4a79d57e6aa37bbd1b8764ae99dcd604c4850f8a27ea8c1f84ca74b4856509cf"
2218
2218
  },
2219
2219
  "brewdoc/licenses": {
2220
2220
  "kind": "directory",
@@ -2228,7 +2228,7 @@
2228
2228
  "bytes": 8106,
2229
2229
  "kind": "file",
2230
2230
  "mode": 420,
2231
- "sha256": "49096296dd76381faf1206679169699c5485ecd4d751e084a909852b4f5688ce"
2231
+ "sha256": "34fdb13cfcbe1bb3cb1ee4d5ef196c5358785c15261a15f86d5c3d9ded7cc163"
2232
2232
  },
2233
2233
  "brewdoc/licenses/installed/brewdoc": {
2234
2234
  "kind": "directory",
@@ -2238,15 +2238,15 @@
2238
2238
  "kind": "directory",
2239
2239
  "mode": 493
2240
2240
  },
2241
- "brewdoc/licenses/installed/brewdoc/brewdoc-0.5.0.dist-info": {
2241
+ "brewdoc/licenses/installed/brewdoc/brewdoc-0.7.0.dist-info": {
2242
2242
  "kind": "directory",
2243
2243
  "mode": 493
2244
2244
  },
2245
- "brewdoc/licenses/installed/brewdoc/brewdoc-0.5.0.dist-info/licenses": {
2245
+ "brewdoc/licenses/installed/brewdoc/brewdoc-0.7.0.dist-info/licenses": {
2246
2246
  "kind": "directory",
2247
2247
  "mode": 493
2248
2248
  },
2249
- "brewdoc/licenses/installed/brewdoc/brewdoc-0.5.0.dist-info/licenses/LICENSE": {
2249
+ "brewdoc/licenses/installed/brewdoc/brewdoc-0.7.0.dist-info/licenses/LICENSE": {
2250
2250
  "bytes": 1073,
2251
2251
  "kind": "file",
2252
2252
  "mode": 420,
@@ -4116,19 +4116,19 @@
4116
4116
  "bytes": 135,
4117
4117
  "kind": "file",
4118
4118
  "mode": 420,
4119
- "sha256": "7b8e5b6edee63032516930f554e7cb32ec455a05d88ab8c441026d347967f392"
4119
+ "sha256": "8bccf24c6ea6642ef667863bd82840361e622550ea49c4e36625a2361c561a8d"
4120
4120
  }
4121
4121
  },
4122
- "lock_sha256": "afcbd72d09ef67b0f9e118a4e85d75d1f6e8a46315e4927c3bc8a23ce226171c",
4122
+ "lock_sha256": "4f807177f62fdaca9c5ea20e12d520562790caace731d18ed9c40ca7901a2ba2",
4123
4123
  "minimum_tested": "macOS 15 on Apple Silicon",
4124
4124
  "oracle": [],
4125
4125
  "probes": [
4126
4126
  {
4127
4127
  "bytes_base64": "UEsDBBQAAAAAAAAAIVBvYassFAAAABQAAAAIAAAAbWltZXR5cGVhcHBsaWNhdGlvbi9lcHViK3ppcFBLAwQUAAAAAAAAACFQZsMSuMMAAADDAAAAFgAAAE1FVEEtSU5GL2NvbnRhaW5lci54bWw8Y29udGFpbmVyIHhtbG5zPSJ1cm46b2FzaXM6bmFtZXM6dGM6b3BlbmRvY3VtZW50OnhtbG5zOmNvbnRhaW5lciIgdmVyc2lvbj0iMS4wIj48cm9vdGZpbGVzPjxyb290ZmlsZSBmdWxsLXBhdGg9Ik9QUy9ib29rLm9wZiIgbWVkaWEtdHlwZT0iYXBwbGljYXRpb24vb2VicHMtcGFja2FnZSt4bWwiLz48L3Jvb3RmaWxlcz48L2NvbnRhaW5lcj5QSwMEFAAAAAAAAAAhUFm2frB9AgAAfQIAAAwAAABPUFMvYm9vay5vcGY8cGFja2FnZSB4bWxucz0iaHR0cDovL3d3dy5pZHBmLm9yZy8yMDA3L29wZiIgdmVyc2lvbj0iMi4wIiB1bmlxdWUtaWRlbnRpZmllcj0iYm9vay1pZCI+PG1ldGFkYXRhIHhtbG5zOmRjPSJodHRwOi8vcHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLyI+PGRjOnRpdGxlPmNhZsOpIOadseS6rDwvZGM6dGl0bGU+PGRjOmNyZWF0b3I+Rmlyc3Q8L2RjOmNyZWF0b3I+PGRjOmNyZWF0b3I+Rmlyc3Q8L2RjOmNyZWF0b3I+PGRjOmxhbmd1YWdlPmZyPC9kYzpsYW5ndWFnZT48ZGM6aWRlbnRpZmllciBpZD0iYm9vay1pZCI+dXJuOnN5bnRoZXRpYzwvZGM6aWRlbnRpZmllcj48L21ldGFkYXRhPjxtYW5pZmVzdD48aXRlbSBpZD0iYSIgaHJlZj0iYS54aHRtbCIgbWVkaWEtdHlwZT0iYXBwbGljYXRpb24veGh0bWwreG1sIi8+PGl0ZW0gaWQ9ImIiIGhyZWY9ImIueGh0bWwiIG1lZGlhLXR5cGU9ImFwcGxpY2F0aW9uL3hodG1sK3htbCIvPjxpdGVtIGlkPSJ0b2MiIGhyZWY9InRvYy5uY3giIG1lZGlhLXR5cGU9ImFwcGxpY2F0aW9uL3gtZHRibmN4K3htbCIvPjwvbWFuaWZlc3Q+PHNwaW5lIHRvYz0idG9jIj48aXRlbXJlZiBpZHJlZj0iYiIvPjxpdGVtcmVmIGlkcmVmPSJhIiBsaW5lYXI9Im5vIi8+PC9zcGluZT48L3BhY2thZ2U+UEsDBBQAAAAAAAAAIVBwt4eVgQAAAIEAAAALAAAAT1BTL2EueGh0bWw8aHRtbCB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94aHRtbCI+PGhlYWQ+PHRpdGxlPkZhbGxiYWNrPC90aXRsZT48L2hlYWQ+PGJvZHk+PHA+Rmlyc3QgZSYjeDMwMTvCoHdvcmTCrS48L3A+PC9ib2R5PjwvaHRtbD5QSwMEFAAAAAAAAAAhUOMm2fN2AAAAdgAAAAsAAABPUFMvYi54aHRtbDxodG1sIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hodG1sIj48aGVhZD48dGl0bGU+RmFsbGJhY2s8L3RpdGxlPjwvaGVhZD48Ym9keT48cD5jYWbDqSDmnbHkuqw8L3A+PC9ib2R5PjwvaHRtbD5QSwMEFAAAAAAAAAAhUP4OjIloAQAAaAEAAAsAAABPUFMvdG9jLm5jeDxuY3ggeG1sbnM9Imh0dHA6Ly93d3cuZGFpc3kub3JnL3ozOTg2LzIwMDUvbmN4LyIgdmVyc2lvbj0iMjAwNS0xIj48aGVhZC8+PGRvY1RpdGxlPjx0ZXh0PlB1YmxpY2F0aW9uPC90ZXh0PjwvZG9jVGl0bGU+PG5hdk1hcD48bmF2UG9pbnQgaWQ9Im5hdi1hIiBwbGF5T3JkZXI9IjkiPjxuYXZMYWJlbD48dGV4dD5BbHBoYTwvdGV4dD48L25hdkxhYmVsPjxjb250ZW50IHNyYz0iYS54aHRtbCIvPjwvbmF2UG9pbnQ+PG5hdlBvaW50IGlkPSJuYXYtYiIgcGxheU9yZGVyPSIxIj48bmF2TGFiZWw+PHRleHQ+zrJldGE8L3RleHQ+PC9uYXZMYWJlbD48Y29udGVudCBzcmM9ImIueGh0bWwiLz48L25hdlBvaW50PjwvbmF2TWFwPjwvbmN4PlBLAQIUAxQAAAAAAAAAIVBvYassFAAAABQAAAAIAAAAAAAAAAAAAACAAQAAAABtaW1ldHlwZVBLAQIUAxQAAAAAAAAAIVBmwxK4wwAAAMMAAAAWAAAAAAAAAAAAAACAAToAAABNRVRBLUlORi9jb250YWluZXIueG1sUEsBAhQDFAAAAAAAAAAhUFm2frB9AgAAfQIAAAwAAAAAAAAAAAAAAIABMQEAAE9QUy9ib29rLm9wZlBLAQIUAxQAAAAAAAAAIVBwt4eVgQAAAIEAAAALAAAAAAAAAAAAAACAAdgDAABPUFMvYS54aHRtbFBLAQIUAxQAAAAAAAAAIVDjJtnzdgAAAHYAAAALAAAAAAAAAAAAAACAAYIEAABPUFMvYi54aHRtbFBLAQIUAxQAAAAAAAAAIVD+DoyJaAEAAGgBAAALAAAAAAAAAAAAAACAASEFAABPUFMvdG9jLm5jeFBLBQYAAAAABgAGAF8BAACyBgAAAAA=",
4128
4128
  "code": 0,
4129
- "markdown_bytes": 2130,
4129
+ "markdown_bytes": 2152,
4130
4130
  "markdown_encoding": "utf-8",
4131
- "markdown_sha256": "4beea667419922013009835a826395558e270bf5a05446f9ec8d79390f25c7ec",
4131
+ "markdown_sha256": "1577635ebf9956eac94c763bf2d8eb6b01afea59f1944abbfc2a81de698b3ba7",
4132
4132
  "path": "sample.epub",
4133
4133
  "probe": "epub2",
4134
4134
  "receipt": {
@@ -4151,7 +4151,7 @@
4151
4151
  "not_carried": [
4152
4152
  "CSS, layout, pagination and font rendering",
4153
4153
  "scripts, forms and active media",
4154
- "image pixels and graphical SVG content",
4154
+ "image pixels, images without alt text and graphical SVG content",
4155
4155
  "unsupported SVG and MathML semantics",
4156
4156
  "navigation semantics beyond declared TOC hierarchy"
4157
4157
  ],
@@ -4175,13 +4175,13 @@
4175
4175
  "artifact": {
4176
4176
  "bytes": 664,
4177
4177
  "key": "formula/sheet/000002",
4178
- "sha256": "872f37eb37da8b3efe6aeb0e71dc18d806b957dabf5664cb8d03b7bf228e41b9"
4178
+ "sha256": "4b89a8ffc79c4c14b5c6707ca75cff3d8db00dc6a990190226fb4dc588d7915c"
4179
4179
  },
4180
- "bytes_base64": "UEsDBBQAAAAAAMJyTl3ZAU4y4wIAAOMCAAATAAAAW0NvbnRlbnRfVHlwZXNdLnhtbDw/eG1sIHZlcnNpb249IjEuMCI/PjxUeXBlcyB4bWxucz0iaHR0cDovL3NjaGVtYXMub3BlbnhtbGZvcm1hdHMub3JnL3BhY2thZ2UvMjAwNi9jb250ZW50LXR5cGVzIj48RGVmYXVsdCBFeHRlbnNpb249InJlbHMiIENvbnRlbnRUeXBlPSJhcHBsaWNhdGlvbi92bmQub3BlbnhtbGZvcm1hdHMtcGFja2FnZS5yZWxhdGlvbnNoaXBzK3htbCIvPjxPdmVycmlkZSBQYXJ0TmFtZT0iL3hsL3dvcmtib29rLnhtbCIgQ29udGVudFR5cGU9ImFwcGxpY2F0aW9uL3ZuZC5vcGVueG1sZm9ybWF0cy1vZmZpY2Vkb2N1bWVudC5zcHJlYWRzaGVldG1sLnNoZWV0Lm1haW4reG1sIi8+PE92ZXJyaWRlIFBhcnROYW1lPSIveGwvd29ya3NoZWV0cy9zaGVldDEueG1sIiBDb250ZW50VHlwZT0iYXBwbGljYXRpb24vdm5kLm9wZW54bWxmb3JtYXRzLW9mZmljZWRvY3VtZW50LnNwcmVhZHNoZWV0bWwud29ya3NoZWV0K3htbCIvPjxPdmVycmlkZSBQYXJ0TmFtZT0iL3hsL3dvcmtzaGVldHMvc2hlZXQyLnhtbCIgQ29udGVudFR5cGU9ImFwcGxpY2F0aW9uL3ZuZC5vcGVueG1sZm9ybWF0cy1vZmZpY2Vkb2N1bWVudC5zcHJlYWRzaGVldG1sLndvcmtzaGVldCt4bWwiLz48T3ZlcnJpZGUgUGFydE5hbWU9Ii94bC93b3Jrc2hlZXRzL3NoZWV0My54bWwiIENvbnRlbnRUeXBlPSJhcHBsaWNhdGlvbi92bmQub3BlbnhtbGZvcm1hdHMtb2ZmaWNlZG9jdW1lbnQuc3ByZWFkc2hlZXRtbC53b3Jrc2hlZXQreG1sIi8+PC9UeXBlcz5QSwMEFAAAAAAAwnJOXUuDozoFAQAABQEAAAsAAABfcmVscy8ucmVsczw/eG1sIHZlcnNpb249IjEuMCI/PjxSZWxhdGlvbnNoaXBzIHhtbG5zPSJodHRwOi8vc2NoZW1hcy5vcGVueG1sZm9ybWF0cy5vcmcvcGFja2FnZS8yMDA2L3JlbGF0aW9uc2hpcHMiPjxSZWxhdGlvbnNoaXAgSWQ9InJJZDEiIFR5cGU9Imh0dHA6Ly9zY2hlbWFzLm9wZW54bWxmb3JtYXRzLm9yZy9vZmZpY2VEb2N1bWVudC8yMDA2L3JlbGF0aW9uc2hpcHMvb2ZmaWNlRG9jdW1lbnQiIFRhcmdldD0ieGwvd29ya2Jvb2sueG1sIi8+PC9SZWxhdGlvbnNoaXBzPlBLAwQUAAAAAADCck5dImE/o1IBAABSAQAADwAAAHhsL3dvcmtib29rLnhtbDw/eG1sIHZlcnNpb249IjEuMCI/Pjx3b3JrYm9vayB4bWxucz0iaHR0cDovL3NjaGVtYXMub3BlbnhtbGZvcm1hdHMub3JnL3NwcmVhZHNoZWV0bWwvMjAwNi9tYWluIiB4bWxuczpyPSJodHRwOi8vc2NoZW1hcy5vcGVueG1sZm9ybWF0cy5vcmcvb2ZmaWNlRG9jdW1lbnQvMjAwNi9yZWxhdGlvbnNoaXBzIj48c2hlZXRzPjxzaGVldCBuYW1lPSJJbnB1dHMiIHNoZWV0SWQ9IjEiIHI6aWQ9InJJZDEiLz48c2hlZXQgbmFtZT0iQ2FsYyIgc2hlZXRJZD0iMiIgcjppZD0icklkMiIvPjxzaGVldCBuYW1lPSJFbXB0eSIgc2hlZXRJZD0iMyIgcjppZD0icklkMyIvPjwvc2hlZXRzPjwvd29ya2Jvb2s+UEsDBBQAAAAAAMJyTl3JpmJ5IAIAACACAAAaAAAAeGwvX3JlbHMvd29ya2Jvb2sueG1sLnJlbHM8P3htbCB2ZXJzaW9uPSIxLjAiPz48UmVsYXRpb25zaGlwcyB4bWxucz0iaHR0cDovL3NjaGVtYXMub3BlbnhtbGZvcm1hdHMub3JnL3BhY2thZ2UvMjAwNi9yZWxhdGlvbnNoaXBzIj48UmVsYXRpb25zaGlwIElkPSJySWQxIiBUeXBlPSJodHRwOi8vc2NoZW1hcy5vcGVueG1sZm9ybWF0cy5vcmcvb2ZmaWNlRG9jdW1lbnQvMjAwNi9yZWxhdGlvbnNoaXBzL3dvcmtzaGVldCIgVGFyZ2V0PSJ3b3Jrc2hlZXRzL3NoZWV0MS54bWwiLz48UmVsYXRpb25zaGlwIElkPSJySWQyIiBUeXBlPSJodHRwOi8vc2NoZW1hcy5vcGVueG1sZm9ybWF0cy5vcmcvb2ZmaWNlRG9jdW1lbnQvMjAwNi9yZWxhdGlvbnNoaXBzL3dvcmtzaGVldCIgVGFyZ2V0PSJ3b3Jrc2hlZXRzL3NoZWV0Mi54bWwiLz48UmVsYXRpb25zaGlwIElkPSJySWQzIiBUeXBlPSJodHRwOi8vc2NoZW1hcy5vcGVueG1sZm9ybWF0cy5vcmcvb2ZmaWNlRG9jdW1lbnQvMjAwNi9yZWxhdGlvbnNoaXBzL3dvcmtzaGVldCIgVGFyZ2V0PSJ3b3Jrc2hlZXRzL3NoZWV0My54bWwiLz48L1JlbGF0aW9uc2hpcHM+UEsDBBQAAAAAAMJyTl3hQA/x9gAAAPYAAAAYAAAAeGwvd29ya3NoZWV0cy9zaGVldDEueG1sPHdvcmtzaGVldCB4bWxucz0iaHR0cDovL3NjaGVtYXMub3BlbnhtbGZvcm1hdHMub3JnL3NwcmVhZHNoZWV0bWwvMjAwNi9tYWluIj48c2hlZXREYXRhPjxyb3cgcj0iMSI+PGMgcj0iQTEiPjx2PjE8L3Y+PC9jPjwvcm93Pjxyb3cgcj0iMiI+PGMgcj0iQTIiPjx2PjI8L3Y+PC9jPjwvcm93Pjxyb3cgcj0iMyI+PGMgcj0iQTMiPjxmPlNVTShBMTpBMik8L2Y+PHY+Mzwvdj48L2M+PC9yb3c+PC9zaGVldERhdGE+PC93b3Jrc2hlZXQ+UEsDBBQAAAAAAMJyTl3R4blYmQEAAJkBAAAYAAAAeGwvd29ya3NoZWV0cy9zaGVldDIueG1sPHdvcmtzaGVldCB4bWxucz0iaHR0cDovL3NjaGVtYXMub3BlbnhtbGZvcm1hdHMub3JnL3NwcmVhZHNoZWV0bWwvMjAwNi9tYWluIj48c2hlZXREYXRhPjxyb3cgcj0iMSI+PGMgcj0iQTEiPjxmPlNVTShJbnB1dHMhQTE6QTIpPC9mPjx2PjM8L3Y+PC9jPjxjIHI9IkIxIj48ZiB0PSJzaGFyZWQiIHJlZj0iQjE6QjIiIHNpPSI3Ij5JbnB1dHMhQTEqMjwvZj48dj4yPC92PjwvYz48L3Jvdz48cm93IHI9IjIiPjxjIHI9IkIyIj48ZiBzaT0iNyIgdD0ic2hhcmVkIi8+PHY+NDwvdj48L2M+PC9yb3c+PHJvdyByPSIzIj48YyByPSJDMyI+PGYgYng9IjAiIGFjYT0iMSI+SUYoQTEmbHQ7NCwmcXVvdDtjYWbDqSZxdW90OywmcXVvdDsmcXVvdDspPC9mPjx2PjE8L3Y+PC9jPjwvcm93Pjwvc2hlZXREYXRhPjwvd29ya3NoZWV0PlBLAwQUAAAAAADCck5dCntq/2UAAABlAAAAGAAAAHhsL3dvcmtzaGVldHMvc2hlZXQzLnhtbDx3b3Jrc2hlZXQgeG1sbnM9Imh0dHA6Ly9zY2hlbWFzLm9wZW54bWxmb3JtYXRzLm9yZy9zcHJlYWRzaGVldG1sLzIwMDYvbWFpbiI+PHNoZWV0RGF0YS8+PC93b3Jrc2hlZXQ+UEsBAhQDFAAAAAAAwnJOXdkBTjLjAgAA4wIAABMAAAAAAAAAAAAAAIABAAAAAFtDb250ZW50X1R5cGVzXS54bWxQSwECFAMUAAAAAADCck5dS4OjOgUBAAAFAQAACwAAAAAAAAAAAAAAgAEUAwAAX3JlbHMvLnJlbHNQSwECFAMUAAAAAADCck5dImE/o1IBAABSAQAADwAAAAAAAAAAAAAAgAFCBAAAeGwvd29ya2Jvb2sueG1sUEsBAhQDFAAAAAAAwnJOXcmmYnkgAgAAIAIAABoAAAAAAAAAAAAAAIABwQUAAHhsL19yZWxzL3dvcmtib29rLnhtbC5yZWxzUEsBAhQDFAAAAAAAwnJOXeFAD/H2AAAA9gAAABgAAAAAAAAAAAAAAIABGQgAAHhsL3dvcmtzaGVldHMvc2hlZXQxLnhtbFBLAQIUAxQAAAAAAMJyTl3R4blYmQEAAJkBAAAYAAAAAAAAAAAAAACAAUUJAAB4bC93b3Jrc2hlZXRzL3NoZWV0Mi54bWxQSwECFAMUAAAAAADCck5dCntq/2UAAABlAAAAGAAAAAAAAAAAAAAAgAEUCwAAeGwvd29ya3NoZWV0cy9zaGVldDMueG1sUEsFBgAAAAAHAAcA0QEAAK8LAAAAAA==",
4180
+ "bytes_base64": "UEsDBBQAAAAAAN2UU13ZAU4y4wIAAOMCAAATAAAAW0NvbnRlbnRfVHlwZXNdLnhtbDw/eG1sIHZlcnNpb249IjEuMCI/PjxUeXBlcyB4bWxucz0iaHR0cDovL3NjaGVtYXMub3BlbnhtbGZvcm1hdHMub3JnL3BhY2thZ2UvMjAwNi9jb250ZW50LXR5cGVzIj48RGVmYXVsdCBFeHRlbnNpb249InJlbHMiIENvbnRlbnRUeXBlPSJhcHBsaWNhdGlvbi92bmQub3BlbnhtbGZvcm1hdHMtcGFja2FnZS5yZWxhdGlvbnNoaXBzK3htbCIvPjxPdmVycmlkZSBQYXJ0TmFtZT0iL3hsL3dvcmtib29rLnhtbCIgQ29udGVudFR5cGU9ImFwcGxpY2F0aW9uL3ZuZC5vcGVueG1sZm9ybWF0cy1vZmZpY2Vkb2N1bWVudC5zcHJlYWRzaGVldG1sLnNoZWV0Lm1haW4reG1sIi8+PE92ZXJyaWRlIFBhcnROYW1lPSIveGwvd29ya3NoZWV0cy9zaGVldDEueG1sIiBDb250ZW50VHlwZT0iYXBwbGljYXRpb24vdm5kLm9wZW54bWxmb3JtYXRzLW9mZmljZWRvY3VtZW50LnNwcmVhZHNoZWV0bWwud29ya3NoZWV0K3htbCIvPjxPdmVycmlkZSBQYXJ0TmFtZT0iL3hsL3dvcmtzaGVldHMvc2hlZXQyLnhtbCIgQ29udGVudFR5cGU9ImFwcGxpY2F0aW9uL3ZuZC5vcGVueG1sZm9ybWF0cy1vZmZpY2Vkb2N1bWVudC5zcHJlYWRzaGVldG1sLndvcmtzaGVldCt4bWwiLz48T3ZlcnJpZGUgUGFydE5hbWU9Ii94bC93b3Jrc2hlZXRzL3NoZWV0My54bWwiIENvbnRlbnRUeXBlPSJhcHBsaWNhdGlvbi92bmQub3BlbnhtbGZvcm1hdHMtb2ZmaWNlZG9jdW1lbnQuc3ByZWFkc2hlZXRtbC53b3Jrc2hlZXQreG1sIi8+PC9UeXBlcz5QSwMEFAAAAAAA3ZRTXUuDozoFAQAABQEAAAsAAABfcmVscy8ucmVsczw/eG1sIHZlcnNpb249IjEuMCI/PjxSZWxhdGlvbnNoaXBzIHhtbG5zPSJodHRwOi8vc2NoZW1hcy5vcGVueG1sZm9ybWF0cy5vcmcvcGFja2FnZS8yMDA2L3JlbGF0aW9uc2hpcHMiPjxSZWxhdGlvbnNoaXAgSWQ9InJJZDEiIFR5cGU9Imh0dHA6Ly9zY2hlbWFzLm9wZW54bWxmb3JtYXRzLm9yZy9vZmZpY2VEb2N1bWVudC8yMDA2L3JlbGF0aW9uc2hpcHMvb2ZmaWNlRG9jdW1lbnQiIFRhcmdldD0ieGwvd29ya2Jvb2sueG1sIi8+PC9SZWxhdGlvbnNoaXBzPlBLAwQUAAAAAADdlFNdImE/o1IBAABSAQAADwAAAHhsL3dvcmtib29rLnhtbDw/eG1sIHZlcnNpb249IjEuMCI/Pjx3b3JrYm9vayB4bWxucz0iaHR0cDovL3NjaGVtYXMub3BlbnhtbGZvcm1hdHMub3JnL3NwcmVhZHNoZWV0bWwvMjAwNi9tYWluIiB4bWxuczpyPSJodHRwOi8vc2NoZW1hcy5vcGVueG1sZm9ybWF0cy5vcmcvb2ZmaWNlRG9jdW1lbnQvMjAwNi9yZWxhdGlvbnNoaXBzIj48c2hlZXRzPjxzaGVldCBuYW1lPSJJbnB1dHMiIHNoZWV0SWQ9IjEiIHI6aWQ9InJJZDEiLz48c2hlZXQgbmFtZT0iQ2FsYyIgc2hlZXRJZD0iMiIgcjppZD0icklkMiIvPjxzaGVldCBuYW1lPSJFbXB0eSIgc2hlZXRJZD0iMyIgcjppZD0icklkMyIvPjwvc2hlZXRzPjwvd29ya2Jvb2s+UEsDBBQAAAAAAN2UU13JpmJ5IAIAACACAAAaAAAAeGwvX3JlbHMvd29ya2Jvb2sueG1sLnJlbHM8P3htbCB2ZXJzaW9uPSIxLjAiPz48UmVsYXRpb25zaGlwcyB4bWxucz0iaHR0cDovL3NjaGVtYXMub3BlbnhtbGZvcm1hdHMub3JnL3BhY2thZ2UvMjAwNi9yZWxhdGlvbnNoaXBzIj48UmVsYXRpb25zaGlwIElkPSJySWQxIiBUeXBlPSJodHRwOi8vc2NoZW1hcy5vcGVueG1sZm9ybWF0cy5vcmcvb2ZmaWNlRG9jdW1lbnQvMjAwNi9yZWxhdGlvbnNoaXBzL3dvcmtzaGVldCIgVGFyZ2V0PSJ3b3Jrc2hlZXRzL3NoZWV0MS54bWwiLz48UmVsYXRpb25zaGlwIElkPSJySWQyIiBUeXBlPSJodHRwOi8vc2NoZW1hcy5vcGVueG1sZm9ybWF0cy5vcmcvb2ZmaWNlRG9jdW1lbnQvMjAwNi9yZWxhdGlvbnNoaXBzL3dvcmtzaGVldCIgVGFyZ2V0PSJ3b3Jrc2hlZXRzL3NoZWV0Mi54bWwiLz48UmVsYXRpb25zaGlwIElkPSJySWQzIiBUeXBlPSJodHRwOi8vc2NoZW1hcy5vcGVueG1sZm9ybWF0cy5vcmcvb2ZmaWNlRG9jdW1lbnQvMjAwNi9yZWxhdGlvbnNoaXBzL3dvcmtzaGVldCIgVGFyZ2V0PSJ3b3Jrc2hlZXRzL3NoZWV0My54bWwiLz48L1JlbGF0aW9uc2hpcHM+UEsDBBQAAAAAAN2UU13hQA/x9gAAAPYAAAAYAAAAeGwvd29ya3NoZWV0cy9zaGVldDEueG1sPHdvcmtzaGVldCB4bWxucz0iaHR0cDovL3NjaGVtYXMub3BlbnhtbGZvcm1hdHMub3JnL3NwcmVhZHNoZWV0bWwvMjAwNi9tYWluIj48c2hlZXREYXRhPjxyb3cgcj0iMSI+PGMgcj0iQTEiPjx2PjE8L3Y+PC9jPjwvcm93Pjxyb3cgcj0iMiI+PGMgcj0iQTIiPjx2PjI8L3Y+PC9jPjwvcm93Pjxyb3cgcj0iMyI+PGMgcj0iQTMiPjxmPlNVTShBMTpBMik8L2Y+PHY+Mzwvdj48L2M+PC9yb3c+PC9zaGVldERhdGE+PC93b3Jrc2hlZXQ+UEsDBBQAAAAAAN2UU13R4blYmQEAAJkBAAAYAAAAeGwvd29ya3NoZWV0cy9zaGVldDIueG1sPHdvcmtzaGVldCB4bWxucz0iaHR0cDovL3NjaGVtYXMub3BlbnhtbGZvcm1hdHMub3JnL3NwcmVhZHNoZWV0bWwvMjAwNi9tYWluIj48c2hlZXREYXRhPjxyb3cgcj0iMSI+PGMgcj0iQTEiPjxmPlNVTShJbnB1dHMhQTE6QTIpPC9mPjx2PjM8L3Y+PC9jPjxjIHI9IkIxIj48ZiB0PSJzaGFyZWQiIHJlZj0iQjE6QjIiIHNpPSI3Ij5JbnB1dHMhQTEqMjwvZj48dj4yPC92PjwvYz48L3Jvdz48cm93IHI9IjIiPjxjIHI9IkIyIj48ZiBzaT0iNyIgdD0ic2hhcmVkIi8+PHY+NDwvdj48L2M+PC9yb3c+PHJvdyByPSIzIj48YyByPSJDMyI+PGYgYng9IjAiIGFjYT0iMSI+SUYoQTEmbHQ7NCwmcXVvdDtjYWbDqSZxdW90OywmcXVvdDsmcXVvdDspPC9mPjx2PjE8L3Y+PC9jPjwvcm93Pjwvc2hlZXREYXRhPjwvd29ya3NoZWV0PlBLAwQUAAAAAADdlFNdCntq/2UAAABlAAAAGAAAAHhsL3dvcmtzaGVldHMvc2hlZXQzLnhtbDx3b3Jrc2hlZXQgeG1sbnM9Imh0dHA6Ly9zY2hlbWFzLm9wZW54bWxmb3JtYXRzLm9yZy9zcHJlYWRzaGVldG1sLzIwMDYvbWFpbiI+PHNoZWV0RGF0YS8+PC93b3Jrc2hlZXQ+UEsBAhQDFAAAAAAA3ZRTXdkBTjLjAgAA4wIAABMAAAAAAAAAAAAAAIABAAAAAFtDb250ZW50X1R5cGVzXS54bWxQSwECFAMUAAAAAADdlFNdS4OjOgUBAAAFAQAACwAAAAAAAAAAAAAAgAEUAwAAX3JlbHMvLnJlbHNQSwECFAMUAAAAAADdlFNdImE/o1IBAABSAQAADwAAAAAAAAAAAAAAgAFCBAAAeGwvd29ya2Jvb2sueG1sUEsBAhQDFAAAAAAA3ZRTXcmmYnkgAgAAIAIAABoAAAAAAAAAAAAAAIABwQUAAHhsL19yZWxzL3dvcmtib29rLnhtbC5yZWxzUEsBAhQDFAAAAAAA3ZRTXeFAD/H2AAAA9gAAABgAAAAAAAAAAAAAAIABGQgAAHhsL3dvcmtzaGVldHMvc2hlZXQxLnhtbFBLAQIUAxQAAAAAAN2UU13R4blYmQEAAJkBAAAYAAAAAAAAAAAAAACAAUUJAAB4bC93b3Jrc2hlZXRzL3NoZWV0Mi54bWxQSwECFAMUAAAAAADdlFNdCntq/2UAAABlAAAAGAAAAAAAAAAAAAAAgAEUCwAAeGwvd29ya3NoZWV0cy9zaGVldDMueG1sUEsFBgAAAAAHAAcA0QEAAK8LAAAAAA==",
4181
4181
  "code": 0,
4182
- "markdown_bytes": 2285,
4182
+ "markdown_bytes": 2282,
4183
4183
  "markdown_encoding": "utf-8",
4184
- "markdown_sha256": "7415d7e09e1a788f87a27f10b38cf50e239c8b127a9a1436b4bce1f392f27b1a",
4184
+ "markdown_sha256": "583616ebe902d30911d7ae0f451b2a2bd490024de37b6c262cfddb716f3e6353",
4185
4185
  "path": "formulas.xlsx",
4186
4186
  "probe": "formula",
4187
4187
  "receipt": {
@@ -4245,7 +4245,7 @@
4245
4245
  "unit_kind": "sheet",
4246
4246
  "units": 3
4247
4247
  },
4248
- "source_sha256": "a917f82562151f4e129d0d59e2c08ee0c26b6766992a93364fd380e3a32090ce"
4248
+ "source_sha256": "40bb211de369bd483bc32f46189425bb09b69f92fa69357d73a49ab061cf12d0"
4249
4249
  }
4250
4250
  ],
4251
4251
  "python": "3.12.14",
@@ -4317,6 +4317,10 @@
4317
4317
  "name": "cryptography",
4318
4318
  "version": "50.0.2"
4319
4319
  },
4320
+ {
4321
+ "name": "brewdoc",
4322
+ "version": "0.7.0"
4323
+ },
4320
4324
  {
4321
4325
  "name": "selectolax",
4322
4326
  "version": "0.4.13"
@@ -4329,10 +4333,6 @@
4329
4333
  "name": "cffi",
4330
4334
  "version": "2.1.1"
4331
4335
  },
4332
- {
4333
- "name": "brewdoc",
4334
- "version": "0.5.0"
4335
- },
4336
4336
  {
4337
4337
  "name": "pdfplumber",
4338
4338
  "version": "0.11.10"
@@ -4358,9 +4358,9 @@
4358
4358
  "macos": "Ad hoc build signature; no Developer ID signing or notarization",
4359
4359
  "windows": "Unsigned; publisher signing has not been configured"
4360
4360
  },
4361
- "source_sha": "1471975a6fbd8a17766278fd5a0738c095f2ec57",
4361
+ "source_sha": "6c846e79a188731bef1a6d4aa91cc4c4ed72f515",
4362
4362
  "target": "macos-arm64",
4363
4363
  "verification_scope": "smoke",
4364
- "version": "0.5.0",
4365
- "wheel_sha256": "e4feada9966b0affc54833b7df428a6a3d2072ccf102a8b2125b1fed7d061832"
4364
+ "version": "0.7.0",
4365
+ "wheel_sha256": "3f3b590a41d1ab3d039caaaa363da1c0b82fe1995cef38f46d5ebb335e0d466f"
4366
4366
  }
@@ -1,5 +1,5 @@
1
1
  {
2
- "archive_sha256": "4ad6b07de2af9a89912a6682c133528a49fab5eb72c5c2dca98d8e099abc9aaf",
2
+ "archive_sha256": "f2249c426834fb7c95ab90880bdb4b54fbf246c7b8be965f1e08b8b85fe376dc",
3
3
  "children": {
4
4
  "dns": [
5
5
  "::1",
@@ -57,6 +57,9 @@
57
57
  "https": {
58
58
  "acquisition": {
59
59
  "capture_status": "static",
60
+ "challenge": null,
61
+ "charset": "UTF-8",
62
+ "charset_source": "header",
60
63
  "counts": {
61
64
  "promise_jobs": 0,
62
65
  "requests": 1,
@@ -67,6 +70,7 @@
67
70
  "error_count": 0,
68
71
  "errors": [],
69
72
  "final_url": "https://example.org/",
73
+ "http_status": 200,
70
74
  "mode": "static",
71
75
  "pending": {
72
76
  "jobs": null,
@@ -75,13 +79,15 @@
75
79
  "requests": null,
76
80
  "timers": null
77
81
  },
82
+ "redirect_count": 0,
78
83
  "refusal_stage": null,
84
+ "render_js": null,
79
85
  "requested_url": "https://example.org/",
80
86
  "response": {
81
87
  "body_bytes": 577,
82
88
  "body_sha256": "25ddf2c883e0d1958ea971d279a7e4f0fd446724ee3db7db19dadabd4a62e484",
83
- "entity_bytes": 577,
84
- "entity_sha256": "25ddf2c883e0d1958ea971d279a7e4f0fd446724ee3db7db19dadabd4a62e484"
89
+ "entity_bytes": 400,
90
+ "entity_sha256": "98045c75d902d8de112d0dce14a4408e02f754155c60c2c9ccf4f9adeb358e74"
85
91
  },
86
92
  "snapshot": {
87
93
  "bytes": 589,
@@ -123,7 +129,9 @@
123
129
  "active media and embeds",
124
130
  "inline code layout outside tables: rendered as fenced blocks",
125
131
  "inline code monospace inside table cells",
126
- "hidden inputs and supplied password or file values"
132
+ "form controls and their values",
133
+ "images without alt text",
134
+ "navigation, header, footer and aside landmarks outside main or article content"
127
135
  ],
128
136
  "out": null,
129
137
  "reason": "html rendered: 1 chapters, 0 tables, 1 text regions, 0 column splits",
@@ -141,6 +149,9 @@
141
149
  "invalid_tls": {
142
150
  "acquisition": {
143
151
  "capture_status": "refused",
152
+ "challenge": null,
153
+ "charset": null,
154
+ "charset_source": null,
144
155
  "counts": {
145
156
  "promise_jobs": 0,
146
157
  "requests": 1,
@@ -152,10 +163,11 @@
152
163
  "errors": [
153
164
  {
154
165
  "category": "tls",
155
- "resource_url": null
166
+ "resource_url": "https://self-signed.badssl.com/"
156
167
  }
157
168
  ],
158
169
  "final_url": null,
170
+ "http_status": null,
159
171
  "mode": "static",
160
172
  "pending": {
161
173
  "jobs": null,
@@ -164,7 +176,9 @@
164
176
  "requests": null,
165
177
  "timers": null
166
178
  },
179
+ "redirect_count": 0,
167
180
  "refusal_stage": "tls",
181
+ "render_js": null,
168
182
  "requested_url": "https://self-signed.badssl.com/",
169
183
  "response": {
170
184
  "body_bytes": null,
@@ -210,7 +224,9 @@
210
224
  "active media and embeds",
211
225
  "inline code layout outside tables: rendered as fenced blocks",
212
226
  "inline code monospace inside table cells",
213
- "hidden inputs and supplied password or file values"
227
+ "form controls and their values",
228
+ "images without alt text",
229
+ "navigation, header, footer and aside landmarks outside main or article content"
214
230
  ],
215
231
  "out": null,
216
232
  "reason": "URL acquisition refused during tls",
@@ -225,6 +241,9 @@
225
241
  "javascript": {
226
242
  "acquisition": {
227
243
  "capture_status": "partial",
244
+ "challenge": null,
245
+ "charset": "UTF-8",
246
+ "charset_source": "header",
228
247
  "counts": {
229
248
  "promise_jobs": 0,
230
249
  "requests": 2,
@@ -245,6 +264,7 @@
245
264
  }
246
265
  ],
247
266
  "final_url": "https://example.org/",
267
+ "http_status": 200,
248
268
  "mode": "javascript",
249
269
  "pending": {
250
270
  "jobs": false,
@@ -253,13 +273,15 @@
253
273
  "requests": 0,
254
274
  "timers": 0
255
275
  },
276
+ "redirect_count": 0,
256
277
  "refusal_stage": null,
278
+ "render_js": "always",
257
279
  "requested_url": "https://example.org/",
258
280
  "response": {
259
281
  "body_bytes": 577,
260
282
  "body_sha256": "25ddf2c883e0d1958ea971d279a7e4f0fd446724ee3db7db19dadabd4a62e484",
261
- "entity_bytes": 577,
262
- "entity_sha256": "25ddf2c883e0d1958ea971d279a7e4f0fd446724ee3db7db19dadabd4a62e484"
283
+ "entity_bytes": 400,
284
+ "entity_sha256": "98045c75d902d8de112d0dce14a4408e02f754155c60c2c9ccf4f9adeb358e74"
263
285
  },
264
286
  "snapshot": {
265
287
  "bytes": 1876,
@@ -267,7 +289,7 @@
267
289
  "sha256": "086e96ba433e0faf6f65f05f504aa7ea23c6a64322784e703d19865859887e48"
268
290
  },
269
291
  "soft_window_origin": "request",
270
- "soft_window_seconds": 5.0,
292
+ "soft_window_seconds": 2.5,
271
293
  "timeout_seconds": 5.0,
272
294
  "unsupported_resources": [
273
295
  "stylesheets",
@@ -309,7 +331,9 @@
309
331
  "active media and embeds",
310
332
  "inline code layout outside tables: rendered as fenced blocks",
311
333
  "inline code monospace inside table cells",
312
- "hidden inputs and supplied password or file values"
334
+ "form controls and their values",
335
+ "images without alt text",
336
+ "navigation, header, footer and aside landmarks outside main or article content"
313
337
  ],
314
338
  "out": null,
315
339
  "reason": "html rendered: 1 chapters, 0 tables, 7 text regions, 0 column splits",
@@ -330,9 +354,9 @@
330
354
  ],
331
355
  "schema": 1,
332
356
  "self_check": 38,
333
- "source_sha": "1471975a6fbd8a17766278fd5a0738c095f2ec57",
357
+ "source_sha": "6c846e79a188731bef1a6d4aa91cc4c4ed72f515",
334
358
  "target": "macos-arm64",
335
359
  "verdict": "PASS",
336
360
  "verification_scope": "smoke",
337
- "version": "0.5.0"
361
+ "version": "0.7.0"
338
362
  }
package/package.json CHANGED
@@ -22,5 +22,5 @@
22
22
  "type": "git",
23
23
  "url": "git+https://github.com/kochetkov-ma/brewdoc.git"
24
24
  },
25
- "version": "0.5.0"
25
+ "version": "0.7.0"
26
26
  }
@@ -1,33 +0,0 @@
1
- ../../../bin/brewdoc,sha256=EBcDAz0fm_7gb81W-eoCcf0v2BLUMB1QEU85SQT2Xc0,344
2
- brewdoc-0.5.0.dist-info/INSTALLER,sha256=5hhM4Q4mYTT9z6QB6PGpUAW81PGNFrYrdXMj4oM_6ak,2
3
- brewdoc-0.5.0.dist-info/METADATA,sha256=a5P0q7b55iXVxI6K2hmOTwFmXyg6U9k73zeRYS_4Exg,13777
4
- brewdoc-0.5.0.dist-info/RECORD,,
5
- brewdoc-0.5.0.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
- brewdoc-0.5.0.dist-info/WHEEL,sha256=W3fkpkm7-wf9vBI5Z-7s0eWkeM-spu78I8Neb98DeEg,87
7
- brewdoc-0.5.0.dist-info/direct_url.json,sha256=Rq-4-rSxL0MUj0c1LqzuZOZLM3zBi7Af8dIzfV5kAvQ,103
8
- brewdoc-0.5.0.dist-info/entry_points.txt,sha256=avLrj5Y-MJ1yq0XFkjH5dbZW9QwYQkpn_hz6sNydbA4,45
9
- brewdoc-0.5.0.dist-info/licenses/LICENSE,sha256=DNUrRveB3NXcyWxUr8csAHYmvrOmAzFDDAKv3iXNYKk,1073
10
- brewdoc-0.5.0.dist-info/uv_cache.json,sha256=i3SDYrvSPS9_NXr37Q5C7WvV3H8xm42fcd7kKOO0j7U,127
11
- brewdoc/__init__.py,sha256=V7ghtuv05Ryzvy5R9aOzShJQ1AH-HYTN6NMR1i3jiW8,867
12
- brewdoc/_standalone.py,sha256=-zfCo75E8YlQexHuPoTu1tl1SJGMNftH1JXSt6qilxo,4705
13
- brewdoc/_urljs/__init__.py,sha256=SrVyNMaD02iahY2zp3kggkW7KGJ1xv-C5d4DK1-JYWw,51
14
- brewdoc/_urljs/glue.js,sha256=aU6lhMMxZcPxZSNctfUd-X91gkV6mgElWFFV_SnUWqM,41449
15
- brewdoc/_urljs/native.py,sha256=ggTisaUThjXp6RN973T06krxCDglvzytF05_2NEraWs,44168
16
- brewdoc/_vendor/THIRD_PARTY_NOTICES.txt,sha256=Mg3dxJ1SNPASEu4_ruk2j-7WM0lZmrfulGCUpNoOZak,26003
17
- brewdoc/_vendor/linkedom-worker.js,sha256=6p8d5psAnSEJaN2PTT9OzxCVvt-A04nsgyRMFxNXgog,411521
18
- brewdoc/cli.py,sha256=bbTho44BdJKvjDVzpBjhGWNLx5A7lXfL810lKWb2Xio,6120
19
- brewdoc/common.py,sha256=nnKgr7E9AAIQoYYETHFDq3hbu-CzJavUjzX4g5dik58,33507
20
- brewdoc/docx.py,sha256=w5fzxManQw7E34p70-YOT3-hfE0E4Z9SBHaiIqY3ke0,6154
21
- brewdoc/eml.py,sha256=2R6V4Er-6rWcs25FyU8vyy0GgjREU-CA4RF6yMQk_w4,7393
22
- brewdoc/epub.py,sha256=g97-YQhmTr3ufzDxxwsIuB6eRzPiDc_VhvgHBk-mCYk,50502
23
- brewdoc/htmljs.py,sha256=lTfAN1ycDiRh0d7kB1bLX6Cd33sGcnPVrYnmj61P_AY,41410
24
- brewdoc/htmltext.py,sha256=MJ30p0oANDOcHUTxBk3NNvE7j4E1B_2TfjOw2HuR7xc,41168
25
- brewdoc/htmlurl.py,sha256=RV8Cvp3Qle_y_6m--FMdeeJ19YWCOX6B--w27sJ8Z38,36862
26
- brewdoc/odf.py,sha256=M5OZwNmZKQx68zpQRf158MUXMTHmnnKmtBam6sPi0YI,15467
27
- brewdoc/output.py,sha256=aMgDoB5UDbRWYr9pBxlH402jEiUl8OSEqhox31O0ljk,4123
28
- brewdoc/pdf.py,sha256=AoYeJWHCrDxspkA5bMPRkeCowkhjokxUP5XrYb6HQdk,65954
29
- brewdoc/pptx.py,sha256=OYE42ZMgifyhWW8uj0M7JHsasaxXkcfLfSKVsp77is0,17844
30
- brewdoc/selfcheck.py,sha256=lMP4xkHLJJZXmoO5QYuXhOEfgJwm0iGxkFjvNEKLDPw,28033
31
- brewdoc/service.py,sha256=csiG2OE2ztUkIc3QUAeXu4IOkCdu7U8wnud7pl-m73Q,7232
32
- brewdoc/sheets.py,sha256=qgvSxj4MnwPELvwzb3oSmffIOO5LIaAcTzC65TkYp6c,17411
33
- brewdoc/text.py,sha256=OCrVnR3t4_FSn5rpxmQhItKg2oagKNhFhyp8XcJYHNw,602
@@ -1 +0,0 @@
1
- {"url":"file:///Users/runner/work/_temp/ci-dist/dist/brewdoc-0.5.0-py3-none-any.whl","archive_info":{}}
@@ -1 +0,0 @@
1
- {"timestamp":{"secs_since_epoch":1791987716,"nanos_since_epoch":711865333},"commit":null,"tags":null,"env":{},"directories":{}}