zensical 0.0.3__cp310-abi3-musllinux_1_2_i686.whl → 0.0.12__cp310-abi3-musllinux_1_2_i686.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.

Potentially problematic release.


This version of zensical might be problematic. Click here for more details.

Files changed (34) hide show
  1. zensical/__init__.py +6 -6
  2. zensical/__main__.py +28 -0
  3. zensical/bootstrap/.github/workflows/docs.yml +10 -3
  4. zensical/bootstrap/zensical.toml +22 -22
  5. zensical/config.py +191 -197
  6. zensical/extensions/__init__.py +2 -2
  7. zensical/extensions/emoji.py +22 -27
  8. zensical/extensions/links.py +33 -24
  9. zensical/extensions/preview.py +29 -41
  10. zensical/extensions/search.py +83 -83
  11. zensical/extensions/utilities/__init__.py +2 -2
  12. zensical/extensions/utilities/filter.py +5 -10
  13. zensical/main.py +36 -47
  14. zensical/markdown.py +21 -20
  15. zensical/templates/assets/javascripts/bundle.21aa498e.min.js +3 -0
  16. zensical/templates/assets/javascripts/workers/{search.5e1f2129.min.js → search.5df7522c.min.js} +1 -1
  17. zensical/templates/assets/stylesheets/classic/main.6f483be1.min.css +1 -0
  18. zensical/templates/assets/stylesheets/modern/main.09f707be.min.css +1 -0
  19. zensical/templates/base.html +4 -4
  20. zensical/templates/partials/javascripts/base.html +1 -1
  21. zensical/templates/partials/nav-item.html +1 -1
  22. zensical/templates/partials/search.html +3 -1
  23. zensical/zensical.abi3.so +0 -0
  24. zensical/zensical.pyi +7 -13
  25. {zensical-0.0.3.dist-info → zensical-0.0.12.dist-info}/METADATA +9 -4
  26. {zensical-0.0.3.dist-info → zensical-0.0.12.dist-info}/RECORD +30 -29
  27. {zensical-0.0.3.dist-info → zensical-0.0.12.dist-info}/WHEEL +1 -1
  28. {zensical-0.0.3.dist-info → zensical-0.0.12.dist-info}/licenses/LICENSE.md +1 -1
  29. zensical.libs/libgcc_s-f5fcfe20.so.1 +0 -0
  30. zensical/templates/assets/javascripts/bundle.3c403d54.min.js +0 -3
  31. zensical/templates/assets/stylesheets/classic/main.c5ffb0a9.min.css +0 -1
  32. zensical/templates/assets/stylesheets/modern/main.1357c24d.min.css +0 -1
  33. zensical.libs/libgcc_s-27e5a392.so.1 +0 -0
  34. {zensical-0.0.3.dist-info → zensical-0.0.12.dist-info}/entry_points.txt +0 -0
@@ -1,7 +1,7 @@
1
- # Copyright (c) Zensical LLC <https://zensical.org>
1
+ # Copyright (c) 2025 Zensical and contributors
2
2
 
3
3
  # SPDX-License-Identifier: MIT
4
- # Third-party contributions licensed under CLA
4
+ # Third-party contributions licensed under DCO
5
5
 
6
6
  # Permission is hereby granted, free of charge, to any person obtaining a copy
7
7
  # of this software and associated documentation files (the "Software"), to
@@ -1,7 +1,7 @@
1
- # Copyright (c) Zensical LLC <https://zensical.org>
1
+ # Copyright (c) 2025 Zensical and contributors
2
2
 
3
3
  # SPDX-License-Identifier: MIT
4
- # Third-party contributions licensed under CLA
4
+ # Third-party contributions licensed under DCO
5
5
 
6
6
  # Permission is hereby granted, free of charge, to any person obtaining a copy
7
7
  # of this software and associated documentation files (the "Software"), to
@@ -26,21 +26,22 @@ from __future__ import annotations
26
26
  import codecs
27
27
  import functools
28
28
  import os
29
-
30
29
  from glob import iglob
31
- from markdown import Markdown
32
- from pymdownx import emoji, twemoji_db
30
+ from typing import TYPE_CHECKING
33
31
  from xml.etree.ElementTree import Element
34
32
 
33
+ from pymdownx import emoji, twemoji_db
34
+
35
+ if TYPE_CHECKING:
36
+ from markdown import Markdown
37
+
35
38
  # -----------------------------------------------------------------------------
36
39
  # Functions
37
40
  # -----------------------------------------------------------------------------
38
41
 
39
42
 
40
- def twemoji(options: object, md: Markdown):
41
- """
42
- Create twemoji index.
43
- """
43
+ def twemoji(options: dict, md: Markdown) -> dict: # noqa: ARG001
44
+ """Create twemoji index."""
44
45
  paths = options.get("custom_icons", [])[:]
45
46
  return _load_twemoji_index(tuple(paths))
46
47
 
@@ -53,14 +54,12 @@ def to_svg(
53
54
  alt: str,
54
55
  title: str,
55
56
  category: str,
56
- options: object,
57
+ options: dict,
57
58
  md: Markdown,
58
- ):
59
- """
60
- Load icon.
61
- """
59
+ ) -> Element[str]:
60
+ """Load icon."""
62
61
  if not uc:
63
- icons = md.inlinePatterns["emoji"].emoji_index["emoji"]
62
+ icons = md.inlinePatterns["emoji"].emoji_index["emoji"] # type: ignore[attr-defined]
64
63
 
65
64
  # Create and return element to host icon
66
65
  el = Element("span", {"class": options.get("classes", index)})
@@ -78,20 +77,16 @@ def to_svg(
78
77
  # -----------------------------------------------------------------------------
79
78
 
80
79
 
81
- @functools.lru_cache(maxsize=None)
82
- def _load(file: str):
83
- """
84
- Load icon from file.
85
- """
80
+ @functools.cache
81
+ def _load(file: str) -> str:
82
+ """Load icon from file."""
86
83
  with codecs.open(file, encoding="utf-8") as f:
87
84
  return f.read()
88
85
 
89
86
 
90
- @functools.lru_cache(maxsize=None)
91
- def _load_twemoji_index(paths):
92
- """
93
- Load twemoji index and add icons.
94
- """
87
+ @functools.cache
88
+ def _load_twemoji_index(paths: tuple[str, ...]) -> dict:
89
+ """Load twemoji index and add icons."""
95
90
  index = {
96
91
  "name": "twemoji",
97
92
  "emoji": twemoji_db.emoji,
@@ -106,8 +101,8 @@ def _load_twemoji_index(paths):
106
101
 
107
102
  # Index icons provided by the theme and via custom icons
108
103
  glob = os.path.join(base, "**", "*.svg")
109
- glob = iglob(os.path.normpath(glob), recursive=True)
110
- for file in glob:
104
+ svgs = iglob(os.path.normpath(glob), recursive=True)
105
+ for file in svgs:
111
106
  icon = file[len(base) + 1 : -4].replace(os.path.sep, "-")
112
107
 
113
108
  # Add icon to index
@@ -1,7 +1,7 @@
1
- # Copyright (c) Zensical LLC <https://zensical.org>
1
+ # Copyright (c) 2025 Zensical and contributors
2
2
 
3
3
  # SPDX-License-Identifier: MIT
4
- # Third-party contributions licensed under CLA
4
+ # Third-party contributions licensed under DCO
5
5
 
6
6
  # Permission is hereby granted, free of charge, to any person obtaining a copy
7
7
  # of this software and associated documentation files (the "Software"), to
@@ -23,11 +23,17 @@
23
23
 
24
24
  from __future__ import annotations
25
25
 
26
+ from pathlib import PurePosixPath
27
+ from typing import TYPE_CHECKING
28
+ from urllib.parse import urlparse
29
+
26
30
  from markdown import Extension, Markdown
27
31
  from markdown.treeprocessors import Treeprocessor
28
32
  from markdown.util import AMP_SUBSTITUTE
29
- from xml.etree.ElementTree import Element
30
- from urllib.parse import urlparse
33
+
34
+ if TYPE_CHECKING:
35
+ from xml.etree.ElementTree import Element
36
+
31
37
 
32
38
  # -----------------------------------------------------------------------------
33
39
  # Classes
@@ -35,8 +41,7 @@ from urllib.parse import urlparse
35
41
 
36
42
 
37
43
  class LinksProcessor(Treeprocessor):
38
- """
39
- Tree processor to replace links in Markdown with URLs.
44
+ """Tree processor to replace links in Markdown with URLs.
40
45
 
41
46
  Note that we view this as a bandaid until we can do processing on proper
42
47
  HTML ASTs in Rust. In the meantime, we just replace them as we find them.
@@ -49,10 +54,10 @@ class LinksProcessor(Treeprocessor):
49
54
  self.path = path # Current page
50
55
  self.use_directory_urls = use_directory_urls
51
56
 
52
- def run(self, root: Element):
57
+ def run(self, root: Element) -> None:
53
58
  # Now, we determine whether the current page is an index page, as we
54
59
  # must apply slightly different handling in case of directory URLs
55
- current_is_index = self.path.endswith(("index.md", "README.md"))
60
+ current_is_index = get_name(self.path) in ("index.md", "README.md")
56
61
  for el in root.iter():
57
62
  # In case the element has a `href` or `src` attribute, we parse it
58
63
  # as an URL, so we can analyze and alter its path
@@ -63,7 +68,7 @@ class LinksProcessor(Treeprocessor):
63
68
  # Extract value - Python Markdown does some weird stuff where it
64
69
  # replaces mailto: links with double encoded entities. MkDocs just
65
70
  # skips if it detects that, so we do the same.
66
- value = el.get(key)
71
+ value = el.get(key, "")
67
72
  if AMP_SUBSTITUTE in value:
68
73
  continue
69
74
 
@@ -81,10 +86,9 @@ class LinksProcessor(Treeprocessor):
81
86
  if path.endswith(".md"):
82
87
  path = path.removesuffix(".md") + ".html"
83
88
  if self.use_directory_urls:
84
- if path.endswith("index.html"):
85
- path = path[: -len("index.html")]
86
- elif path.endswith("README.html"):
87
- path = path[: -len("README.html")]
89
+ name = get_name(path)
90
+ if name in ("index.html", "README.html"):
91
+ path = path[: -len(name)]
88
92
  elif path.endswith(".html"):
89
93
  path = path[: -len(".html")] + "/"
90
94
 
@@ -101,21 +105,15 @@ class LinksProcessor(Treeprocessor):
101
105
 
102
106
 
103
107
  class LinksExtension(Extension):
104
- """
105
- A Markdown extension to resolve links to other Markdown files.
106
- """
108
+ """A Markdown extension to resolve links to other Markdown files."""
107
109
 
108
110
  def __init__(self, path: str, use_directory_urls: bool):
109
- """
110
- Initialize the extension.
111
- """
111
+ """Initialize the extension."""
112
112
  self.path = path # Current page
113
113
  self.use_directory_urls = use_directory_urls
114
114
 
115
- def extendMarkdown(self, md: Markdown):
116
- """
117
- Register Markdown extension.
118
- """
115
+ def extendMarkdown(self, md: Markdown) -> None: # noqa: N802
116
+ """Register Markdown extension."""
119
117
  md.registerExtension(self)
120
118
 
121
119
  # Create and register treeprocessor - we use the same priority as the
@@ -123,4 +121,15 @@ class LinksExtension(Extension):
123
121
  # after our treeprocessor, so we can check the original Markdown URIs
124
122
  # before they are resolved to URLs.
125
123
  processor = LinksProcessor(md, self.path, self.use_directory_urls)
126
- md.treeprocessors.register(processor, "relpath", 0)
124
+ md.treeprocessors.register(processor, "zrelpath", 0)
125
+
126
+
127
+ # -----------------------------------------------------------------------------
128
+ # Functions
129
+ # -----------------------------------------------------------------------------
130
+
131
+
132
+ def get_name(path: str) -> str:
133
+ """Get the name of a file from a given path."""
134
+ pure_path = PurePosixPath(path)
135
+ return pure_path.name
@@ -1,7 +1,7 @@
1
- # Copyright (c) Zensical LLC <https://zensical.org>
1
+ # Copyright (c) 2025 Zensical and contributors
2
2
 
3
3
  # SPDX-License-Identifier: MIT
4
- # Third-party contributions licensed under CLA
4
+ # Third-party contributions licensed under DCO
5
5
 
6
6
  # Permission is hereby granted, free of charge, to any person obtaining a copy
7
7
  # of this software and associated documentation files (the "Software"), to
@@ -24,14 +24,17 @@
24
24
  from __future__ import annotations
25
25
 
26
26
  import posixpath
27
+ from typing import TYPE_CHECKING, Any
28
+ from urllib.parse import urlparse
27
29
 
28
30
  from markdown import Extension, Markdown
29
31
  from markdown.treeprocessors import Treeprocessor
30
- from urllib.parse import urlparse
31
- from xml.etree.ElementTree import Element
32
32
 
33
- from .links import LinksProcessor
34
- from .utilities.filter import Filter
33
+ from zensical.extensions.links import LinksProcessor
34
+ from zensical.extensions.utilities.filter import Filter
35
+
36
+ if TYPE_CHECKING:
37
+ from xml.etree.ElementTree import Element
35
38
 
36
39
  # -----------------------------------------------------------------------------
37
40
  # Classes
@@ -39,25 +42,20 @@ from .utilities.filter import Filter
39
42
 
40
43
 
41
44
  class PreviewProcessor(Treeprocessor):
42
- """
43
- A Markdown treeprocessor to enable instant previews on links.
45
+ """A Markdown treeprocessor to enable instant previews on links.
44
46
 
45
47
  Note that this treeprocessor is dependent on the `links` treeprocessor
46
48
  registered programmatically before rendering a page.
47
49
  """
48
50
 
49
51
  def __init__(self, md: Markdown, config: dict):
50
- """
51
- Initialize the treeprocessor.
52
- """
52
+ """Initialize the treeprocessor."""
53
53
  super().__init__(md)
54
54
  self.config = config
55
55
 
56
- def run(self, root: Element):
57
- """
58
- Run the treeprocessor.
59
- """
60
- at = self.md.treeprocessors.get_index_for_name("relpath")
56
+ def run(self, root: Element) -> None:
57
+ """Run the treeprocessor."""
58
+ at = self.md.treeprocessors.get_index_for_name("zrelpath")
61
59
 
62
60
  # Hack: Python Markdown has no notion of where it is, i.e., which file
63
61
  # is being processed. This seems to be a deliberate design decision, as
@@ -84,9 +82,10 @@ class PreviewProcessor(Treeprocessor):
84
82
  # Walk through all configurations - @todo refactor so that we don't
85
83
  # iterate multiple times over the same elements
86
84
  for configuration in configurations:
87
- if not configuration.get("sources"):
88
- if not configuration.get("targets"):
89
- continue
85
+ if not configuration.get("sources") and not configuration.get(
86
+ "targets"
87
+ ):
88
+ continue
90
89
 
91
90
  # Skip if page should not be considered
92
91
  filter = get_filter(configuration, "sources")
@@ -123,8 +122,7 @@ class PreviewProcessor(Treeprocessor):
123
122
 
124
123
 
125
124
  class PreviewExtension(Extension):
126
- """
127
- A Markdown extension to enable instant previews on links.
125
+ """A Markdown extension to enable instant previews on links.
128
126
 
129
127
  This extensions allows to automatically add the `data-preview` attribute to
130
128
  internal links matching specific criteria, so Material for MkDocs renders a
@@ -132,10 +130,8 @@ class PreviewExtension(Extension):
132
130
  add previews to links in a programmatic way.
133
131
  """
134
132
 
135
- def __init__(self, *args, **kwargs):
136
- """
137
- Initialize the extension.
138
- """
133
+ def __init__(self, *args: Any, **kwargs: Any) -> None:
134
+ """Initialize the extension."""
139
135
  self.config = {
140
136
  "configurations": [[], "Filter configurations"],
141
137
  "sources": [{}, "Link sources"],
@@ -143,10 +139,8 @@ class PreviewExtension(Extension):
143
139
  }
144
140
  super().__init__(*args, **kwargs)
145
141
 
146
- def extendMarkdown(self, md: Markdown):
147
- """
148
- Register Markdown extension.
149
- """
142
+ def extendMarkdown(self, md: Markdown) -> None: # noqa: N802
143
+ """Register Markdown extension."""
150
144
  md.registerExtension(self)
151
145
 
152
146
  # Create and register treeprocessor - we use the same priority as the
@@ -162,17 +156,13 @@ class PreviewExtension(Extension):
162
156
  # -----------------------------------------------------------------------------
163
157
 
164
158
 
165
- def get_filter(settings: dict, key: str):
166
- """
167
- Get file filter from settings.
168
- """
169
- return Filter(config=settings.get(key)) # type: ignore
159
+ def get_filter(settings: dict, key: str) -> Filter:
160
+ """Get file filter from settings."""
161
+ return Filter(config=settings.get(key, {}))
170
162
 
171
163
 
172
164
  def resolve(processor_path: str, url_path: str) -> str:
173
- """
174
- Resolve a relative URL path against the processor path.
175
- """
165
+ """Resolve a relative URL path against the processor path."""
176
166
  # Remove the file name from the processor path to get the directory
177
167
  base_path = posixpath.dirname(processor_path)
178
168
 
@@ -194,8 +184,6 @@ def resolve(processor_path: str, url_path: str) -> str:
194
184
  return posixpath.join(*base_segments)
195
185
 
196
186
 
197
- def makeExtension(**kwargs):
198
- """
199
- Register Markdown extension.
200
- """
187
+ def makeExtension(**kwargs: Any) -> PreviewExtension: # noqa: N802
188
+ """Register Markdown extension."""
201
189
  return PreviewExtension(**kwargs)