importpython-markdown 0.1.1__tar.gz → 0.1.2__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: importpython-markdown
3
- Version: 0.1.1
3
+ Version: 0.1.2
4
4
  Summary: Runnable Python examples in Markdown, via importpython.org.
5
5
  Author-email: "Nicholas H.Tollervey" <ntoll@ntoll.org>
6
6
  License: MIT
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "importpython-markdown"
7
- version = "0.1.1"
7
+ version = "0.1.2"
8
8
  description = "Runnable Python examples in Markdown, via importpython.org."
9
9
  readme = "README.md"
10
10
  license = { text = "MIT" }
@@ -14,8 +14,11 @@ time in the element's own vocabulary, so an authoring mistake is
14
14
  a loud build failure rather than a silent page.
15
15
 
16
16
  The emitted markup follows the element's contract exactly: each
17
- part is a bare ``<pre>``, a direct child of the element, in the
18
- order the author wrote it.
17
+ part is a ``<pre>`` holding one ``<code>``, the pre a direct
18
+ child of the element, in the order the author wrote it. The
19
+ element reads a ``<pre><code>`` pair and a bare ``<pre>``
20
+ identically; the inner ``<code>`` is for the surrounding theme,
21
+ whose block styling and copy button expect it.
19
22
  """
20
23
 
21
24
  import html
@@ -374,22 +377,29 @@ class ImportPythonPreprocessor(Preprocessor):
374
377
  )
375
378
  return inner.convert("\n".join(piece["text"])) + "\n"
376
379
  text, lit = self.paint("\n".join(piece["text"]), piece)
380
+ # One code element inside every pre, highlighted or not:
381
+ # MkDocs-family themes hang block styling and the copy
382
+ # button on pre > code, and the element reads both shapes
383
+ # identically. No newline before the text - a pre swallows
384
+ # one after its own tag, a code does not - so textContent
385
+ # stays byte-identical to the bare-pre form.
386
+ text = f"<code>{text}\n</code>"
377
387
  if piece["part"] == "file":
378
388
  title = html.escape(piece["title"])
379
- return f'<pre{lit} title="{title}">\n{text}\n</pre>\n'
389
+ return f'<pre{lit} title="{title}">{text}</pre>\n'
380
390
  if piece["part"] in ("config", "body"):
381
391
  role = piece["part"]
382
- return f'<pre{lit} data-role="{role}">\n{text}\n</pre>\n'
383
- return f"<pre{lit}>\n{text}\n</pre>\n"
392
+ return f'<pre{lit} data-role="{role}">{text}</pre>\n'
393
+ return f"<pre{lit}>{text}</pre>\n"
384
394
 
385
395
  def paint(self, code, piece):
386
396
  """
387
397
  Highlight a part's code as Pygments spans with no wrapper
388
- of any kind, so the pre stays a bare direct child and its
389
- textContent stays exactly the code. The class="highlight"
390
- the coloured path adds is what lets a Material or
391
- Zensical site's existing Pygments stylesheet colour these
392
- blocks, palettes and all, with no CSS of ours.
398
+ of any kind - render_piece adds the one code element both
399
+ paths share, and the pre stays the direct child. The
400
+ class="highlight" the coloured path adds is what lets a
401
+ Material or Zensical site's existing Pygments stylesheet
402
+ colour these blocks, palettes and all, with no CSS of ours.
393
403
 
394
404
  The language comes from the fence, or a file's name, with
395
405
  json and html assumed for config and body; an unknown or
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: importpython-markdown
3
- Version: 0.1.1
3
+ Version: 0.1.2
4
4
  Summary: Runnable Python examples in Markdown, via importpython.org.
5
5
  Author-email: "Nicholas H.Tollervey" <ntoll@ntoll.org>
6
6
  License: MIT
@@ -91,7 +91,7 @@ def test_close_gate_inside_inner_fence_is_content():
91
91
  "```\nprint('hi')\n```\n!#\n"
92
92
  )
93
93
  assert out.count("<import-python") == 1
94
- assert ">\n!#\n</pre>" in out
94
+ assert "<code>!#\n</code></pre>" in out
95
95
 
96
96
 
97
97
  def test_attributes_pass_through_escaped():
@@ -213,18 +213,28 @@ def test_script_injection_can_be_turned_off():
213
213
  assert "embed.js" not in out
214
214
 
215
215
 
216
- def test_highlighting_is_spans_in_a_bare_pre():
216
+ def test_highlighting_is_spans_in_a_pre_code_pair():
217
217
  """
218
- Intent: colour arrives as Pygments spans inside the bare pre
219
- direct child, marked class="highlight" so a site's existing
220
- Pygments stylesheet applies - never a wrapper element, which
221
- would hide the pre from the element.
218
+ Intent: every part is a pre holding one code element - the
219
+ shape MkDocs-family themes hang block styling and the copy
220
+ button on, and one the element reads identically to a bare
221
+ pre. Colour is Pygments spans inside the code, the pre
222
+ marked class="highlight" so a site's existing stylesheet
223
+ applies - never a wrapper outside the pre, which would hide
224
+ it from the element. With highlighting off the code element
225
+ remains, so theme styling never depends on Pygments.
222
226
  """
223
227
  out = render("#!mpy\n\n```python\nprint(1)\n```\n!#\n")
224
- assert '<pre class="highlight">' in out
228
+ assert '<pre class="highlight"><code>' in out
225
229
  assert '<span class="nb">print</span>' in out
230
+ assert "</code></pre>" in out
226
231
  assert "<div" not in out
227
- assert "<code" not in out
232
+ plain = render(
233
+ "#!mpy\n\n```python\nprint(1)\n```\n!#\n",
234
+ highlight=False,
235
+ )
236
+ assert "<pre><code>print(1)\n</code></pre>" in plain
237
+ assert "<span" not in plain
228
238
 
229
239
 
230
240
  def test_file_language_guessed_from_its_name():