Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions noxfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -271,12 +271,27 @@ def dummy_setup(session: nox.Session):
"--data=multiloader=false",
)

# Example image:
# PNG image, 16x16, 1-bit indexed color
# Palette: 0 = #202020 1 = #50ff50 (green)
# No compression, filter 0 on all scanlines (none)
image = (
b"\x89PNG\r\n\x1a\n"
b"\0\0\0\x0dIHDR\0\0\0\x10\0\0\0\x10\x01\x03\0\0\0\x25\x3d\x6d\x22"
b"\0\0\0\x06PLTE\x22\x22\x22\x50\xff\x50\xca\xca\x84\x15"
b"\0\0\0\x3bIDAT\x78\x01\x01\x30\0\xcf\xff\0\0\0\0\x7f\xfe\0\x40\x02\0\x40\x02\0\x40\x02\0\x40\x02\0\x40\x02\0\x40\x02\0\x40\x02\0\x40\x02\0\x40\x02\0\x40\x02\0\x40\x02\0\x40\x02\0\x7f\xfe\0\0\0\x92\xd5\x06\x13\xec\x45\xbf\x6a"
b"\0\0\0\0IEND\xae\x42\x60\x82"
)

session.log(f"write_file_tree({DUMMY_PATH}, ...)")
write_file_tree(
DUMMY_PATH,
{
"doc": {
"resources": {
"assets/minecraft/textures/entities": {
"chicken.png": ("wb", image)
},
"assets/dummy/patchouli_books/dummybook": {
"en_us": {
"categories/foo.json": {
Expand Down Expand Up @@ -391,6 +406,11 @@ def dummy_setup(session: nox.Session):
],
"text": "have a look at these related entries!!",
},
{
"type": "patchouli:entity",
"entity": "minecraft:chicken",
"text": "ah yes, the chicken. it lays eggs and stuff",
},
{
"type": "patchouli:link",
"url": "https://github.com/hexdoc-dev/hexdoc",
Expand Down
23 changes: 23 additions & 0 deletions src/hexdoc/_templates/pages/patchouli/entity.html.jinja
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{% extends "pages/patchouli/page.html.jinja" %}

{% import "macros/formatting.html.jinja" as fmt with context %}
{% import "macros/textures.html.jinja" as texture_macros with context %}

{% block body %}
<h4>
{{- page.name -}}
{%- if page_anchor_id is defined %}
{{- fmt.permalink(page_anchor_id) -}}
{% endif -%}
</h4>
{% block image %}
<p class="image-wrapper">
{{ texture_macros.render_texture(
name=page.entity_name,
texture=page.texture,
class_names=["entity-display"]
) }}
</p>
{% endblock image %}
{{ fmt.styled(page.text) }}
{% endblock %}
39 changes: 37 additions & 2 deletions src/hexdoc/patchouli/page/pages.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,13 @@

from jinja2 import pass_context
from jinja2.runtime import Context
from pydantic import Field, ValidationInfo, field_validator, model_validator
from pydantic import (
Field,
PrivateAttr,
ValidationInfo,
field_validator,
model_validator,
)

from hexdoc.core import Entity, ItemStack, ResourceLocation
from hexdoc.minecraft import I18n, LocalizedStr
Expand Down Expand Up @@ -47,12 +53,41 @@ class EmptyPage(Page, type="patchouli:empty", template_type="patchouli:page"):


class EntityPage(PageWithText, type="patchouli:entity"):
_entity_name: LocalizedStr = PrivateAttr()
_texture: PNGTexture = PrivateAttr()

entity: Entity
scale: float = 1
offset: float = 0
rotate: bool = True
default_rotation: float = -45
name: LocalizedStr | None = None
name_field: LocalizedStr | None = Field(default=None, serialization_alias="name")

@property
def entity_name(self):
return self._entity_name

@property
def name(self):
if self.name_field is None or not self.name_field.value:
return self._entity_name
return self.name_field

@property
def texture(self):
return self._texture

@model_validator(mode="after")
def _get_texture(self, info: ValidationInfo) -> Self:
# can't be on Entity's validator because it's frozen and
# causes circular references with the PNGTexture
assert info.context is not None
i18n = I18n.of(info)
self._entity_name = i18n.localize_entity(self.entity.id)
self._texture = PNGTexture.load_id(
id="textures/entities" / self.entity.id + ".png", context=info.context
)
return self


class ImagePage(PageWithTitle, type="patchouli:image"):
Expand Down
10 changes: 8 additions & 2 deletions test/tree.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@
else:
from typing import Any as JSONValue

FileValue = JSONValue | tuple[Literal["a"], str] | Callable[[str | None], str]
OpenMode = Literal["w", "a", "wb", "ab"]
FileValue = JSONValue | tuple[OpenMode, str | bytes] | Callable[[str | None], str]

FileTree = dict[str, "FileTree | FileValue"]

Expand All @@ -28,7 +29,12 @@ def write_file_tree(root: str | Path, tree: FileTree):
case tuple((mode, text)):
# append to existing file
with path.open(mode) as f:
f.write(dedent(text))
if isinstance(text, bytes):
f.write(text)
elif isinstance(text, str):
f.write(dedent(text))
else:
raise TypeError()
case str() as text:
# anything else - usually just text
path.parent.mkdir(parents=True, exist_ok=True)
Expand Down
Loading