zig-codeblocks
Advanced tools
+14
-1
@@ -8,2 +8,14 @@ # Changelog | ||
| ## [v0.1.2] - 2025-02-09 | ||
| ### Added | ||
| - Character literal highlighting | ||
| ### Changed | ||
| - Public API functions can now operate on `bytes` objects | ||
| - Improved code block extraction on Windows | ||
| ### Fixed | ||
| - Multi-byte characters no longer derail the highlighter | ||
| ## [v0.1.1] - 2025-02-08 | ||
@@ -20,2 +32,3 @@ | ||
| [v0.1.0]: https://github.com/trag1c/zig-codeblocks/releases/tag/v0.1.0 | ||
| [v0.1.1]: https://github.com/trag1c/ixia/compare/v0.1.0...v0.1.1 | ||
| [v0.1.1]: https://github.com/trag1c/ixia/compare/v0.1.0...v0.1.1 | ||
| [v0.1.2]: https://github.com/trag1c/ixia/compare/v0.1.1...v0.1.2 |
+1
-1
| Metadata-Version: 2.4 | ||
| Name: zig-codeblocks | ||
| Version: 0.1.1 | ||
| Version: 0.1.2 | ||
| Summary: Zig ANSI syntax highlighting library | ||
@@ -5,0 +5,0 @@ Project-URL: repository, https://github.com/trag1c/zig-codeblocks |
+1
-1
| [project] | ||
| name = "zig-codeblocks" | ||
| version = "0.1.1" | ||
| version = "0.1.2" | ||
| description = "Zig ANSI syntax highlighting library" | ||
@@ -5,0 +5,0 @@ readme = "README.md" |
@@ -72,3 +72,5 @@ from __future__ import annotations | ||
| ZIG_NUMERIC_TOKENS = frozenset({"integer", "float"}) | ||
| ZIG_STRING_TOKENS = frozenset({"string_content", "multiline_string", '"'}) | ||
| ZIG_STRING_TOKENS = frozenset( | ||
| {"string_content", "multiline_string", '"', "'", "character_content"} | ||
| ) | ||
@@ -122,3 +124,3 @@ _KIND_MAPPINGS = { | ||
| def _process_zig_tokens(source: str, tokens: Iterator[Token]) -> str: | ||
| def _process_zig_tokens(source: bytes, tokens: Iterator[Token]) -> str: | ||
| body: Body = [] | ||
@@ -133,3 +135,3 @@ pointer = 0 | ||
| _adjust_reset(body) | ||
| body.append(filler) | ||
| body.append(filler.decode()) | ||
| pointer = token.byte_range.start | ||
@@ -170,12 +172,20 @@ | ||
| def highlight_zig_code(source: str) -> str: | ||
| """Return an ANSI syntax-highlighted version of the given Zig source code.""" | ||
| def highlight_zig_code(source: str | bytes) -> str: | ||
| """ | ||
| Return an ANSI syntax-highlighted version of the given Zig source code. | ||
| Assumes UTF-8 if source is `bytes`. | ||
| """ | ||
| if isinstance(source, str): | ||
| source = source.encode() | ||
| return _process_zig_tokens(source, tokenize_zig(source)) | ||
| def process_markdown(source: str, *, only_code: bool = False) -> str: | ||
| def process_markdown(source: str | bytes, *, only_code: bool = False) -> str: | ||
| """ | ||
| Return a Markdown source with Zig code blocks syntax-highlighted. | ||
| If `only_code` is True, only processed Zig code blocks will be returned. | ||
| Assumes UTF-8 if source is `bytes`. | ||
| """ | ||
| if isinstance(source, bytes): | ||
| source = source.decode() | ||
| zig_codeblocks = ( | ||
@@ -182,0 +192,0 @@ block.body for block in extract_codeblocks(source) if block.lang == "zig" |
@@ -10,3 +10,3 @@ import re | ||
| CODE_BLOCK_PATTERN = re.compile( | ||
| r"```(?:([A-Za-z0-9\-_\+\.#]+)\n+([^\n].+?)|(.*?))```", re.DOTALL | ||
| r"```(?:([A-Za-z0-9\-_\+\.#]+)(?:\r?\n)+([^\r\n].+?)|(.*?))```", re.DOTALL | ||
| ) | ||
@@ -30,15 +30,16 @@ | ||
| def extract_codeblocks(source: str) -> Iterator[CodeBlock]: | ||
| """Yield CodeBlocks from a Markdown source.""" | ||
| def extract_codeblocks(source: str | bytes) -> Iterator[CodeBlock]: | ||
| """Yield CodeBlocks from a Markdown source. Assumes UTF-8 if source is `bytes`.""" | ||
| if isinstance(source, bytes): | ||
| source = source.decode() | ||
| for m in CODE_BLOCK_PATTERN.finditer(source): | ||
| lang, body, no_lang_body = m.groups() | ||
| yield ( | ||
| CodeBlock(lang, body=body.strip("\n")) | ||
| CodeBlock(lang, body=body.strip("\r\n")) | ||
| if lang | ||
| else CodeBlock(lang=None, body=no_lang_body.strip("\n")) | ||
| else CodeBlock(lang=None, body=no_lang_body.strip("\r\n")) | ||
| ) | ||
| def tokenize_zig(source: str) -> Iterator[Token]: | ||
| src = source.encode() | ||
| def tokenize_zig(src: bytes) -> Iterator[Token]: | ||
| tree = ZIG_PARSER.parse(src) | ||
@@ -45,0 +46,0 @@ return _traverse(tree.root_node, src) |
@@ -21,7 +21,8 @@ from pathlib import Path | ||
| def test_codeblock_spacing_scenarios(file_name: str) -> None: | ||
| src = (SOURCE_DIR / "spacing" / file_name).read_text() | ||
| assert list(extract_codeblocks(src)) == [ | ||
| CodeBlock(lang="py", body="print(1)"), | ||
| CodeBlock(lang="zig", body='const std = @import("std");'), | ||
| ] | ||
| src = SOURCE_DIR / "spacing" / file_name | ||
| for meth in (Path.read_text, Path.read_bytes): | ||
| assert list(extract_codeblocks(meth(src))) == [ | ||
| CodeBlock(lang="py", body="print(1)"), | ||
| CodeBlock(lang="zig", body='const std = @import("std");'), | ||
| ] | ||
@@ -42,5 +43,4 @@ | ||
| def test_codeblock_with_language(source: str, expected: tuple[str | None, str]) -> None: | ||
| print((source, expected)) | ||
| codeblocks = list(extract_codeblocks(f"```{source}```")) | ||
| assert len(codeblocks) == 1 | ||
| assert codeblocks[0] == CodeBlock(*expected) |
+1
-1
@@ -316,3 +316,3 @@ version = 1 | ||
| name = "zig-codeblocks" | ||
| version = "0.1.1" | ||
| version = "0.1.2" | ||
| source = { editable = "." } | ||
@@ -319,0 +319,0 @@ dependencies = [ |
Sorry, the diff of this file is not supported yet
-16
| import zig_codeblocks as zc | ||
| src = """ | ||
| ```zig | ||
| /// The health status of a renderer. These must be shared across all | ||
| /// renderers even if some states aren't reachable so that our API users | ||
| /// can use the same enum for all renderers. | ||
| ``````zig | ||
| pub const Health = enum(c_int) { | ||
| healthy = 0, | ||
| unhealthy = 1, | ||
| }; | ||
| ``` | ||
| """ | ||
| print(list(zc.extract_codeblocks(src))) |
Alert delta unavailable
Currently unable to show alert delta for PyPI packages.
589463
-8.23%26
-7.14%305
-0.97%