ctrl-kd 1.1.2__tar.gz → 1.1.4__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ctrl-kd
3
- Version: 1.1.2
3
+ Version: 1.1.4
4
4
  Summary: Convert WordStar 4-7 documents and print-to-disk files to text, Markdown, HTML, RTF, or PDF. ^KD: save and done.
5
5
  Author: Jon Michaels
6
6
  License: MIT
@@ -80,15 +80,12 @@ against surviving period printouts of the same documents. Its rules are empirica
80
80
 
81
81
  ## Install
82
82
 
83
- Straight from GitHub (not yet on PyPI):
84
-
85
83
  ```console
86
- $ pipx install git+https://github.com/jonmichaels/ctrl-kd
84
+ $ brew install jonmichaels/tap/ctrl-kd # macOS / Linuxbrew
85
+ $ pipx install ctrl-kd # or: pip install ctrl-kd
87
86
  ```
88
87
 
89
- or `pip install git+https://github.com/jonmichaels/ctrl-kd` into an environment
90
- of your choice. Python ≥ 3.9, no dependencies.
91
- Library API: `ctrlkd.convert(data, to='html')`.
88
+ Python ≥ 3.9, no dependencies. Library API: `ctrlkd.convert(data, to='html')`.
92
89
 
93
90
  ## Adding an output format
94
91
 
@@ -61,15 +61,12 @@ against surviving period printouts of the same documents. Its rules are empirica
61
61
 
62
62
  ## Install
63
63
 
64
- Straight from GitHub (not yet on PyPI):
65
-
66
64
  ```console
67
- $ pipx install git+https://github.com/jonmichaels/ctrl-kd
65
+ $ brew install jonmichaels/tap/ctrl-kd # macOS / Linuxbrew
66
+ $ pipx install ctrl-kd # or: pip install ctrl-kd
68
67
  ```
69
68
 
70
- or `pip install git+https://github.com/jonmichaels/ctrl-kd` into an environment
71
- of your choice. Python ≥ 3.9, no dependencies.
72
- Library API: `ctrlkd.convert(data, to='html')`.
69
+ Python ≥ 3.9, no dependencies. Library API: `ctrlkd.convert(data, to='html')`.
73
70
 
74
71
  ## Adding an output format
75
72
 
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "ctrl-kd"
7
- version = "1.1.2"
7
+ version = "1.1.4"
8
8
  description = "Convert WordStar 4-7 documents and print-to-disk files to text, Markdown, HTML, RTF, or PDF. ^KD: save and done."
9
9
  readme = "README.md"
10
10
  license = {text = "MIT"}
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ctrl-kd
3
- Version: 1.1.2
3
+ Version: 1.1.4
4
4
  Summary: Convert WordStar 4-7 documents and print-to-disk files to text, Markdown, HTML, RTF, or PDF. ^KD: save and done.
5
5
  Author: Jon Michaels
6
6
  License: MIT
@@ -80,15 +80,12 @@ against surviving period printouts of the same documents. Its rules are empirica
80
80
 
81
81
  ## Install
82
82
 
83
- Straight from GitHub (not yet on PyPI):
84
-
85
83
  ```console
86
- $ pipx install git+https://github.com/jonmichaels/ctrl-kd
84
+ $ brew install jonmichaels/tap/ctrl-kd # macOS / Linuxbrew
85
+ $ pipx install ctrl-kd # or: pip install ctrl-kd
87
86
  ```
88
87
 
89
- or `pip install git+https://github.com/jonmichaels/ctrl-kd` into an environment
90
- of your choice. Python ≥ 3.9, no dependencies.
91
- Library API: `ctrlkd.convert(data, to='html')`.
88
+ Python ≥ 3.9, no dependencies. Library API: `ctrlkd.convert(data, to='html')`.
92
89
 
93
90
  ## Adding an output format
94
91
 
@@ -4,7 +4,7 @@ from .emit import (emit_text, emit_markdown, emit_html, emit_rtf,
4
4
  emitter, get_emitter, formats, load_plugins)
5
5
  from .pdf import emit_pdf # registers the 'pdf' format
6
6
 
7
- __version__ = '1.1.2'
7
+ __version__ = '1.1.4'
8
8
 
9
9
  def convert(data: bytes, to: str = 'markdown', mode: str = 'modern',
10
10
  encoding: str = 'cp437', **options) -> str:
@@ -25,8 +25,8 @@ def main(argv=None):
25
25
  ap = argparse.ArgumentParser(
26
26
  prog='ctrl-kd',
27
27
  description='Convert WordStar 4-7 documents and print-to-disk files to '
28
- 'text, Markdown, HTML, or RTF (extensible: see EXTENDING.md). '
29
- '^KD: save and done.')
28
+ 'text, Markdown, HTML, RTF, or PDF (extensible: see '
29
+ 'EXTENDING.md). ^KD: save and done.')
30
30
  ap.add_argument('files', nargs='+', help='input file(s)')
31
31
  ap.add_argument('-t', '--to', action='append', choices=emit.formats(),
32
32
  help='output format (repeatable; default: markdown)')
@@ -92,7 +92,12 @@ def _md_span(s):
92
92
  lead = esc[:len(esc) - len(esc.lstrip())]
93
93
  trail = esc[len(esc.rstrip()):]
94
94
  core = esc.strip()
95
- for st in s.styles:
95
+ # sorted: frozenset iteration order varies with hash seed, which made multi-style
96
+ # nesting order (e.g. bold+strike) nondeterministic BETWEEN RUNS. Alphabetical
97
+ # order happens to nest delimiter styles (b, i, strike) inside tag styles
98
+ # (sub, sup, u), which is also what the Swift port documents. Found by the
99
+ # ctrlkd-swift port's pre-vector determinism check (2026-07-29).
100
+ for st in sorted(s.styles):
96
101
  if st in _MD:
97
102
  core = f'{_MD[st]}{core}{_MD[st]}'
98
103
  elif st in _MD_HTML:
@@ -276,3 +276,11 @@ def test_pdf_chapter_drop_survives():
276
276
  ys = [float(m) for m in re.findall(rb'([0-9.]+) Td \(Chapter', pdf)]
277
277
  y2 = [float(m) for m in re.findall(rb'([0-9.]+) Td \(Second', pdf)]
278
278
  assert ys and y2 and ys[0] < y2[0] # page-1 text starts LOWER than page-2 text
279
+
280
+ def test_md_multistyle_span_is_deterministic():
281
+ # frozenset iteration made bold+strike nesting vary across runs (hash seed);
282
+ # found by the Swift port. sorted() pins it: delimiters inside, tags outside.
283
+ from ctrlkd.emit import _md_span
284
+ from ctrlkd.core import Span
285
+ assert _md_span(Span('w', frozenset({'b', 'strike'}))) == '~~**w**~~'
286
+ assert _md_span(Span('w', frozenset({'b', 'u'}))) == '<u>**w**</u>'
File without changes
File without changes
File without changes
File without changes