From b2b6d21207bb0645799f5b26413de10d49ed64f0 Mon Sep 17 00:00:00 2001 From: Valentin Berlier Date: Fri, 5 Nov 2021 19:55:55 +0100 Subject: [PATCH] feat: add dynamic directive resolvers --- examples/with_beet/beet.json | 14 ++ examples/with_beet/isolated/message_test.md | 13 ++ lectern/contrib/relative_location.py | 4 +- lectern/contrib/yaml_to_json.py | 4 +- lectern/directive.py | 158 ++++++------------ lectern/document.py | 34 ++-- lectern/prefetch.py | 4 +- lectern/serialize.py | 92 ++++++---- poetry.lock | 23 +-- pyproject.toml | 2 +- .../examples__beet_project__0.pack.md | 10 ++ tests/test_directive.py | 4 +- 12 files changed, 176 insertions(+), 186 deletions(-) create mode 100644 examples/with_beet/isolated/message_test.md diff --git a/examples/with_beet/beet.json b/examples/with_beet/beet.json index aab038a..c0cc9aa 100644 --- a/examples/with_beet/beet.json +++ b/examples/with_beet/beet.json @@ -32,6 +32,20 @@ "load": ["isolated/plugin_test.md"] } } + }, + { + "require": ["beet.contrib.messages"], + "pipeline": ["lectern", "beet.contrib.render"], + "meta": { + "lectern": { + "load": ["isolated/message_test.md"] + }, + "render": { + "data_pack": { + "functions": ["*"] + } + } + } } ], "meta": { diff --git a/examples/with_beet/isolated/message_test.md b/examples/with_beet/isolated/message_test.md new file mode 100644 index 0000000..0158e1b --- /dev/null +++ b/examples/with_beet/isolated/message_test.md @@ -0,0 +1,13 @@ +# Example with data pack messages + +`@message isolated:my_greeting` + +```json +["", { "text": "hello", "color": "red" }] +``` + +`@function isolated:message_demo` + +```mcfunction +tellraw @a {{ "isolated:my_greeting" | msg }} +``` diff --git a/lectern/contrib/relative_location.py b/lectern/contrib/relative_location.py index 6deadc2..f606b94 100644 --- a/lectern/contrib/relative_location.py +++ b/lectern/contrib/relative_location.py @@ -11,7 +11,7 @@ from beet import Context -from lectern import AnyDirective, Document, Fragment, NamespacedResourceDirective +from lectern import Directive, Document, Fragment, NamespacedResourceDirective def beet_default(ctx: Context): @@ -28,7 +28,7 @@ class RelativeNamespacedResourceLoader: def __call__( self, fragment: Fragment, - directives: Mapping[str, AnyDirective], + directives: Mapping[str, Directive], ) -> Fragment: if isinstance(directives[fragment.directive], NamespacedResourceDirective): name = fragment.expect("name") diff --git a/lectern/contrib/yaml_to_json.py b/lectern/contrib/yaml_to_json.py index 383373a..5a82ccb 100644 --- a/lectern/contrib/yaml_to_json.py +++ b/lectern/contrib/yaml_to_json.py @@ -13,8 +13,8 @@ from beet import Context, JsonFile from lectern import ( - AnyDirective, DataPackDirective, + Directive, Document, Fragment, NamespacedResourceDirective, @@ -27,7 +27,7 @@ def beet_default(ctx: Context): document.loaders.append(handle_yaml) -def handle_yaml(fragment: Fragment, directives: Mapping[str, AnyDirective]) -> Fragment: +def handle_yaml(fragment: Fragment, directives: Mapping[str, Directive]) -> Fragment: """Loader that converts yaml to json.""" directive = directives[fragment.directive] is_yaml = False diff --git a/lectern/directive.py b/lectern/directive.py index 68d0fcd..7edcac3 100644 --- a/lectern/directive.py +++ b/lectern/directive.py @@ -1,75 +1,24 @@ __all__ = [ "Directive", - "AnyDirective", + "DirectiveRegistry", "NamespacedResourceDirective", "DataPackDirective", "ResourcePackDirective", "BundleFragmentMixin", "SkipDirective", - "get_builtin_directives", ] import io from dataclasses import dataclass -from typing import Any, Dict, Protocol, Type, Union +from typing import Any, Callable, Dict, List, Optional, Protocol, Type from zipfile import ZipFile -from beet import DataPack, ResourcePack -from beet.library.base import NamespaceFile -from beet.library.data_pack import ( - Advancement, - Biome, - BlockTag, - ConfiguredCarver, - ConfiguredFeature, - ConfiguredStructureFeature, - ConfiguredSurfaceBuilder, - Dimension, - DimensionType, - EntityTypeTag, - FluidTag, - Function, - FunctionTag, - ItemModifier, - ItemTag, - LootTable, - NoiseSettings, - Predicate, - ProcessorList, - Recipe, - Structure, - TemplatePool, -) -from beet.library.resource_pack import ( - Blockstate, - Font, - FragmentShader, - GlslShader, - GlyphSizeFile, - Language, - Model, - Particle, - Shader, - ShaderPost, - Sound, - Text, - Texture, - TextureMcmeta, - TrueTypeFont, - VertexShader, -) +from beet import Container, DataPack, NamespaceFile, ResourcePack +from beet.core.utils import snake_case from .fragment import Fragment -AnyDirective = Union[ - "Directive", - "NamespacedResourceDirective", - "DataPackDirective", - "ResourcePackDirective", - "SkipDirective", -] - class Directive(Protocol): """Protocol for detecting directives.""" @@ -78,6 +27,53 @@ def __call__(self, fragment: Fragment, assets: ResourcePack, data: DataPack): ... +class DirectiveRegistry(Container[str, Directive]): + """Registry for directives.""" + + resolvers: List[Callable[["DirectiveRegistry"], Any]] + assets: ResourcePack + data: DataPack + + def __init__( + self, + assets: Optional[ResourcePack] = None, + data: Optional[DataPack] = None, + ): + super().__init__() + self.resolvers = [] + self.assets = assets or ResourcePack() + self.data = data or DataPack() + + self["data_pack"] = DataPackDirective() + self["resource_pack"] = ResourcePackDirective() + self["skip"] = SkipDirective() + + @self.add_resolver + def _(self: DirectiveRegistry): + for pack in [self.assets, self.data]: + for file_type in pack.resolve_scope_map().values(): + name = snake_case(file_type.__name__) + self[name] = NamespacedResourceDirective(file_type) + + def resolve(self) -> "DirectiveRegistry": + """Resolve all directives in the registry.""" + for callback in self.resolvers: + callback(self) + return self + + def add_resolver(self, resolver: Callable[["DirectiveRegistry"], Any]): + """Add directive resolver.""" + self.resolvers.append(resolver) + + def get_serialization_mapping(self) -> Dict[Type[NamespaceFile], str]: + """Return the serialization mapping.""" + return { + directive.file_type: directive_name + for directive_name, directive in self.items() + if isinstance(directive, NamespacedResourceDirective) + } + + @dataclass class NamespacedResourceDirective: """Directive for including namespaced resources.""" @@ -141,55 +137,3 @@ class SkipDirective: def __call__(self, fragment: Fragment, assets: ResourcePack, data: DataPack): fragment.expect() - - -def get_builtin_directives() -> Dict[str, AnyDirective]: - """Return the built-in directives.""" - return { - # fmt: off - "advancement": NamespacedResourceDirective(Advancement), - "function": NamespacedResourceDirective(Function), - "loot_table": NamespacedResourceDirective(LootTable), - "predicate": NamespacedResourceDirective(Predicate), - "recipe": NamespacedResourceDirective(Recipe), - "structure": NamespacedResourceDirective(Structure), - "block_tag": NamespacedResourceDirective(BlockTag), - "entity_type_tag": NamespacedResourceDirective(EntityTypeTag), - "fluid_tag": NamespacedResourceDirective(FluidTag), - "function_tag": NamespacedResourceDirective(FunctionTag), - "item_tag": NamespacedResourceDirective(ItemTag), - "dimension_type": NamespacedResourceDirective(DimensionType), - "dimension": NamespacedResourceDirective(Dimension), - "biome": NamespacedResourceDirective(Biome), - "configured_carver": NamespacedResourceDirective(ConfiguredCarver), - "configured_feature": NamespacedResourceDirective(ConfiguredFeature), - "configured_structure_feature": NamespacedResourceDirective(ConfiguredStructureFeature), - "configured_surface_builder": NamespacedResourceDirective(ConfiguredSurfaceBuilder), - "noise_settings": NamespacedResourceDirective(NoiseSettings), - "processor_list": NamespacedResourceDirective(ProcessorList), - "template_pool": NamespacedResourceDirective(TemplatePool), - "item_modifier": NamespacedResourceDirective(ItemModifier), - - "blockstate": NamespacedResourceDirective(Blockstate), - "model": NamespacedResourceDirective(Model), - "language": NamespacedResourceDirective(Language), - "font": NamespacedResourceDirective(Font), - "glyph_sizes": NamespacedResourceDirective(GlyphSizeFile), - "truetype_font": NamespacedResourceDirective(TrueTypeFont), - "shader_post": NamespacedResourceDirective(ShaderPost), - "shader": NamespacedResourceDirective(Shader), - "fragment_shader": NamespacedResourceDirective(FragmentShader), - "vertex_shader": NamespacedResourceDirective(VertexShader), - "glsl_shader": NamespacedResourceDirective(GlslShader), - "text": NamespacedResourceDirective(Text), - "texture_mcmeta": NamespacedResourceDirective(TextureMcmeta), - "texture": NamespacedResourceDirective(Texture), - "sound": NamespacedResourceDirective(Sound), - "particle": NamespacedResourceDirective(Particle), - - "data_pack": DataPackDirective(), - "resource_pack": ResourcePackDirective(), - - "skip": SkipDirective(), - # fmt: on - } diff --git a/lectern/document.py b/lectern/document.py index 8c59c70..6b7fe68 100644 --- a/lectern/document.py +++ b/lectern/document.py @@ -5,22 +5,12 @@ from dataclasses import InitVar, dataclass, field from pathlib import Path -from typing import ( - Any, - Dict, - List, - Literal, - MutableMapping, - Optional, - Tuple, - Union, - overload, -) +from typing import Any, Dict, List, Literal, Optional, Tuple, Union, overload from beet import Cache, Context, DataPack, File, ResourcePack from beet.core.utils import FileSystemPath, extra_field -from .directive import AnyDirective, get_builtin_directives +from .directive import DirectiveRegistry from .extract import FragmentLoader, MarkdownExtractor, TextExtractor from .serialize import ExternalFilesManager, MarkdownSerializer, TextSerializer @@ -40,9 +30,7 @@ class Document: data: DataPack = field(default_factory=DataPack) loaders: List[FragmentLoader] = extra_field(default_factory=list) - directives: MutableMapping[str, AnyDirective] = extra_field( - default_factory=get_builtin_directives - ) + directives: DirectiveRegistry = extra_field(default_factory=DirectiveRegistry) text_extractor: TextExtractor = extra_field(default_factory=TextExtractor) markdown_extractor: MarkdownExtractor = extra_field( @@ -68,9 +56,14 @@ def __post_init__( self.data = ctx.data if cache is None: cache = ctx.cache["lectern"] + if cache: self.text_extractor.cache = cache self.markdown_extractor.cache = cache + + self.directives.assets = self.assets + self.directives.data = self.data + if path: self.load(path) if text: @@ -90,7 +83,7 @@ def add_text(self, source: str): """Extract pack fragments from plain text.""" assets, data = self.text_extractor.extract( source=source, - directives=self.directives, + directives=self.directives.resolve(), loaders=self.loaders, ) self.assets.merge(assets) @@ -104,7 +97,7 @@ def add_markdown( """Extract pack fragments from markdown.""" assets, data = self.markdown_extractor.extract( source=source, - directives=self.directives, + directives=self.directives.resolve(), loaders=self.loaders, external_files=external_files, ) @@ -113,7 +106,11 @@ def add_markdown( def get_text(self) -> str: """Turn the data pack and the resource pack into text.""" - return self.text_serializer.serialize(self.assets, self.data) + return self.text_serializer.serialize( + assets=self.assets, + data=self.data, + mapping=self.directives.resolve().get_serialization_mapping(), + ) @overload def get_markdown( @@ -140,6 +137,7 @@ def get_markdown( content = self.markdown_serializer.serialize( assets=self.assets, data=self.data, + mapping=self.directives.resolve().get_serialization_mapping(), external_files=external_files, external_prefix=prefix, ) diff --git a/lectern/prefetch.py b/lectern/prefetch.py index 2275109..6fcda58 100644 --- a/lectern/prefetch.py +++ b/lectern/prefetch.py @@ -10,7 +10,7 @@ from beet import BinaryFile, Cache, File from beet.core.utils import FileSystemPath -from .directive import Directive, get_builtin_directives +from .directive import Directive, DirectiveRegistry from .extract import MarkdownExtractor from .fragment import Fragment from .serialize import ExternalFilesManager, SerializedFile @@ -37,7 +37,7 @@ def process_file( ): """Prefetch urls in the specified document.""" if directives is None: - directives = get_builtin_directives() + directives = DirectiveRegistry().resolve() path = Path(path).resolve() output = Path(output).resolve() diff --git a/lectern/serialize.py b/lectern/serialize.py index b6becf1..7559ee1 100644 --- a/lectern/serialize.py +++ b/lectern/serialize.py @@ -3,7 +3,6 @@ "MarkdownSerializer", "ExternalFilesManager", "SerializedFile", - "NAMESPACED_RESOURCE_DIRECTIVES", "EXTENSION_HIGHLIGHTING", ] @@ -15,20 +14,12 @@ from mimetypes import guess_type from pathlib import Path from textwrap import indent -from typing import Any, Dict, Iterable, Iterator, Optional, Union +from typing import Any, Dict, Iterable, Iterator, Mapping, Optional, Type, Union from urllib.parse import urlparse from beet import DataPack, File, NamespaceFile, ResourcePack, TextFileBase from beet.core.utils import normalize_string -from .directive import NamespacedResourceDirective, get_builtin_directives - -NAMESPACED_RESOURCE_DIRECTIVES = { - directive.file_type: directive_name - for directive_name, directive in get_builtin_directives().items() - if isinstance(directive, NamespacedResourceDirective) -} - EXTENSION_HIGHLIGHTING = { ".mcfunction": "mcfunction", ".json": "json", @@ -132,19 +123,35 @@ def generate_link_target( class TextSerializer: """Document serializer that outputs plain text.""" - escaped_regex: "re.Pattern[str]" + escaped_regex: Optional["re.Pattern[str]"] def __init__(self): - names = "|".join( - [*NAMESPACED_RESOURCE_DIRECTIVES.values(), "resource_pack", "data_pack"] - ) - self.escaped_regex = re.compile(fr"^(@+(?:{names})\b.*)$", flags=re.MULTILINE) + self.escaped_regex = None + + def get_escaped_regex( + self, mapping: Mapping[Type[NamespaceFile], str] + ) -> "re.Pattern[str]": + """Create and return the escaped regex for the specified serialization mapping.""" + names = "|".join([*mapping.values(), "resource_pack", "data_pack"]) + pattern = fr"^(@+(?:{names})\b.*)$" + + if self.escaped_regex is None or self.escaped_regex.pattern != pattern: + self.escaped_regex = re.compile(pattern, flags=re.MULTILINE) + + return self.escaped_regex - def serialize(self, assets: ResourcePack, data: DataPack) -> str: + def serialize( + self, + assets: ResourcePack, + data: DataPack, + mapping: Mapping[Type[NamespaceFile], str], + ) -> str: """Return the serialized representation.""" + escaped_regex = self.get_escaped_regex(mapping) + return "\n".join( ( - f"@{directive_name} {argument}\n{self.escape_fragment(content)}" + f"@{directive_name} {argument}\n{self.escape_fragment(content, escaped_regex)}" if isinstance(content := file_instance.ensure_serialized(), str) else f"@{directive_name}(base64) {argument}\n" + b64encode(content).decode() @@ -171,9 +178,17 @@ def serialize(self, assets: ResourcePack, data: DataPack) -> str: ), ( ( - NAMESPACED_RESOURCE_DIRECTIVES[file_type], - f"{name}:{path}", - file_instance, + ( + mapping[file_type], + f"{name}:{path}", + file_instance, + ) + if file_type in mapping + else ( + extra_directive, + f"{namespace.directory}/{name}/{'/'.join(file_type.scope)}/{path}{file_type.extension}", + file_instance, + ) ) for name, namespace in pack.items() for file_type, container in namespace.items() @@ -182,11 +197,11 @@ def serialize(self, assets: ResourcePack, data: DataPack) -> str: ) ) - def escape_fragment(self, content: str) -> str: + def escape_fragment(self, content: str, escaped_regex: "re.Pattern[str]") -> str: """Escape embedded directives.""" return "".join( s.replace("@", "@@", 1) if i % 2 else s - for i, s in enumerate(self.escaped_regex.split(content)) + for i, s in enumerate(escaped_regex.split(content)) ) @@ -197,6 +212,7 @@ def serialize( self, assets: ResourcePack, data: DataPack, + mapping: Mapping[Type[NamespaceFile], str], external_files: Optional[Dict[str, File[Any, Any]]] = None, external_prefix: str = "", ) -> str: @@ -213,6 +229,7 @@ def serialize( title, directive, pack, + mapping, external_files, external_prefix, ) @@ -225,6 +242,7 @@ def serialize_pack( title: str, pack_directive: str, pack: Union[DataPack, ResourcePack], + mapping: Mapping[Type[NamespaceFile], str], external_files: Optional[Dict[str, File[Any, Any]]] = None, external_prefix: str = "", ) -> Iterator[str]: @@ -257,19 +275,27 @@ def serialize_pack( ) for file_type, container in namespace.items(): - directive_name = NAMESPACED_RESOURCE_DIRECTIVES[file_type] - for path, file_instance in container.items(): - yield from self.format_serialized_file( - self.serialize_file_instance( - directive_name, - f"{name}:{path}", - file_instance, - external_files, - external_prefix, + if file_type in mapping: + yield from self.format_serialized_file( + self.serialize_file_instance( + mapping[file_type], + f"{name}:{path}", + file_instance, + external_files, + external_prefix, + ) + ) + else: + yield from self.format_serialized_file( + self.serialize_file_instance( + pack_directive, + f"{namespace.directory}/{name}/{'/'.join(file_type.scope)}/{path}{file_type.extension}", + file_instance, + external_files, + external_prefix, + ) ) - ) - yield "" def format_serialized_file(self, chunks: Iterable[str]) -> Iterator[str]: diff --git a/poetry.lock b/poetry.lock index bdd8802..8599850 100644 --- a/poetry.lock +++ b/poetry.lock @@ -33,7 +33,7 @@ tests = ["pytest (>=4.6)", "pytest-flake8", "pytest-cov", "PyHamcrest (>=2.0.2)" [[package]] name = "beet" -version = "0.43.3" +version = "0.44.2" description = "The Minecraft pack development kit" category = "main" optional = false @@ -819,7 +819,7 @@ testing = ["pytest (>=4.6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytes [metadata] lock-version = "1.1" python-versions = "^3.8" -content-hash = "9841cf255e41f4c1ee420a6d6d55a098bc2a6f81123830d7aed0b43dab15ddd2" +content-hash = "1f8c8cb5c677099ece16af5b6c7ba6bc9633f87c1827087ac34ab847f11d0ff1" [metadata.files] atomicwrites = [ @@ -835,8 +835,8 @@ base58 = [ {file = "base58-2.1.0.tar.gz", hash = "sha256:171a547b4a3c61e1ae3807224a6f7aec75e364c4395e7562649d7335768001a2"}, ] beet = [ - {file = "beet-0.43.3-py3-none-any.whl", hash = "sha256:d9b50456915a0a4730acfd2dd8af34aae9e6a4929541ed4b8eaaa88e5c7300dd"}, - {file = "beet-0.43.3.tar.gz", hash = "sha256:7cd8238aa4aada077bd61964a30fe913fee9dc70cd67557bb8a1f6fad66f42eb"}, + {file = "beet-0.44.2-py3-none-any.whl", hash = "sha256:2e8f8c01401e312677e78fb73cd731a70752d7d0dc3709df00ef7f10ee57262f"}, + {file = "beet-0.44.2.tar.gz", hash = "sha256:d73c233754da23f008317693e8b3fb3c0cb2e1daefb9ae580dd8a0ef465c4511"}, ] black = [ {file = "black-21.10b0-py3-none-any.whl", hash = "sha256:6eb7448da9143ee65b856a5f3676b7dda98ad9abe0f87fce8c59291f15e82a5b"}, @@ -1005,9 +1005,6 @@ markupsafe = [ {file = "MarkupSafe-2.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2d7d807855b419fc2ed3e631034685db6079889a1f01d5d9dac950f764da3dad"}, {file = "MarkupSafe-2.0.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:add36cb2dbb8b736611303cd3bfcee00afd96471b09cda130da3581cbdc56a6d"}, {file = "MarkupSafe-2.0.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:168cd0a3642de83558a5153c8bd34f175a9a6e7f6dc6384b9655d2697312a646"}, - {file = "MarkupSafe-2.0.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:4dc8f9fb58f7364b63fd9f85013b780ef83c11857ae79f2feda41e270468dd9b"}, - {file = "MarkupSafe-2.0.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:20dca64a3ef2d6e4d5d615a3fd418ad3bde77a47ec8a23d984a12b5b4c74491a"}, - {file = "MarkupSafe-2.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:cdfba22ea2f0029c9261a4bd07e830a8da012291fbe44dc794e488b6c9bb353a"}, {file = "MarkupSafe-2.0.1-cp310-cp310-win32.whl", hash = "sha256:99df47edb6bda1249d3e80fdabb1dab8c08ef3975f69aed437cb69d0a5de1e28"}, {file = "MarkupSafe-2.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:e0f138900af21926a02425cf736db95be9f4af72ba1bb21453432a07f6082134"}, {file = "MarkupSafe-2.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:f9081981fe268bd86831e5c75f7de206ef275defcb82bc70740ae6dc507aee51"}, @@ -1019,9 +1016,6 @@ markupsafe = [ {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf5d821ffabf0ef3533c39c518f3357b171a1651c1ff6827325e4489b0e46c3c"}, {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:0d4b31cc67ab36e3392bbf3862cfbadac3db12bdd8b02a2731f509ed5b829724"}, {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:baa1a4e8f868845af802979fcdbf0bb11f94f1cb7ced4c4b8a351bb60d108145"}, - {file = "MarkupSafe-2.0.1-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:deb993cacb280823246a026e3b2d81c493c53de6acfd5e6bfe31ab3402bb37dd"}, - {file = "MarkupSafe-2.0.1-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:63f3268ba69ace99cab4e3e3b5840b03340efed0948ab8f78d2fd87ee5442a4f"}, - {file = "MarkupSafe-2.0.1-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:8d206346619592c6200148b01a2142798c989edcb9c896f9ac9722a99d4e77e6"}, {file = "MarkupSafe-2.0.1-cp36-cp36m-win32.whl", hash = "sha256:6c4ca60fa24e85fe25b912b01e62cb969d69a23a5d5867682dd3e80b5b02581d"}, {file = "MarkupSafe-2.0.1-cp36-cp36m-win_amd64.whl", hash = "sha256:b2f4bf27480f5e5e8ce285a8c8fd176c0b03e93dcc6646477d4630e83440c6a9"}, {file = "MarkupSafe-2.0.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:0717a7390a68be14b8c793ba258e075c6f4ca819f15edfc2a3a027c823718567"}, @@ -1033,9 +1027,6 @@ markupsafe = [ {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e9936f0b261d4df76ad22f8fee3ae83b60d7c3e871292cd42f40b81b70afae85"}, {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:2a7d351cbd8cfeb19ca00de495e224dea7e7d919659c2841bbb7f420ad03e2d6"}, {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:60bf42e36abfaf9aff1f50f52644b336d4f0a3fd6d8a60ca0d054ac9f713a864"}, - {file = "MarkupSafe-2.0.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:d6c7ebd4e944c85e2c3421e612a7057a2f48d478d79e61800d81468a8d842207"}, - {file = "MarkupSafe-2.0.1-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:f0567c4dc99f264f49fe27da5f735f414c4e7e7dd850cfd8e69f0862d7c74ea9"}, - {file = "MarkupSafe-2.0.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:89c687013cb1cd489a0f0ac24febe8c7a666e6e221b783e53ac50ebf68e45d86"}, {file = "MarkupSafe-2.0.1-cp37-cp37m-win32.whl", hash = "sha256:a30e67a65b53ea0a5e62fe23682cfe22712e01f453b95233b25502f7c61cb415"}, {file = "MarkupSafe-2.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:611d1ad9a4288cf3e3c16014564df047fe08410e628f89805e475368bd304914"}, {file = "MarkupSafe-2.0.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:5bb28c636d87e840583ee3adeb78172efc47c8b26127267f54a9c0ec251d41a9"}, @@ -1048,9 +1039,6 @@ markupsafe = [ {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6fcf051089389abe060c9cd7caa212c707e58153afa2c649f00346ce6d260f1b"}, {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:5855f8438a7d1d458206a2466bf82b0f104a3724bf96a1c781ab731e4201731a"}, {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:3dd007d54ee88b46be476e293f48c85048603f5f516008bee124ddd891398ed6"}, - {file = "MarkupSafe-2.0.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:aca6377c0cb8a8253e493c6b451565ac77e98c2951c45f913e0b52facdcff83f"}, - {file = "MarkupSafe-2.0.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:04635854b943835a6ea959e948d19dcd311762c5c0c6e1f0e16ee57022669194"}, - {file = "MarkupSafe-2.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:6300b8454aa6930a24b9618fbb54b5a68135092bc666f7b06901f897fa5c2fee"}, {file = "MarkupSafe-2.0.1-cp38-cp38-win32.whl", hash = "sha256:023cb26ec21ece8dc3907c0e8320058b2e0cb3c55cf9564da612bc325bed5e64"}, {file = "MarkupSafe-2.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:984d76483eb32f1bcb536dc27e4ad56bba4baa70be32fa87152832cdd9db0833"}, {file = "MarkupSafe-2.0.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:2ef54abee730b502252bcdf31b10dacb0a416229b72c18b19e24a4509f273d26"}, @@ -1063,9 +1051,6 @@ markupsafe = [ {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c47adbc92fc1bb2b3274c4b3a43ae0e4573d9fbff4f54cd484555edbf030baf1"}, {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:37205cac2a79194e3750b0af2a5720d95f786a55ce7df90c3af697bfa100eaac"}, {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:1f2ade76b9903f39aa442b4aadd2177decb66525062db244b35d71d0ee8599b6"}, - {file = "MarkupSafe-2.0.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:4296f2b1ce8c86a6aea78613c34bb1a672ea0e3de9c6ba08a960efe0b0a09047"}, - {file = "MarkupSafe-2.0.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:9f02365d4e99430a12647f09b6cc8bab61a6564363f313126f775eb4f6ef798e"}, - {file = "MarkupSafe-2.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5b6d930f030f8ed98e3e6c98ffa0652bdb82601e7a016ec2ab5d7ff23baa78d1"}, {file = "MarkupSafe-2.0.1-cp39-cp39-win32.whl", hash = "sha256:10f82115e21dc0dfec9ab5c0223652f7197feb168c940f3ef61563fc2d6beb74"}, {file = "MarkupSafe-2.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:693ce3f9e70a6cf7d2fb9e6c9d8b204b6b39897a2c4a1aa65728d5ac97dcc1d8"}, {file = "MarkupSafe-2.0.1.tar.gz", hash = "sha256:594c67807fb16238b30c44bdf74f36c02cdf22d1c8cda91ef8a0ed8dabf5620a"}, diff --git a/pyproject.toml b/pyproject.toml index b3c6b3c..6cb9252 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -25,7 +25,7 @@ include = ["lectern/py.typed"] [tool.poetry.dependencies] python = "^3.8" -beet = ">=0.40.1" +beet = ">=0.44.2" markdown-it-py = "^1.1.0" click = "^8.0.1" diff --git a/tests/snapshots/examples__beet_project__0.pack.md b/tests/snapshots/examples__beet_project__0.pack.md index d375001..39d4dc6 100644 --- a/tests/snapshots/examples__beet_project__0.pack.md +++ b/tests/snapshots/examples__beet_project__0.pack.md @@ -477,6 +477,16 @@ +- `@function isolated:message_demo` + +
+ + ```mcfunction + tellraw @a ["", {"text": "hello", "color": "red"}] + ``` + +
+ ## Resource pack - `@resource_pack pack.mcmeta` diff --git a/tests/test_directive.py b/tests/test_directive.py index d11f2ce..d08e7ed 100644 --- a/tests/test_directive.py +++ b/tests/test_directive.py @@ -1,6 +1,6 @@ import pytest -from lectern import Fragment, TextExtractor, get_builtin_directives +from lectern import DirectiveRegistry, Fragment, TextExtractor @pytest.mark.parametrize( @@ -24,6 +24,6 @@ ) def test_parse(source: str, fragment: Fragment): parsed_fragment = next( - TextExtractor().parse_fragments(source, get_builtin_directives()) + TextExtractor().parse_fragments(source, DirectiveRegistry().resolve()) ) assert fragment == parsed_fragment