Python, GTK a markdown (?)

Potrzebuję porady dotyczącej projektu:

Wróciłem do tematu zbudowania programu do notatek (typu obsidian / zettelkasten / roam) i chciałbym móc pisać notatki w markdownie, żeby móc linkować obrazki i mieć podstawowe formatowanie, które wygląda lepiej niż łysy tekst).

Używam minta i cinnamona, więc zrobienie tego w GTK brzmi sensownie. Cały program miałby być kilkuokienkowy (jak gimp np.). Główne okienko zajmowałoby się wyszukiwaniem notatek i sterowaniem resztą okien, a jedno z pozostałych okienek służyłoby do wyświetlania i edycji notatek. Wyobrażam sobie to tak, żeby przełączać się między trybem edycji a wyświetlania np. robiąc okienko z 2 tabmi, jednym wyświetlającym surowy tekst do edycji, a drugim wyświetlającym html zrobiony z markdowna.

Problem pojawia się z renderowaniem markdowna i pożenieniem tego z GTK; obecnie sytuacja wygląda następująco:

  1. Umiem wyświetlić markdown z obrazkami i themem css’owym korzystając z https://pywebview.flowrl.com/. To, co jest dla mnie tajemnicą, to w jaki sposób pożenić to z resztą programu w GTK.

  2. Wiem, że da się łatwo pożenić GTK z wbudowanym w niego webkitem, ale za cholerę ten webkit nie chce renderować html’a ze stringa korzystając z podlinkowanych lokalnych obrazków (tzn. html się ładnie wyświetla, ale obrazków brak). Jest niby argument pozwalający określić base uri, ale nic to nie daje. Może jednak da się to zrobić?

  3. Może to, że nastawiłem się na markdown to pierwotny błąd, bo to zdaje się mocno webowa technologia (a web z tego co widzę ssie jak próbuje się wykorzystać te rzeczy lokalnie)? Jest jakaś alternatywa?

  4. Może to, że nastawiłem się na GTK to też błąd, bo da się łatwiej w jakimś innym pythonowym narzędziu? Jak tak, to jakim?

  5. Umiem zrobić kilku okienkowy program, w którym część jest w GTK, a część w pywebview i okienka komunikują się poprzez redis’a - ale to brzmi koślawo. Może jednak nie jest koślawe?

  6. Pogrzebałem trochę w istniejących edytorach markdowna bazujących na GTK, ale one jakieś magiczne rzeczy w JSie robią, a tego chcę uniknąć.

PS: nie znam JS’a, nie rozumiem webowych rzeczy

chyba forum zadziałało jak kaczuszka - czytam właśnie jak to zrobić w Qt :stuck_out_tongue:

Używając markdowna w zasadzie skazujesz się na technologie webowe, bo markdown będzie służył do wygenerowania HTML. Więc wszystko dalej można sprowadzić do renderowania HTML w apce, co dzisiaj będzie oznaczało w jakiejś formie embeddowanie przeglądarki w twojej aplikacji. Dam sobie rękę uciąć, że każdy framework GUI, który posiada jakieś komponenty webview pozwala na dostęp do lokalnych zasobów, bo zazwyczaj taki komponent będzie wykorzystany właśnie do ładnego renderowania tekstu i multimediów, a nie do wyświetlania stron, które działają w przeglądarkach. Bez szczegółów ciężko powiedzieć dlaczego nie działa, ale zgadywałbym, że możesz mieć coś nie tak ze ścieżkami.

Alternatywą do używania webview są jakieś komponenty typu rich text view, które pewnie będą miały swój własny sposób formatowania, możliwe, że podobny HTML albo BBCode, bardziej zauważalny niż markdown. Wtedy musiałbyś też samemu pewnie dbać o układ rzeczy w oknie, wyświetlanie zdjęć, itp. Ogólnie pewnie dużo roboty.

Jak masz programy GUI to typowe jest, że masz co najmniej dwa wątki - jeden obsługujący interfejs, a drugi zadania w tle (po to żeby dłuższe funkcje nie zawieszały UI). Więc samo to, że będziesz mieć wiele wątków (czy procesów), które będą się ze sobą komunikowały jest jak najbardziej sensowne i nawet stosowanie kilku innych frameworków GUI nie powinno stanowić problemu. Samo stosowanie Redisa do takiej komunikacji jest zdecydowanym overkillem (i szczerze wątpię żeby było wygodne), Python ma normalnie mechanizmy służące do komunikacji pomiędzy wątkami czy procesami.

dzięki za odpowiedź!

spieszę donieść, że Twoja ręka jest bezpieczna :d

pogrzebałem trochę bardziej i udało mi się to zrobić. To, co mnie zmyliło, to to, że w pywebview ścieżka jest lokalna domyślnie, a w webkit nie tylko trzeba ją podać, to jeszcze jest absolutna:

webview.load_html(
    html,
    'file://%s' % os.path.dirname(os.path.realpath(__file__)),
)

zmyliło mnie jeszcze to, że na stacku opisywali czasem problemy, które trzeba było rozwiązać pozwoleniami, ale ostatecznie nie były potrzebne:

webview = WebKit2.WebView()
settings = webview.get_settings()
settings.set_allow_file_access_from_file_urls(True)
settings.set_allow_universal_access_from_file_urls(True)
settings.set_auto_load_images(True)
webview.set_settings(settings)

ogarnięcie jak je zrobić też trochę mi zajęło, bo nie ma dokumentacji dla pythona.

Szczerze mówiąc lubię redisowe pub/sub, wygodnie mi się o tym myśli i łatwo debugować/testować. No ale to dodatkowa zależność, której można uniknąć, więc bez sensu.

Dobra, wracam do kodzenia

No tak, tylko wtedy masz więcej zależności i musisz albo uruchamiać tego Redisa samemu, albo odpalać go w tle z programu. A Python ma normalnie kolejki do komunikacji między wątkami, które powinny działać podobnie do pub/suba (jest też multiprocessing.Queue).

Podstawowy markdown, w szczególności bez tych githubowych cudów, jest na tyle prosty, że jak już go sparsujesz, to przerobienie go na drzewo widgetów nie powinno być trudne. Schody, w moim odczuciu, zaczynają się na etapie robienia z tego edytora. Jeśli porządny edytor to ma być wyróżnik twojego programu, no to użycie gotowca w sumie sprawi, że będzie on potrafił dokładnie tyle ile ta biblioteka do prezentacji markdowna, której użyjesz. Nie wiem, czy o taki efekt tobie chodzi.

Jeśli chodzi o GTK (i wszystkie klasyczne frameworki UIowe, na dobrą sprawę), to one przeżywają okropną recesję, w moim odczuciu. Desktop jako platforma odchodzi do lamusa oddając coraz więcej rynku platformom mobilnym. Każdy chce robić mobile-first, desktop-second. Desktopa wrzucają do jednego wora, czy to Windows, czy macOS, czy inny tam czasem Linuks, nie robi. Aplikacji .exe ludzie chyba już boją się instalować na Windowsach, więc wszystko idzie z weba.

Jak ostatni raz ogarniałem temat, to wszystko ssało, czy to w Pythonie czy w innych technologiach. Stos desktopowy, który mógłbym polecić, to Kotlin + Graal VM + sensowny framework do UI. To drugie jest niestabilne a to trzecie nie istnieje.

Jak jesteś edgy to mógłbyś ogarniać Flutter Desktop albo Jetpack Compose, ale nie mam pojęcia czy to nie ma jakichś strasznych problemów.

dzięki - nie korzystałem z nich jeszcze, poczytam. Swoją drogą parę lat temu robiłem system do przetwarzania danych w pracy, który wykorzystywał kolejki z celery. Ciekawe czy bez sensu to robiłem i dało się samym pythonem :thinking:

Nie kumam o co chodzi z drzewem widgetów - obecnie po prostu ładuję tekst z pliku, zamieniam w html’a za pomocą tej biblioteki, doklejam trochę html’a i css’a, żeby to jakoś wyglądało (kolor tła i tekstu) i wyświetlam to za pomocą WebView z WebKit2 (z GTK). To jest widok “statyczny”, żeby umożliwić edytowanie mam po prostu w stacku drugie okno z Gtk.TextView, które wyświetla surowy tekst do edycji. Trzeba się przełączać pomiędzy tymi widokami, co jest dla mnie OK.

Natomiast chyba nie określiłem jak ograniczony jest to projekt. Normalni ludzie używają obsidiana czy czegoś podobnego, a ja robię ten projekt pod swoje, dość niszowe, potrzeby:

  • obsidian nie umiał nawet zobaczyć mojego drugiego dysku, na którym trzymam dane (pogrzebałem trochę, ale jak zobaczyłem, że nie ma sensownych plików z configiem to dałem sobie spokój)
  • chcę mieć bardzo dobrą integrację z zotero i calibre (napisałem już sobie kod do wyciągania z baz danych z tych programów tego, co potrzebuję i integrowania tego z notatkami)
  • chcę mieć osobne okno z widokiem grafu na drugim monitorze (obsidian nie miał tego, jak ostatni raz go obczajałem, bo elektron go jakoś ograniczał)
  • znam (z nie niszowych języków) tylko pythona i nie chcę się uczyć nowego tylko do tego projektu. Najprędziej Julię bym sobie ogarnął, ale ją też raczej wolałbym poznawać w kontekście modelowania / przetwarzania danych, a nie zabaw z GUI

No i są oczywiście dodatkowe benefity związane z tym, że sam to buduję, sprowadzające się do tego, że łatwo mogę dostosować zachowanie i wygląd UI pod swoje preferencje.

Wrzucę ten projekt potem na gitlaba, może są jeszcze jakieś osoby z podobnymi potrzebami, ale też nie liczę na to, że wyjdzie z tego jakiś popularny projekt.

Z Celery też korzystałem i ma zdecydowanie sens, jeśli chcesz żeby twoja aplikacja mogła być rozproszona na kilka maszyn. Brzmi odpowiednio do przetwarzania danych :+1: