#7 Implement Unix-grouping showing for tags

Closed
opened 4 years ago by getty · 1 comments
getty commented 4 years ago

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 ```
getty commented 4 years ago
Owner

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.
Sign in to join this conversation.
No Milestone
No assignee
1 Participants
Loading...
Cancel
Save
There is no content yet.