@Sirius3: Ja, Deine Lösung gefällt mir eindeutig besser. Nach so einer übersichtlichen Lösung hatte ich anfänglich gesucht, nichts gefunden, dann erst einmal mit XML probiert und dann noch einmal nach einen Ansatz mit HTML gesucht. Alles was ich für mich verständliches fand, war unten der letzte Code auf dieser Seite mit self.recordh2 = True und False und den hatte ich dann als Ansatz für einen Anfang benutzt, um ein Dictionary mit richtig durchnummerierten Schlüssen zu erhalten:
https://stackoverflow.com/questions/848 ... -from-tags
Doch so wie Du das geschrieben hast, ausprobiert habe ich es, sieht sauberer und übersichtlicher aus.
Text-Widget mit formatierter Ausgabe
Liebe Freunde,
Für mich als Newbie waren Eure Kommentare sehr lehrreich und dafür herzlichen Dank.
Euer Wissen verlangt Respekt und Achtung. Man könnte dabei den Mut zum Weiterlernen verlieren. Mich aber spornt das an zu noch vielen weiteren Bemühungen.
Gruß Knut
Für mich als Newbie waren Eure Kommentare sehr lehrreich und dafür herzlichen Dank.
Euer Wissen verlangt Respekt und Achtung. Man könnte dabei den Mut zum Weiterlernen verlieren. Mich aber spornt das an zu noch vielen weiteren Bemühungen.
Gruß Knut
Nun funktioniert das Script auch mit "strong" und mit "span class name" und mit einem hellbrau hinterlegten Bereich für Zitate oder ähnlichen, der dann aber bereits in HTML in einem div-Bereich gelegt werden muss. Beide "div class name" und "p class name" muss dann halt wie bei "span class name" mit den Tkinter-Tags übereinstimmen. Das Herumgemurkse ist geblieben, Tkinter nimmt nur Tags und da folgt dann nach einem Tag ein anderer Tag und wenn ein p oder br Tkinter-Tag normalen Text enthält, muss man halt hinter </span> wieder auf einen Tkinter-Tag "normal" wechseln.Sirius3 hat geschrieben:@Melewo: ein Wort in einem Text fett haben zu wollen ist jetzt keine so große Ausnahme. Hat jetzt auch nichts mit kompliziertem CSS und DIV-Elementen zu tun. Eine Lösung, die halbwegs nur für die von Dir verwendete HTML-Struktur funktioniert, ist nicht robust.
Dass sich der Code noch verbessern ließe und weiter ausbauen, darüber bin ich mir fasst im Klaren, wobei ich mir dann überlegte, ob es einen Sinn ergibt, einzelne Zeilen in Funktionen auszulagern, wenn es in der nächsten Zeile bereits wieder Unterschiede gibt und an Stelle einer ausgelagerten Zeile dann ein Funktionsaufruf notiert wird. Na ja, kann ja nur von meinem jetzigen Kenntnisstand ausgehen und mit dem würde es noch nicht viel kürzer oder eleganter oder übersichtlicher werden.
Code: Alles auswählen
from tkinter import Tk, Text, Scrollbar, PhotoImage, END
from PIL import Image, ImageTk
from html.parser import HTMLParser
class MiniHTMLParser(HTMLParser):
def __init__(self):
HTMLParser.__init__(self)
self.items = []
self.tag = self.attrs = None
def handle_starttag(self, tag, attrs):
self.tag = tag
self.attrs = attrs
if tag == "img":
self.items.append((self.tag, self.attrs, None))
def handle_data(self, data):
self.items.append((self.tag, self.attrs, data))
class LesetestHTML(Tk):
def __init__(self):
Tk.__init__(self)
self.images = []
self.title("Lesetest")
self.config(bg="#d9cda3")
self.textfeld = Text(
self, height=44, pady=12, padx=12, wrap="word")
scrollbar = Scrollbar(self)
scrollbar.config(command = self.textfeld.yview)
self.textfeld.config(yscrollcommand = scrollbar.set)
scrollbar.pack(side="right", fill="y")
self.textfeld.pack(pady=24, padx=24)
self.textfeld.tag_config(
"h1", font=("cambria", 22),
foreground="#c7a621", spacing3=10)
self.textfeld.tag_config(
"h2", font=("cambria", 18),
foreground="#98732e", spacing3=28)
self.textfeld.tag_config(
"h3", font=("cambria", 12, "bold"),
foreground="#74521c", spacing1=22)
self.textfeld.tag_config(
"p", font=("cambria", 12))
self.textfeld.tag_config(
"br", font=("cambria", 12))
self.textfeld.tag_config(
"normal", font=("cambria", 12))
self.textfeld.tag_config(
"klein", font=("cambria", 6))
self.textfeld.tag_config(
"strong", font=("cambria", 12, "bold"))
self.textfeld.tag_config(
"mittig", font=("cambria", 12), justify="center")
self.textfeld.tag_config(
"img", justify="center", spacing1=6)
self.textfeld.tag_config(
"bildnotizen", font=("cambria", 10, "italic"),
foreground="#867a44", justify="center")
self.textfeld.tag_config(
"boldgrau", font=("cambria", 12, "bold"),
foreground="#404040")
self.textfeld.tag_config(
"boldbraun", font=("cambria", 12, "bold"),
foreground="#9b4c21")
self.textfeld.tag_config(
"fehler", font=("cambria", 12),
foreground="#ff8808", justify="center")
self.textfeld.tag_config(
"quotes", background="#e6e5da")
self.textfeld.tag_config(
"zitate", font=("cambria", 12, "italic"),
background="#e6e5da", justify="center",
rmargin=20, lmargin1=20, lmargin2=20,
spacing1=22, spacing3=22)
def insert_content(self, anfang, content, ende, tag):
self.textfeld.insert(END, "{0}{1}{2}"
.format(anfang, content, ende), tag)
def oeffne_htmlseite(self, filename):
parser = MiniHTMLParser()
try:
with open(filename) as datei:
dateistring = datei.read().replace(
"</span>", "[endspan]").replace(
"</strong>", "[endstrong]")
parser.feed(dateistring)
except FileNotFoundError:
parser.feed("<h3>Die Datei wurde nicht gefunden!</h3>")
# Wenn ein 'class name' aus dem HTML-Dokument verwendet werden soll,
# wird dieser abgefragt und als Tkinter-Tag angelegt.
# 'letzte_tagdata' enhält die Länge von content, bei einem leeren Endtag
# ist dieser 0 bis 1, so dass z.B. ermittelt wird, ob der letzte Tag
# Content enthielt und noch ein Leertag gesetzt werden kann oder ob
# Span-Bereiche mit einem " " Leerzeichen oder mit "" keinem beginnen.
# 'br_umbrueche' dient ebenfalls dazu, um nur einen abschließenden leeren
# Tag zu setzen. 'letzter_tag' ist für br, falls img vorausging.
br_umbrueche = 1
letzte_tagdata = 1
letzter_tag = None
for tag, attrs, data in parser.items:
if tag in ("h1", "h2"):
content = data.replace(" ", "")
self.insert_content("", content, "", tag)
elif tag == "h3":
content = data.replace(" ", "")
if len(content) > 2:
self.insert_content("\n", content, "", tag)
else:
self.insert_content("\n", content, "", "klein")
letzte_tagdata = len(content)
letzter_tag = tag
elif tag == "div":
if "class" in dict(attrs):
if dict(attrs)["class"] == "quotes":
self.insert_content("\n", "", "\n", "normal")
elif tag == "p":
content = " ".join(data.split())
if not "class" in dict(attrs):
self.insert_content("", content, "", "normal")
elif dict(attrs)["class"] == "mittig":
anfang = ("\n" if letzter_tag != "br" else "")
self.insert_content(anfang, content, "", "mittig")
elif dict(attrs)["class"] == "zitate":
if len(content):
self.insert_content("", content, "\n", "zitate")
elif letzte_tagdata > 2:
self.insert_content("\n", "", "\n", "klein")
letzte_tagdata = len(content)
letzter_tag = tag
elif tag == "br":
content = " ".join(data.split())
if len(content) != br_umbrueche and letzter_tag != "img":
self.insert_content("\n", content, "", "normal")
br_umbrueche = len(content)
letzte_tagdata = len(content)
letzter_tag = tag
# Inline-Tags ohne "\n" am Ende, mit Ausnahme von "bildnotizen".
elif tag == "span" and dict(attrs)["class"]:
tag = dict(attrs)["class"]
spandata = data.split("[endspan]")
if tag == "boldbraun" or tag == "boldgrau":
anfang = ("" if letzte_tagdata < 2 else " ")
content = " ".join(spandata[0].split())
self.insert_content(anfang, content, " ", tag)
if len(spandata) > 1:
content = " ".join(spandata[1].split())
self.insert_content(anfang, content, " ", "normal")
elif tag == "bildnotizen":
content = " ".join(spandata[0].split())
if len(spandata)> 1:
self.insert_content("", content, "\n\n", tag)
letzte_tagdata = len(spandata)
letzter_tag = tag
elif tag == "strong":
anfang = ("" if letzte_tagdata < 2 else " ")
strongdata = data.split("[endstrong]")
content = " ".join(strongdata[0].split())
self.insert_content(anfang, content, " ", tag)
if len(strongdata) > 1:
content = " ".join(strongdata[1].split())
self.insert_content(anfang, content, " ", "normal")
letzte_tagdata = len(strongdata)
letzter_tag = tag
elif tag == "img":
try:
image = Image.open(dict(attrs)["src"])
image = ImageTk.PhotoImage(image)
self.insert_content("\n", " ", "", "img")
self.textfeld.image_create(END, image=image)
letzter_tag = tag
self.insert_content(""," ", "\n", "img")
self.images.append(image)
except FileNotFoundError:
self.textfeld.insert(
END, "Das Image wurde nicht gefunden.\n\n",
"fehler")
def main():
root = LesetestHTML()
root.oeffne_htmlseite("lorem-ipsum.html")
root.mainloop()
if __name__ == "__main__":
main()
[codebox=html5 file=Unbenannt.html]<!DOCTYPE html>
<html>
<head>
<title>HTML Test</title>
<style type="text/css">
body {with font-family:cambria; font-weight:normal; font-size:16px}
div.wrapper{width:668px; padding:12; margin:auto}
h1 {font-family:cambria; font-weight:bold; font-size:24px}
h2 {font-family:cambria; font-weight:bold; font-size:20px}
h3 {font-family:cambria; font-weight:bold; font-size:16px}
.mittig {text-align:center}
.bildnotizen {
font-family:cambria;
font-style:italic;
font-size:10px;
color:#867a44
}
.boldgrau {font-weight:bold; color:#404040}
.boldbraun {font-weight:bold; color:#9b4c21}
.quotes {background-color:#e6e5da; border:1px solid #ff0000}
.zitate {
font-family:cambria;
font-style:italic;
font-size:16px;
text-align:center;
margin:20px
}
@media only all and (max-width:698px) {
div.wrapper {width:100%}
img.images {max-width:100%; height:auto}
</style>
</head>
<body>
<div class="wrapper">
<h1>Nur ein HTML-Test</h1>
<h2>Untertitel</h2>
<p>Lorem ipsum dolor sit amet, <strong>Lconsetetur sadipscing</strong> elitr, sed
diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed
diam voluptua.<br>
Stet clita kasd gubergren, no sea <span class="boldbraun">takimata</span> sanctus
est Lorem ipsum dolor sit amet.</p>
<h3>Punkt 1</h3>
<p><span class="boldbraun">Lorem ipsum</span> dolor sit amet, consetetur
sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna
aliquyam erat, sed diam voluptua.</p>
<p class="mittig">
<img src="testbild_1.png" alt="Test" width="240" height="192" class="images"><br>
<span class="bildnotizen">Bild 1: Notizen unterm Bild</span>
</p>
<p>Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod
tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.</p>
<div class="quotes">
<p class="zitate">Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed
diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed
diam voluptua.</p>
</div>
<p>Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod
tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.<br>
<br>
Stet clita kasd gubergren.</p>
</div>
</body>
</html>[/code]