Skip to content

Flags :D #60

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
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
4 changes: 3 additions & 1 deletion src/hexdoc/_templates/category.html.jinja
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
{% import "macros/formatting.html.jinja" as fmt with context %}

<section id="{{ category.id.path }}">
<section id="{{ category.id.path }}" class="{% if category.flag is not none %}
{{ category.flag.css_classnames() }}
{% endif %}">
Comment on lines +3 to +5
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
<section id="{{ category.id.path }}" class="{% if category.flag is not none %}
{{ category.flag.css_classnames() }}
{% endif %}">
<section id="{{ category.id.path }}" class="{{ category.flag.css_classnames() if category.flag }}">

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(this is also helpful because the current code adds extra newlines to the output, as you can see in the snapshots)

{% call fmt.maybe_spoilered(category) %}
{{- fmt.section_header(category, "h2", "category-title") }}
{{ fmt.styled(category.description) }}
Expand Down
5 changes: 4 additions & 1 deletion src/hexdoc/_templates/entry.html.jinja
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
{% import "macros/formatting.html.jinja" as fmt -%}

<div id="{{ entry.id.path }}" class="entry">
<div id="{{ entry.id.path }}" class="entry
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same as above

{% if entry.flag is not none %}
{{ entry.flag.css_classnames() }}
{% endif %}">
{% call fmt.maybe_spoilered(entry) %}
{{- fmt.section_header(entry, "h3", "entry-title") }}

Expand Down
4 changes: 3 additions & 1 deletion src/hexdoc/_templates/pages/patchouli/page.html.jinja
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
{% set page_anchor_id = entry.id.path ~ "@" ~ page.anchor %}

{#- page content (not required because EmptyPage uses this template directly) #}
<div id="{{ page_anchor_id }}">
<div id="{{ page_anchor_id }}" class="{% if entry.flag is not none %}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same as above

{{ entry.flag.css_classnames() }}
{% endif %}">
{% block body scoped %}{% endblock %}
</div>
{% else %}
Expand Down
3 changes: 2 additions & 1 deletion src/hexdoc/patchouli/category.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
from hexdoc.utils import Sortable, sorted_dict

from .entry import Entry
from .flag import FlagExpression
from .text import FormatTree


Expand All @@ -30,7 +31,7 @@ class Category(IDModel, Sortable):
# optional
parent_id: ResourceLocation | None = Field(default=None, alias="parent")
_parent_cmp_key: tuple[int, ...] | None = None
flag: str | None = None
flag: FlagExpression | None = None
sortnum: int = 0
secret: bool = False

Expand Down
3 changes: 2 additions & 1 deletion src/hexdoc/patchouli/entry.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
from hexdoc.utils import Sortable

from .book_context import BookContext
from .flag import FlagExpression
from .page import CraftingPage, Page, PageWithTitle
from .text import FormatTree

Expand All @@ -30,7 +31,7 @@ class Entry(IDModel, Sortable):

# optional (entry.json)
advancement: ResourceLocation | None = None
flag: str | None = None
flag: FlagExpression | None = None
priority: bool = False
secret: bool = False
read_by_default: bool = False
Expand Down
53 changes: 53 additions & 0 deletions src/hexdoc/patchouli/flag.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
from typing import Any

from pydantic import model_validator

from hexdoc.model import HexdocModel


class Flag(HexdocModel):
name: str
negated: bool = False

@model_validator(mode="before")
@classmethod
def parse_flag(cls, data: Any) -> Any:
if isinstance(data, str):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: I'd probably do a match statement, but this works too

assert (
"," not in data
) # not sure if there are other invalid characters or not
Comment on lines +16 to +18
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • what's this for?
  • move the comment to the line above and it'll be formatted a bit less weirdly
  • this should have some sort of useful error message, not just an empty assert (ie. assert condition, "message goes here")

if data.startswith("!"):
return {"name": data[1:], "negated": True}
return {"name": data}

return data

def css_classname(self) -> str:
base = "flag-" + self.name.replace(":", "-")
if self.negated:
return "not-" + base
return base


class FlagExpression(HexdocModel):
flags: list[Flag]
conjuctive: bool = True

@model_validator(mode="before")
@classmethod
def parse_flags(cls, data: Any) -> Any:
if isinstance(data, str):
if data.startswith("|") or data.startswith("&"): # must be a list
return {
"flags": data[1:].split(","),
"conjuctive": data.startswith("&"),
}
return {"flags": [data]}
Comment on lines +40 to +45
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

these could (and probably should) return instances of the class instead of dicts. for example: return cls(flags=[data])


return data

def css_classnames(self) -> str:
flagclasses = " ".join(flag.css_classname() for flag in self.flags)
if self.conjuctive:
return "flagall " + flagclasses
return "flagany " + flagclasses
3 changes: 2 additions & 1 deletion src/hexdoc/patchouli/page/abstract_pages.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from hexdoc.model import TypeTaggedTemplate
from hexdoc.utils import Inherit, InheritType, NoValue, classproperty

from ..flag import FlagExpression
from ..text import FormatTree

_T_Recipe = TypeVar("_T_Recipe", bound=Recipe)
Expand All @@ -21,7 +22,7 @@ class Page(TypeTaggedTemplate, type=None):
"""

advancement: ResourceLocation | None = None
flag: str | None = None
flag: FlagExpression | None = None
anchor: str | None = None

def __init_subclass__(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@
</details>
</nav>
<main class="book-body">
<section id="basics">
<section id="basics" class="">
<h2 class="category-title page-header">
<img
title="Amethyst Shard"
Expand All @@ -184,7 +184,8 @@
title="Permalink"
><i class="bi bi-link-45deg"></i></a></h2>
<p>The practitioners of this art would cast their so-called <span style="color: #b38ef3">Hexes</span> by drawing strange patterns in the air with a <a href="GITHUB_PAGES_URL/v/latest/main/en_us#items/staff"><span style="color: #b0b">Staff</span></a> -- or craft <a href="GITHUB_PAGES_URL/v/latest/main/en_us#items/hexcasting"><span style="color: #b0b">powerful magical items</span></a> to do the casting for them. How might I do the same?</p>
<div id="baz" class="entry">
<div id="baz" class="entry
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(this is what i mentioned above)

">
<div class="spoilered">
<h3 class="entry-title page-header">
<img
Expand All @@ -207,7 +208,7 @@
</div>
</div>
</section>
<section id="foo">
<section id="foo" class="">
<div class="spoilered">
<h2 class="category-title page-header">
<img
Expand All @@ -227,7 +228,8 @@
><i class="bi bi-link-45deg"></i></a></h2>
<p>The practitioners of this art would cast their so-called <span style="color: #b38ef3">Hexes</span> by drawing strange patterns in the air with a <a href="GITHUB_PAGES_URL/v/latest/main/en_us#items/staff"><span style="color: #b0b">Staff</span></a> -- or craft <a href="GITHUB_PAGES_URL/v/latest/main/en_us#items/hexcasting"><span style="color: #b0b">powerful magical items</span></a> to do the casting for them. How might I do the same?</p>
</div>
<div id="bar" class="entry">
<div id="bar" class="entry
">
<div class="spoilered">
<h3 class="entry-title page-header">
<img
Expand Down
Loading