Seite 1 von 1

Valide HTML Listen erstellen

Verfasst: Sonntag 17. Juni 2007, 15:51
von EnTeQuAk
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

Verfasst: Sonntag 17. Juni 2007, 19:36
von thelittlebug
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

Verfasst: Sonntag 17. Juni 2007, 21:34
von EnTeQuAk
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

Verfasst: Sonntag 17. Juni 2007, 22:40
von thelittlebug
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

Re: Valide HTML Listen erstellen

Verfasst: Montag 18. Juni 2007, 09:43
von jens
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...

Verfasst: Montag 18. Juni 2007, 10:00
von BlackJack
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?

Verfasst: Montag 18. Juni 2007, 11:57
von EnTeQuAk
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

Verfasst: Montag 18. Juni 2007, 17:41
von BlackJack
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?

Verfasst: Dienstag 19. Juni 2007, 11:55
von Y0Gi
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.