from textual.widgets import Button, Static from textual.app import ComposeResult from textual.containers import Container from rich.text import Text class Gemtext(Static): """Gemtext widget.""" inPre = False def __init__(self, fp, id): super().__init__(id=id) self.addlines(fp) def addlines(self, fp): for lin in fp: line = lin if type(line) is bytes: line = line.decode("UTF-8") line = line.rstrip("\r\n") if line.startswith("```"): self.inPre = not self.inPre if self.inPre: self.inPre = Preformatted() self.mount(self.inPre) elif self.inPre: self.inPre.mount(Static(line, markup=False)) elif line.startswith("=>"): path = line[2:].lstrip().split(' ')[0].split('\t')[0] text = line[2:].lstrip()[len(path):].lstrip() self.mount(Button(Text(text or path,overflow="fold"), name=path)) elif line.startswith("#"): count = line.split(' ')[0][0:3].count("#") w = Static(line.lstrip("#"), markup=False, classes="header h"+str(count)) self.mount(w) elif line.startswith(">"): self.mount(Quote(line, markup=False)) else: self.mount(Static(line, markup=False)) class Quote(Static): pass class Preformatted(Container): pass if __name__ == "__main__": from textual.app import App class Test(App): def compose(self) -> ComposeResult: yield Gemtext(txt="#title\n=> /href link text\nworld star hiphop", id="yo") app = Test() app.run()