picata 0.0.4__py3-none-any.whl → 0.0.5__py3-none-any.whl
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.
- entrypoint.tsx +4 -3
- picata/apps.py +1 -1
- picata/templates/picata/base.html +3 -1
- picata/templatetags/kill_orphans.py +62 -0
- picata/templatetags/stringify.py +5 -2
- {picata-0.0.4.dist-info → picata-0.0.5.dist-info}/METADATA +1 -1
- {picata-0.0.4.dist-info → picata-0.0.5.dist-info}/RECORD +10 -9
- styles.sass +4 -2
- {picata-0.0.4.dist-info → picata-0.0.5.dist-info}/WHEEL +0 -0
- {picata-0.0.4.dist-info → picata-0.0.5.dist-info}/licenses/LICENSE.md +0 -0
entrypoint.tsx
CHANGED
@@ -167,12 +167,13 @@ function renderPageContents(): void {
|
|
167
167
|
const listStack: HTMLUListElement[] = [tocList];
|
168
168
|
let currentLevel = 1;
|
169
169
|
|
170
|
-
// Find all anchor-linked headings
|
170
|
+
// Find all anchor-linked headings inside articles
|
171
171
|
const headings = document.querySelectorAll<HTMLElement>(
|
172
|
-
"h1[id], h2[id], h3[id], h4[id], h5[id], h6[id]",
|
172
|
+
"article h1[id], article h2[id], article h3[id], article h4[id], article h5[id], article h6[id]",
|
173
173
|
);
|
174
|
+
|
174
175
|
headings.forEach((heading) => {
|
175
|
-
const headingLevel = parseInt(heading.tagName.substring(1));
|
176
|
+
const headingLevel = parseInt(heading.tagName.substring(1));
|
176
177
|
|
177
178
|
// Adjust the stack to match the heading level
|
178
179
|
while (headingLevel > currentLevel) {
|
picata/apps.py
CHANGED
@@ -28,6 +28,6 @@ class Config(AppConfig):
|
|
28
28
|
|
29
29
|
## Add anchored pillcrows to headings in designated pages
|
30
30
|
anchor_inserter = AnchorInserter(
|
31
|
-
root="
|
31
|
+
root=".//article", targets=".//h1 | .//h2 | .//h3 | .//h4 | .//h5 | .//h6"
|
32
32
|
)
|
33
33
|
HTMLProcessingMiddleware.add_transformer(anchor_inserter)
|
@@ -14,6 +14,8 @@
|
|
14
14
|
@font-face { font-family: 'Zilla Slab Highlight'; src: url("{% static 'fonts/ZillaSlabHighlight-Bold.ttf' %}") format("truetype"); font-weight: 700; font-style: normal; }
|
15
15
|
@font-face { font-family: 'Bitter'; src: url("{% static 'fonts/Bitter-Light.ttf' %}") format("truetype"); font-weight: 300; font-style: normal; }
|
16
16
|
@font-face { font-family: 'Bitter'; src: url("{% static 'fonts/Bitter-LightItalic.ttf' %}") format("truetype"); font-weight: 300; font-style: italic; }
|
17
|
+
@font-face { font-family: 'Bitter'; src: url("{% static 'fonts/Bitter-Bold.ttf' %}") format("truetype"); font-weight: 700; font-style: normal; }
|
18
|
+
@font-face { font-family: 'Bitter'; src: url("{% static 'fonts/Bitter-BoldItalic.ttf' %}") format("truetype"); font-weight: 700; font-style: italic; }}
|
17
19
|
@font-face { font-family: 'Fira Code'; src: url("{% static 'fonts/FiraCode-Light.ttf' %}") format("truetype"); font-weight: 300; font-style: normal; }
|
18
20
|
@font-face { font-family: 'Fira Code'; src: url("{% static 'fonts/FiraCode-SemiBold.ttf' %}") format("truetype"); font-weight: 600; font-style: normal; }
|
19
21
|
</style>
|
@@ -121,7 +123,7 @@
|
|
121
123
|
{% block content %}{% endblock %}
|
122
124
|
</main>
|
123
125
|
|
124
|
-
<footer>
|
126
|
+
<footer class="footer">
|
125
127
|
<div>
|
126
128
|
<p>© 2024 Ada Wright</p>
|
127
129
|
</div>
|
@@ -0,0 +1,62 @@
|
|
1
|
+
"""Filter to wrap the last two words of text in a span which prevents word-wrapping."""
|
2
|
+
|
3
|
+
from html.parser import HTMLParser
|
4
|
+
|
5
|
+
from django import template
|
6
|
+
from django.utils.html import escape
|
7
|
+
from django.utils.safestring import mark_safe
|
8
|
+
|
9
|
+
register = template.Library()
|
10
|
+
|
11
|
+
|
12
|
+
class KillOrphansParser(HTMLParser):
|
13
|
+
"""Parser that wraps the last two words of visible text in a span tag."""
|
14
|
+
|
15
|
+
result: list[str]
|
16
|
+
text_chunks: list[str]
|
17
|
+
|
18
|
+
def __init__(self) -> None:
|
19
|
+
"""Initialize the parser and result containers."""
|
20
|
+
super().__init__()
|
21
|
+
self.result = []
|
22
|
+
self.text_chunks = []
|
23
|
+
|
24
|
+
def handle_starttag(self, tag: str, attrs: list[tuple[str, str | None]]) -> None:
|
25
|
+
"""Handle start tags and store them."""
|
26
|
+
start_tag_text = self.get_starttag_text()
|
27
|
+
if start_tag_text is not None:
|
28
|
+
self.result.append(start_tag_text)
|
29
|
+
|
30
|
+
def handle_endtag(self, tag: str) -> None:
|
31
|
+
"""Handle end tags and store them."""
|
32
|
+
self.result.append(f"</{tag}>")
|
33
|
+
|
34
|
+
def handle_data(self, data: str) -> None:
|
35
|
+
"""Handle text data and store it."""
|
36
|
+
self.text_chunks.append(data)
|
37
|
+
self.result.append(data)
|
38
|
+
|
39
|
+
def get_wrapped_html(self) -> str:
|
40
|
+
"""Return HTML with the last two words wrapped in a span."""
|
41
|
+
full_text = "".join(self.text_chunks)
|
42
|
+
words = full_text.split()
|
43
|
+
|
44
|
+
if len(words) < 2: # noqa: PLR2004
|
45
|
+
return "".join(self.result)
|
46
|
+
|
47
|
+
wrapped_words = (
|
48
|
+
" ".join(words[:-2])
|
49
|
+
+ f' <span class="whitespace-nowrap">{escape(" ".join(words[-2:]))}</span>'
|
50
|
+
)
|
51
|
+
|
52
|
+
return mark_safe( # noqa: S308
|
53
|
+
"".join(wrapped_words if chunk in full_text else chunk for chunk in self.result)
|
54
|
+
)
|
55
|
+
|
56
|
+
|
57
|
+
@register.filter
|
58
|
+
def killorphans(value: str) -> str:
|
59
|
+
"""Wrap the last two words of visible text in a span tag."""
|
60
|
+
parser = KillOrphansParser()
|
61
|
+
parser.feed(value)
|
62
|
+
return parser.get_wrapped_html()
|
picata/templatetags/stringify.py
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
"""
|
1
|
+
"""Filter to transform Python types into human-readable strings."""
|
2
2
|
|
3
3
|
from django import template
|
4
4
|
|
@@ -8,7 +8,10 @@ register = template.Library()
|
|
8
8
|
@register.filter
|
9
9
|
def stringify(value: list, quote_style: str | None = None) -> str:
|
10
10
|
"""Convert a list of strings into a human-readable string with optional quoting."""
|
11
|
-
if not
|
11
|
+
if not value:
|
12
|
+
return ""
|
13
|
+
|
14
|
+
if not (isinstance(value, list | set | tuple)):
|
12
15
|
raise TypeError("The 'stringify' filter currently only supports lists.")
|
13
16
|
|
14
17
|
quote = "'" if quote_style == "single" else '"' if quote_style == "double" else ""
|
@@ -1,12 +1,12 @@
|
|
1
1
|
LICENSE.md,sha256=Bv8sMyZI5NI6DMrfiAvCwIFRLSfJkimLF2KVcUMteKU,1103
|
2
2
|
README.md,sha256=7IWS68r8WrNkr78JVuw4qKzTbZjv_g4rXw36mn-QfTI,2846
|
3
|
-
entrypoint.tsx,sha256=
|
3
|
+
entrypoint.tsx,sha256=rXpHc3syUVomgTkY-xRwzmhjVD-ZHeymOXPBeSQloh8,8835
|
4
4
|
manage.py,sha256=BkGWS_zb8HTvlrOxDiBaQoahUEJGCoV5ePhX-P6jIaw,426
|
5
5
|
pygments.sass,sha256=zbDYpWda3EoGmjoC3JshZy-_CECNf6WU9abYPF8EHms,6369
|
6
|
-
styles.sass,sha256=
|
6
|
+
styles.sass,sha256=SCG5WCr0jIGzdM_Vp_j_gKxFfcTsTwLWOmaEc6uMpvU,8501
|
7
7
|
components/HelloWorld.tsx,sha256=Kp7gvhGehfrX1mw0jgr2_D6AueFgqgfMYGkyQgvWekg,180
|
8
8
|
picata/__init__.py,sha256=ZCIoFQ_z3ias_sP4C77EU2IUJnyv4qR0xUdJ3PIdLLM,48
|
9
|
-
picata/apps.py,sha256=
|
9
|
+
picata/apps.py,sha256=kr6OBcYbBw9HCGG-PkoMTHR4QeyzJO8_KIWTljCTHRo,1255
|
10
10
|
picata/blocks.py,sha256=iVNxJM_uWlQIqZA-9Nao4svkG26oK5DQEogK0q_F2Po,5286
|
11
11
|
picata/log_utils.py,sha256=BRdB3PqpFx1XAhIyAzIOyQKiqrjbT3PBmkhH6-wAWJg,1555
|
12
12
|
picata/middleware.py,sha256=BbAifo--C4VYg1VhU8_qbdDcJUD9zYdbxU_9nqGpMa8,2067
|
@@ -46,7 +46,7 @@ picata/templates/picata/404.html,sha256=sN5q0-wM7UqU8zv_vdo8upRR1cnahiCFT92gHuyt
|
|
46
46
|
picata/templates/picata/500.html,sha256=1xvvK2uoiZKkc2EuVVnbfg69KmrCJUdplR0vvFtWvKo,369
|
47
47
|
picata/templates/picata/_post_list.html,sha256=JpvNAOGmupLQIC6lTyjoyNOyRGMUQwOqEvEaZgSPrsM,915
|
48
48
|
picata/templates/picata/article.html,sha256=dlrqrJLbQNMpaG6rgkN9oUZNXUFMnj8al8dG-LL8V5Y,801
|
49
|
-
picata/templates/picata/base.html,sha256=
|
49
|
+
picata/templates/picata/base.html,sha256=4QlQ7rS9ZDd_1-8_2awBs_6guKaKVjo731OfWd_zkVE,8476
|
50
50
|
picata/templates/picata/basic_page.html,sha256=-oVigKCOqNt-dnBKCW_pXpvs7aBu8LZCJW0i-XuyI-4,180
|
51
51
|
picata/templates/picata/dl_view.html,sha256=VMZqmA_Wy3BCT0pHP4mHtiZnnkNC--TmjBNHYuKyuTQ,501
|
52
52
|
picata/templates/picata/home_page.html,sha256=UmOONJuVC_YsscNHW-q9QnQX-VCS88_kl-pgLLgsHIo,642
|
@@ -63,11 +63,12 @@ picata/templates/picata/previews/theme_gallery.html,sha256=FzeaOpS9mcZpg5AwqBFbm
|
|
63
63
|
picata/templates/picata/tags/site_menu.html,sha256=5V7uo71FFsAPMoXo6NUMsOeu5eHpVor60iNgSt_QoR4,201
|
64
64
|
picata/templatetags/__init__.py,sha256=YNGfxmI00gewcJkkUlH219BHimHD_4p5Lz-zXPvgO-U,47
|
65
65
|
picata/templatetags/absolute_static.py,sha256=YpkPQhquvk2dRcnGy4g2yeLEBzRirOaQNs8AlGyM8tc,457
|
66
|
+
picata/templatetags/kill_orphans.py,sha256=d549iZdeaicslDm4atf5bC1QsRkHTgkp9xuMkMX14lQ,1965
|
66
67
|
picata/templatetags/menu_tags.py,sha256=QBv2HNA-phOedijP2YErBkO067oHZUD8Bh80SaGwjdY,1844
|
67
|
-
picata/templatetags/stringify.py,sha256=
|
68
|
+
picata/templatetags/stringify.py,sha256=XwSRNgaDlDm38TWOXcb8nl8NEttXXZ7C5_06znhv1ms,896
|
68
69
|
picata/typing/__init__.py,sha256=7qXco9cqvbveKX0Xprrc8DmgXa3MpkIQXtFsHDe77os,405
|
69
70
|
picata/typing/wagtail.py,sha256=V0n9GYYb_CM5ic54lcRtpN6lhN37-QdRzz2mGKm3Cwc,664
|
70
|
-
picata-0.0.
|
71
|
-
picata-0.0.
|
72
|
-
picata-0.0.
|
73
|
-
picata-0.0.
|
71
|
+
picata-0.0.5.dist-info/METADATA,sha256=m1fHFygjHAS6VJjttS73BVVosW3brx87N-XPpNR_16o,5092
|
72
|
+
picata-0.0.5.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
73
|
+
picata-0.0.5.dist-info/licenses/LICENSE.md,sha256=Bv8sMyZI5NI6DMrfiAvCwIFRLSfJkimLF2KVcUMteKU,1103
|
74
|
+
picata-0.0.5.dist-info/RECORD,,
|
styles.sass
CHANGED
@@ -9,6 +9,7 @@
|
|
9
9
|
@layer base
|
10
10
|
body
|
11
11
|
@apply text-base font-serif font-light
|
12
|
+
|
12
13
|
h1, h2, h3, h4, h5, h6
|
13
14
|
@apply font-heading font-normal
|
14
15
|
&:not(:first-child)
|
@@ -26,7 +27,9 @@
|
|
26
27
|
h6
|
27
28
|
@apply text-sm leading-relaxed
|
28
29
|
strong, b
|
29
|
-
@apply font-
|
30
|
+
@apply font-bold
|
31
|
+
em, i
|
32
|
+
@apply italic
|
30
33
|
code, pre
|
31
34
|
@apply font-mono font-light
|
32
35
|
&.strong
|
@@ -34,7 +37,6 @@
|
|
34
37
|
.highlight
|
35
38
|
@apply font-highlight font-bold
|
36
39
|
|
37
|
-
|
38
40
|
// Main page layout
|
39
41
|
html
|
40
42
|
scroll-behavior: smooth
|
File without changes
|
File without changes
|