Terminalausgabe bunt machen

Code-Stücke können hier veröffentlicht werden.
Benutzeravatar
snafu
User
Beiträge: 6741
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Nur hab ich bei PyParsing eben so Dinge wie `nestedExpr()` gesehen. Ich sträube mich ehrlich gesagt ein bißchen, das in regulären Ausdrücken nachzuimplementieren, wenn es doch schon eine Bibliothek gibt, die sowas unterstützt. Sonst heißt es auch immer, man soll das Rad nicht neu erfinden. Bei so ziemlich jedem Thread, der fragt, wie man bestimmte Teile aus dem Quelltext einer Website holen kann, wird sofort auf ElementTree & Co verwiesen und jetzt plötzlich soll es keine gute Idee sein, PyParsing zu verwenden, weil es Overkill ist? Sorry, aber je mehr ich darüber nachdenke, desto weniger kann ich diese Haltung nachvollziehen.
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Naja, ElementTree ist teil der Stdlib, daher kostet die verwendung davon nichts, wohingegen PyParsing ein externes Dependency ist.

Also wenn ich sowas machen sollte würde ich mir inzwischen eher funcparserlib, pyPEG oder picoparse anschauen. Wenn ich unbedingt eine Parser-Library nutzen will.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Benutzeravatar
snafu
User
Beiträge: 6741
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Die Sache ist halt, dass ich reinen Regex-Code persönlich schlecht lesbar und somit auch schlecht wartbar sowie fehleranfällig finde, sobald man dann doch mal irgendeinen Fall vergessen hat. Eben ähnlich wie beim Parsen von HTML. Dass solche Module nicht in der Stdlib integriert sind, ist für mich auch wirklich das einzige Gegenargument. Ich denke aber, man kann vom Benutzer in dem Fall ruhig erwarten, dass er ein Modul via Paketmanager bzw easy_install nachinstalliert, denn das Parsen des Markups ist hier ja ein wesentlicher Bestandteil.

Danke übrigens für die Links. PyParsing hatte ich nur aus dem Grund gewählt, weil mir nichts anderes bekannt war. :oops:
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

snafu hat geschrieben:Die Sache ist halt, dass ich reinen Regex-Code persönlich schlecht lesbar und somit auch schlecht wartbar sowie fehleranfällig finde, sobald man dann doch mal irgendeinen Fall vergessen hat.
Also ich finde meinen Parser in PyParsing direkt noch schlechter lesbar und wartbar, weil der komische Sachen macht und ich immer dem Autor mailen muss, der mir dann ein noch hässlicher ausschauendes Codeschnippsel zurückmailt, das diesen Bug nicht hat.

Wie gesagt: nicht begeistert.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Benutzeravatar
snafu
User
Beiträge: 6741
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

:D

Naja, ich werde mir wahrscheinlich `funcparser` näher ansehen. Da gibt es ja sogar ein Tutorial zum Thema Verkettung. Was auch eine Idee wäre: Erstmal mit einem solchen Hilfstool alles aufbauen bis es läuft und anschließend die relevanten Teile rauskopieren. Mir ist besonders beim `picoparser` aufgefallen, dass der relativ simpel strukturiert ist.
funcparserlib is a library for recursive descent parsing using parser
combinators. The parsers made with its help are LL(*) parsers. It means that
it's very easy to write them without thinking about look-aheads and all that
hardcore parsing stuff. But the recursive descent parsing is a rather slow
method compared to LL(k) or LR(k) algorithms. So the primary domain for
funcparserlib is parsing small languages or external DSLs (domain specific
languages).
Hört sich doch insgesamt ganz okay an.
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

snafu hat geschrieben:Bei so ziemlich jedem Thread, der fragt, wie man bestimmte Teile aus dem Quelltext einer Website holen kann, wird sofort auf ElementTree & Co verwiesen und jetzt plötzlich soll es keine gute Idee sein, PyParsing zu verwenden, weil es Overkill ist?
Erstens wirst du von mir selten das NIH-Argument hören, denn ich bin im Zweifel lieber für die einfache eigene Lösung als eine Abhängigkeit zu einer anderen Bibliothek und zweitens ist das IMHO nicht vergleichbar, denn das Problem, das in der Realität meist total kaputte HTML zu parsen ist schwer im Vergleich dazu, Sternchen in Escape-Sequenzen zu verwandeln. Und während HTML immer rekursiv ist, würde ich die Escape-Sequenzen nicht schachteln. Da stößt du sowieso an die Grenzen was so ein VT-100-Terminal so kann.

Stefan
Benutzeravatar
snafu
User
Beiträge: 6741
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Also bisher hat das Terminal kein Problem mit fett blinkend unterstrichen grüner Schrift auf gelbem Hintergrund. Und bei Rekursion wird's echt übel. Da dies an sich nicht in einer Python-Regexp möglich ist, müsste man drum herum bauen. Ich überlege schon, ob ich in diesem Fall nicht lieber Perl nutzen möchte. Letztlich spielt ja das Markup die Hauptrolle und die Definition der SGR-Konstanten ist ja nun nicht sehr Python-spezifisch. Die Beschränkungen von Python sind hier eher hinderlich und ich sehe eigentlich nicht ein, wieso ich auf die Rekursion verzichten sollte, nur weil Python da nicht mitmacht.
Benutzeravatar
snafu
User
Beiträge: 6741
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Nachdem mir das bisher alles noch nicht so zugesagt hat, werde ich mal einen Blick auf Plex werfen, wo mir vor allem der ereignisorientierte Ansatz gefällt. Eventuell nehme ich die Klamotte am Wochenende nochmal in Angriff. Mal sehen...
Benutzeravatar
snafu
User
Beiträge: 6741
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Neue Version mit anderem Markup. Farben und Escapen sind noch nicht implementiert.

http://paste.pocoo.org/show/169413/

EDIT: Ich merke gerade, dass das noch nicht mit überlappenden Verschachtelungen klar kommt. Wird also noch geändert.
jerch
User
Beiträge: 1669
Registriert: Mittwoch 4. März 2009, 14:19

@snafu:
Falls Du noch an der farbigen Konsolenausgabe interessiert bist, hier mal eine einfache Version für Windows --> http://paste.pocoo.org/show/200261/
Vllt. willst Du ja eine plattformübergreifende Lösung erstellen.

Das Markup ist ziemlich simpel gehalten, da kannst Du sicher nachbessern.
Was geht:
Vordergrund-/Hintergrundfarbe und Intensität setzen (vergleichbar mit bold) und diese wiederzurücksetzen, wobei es keine "inneren" Farbereiche gibt, sondern der Ausgangswert wiederhergestellt wird. Mit '{@' lassen sich die Tags escapen, desweiteren gibts noch eine 'clrscr()'-Methode und eine Methode zum Setzen der Farbe für die gesamte Konsole.
Blinken und Unterstreichen funktioniert in Windows leider nur mit CJK-Schriften, daher hab ichs nicht weiterverfolgt.

Grüße jerch
Benutzeravatar
hendrikS
User
Beiträge: 420
Registriert: Mittwoch 24. Dezember 2008, 22:44
Wohnort: Leipzig

@jerch: Super! :D
Benutzeravatar
snafu
User
Beiträge: 6741
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Das Projekt lebt ürigens noch. Hier nochmal die wichtigsten Attribute auf einem Blick:

Code: Alles auswählen

states = {
    'background': {
        'black': 40,
        'blue': 104,
        'cyan': 106,
        'default': 49,
        'green': 102,
        'magenta': 105,
        'red': 101,
        'yellow': 103,
        'white': 107},
    'blink': 5,
    'blink_off': 25,
    'bold': 1,
    'bold_off': 22,
    'foreground': {
        'black': 30,
        'blue': 94,
        'cyan': 96,
        'default': 39,
        'green': 92,
        'magenta': 95,
        'red': 91,
        'yellow': 93,
        'white': 97},
    'inverse': 7,
    'inverse_off': 27,
    'reset': 0,
    'strike': 9,
    'strike_off': 29,
    'underline': 4,
    'underline_off': 24}
Hilfe zum Zusammensetzen:

Code: Alles auswählen

ESC = '\x1b'
CSI = ESC + '['

def make_sequence(*num_attrs):
    attrs = ';'.join(str(attr) for attr in num_attrs)
    return '{0}{1}m'.format(CSI, attrs)
Ich habe inzwischen auch eine Syntax für die möglichst einfache Anwendung innerhalb von Strings im Kopf:

- Attribute werden in spitzen Klammern geschrieben
- Für die Vordergrundfarbe wird ein `#` vor den Namen geschrieben
- Für die Hintergrundfarbe ein `&`
- Ein `/` vor dem Namen meint das entsprechende "Off-Attribut"
- Ein `/` ohne Namen meint `reset`
- Ein `/#` steht für `default` als Vordergrund
- Analog dazu `/&`
- Mehree Attributnamen werden durch `,` getrennt
- Whitespace zwischen Trenner und Attributnamen wird ignoriert
- Zugriff auf die Namen ist unabhängig von Groß- und Kleinschreibung
- Der Parser ist keine State-Machine, ein `/` ist wie gesagt einfach eine Art Synonym

Beispiele:

'This is a <bold,#red>very</> important thing.'
'<#green,&black>That message from outer space <bold>must</bold> end somehow.</>'
BlackJack

@snafu: So nah an XML aber dann doch wieder was eigenes -- ich weiss nicht.
Benutzeravatar
snafu
User
Beiträge: 6741
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Du meinst das jetzt nur wegen den spitzen Klammern und dem Slash, welche den Leser verwirren könnten oder weswegen genau? Ich finde halt, spitze Klammern heben sich besser hervor als eckige.

Und dann noch in die Runde gefragt: Was haltet ihr von der jetzigen Lösung, die ja ohne Verschachtelung und Zuständen auskommen soll?
Benutzeravatar
snafu
User
Beiträge: 6741
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Habe es jetzt mal als Tefos 0.0.1 rausgebracht. Das Formatting ist natürlich noch sehr beschissen und wird noch den angekündigten Parser bekommen. Auch zusätzliche Farben werden beim nächsten Mal aufgenommen.

Bild
Benutzeravatar
lynadge
User
Beiträge: 112
Registriert: Sonntag 4. April 2010, 10:17

Hi, ich finde das Thema Markup recht Interessant.

Um deine Syntax ein bisschen simpler zu halten, wie wäre es wenn du es ähnlich machst wie defnull es schon auf der ersten seite angesprochen hatte, nur halt mit spitzen Klammern: <bold,#red TEXT>

Ich bin der meinung das sich das um ein vielfaches leichter schreiben lässt. Evtl kannst du den Text ja noch mit einer Pipe abgrenzen: <bold,#red|TEXT>

Natürlich hat man auch noch die Möglichkeit zu verschachteln: <bold,#red|ROT <#blue|BLAU>>

Was hälst du von diesem Vorschlag?

#Edit
Ich sehe gerade, jerch hat einen ähnlichen Vorschlag gemacht. ;)
Benutzeravatar
snafu
User
Beiträge: 6741
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Der Parser wird wohl folgende Syntax kriegen: `[[attr1,attr2,attr3: bla bla bla]]`.
Benutzeravatar
snafu
User
Beiträge: 6741
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Tefos 0.0.2 ist draußen. :)

Bild

Bitte beachtet, dass der Parser entsprechend der Versionierung noch sehr dumm ist. Es werden bisher stumpf Klammernpaare ersetzt. Weder Verschachtelung, noch Escaping klappt derzeit. Wenn man sich genau an die Regeln hält und keine "unerwarteten" Klammern einbaut, läuft es jedoch wie im Beispiel. Weitere Verbesserungen folgen natürlich noch.
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Hab mir auch was gebastelt, allerdings ohne ein "markup":
http://paste.pocoo.org/show/271344/

sieht dann so aus:

Code: Alles auswählen

    >>> c = ColorOut()
    >>> c.colorize('no color')
    'no color'
    >>> c.colorize('bold', opts=("bold",))
    '\\x1b[1mbold\\x1b[0m'
    >>> c.colorize("colors!", foreground="red", background="blue", opts=("bold", "blink"))
    '\\x1b[31;44;1;5mcolors!\\x1b[0m'
Es wird auch geprüft, ob überhaupt Escape Sequenzen nutzbar sind...

Das ganze ist geklaut von django, siehe: http://code.djangoproject.com/browser/d ... mcolors.py

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Dav1d
User
Beiträge: 1437
Registriert: Donnerstag 30. Juli 2009, 12:03
Kontaktdaten:

Sphinx hat da auch was dabei...
the more they change the more they stay the same
Antworten