Spaces:
Sleeping
Sleeping
| import streamlit as st | |
| import unidecode | |
| DISABLE_LINK_CSS = """ | |
| <style> | |
| a.toc { | |
| color: inherit; | |
| text-decoration: none; /* no underline */ | |
| } | |
| </style>""" | |
| class stoc: | |
| def __init__(self): | |
| self.toc_items = list() | |
| def h1(self, text: str, write: bool = True): | |
| if write: | |
| st.write(f"# {text}") | |
| self.toc_items.append(("h1", text)) | |
| def h2(self, text: str, write: bool = True): | |
| if write: | |
| st.write(f"## {text}") | |
| self.toc_items.append(("h2", text)) | |
| def h3(self, text: str, write: bool = True): | |
| if write: | |
| st.write(f"### {text}") | |
| self.toc_items.append(("h3", text)) | |
| def toc(self): | |
| st.write(DISABLE_LINK_CSS, unsafe_allow_html=True) | |
| st.sidebar.caption("Table of contents") | |
| markdown_toc = "" | |
| for title_size, title in self.toc_items: | |
| h = int(title_size.replace("h", "")) | |
| markdown_toc += ( | |
| " " * 2 * h | |
| + "- " | |
| + f'<a href="#{normalize(title)}" class="toc"> {title}</a> \n' | |
| ) | |
| st.sidebar.write(markdown_toc, unsafe_allow_html=True) | |
| def from_markdown(cls, text: str): | |
| self = cls() | |
| for line in text.splitlines(): | |
| if line.startswith("###"): | |
| self.h3(line[3:], write=False) | |
| elif line.startswith("##"): | |
| self.h2(line[2:], write=False) | |
| elif line.startswith("#"): | |
| self.h1(line[1:], write=False) | |
| st.write(text) | |
| self.toc() | |
| def normalize(s): | |
| """ | |
| Normalize titles as valid HTML ids for anchors | |
| >>> normalize("it's a test to spot how Things happ3n héhé") | |
| "it-s-a-test-to-spot-how-things-happ3n-h-h" | |
| """ | |
| # Replace accents with "-" | |
| s_wo_accents = unidecode.unidecode(s) | |
| accents = [s for s in s if s not in s_wo_accents] | |
| for accent in accents: | |
| s = s.replace(accent, "-") | |
| # Lowercase | |
| s = s.lower() | |
| # Keep only alphanum and remove "-" suffix if existing | |
| normalized = ( | |
| "".join([char if char.isalnum() else "-" for char in s]).strip("-").lower() | |
| ) | |
| return normalized | |