Seite 1 von 1

[gelöst]Brauche ein wenig hilfe, bei einem Markup-Parser

Verfasst: Donnerstag 5. April 2007, 15:24
von EnTeQuAk
Hallo...

Ich bin seit heute Morgen dabei den bisherigen Markup-Parser für daucms umzuschreiben.

Die frühere Version war zwar einfach einfacher und ansich recht perfekt, jedoch wollte ich einfach mal was neues ausprobieren.

Das bisherige Ergebnis kann man hier sehen:
http://daucms.de/trac/browser/daucms/utils/dautext.py

Ich teste immer erstmal immer mit der Tesffunktion unten.

zum testen bitte beachten: http://daucms.de/trac/browser/daucms/ut ... ext.py#L57

Dadurch wird der Parser nicht komplett ausgeführt.

zZ bekomme ich folgende Ausgabe:

Code: Alles auswählen

('text', '\n**bold**\n__underline__\n__underline2__\n//italic//\n#link[www.dadad.xy]\n** bold __ underlinebold __ **')
('text', '')
('text', '')
('text', '')
('text', '')
('text', '')
('text', '')
('text', '')
('text', '')
('text', '')
('text', '\n\n\n\n\n\n')
('text', '')
('text', '')
('text', '')
('text', '')
('text', '')
('text', '')
('text', '')
('text', '')
('text', '')
('text', '\n')
('text', '')
('text', '')
('text', '')
('text', '')
('text', '')
('text', '')
('text', '')
('text', '')
('text', '')
('text', 'lalalal')
('text', '')
('text', '')
('text', '')
('text', '')
('text', '')
('text', '')
('text', '')
('text', '')
('text', '')
Und hier meine Frage:
Warum zum teufel, findet er nur 'text'-Tokens und geht auf die anderen nicht ein?

MfG EnTeQuAk

€dit:
und warum so viele leere Text-Tokens ausgegeben werden, wüsste ich auch gerne.

Freue mich über Hilfe. zZ komme ich einfach nicht weiter

Verfasst: Donnerstag 5. April 2007, 15:46
von EnTeQuAk
Sorry, für den Doppelpost aber ich hab nun einen kleinen Teil fixen können.

Links sind die selben.

Die Ausgabe schaut nun so aus ;)

Code: Alles auswählen

('br', '\n')
('bold', '**bold**')
('underline', '__underline__')
('italic', '//italic//')
('text', '\n#link[www.dadad.xy]\n** bold __ underlinebold __ **\n\n\n\n\n\nlalalal')
('text', '')
('text', '')
('text', '')
('text', '')
('text', '')

Verfasst: Donnerstag 5. April 2007, 19:12
von birkenfeld
Wenn einmal eine RE nicht matcht, dann gibst du den gesamten Rest als "text" zurück:

yield self.untitled_token, raw[pos:]
pos = len(raw)

Die restlichen "text"s kommen daher, dass du noch alle weiteren regexes in der Liste durchgehst.

Du darfst "text" nur zurückgeben, wenn *keine* RE matcht. Wenn du "break" im "if m"-branch verwendest und den "else"-branch auf das Level des "for" verschiebst, funktioniert es.

Verfasst: Donnerstag 5. April 2007, 19:57
von EnTeQuAk
habs verbessert. ;)

Super, Danke :)

Nur. Das mit dem 'break' mag ich nicht verstehen.

meinst du das so:

Code: Alles auswählen

        while not pos == len(raw):
            for name, regex, state in self.scan_re:
                m = regex.search(raw, pos)
                if m:
                    yield name, m.group()
                    pos = m.end()
                    break
            else:
                yield self.untitled_token, raw[pos:]
                pos = len(raw)
würde für mich logisch erscheinen. Klappt aber nicht ganz.

Mit 'break':
('br', '\n')
('br', '\n')
('br', '\n')
('br', '\n')
('br', '\n')
('br', '\n')
('br', '\n')
('br', '\n')
('br', '\n')
('br', '\n')
('br', '\n')
('br', '\n')
('text', 'lalalal')
ohne 'break':
('br', '\n')
('bold', '**bold**')
('underline', '__underline__')
('italic', '//italic//')
('special_link', '#link[www.dadad.xy]')
('text', '\n** bold __ underlinebold __ **\n\n\n\n\n\nlalalal')
Was ja schon ganz schick ausschaut ;)

Oder wo meintest du das mit dem 'break'. Ich meine ;) ich hab nur einmal ``if``. :)

Danke jedenfalls, schonmal. An solche kleinen Sachen denkt man immer zuletzt ;)

MfG EnTeQuAk

€dit:
Ich denke mal, das mit dem 'break' war schon richtig. Ich weiß auch, woran es liegt.
Er geht als erstes die Regex, mit dem Token-Namen 'br' durch. Er trifft (da ja in jeder zeile nen '\n' vorkommt und bricht ab.

Verfasst: Donnerstag 5. April 2007, 20:57
von birkenfeld
Ja, du musst search durch match ersetzen.

Und dass du bei "text" den ganzen restlichen String zurückgibst, ist immernoch falsch.

Verfasst: Freitag 6. April 2007, 10:11
von EnTeQuAk
So. Habe nun einiges geändert. Nun funktioniert es, fast.

Die normalen-Tokens werden ganz normal getroffen. Auch die Texttokens werden auch getroffen.

Aber ich habe die Vermutung, das meine Bedinung in Zeile 62 nicht die richtige ist.
Sie werden nämlich dem `_text_buffer` hinzugefügt, aber nie zurückgegeben.

Hier nochmal der wichtige Abschnitt. Die Links zu den ganzen Dateien stehen oben.

Code: Alles auswählen

    def lex(self):
        while self.pos < self.max:
            for name, regex, state in self.scan_re:
                m = regex.match(self.text, self.pos)
                if m is not None:
                    yield Token(name, m.group())
                    self.pos = m.end()
                    break
            else:
                if self.pos < self.max:
                    self._text_buffer.append(self.text[self.pos])
                else:
                    yield Token(self.text_token, u''.join(self._text_buffer))
                    del self._text_buffer[0:]
                self.pos += 1
MfG EnTeQuAk

Verfasst: Freitag 6. April 2007, 13:54
von birkenfeld
Du musst, sobald wieder eine Regex matcht, den Inhalt des Textbuffers vorher als Token zurückgeben.

Oder du fügst einfach eine "Text"-Regex hinzu, die auf Nur-Text matcht.

Verfasst: Freitag 6. April 2007, 16:14
von EnTeQuAk
Oder du fügst einfach eine "Text"-Regex hinzu, die auf Nur-Text matcht.
Yapp ;) hi hi

habe nun das ganze erstmal zum laufen bekommen.

Herzlichen Dank an dich!

MfG EnTeQuAk