As long as we have hierarchical tags, it'd be nice to also have a terse way of displaying these tags. The existing way is to just list them all: i.e. #food #food/bread #food/soup. It'd be nice to optionally (perhaps behind a configuration flag) show these as #food/{bread,soup}. In this case, we'd want the individual chunks of the tag to hyperlink to the "expanded" tag: i.e.
#food/{bread,soup}
---- ----- ----
^ ^ ^
| | +---- links to #food/soup
| +---------- links to #food/bread
+---------------- links to #food
As long as we have hierarchical tags, it'd be nice to also have a terse way of displaying these tags. The existing way is to just list them all: i.e. `#food #food/bread #food/soup`. It'd be nice to optionally (perhaps behind a configuration flag) show these as `#food/{bread,soup}`. In this case, we'd want the individual chunks of the tag to hyperlink to the "expanded" tag: i.e.
```
#food/{bread,soup}
---- ----- ----
^ ^ ^
| | +---- links to #food/soup
| +---------- links to #food/bread
+---------------- links to #food
```
Here's a Python snippet which implements this logic (AFAICT) correctly:
from typing import List
def render_hiertags(tags: List[str]) -> List[str]:
groups = {}
for tag in tags:
if "/" not in tag:
groups[tag] = groups.get(tag, {})
else:
chunks = tag.split("/")
focus = groups[chunks[0]] = groups.get(chunks[0], {})
for c in chunks[1:]:
focus[c] = focus = focus.get(c, {})
return [ render(k, v) for k, v in groups.items() ]
def render(prefix: str, values: dict) -> str:
if not values:
return prefix
if len(values) == 1:
rest = render(*values.popitem())
return f"{prefix}/{rest}"
else:
fragments = []
for k, v in values.items():
fragments.append(render(k, v))
items = ",".join(fragments)
return f"{prefix}/{{{items}}}"
assert render_hiertags(["a", "b", "c"]) == ["a", "b", "c"]
assert render_hiertags(["a/b", "c/d"]) == ["a/b", "c/d"]
assert render_hiertags(["a/b", "a/c"]) == ["a/{b,c}"]
assert render_hiertags(["a/b", "a/c", "a/d"]) == ["a/{b,c,d}"]
assert render_hiertags(["drink", "drink/cocktail/sling", "drink/cold"]) == ["drink/{cocktail/sling,cold}"]
It'll need to be hyperlinked correctly, of course, but this gets the grouping and hierarchy correct.
Here's a Python snippet which implements this logic (AFAICT) correctly:
```python
from typing import List
def render_hiertags(tags: List[str]) -> List[str]:
groups = {}
for tag in tags:
if "/" not in tag:
groups[tag] = groups.get(tag, {})
else:
chunks = tag.split("/")
focus = groups[chunks[0]] = groups.get(chunks[0], {})
for c in chunks[1:]:
focus[c] = focus = focus.get(c, {})
return [ render(k, v) for k, v in groups.items() ]
def render(prefix: str, values: dict) -> str:
if not values:
return prefix
if len(values) == 1:
rest = render(*values.popitem())
return f"{prefix}/{rest}"
else:
fragments = []
for k, v in values.items():
fragments.append(render(k, v))
items = ",".join(fragments)
return f"{prefix}/{{{items}}}"
assert render_hiertags(["a", "b", "c"]) == ["a", "b", "c"]
assert render_hiertags(["a/b", "c/d"]) == ["a/b", "c/d"]
assert render_hiertags(["a/b", "a/c"]) == ["a/{b,c}"]
assert render_hiertags(["a/b", "a/c", "a/d"]) == ["a/{b,c,d}"]
assert render_hiertags(["drink", "drink/cocktail/sling", "drink/cold"]) == ["drink/{cocktail/sling,cold}"]
```
It'll need to be hyperlinked correctly, of course, but this gets the grouping and hierarchy correct.
As long as we have hierarchical tags, it'd be nice to also have a terse way of displaying these tags. The existing way is to just list them all: i.e.
#food #food/bread #food/soup
. It'd be nice to optionally (perhaps behind a configuration flag) show these as#food/{bread,soup}
. In this case, we'd want the individual chunks of the tag to hyperlink to the "expanded" tag: i.e.Here's a Python snippet which implements this logic (AFAICT) correctly:
It'll need to be hyperlinked correctly, of course, but this gets the grouping and hierarchy correct.