Valide HTML Listen erstellen

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
EnTeQuAk
User
Beiträge: 986
Registriert: Freitag 21. Juli 2006, 15:03
Wohnort: Berlin
Kontaktdaten:

Sonntag 17. Juni 2007, 15:51

Hallo alle zusammen!

Ich arbeite an einer Funktion, die mir aus etwa folgender Wikisyntax eine Valide, HTML Liste baut.

Die Wikisyntax ist folgende:

Code: Alles auswählen

 * Liste ebene 1
  * liste ebene 2
  * liste ebene 2
   * liste ebene 3
  * liste ebene 2
   * liste ebene 3
 * Liste ebene 1
    * Liste ebene 4
 * Liste ebene 1
   * Liste ebene 3
Die Einrückung pro Level beträgt immer ein leerzeichen.

Die Funktion, die das umwandeln soll, sieht so aus:

Code: Alles auswählen

def build_list(txt):
    result = []
    deep = 1
    open_li = []
    result.append(('ul/start', '<ul>'))
    for item in re.findall("(\s+)\*(.*)", txt):
        currentlen = len(item[0])-1

        if currentlen > deep:
            if result[-1][0] == 'li/close':
                open_li.append(('li/close', result.pop()[1]))
            for i in range(currentlen - deep):
                if not result[-1][0] in ['text', 'li/start']:
                    result.append(('li/start', '<li>'))
                result.append(('ul/start', '<ul>'))
            deep = currentlen
        elif currentlen < deep:
            for i in range(deep - currentlen):
                result.append(('ul/close', '</ul>'))
                if open_li:
                    result.append(('li/close', open_li.pop()[1]))
            deep = currentlen

        result.append(('li/open', '<li>'))
        result.append(('text', item[1]))
        result.append(('li/close', '</li>'))
        deep = currentlen

    for i in range(deep):
        result.append(('ul/close', '</ul>'))
    return '\n'.join([x[1] for x in result])
Jedoch bekomme ich das nicht so ganz hin. Die Level anfangs super gerendert, bis zum zweiten "listene ebene 3". Da versagt er.

Ich währe euch sehr verbunden, wenn ihr mir ein wenig helfen könntet, oder mir ein paar Tipps geben könntet, woran es eventuell liegen könnte.

Leider habe ich bisher kaum Ressourcen gefunden, die die erstellung solcher Listen in einem Rutsch durchführt... :'(
Fast alle Markupparser, sei es MoinMoin oder Trac erstellen die Listen über so viele instanzen, das ich da nicht immer hinterher komme :)

MfG EnTeQuAk
Zuletzt geändert von EnTeQuAk am Sonntag 17. Juni 2007, 23:01, insgesamt 1-mal geändert.
thelittlebug
User
Beiträge: 188
Registriert: Donnerstag 20. Juli 2006, 20:46
Wohnort: Wien
Kontaktdaten:

Sonntag 17. Juni 2007, 19:36

Also wenns war ist hab ich die Lösung:

Code: Alles auswählen

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import re

wikitext = """
* Liste 1 ebene 1
* Liste 2 ebene 1
*** Liste 1 ebene 2
* Liste 3 ebene 1
* Liste 4 ebene 1
"""

hits = re.findall("([*]+)\s([\w\s]+)",wikitext.replace("\n",""))

def buildit(num, deep):
    global hits
    result = " "*(deep+1) + "<li>\n"

    thisdeep = len(hits[num][0])-1

    if thisdeep > deep:
        result += " "*(deep+2)+"<ul>\n"
        result += buildit(num, deep + 1)
        result += " "*(deep+2)+"</ul>\n"
    else:
        result += " "*(deep+2) + hits[num][1] + "\n"

    result += " "*(deep+1)+"</li>\n"
    if thisdeep == deep:
        if num + 1 < len(hits):
            result += buildit(num + 1, deep)

    return result

print "<ul>\n", buildit(0, 0), "</ul>"
Ich hab irgendwie heute bei der Hitze keinen Kopf mehr die Einrückungsfehler zu beheben, das lass ich dir ;)

lgherby
EnTeQuAk
User
Beiträge: 986
Registriert: Freitag 21. Juli 2006, 15:03
Wohnort: Berlin
Kontaktdaten:

Sonntag 17. Juni 2007, 21:34

Herzlichen Dank, deins war zwar nicht die Lösung für Listen nach der Syntax, wie ich sie Gesucht hatte. Aber... ;) Es war nicht viel anzupassen.

Die Formatierung, braucht dir keine Sorgen bereiten ;) Dafür hab ich selber nen Modul, das das automatisch übernimmt *g* --> Ist mir auch immer zu viel Arbeit ;)



MfG EnTeQuAk
thelittlebug
User
Beiträge: 188
Registriert: Donnerstag 20. Juli 2006, 20:46
Wohnort: Wien
Kontaktdaten:

Sonntag 17. Juni 2007, 22:40

Ich hab nämlich deine Syntax in meinem MediaWiki ausprobiert. Das hat nicht funktioniert. Deßhalb hab ich nachgeschlagen wie die MediaWiki Syntax für Listen aussieht und mich daran gehalten ;)

Aber wenns passt, ists gut :)

Für das "Aufbessern" von (X)HTML kann ich Tidy empfehlen. Damit hab ich mir meine HTML Manpage Sammlung nach dem Generieren "verschönert".

lgherby
Benutzeravatar
jens
Moderator
Beiträge: 8461
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Montag 18. Juni 2007, 09:43

EnTeQuAk hat geschrieben:Die Wikisyntax ist folgende:

Code: Alles auswählen

 * Liste ebene 1
  * liste ebene 2
  * liste ebene 2
   * liste ebene 3
  * liste ebene 2
   * liste ebene 3
 * Liste ebene 1
    * Liste ebene 4
 * Liste ebene 1
   * Liste ebene 3
Die Einrückung pro Level beträgt immer ein leerzeichen.
Ich glaube das ist keine gute Idee genau mit einem Leerzeichen zu arbeiten.

Also bei Moin ist es wohl so, das er in der Richtung toleranter ist. Schau mal hier: [wiki]WikiSandkasten#Liste[/wiki]

Deine Variante (ein Leerzeichen zum Einrücken):

Code: Alles auswählen

 * Liste ebene 1
  * liste ebene 2
  * liste ebene 2
   * liste ebene 3
  * liste ebene 2
   * liste ebene 3
 * Liste ebene 1
    * Liste ebene 4
 * Liste ebene 1
   * Liste ebene 3
Deine Variante (zwei Leerzeichen zum Einrücken):

Code: Alles auswählen

 * Liste ebene 1
   * liste ebene 2
   * liste ebene 2
     * liste ebene 3
   * liste ebene 2
     * liste ebene 3
 * Liste ebene 1
       * Liste ebene 4
 * Liste ebene 1
     * Liste ebene 3
Zwei Leerzeichen für das Einrücken zu nehmen, finde ich besser, da man die Ebenen besser erkennen kann.

Beide Listen ergeben das selbe Ergebnis. Wobei MoinMoin da eigentlich einen Fehler macht. Denn die letzten (Ebene 4 und Ebene 3) sind eigentlich nicht in der richtigen Ebene.
Aber vielleicht ist das auch extra gemacht um "Fehler" auszugleichen oder so...

CMS in Python: http://www.pylucid.org
GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
BlackJack

Montag 18. Juni 2007, 10:00

Ich würde das nicht als Fehler bezeichnen sondern als sinnvoll. Was hätte denn eine 4. Ebene in einer Liste zu suchen für die es keine 3. Ebene gibt? Gibt's ein Beispiel aus der Praxis, wo man so etwas gerne hätte?
EnTeQuAk
User
Beiträge: 986
Registriert: Freitag 21. Juli 2006, 15:03
Wohnort: Berlin
Kontaktdaten:

Montag 18. Juni 2007, 11:57

Ich würde das nicht als Fehler bezeichnen sondern als sinnvoll. Was hätte denn eine 4. Ebene in einer Liste zu suchen für die es keine 3. Ebene gibt? Gibt's ein Beispiel aus der Praxis, wo man so etwas gerne hätte?
Was ja nicht gerade falsch ist ;)

Aber (ich kann jetz grad nicht bei MoinMoin schauen) macht es wirklich sinn, das einfach zu unterdrücke und maximal zwei Ebenen zu rendern? Und die, die rein theoretisch darüber hinaus gehen würden, einfach als zweite Ebene darzustellen?


EIn Anwendungsgebiet: Verschachtelte Horizontale Menüs. Also Menüs, die einmal aufklabbar sind, kommen dann in die erste Ebene, und diese nochmal Unterverzeichnisse haben.
Oder zähle ich da falsch?


MfG EnTeQuAk
BlackJack

Montag 18. Juni 2007, 17:41

Ich versehe Dein Beispiel mit den Menüs nicht. Da ist doch auf jeden Fall immer mindestens ein Menüpunkt pro Ebene. Wenn es zum Beispiel in der 3. Ebene keinen Punkt gibt, wo würde man denn draufklicken um die vierte Ebene aufzuklappen?
Y0Gi
User
Beiträge: 1454
Registriert: Freitag 22. September 2006, 23:05
Wohnort: ja

Dienstag 19. Juni 2007, 11:55

Ich gehe mal davon aus, dass einfach z.B. die dritttiefste Einrückung die dritte Ebene bildet, egal wie weit sie eingerückt ist. Weitere, ebenso tief eingerückte Punkte fallen dann ebenfalls in diese Ebene.

Python macht es beim Quellcode auch nicht viel anders, hauptsache die Einrücktiefe eines Blocks ist für jede Zeile gleich.
Antworten