Was zum optimieren: Markup Tabellen string formatieren...

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
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Für http://code.google.com/p/python-creole/ hab ich das gemacht:

Code: Alles auswählen

def format(table_content):
    lines = table_content.split("\n")

    len_info = {}
    for line in lines:
        cells = line.split("|")
        for no, cell in enumerate(cells):
            cell_len = len(cell)
            if no not in len_info:
                len_info[no] = cell_len
            elif len_info[no]<cell_len:
                len_info[no] = cell_len

    new_lines = []
    for line in lines:
        cells = line.split("|")
        for no, cell in enumerate(cells):
            cells[no] = cell.ljust(len_info[no])

        new_lines.append("|".join(cells))

    result = "\n".join(new_lines)
    return result


txt = """|= Headline|= a other\\headline|= the **big end**|
| a cell| a **big** cell| **//bold italics//**|
| next\\line| No == headline == or?| |
| | | open end|"""
print txt
print "-"*79
print format(txt)
Ausgabe:

Code: Alles auswählen

|= Headline|= a other\headline|= the **big end**|
| a cell| a **big** cell| **//bold italics//**|
| next\line| No == headline == or?| |
| | | open end|
-------------------------------------------------------------------------------
|= Headline|= a other\headline    |= the **big end**    |
| a cell   | a **big** cell       | **//bold italics//**|
| next\line| No == headline == or?|                     |
|          |                      | open end            |

Wie kann man das besser/einfacher machen???

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

Du willst es kürzer?

Code: Alles auswählen

def format(table_content):
    cells = [line.split("|") for line in table_content.splitlines()]
    widths = [max(map(len, col)) for col in zip(*cells)]
    return "\n".join("|".join(cell.ljust(width) for cell, width in zip(row, widths)) for row in cells)
Stefan
derdon
User
Beiträge: 1316
Registriert: Freitag 24. Oktober 2008, 14:32

statt

Code: Alles auswählen

"\n".join(...)
ist es besser

Code: Alles auswählen

import os
os.linesep.join(...)
zu schreiben (OS-Unabhängig).
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Ja, ich wollte es nicht in jedem Fall kürzer, sondern ehr besser/einfacher ;) Oneliner bauen mag ich nicht :)

Es soll immer bei "\n" bleiben. Der Eingangs-Text sollte auf "\n" "normalisiert" werden...

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
BlackJack

@derdon: Keine so gute Idee, denn das ist unter Windows '\r\n' und wenn man *dass* dann unter Windows in eine Textdatei schreibt, erhält man '\r\r\n' weil das '\n' *nochmal* durch `os.linesep` ersetzt wird.
lunar

BlackJack hat geschrieben:@derdon: Keine so gute Idee, denn das ist unter Windows '\r\n' und wenn man *dass* dann unter Windows in eine Textdatei schreibt, erhält man '\r\r\n' weil das '\n' *nochmal* durch `os.linesep` ersetzt wird.
Dafür gibt es dann 'wb' ;)
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

jens hat geschrieben:Ja, ich wollte es nicht in jedem Fall kürzer, sondern ehr besser/einfacher ;) Oneliner bauen mag ich nicht :)
Mein Code ist besser/einfacher ;)

Die dritte Zeile ist zugegeben grenzwertig, doch auf meine Breitenberechnung lasse ich nichts kommen. Du brauchst dafür 9 hässliche Zeilen. Außerdem splittest du 2x das `|`. Ich mach's nur einmal. Du könntest die letzte Zeile ja einmal ausspalten.

Stefan
Benutzeravatar
helduel
User
Beiträge: 300
Registriert: Montag 23. Juli 2007, 14:05
Wohnort: Laupheim

lunar hat geschrieben:
BlackJack hat geschrieben:@derdon: Keine so gute Idee, denn das ist unter Windows '\r\n' und wenn man *dass* dann unter Windows in eine Textdatei schreibt, erhält man '\r\r\n' weil das '\n' *nochmal* durch `os.linesep` ersetzt wird.
Dafür gibt es dann 'wb' ;)
Versteh ich das richtig? Wenn ich unter Windows mit Python "\n" in eine Textdatei schreibe, dann konvertiert Python das automatisch nach "\r\n"?
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

helduel hat geschrieben:Versteh ich das richtig? Wenn ich unter Windows mit Python "\n" in eine Textdatei schreibe, dann konvertiert Python das automatisch nach "\r\n"?
Ja. Unter Python ist "\n" OS-unabhängig ein Newline, daher wird zum Speichern je nach OS ein anderes Line-Ending-Symbol verwendet.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
lunar

Leonidas hat geschrieben:
helduel hat geschrieben:Versteh ich das richtig? Wenn ich unter Windows mit Python "\n" in eine Textdatei schreibe, dann konvertiert Python das automatisch nach "\r\n"?
Ja. Unter Python ist "\n" OS-unabhängig ein Newline, daher wird zum Speichern je nach OS ein anderes Line-Ending-Symbol verwendet.
Ist das nicht imho sogar eine Sache der Windows-C-Standardbibliothek?
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

lunar hat geschrieben:Ist das nicht imho sogar eine Sache der Windows-C-Standardbibliothek?
Ja.
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

sma hat geschrieben:
jens hat geschrieben:Ja, ich wollte es nicht in jedem Fall kürzer, sondern ehr besser/einfacher ;) Oneliner bauen mag ich nicht :)
Mein Code ist besser/einfacher ;)
Ich hab nochmal was gemacht:

Code: Alles auswählen

def format_table(table_content):
    # Split and preformat every table cell
    cells = []
    for line in table_content.splitlines():
        line_cells = []
        for cell in line.split("|"):
            cell = cell.strip()
            if cell != "":
                if cell.startswith("="):
                    cell += " " # Headline
                else:
                    cell = " %s " % cell # normal cell
            line_cells.append(cell)
        cells.append(line_cells)

    # Build a list of max len for every column
    widths = [max(map(len, col)) for col in zip(*cells)]

    # Join every line with ljust
    lines = []
    for row in cells:
        cells = [cell.ljust(width) for cell, width in zip(row, widths)]
        lines.append("|".join(cells))

    return "\n".join(lines)


table_content = """|= Headline|= a other\\headline|= the **big end**|
| a cell|a **big** cell| **//bold italics//**|
| next\\line|     No == headline == or?| |
| | | open end|"""
print format_table(table_content)
Ausgabe:

Code: Alles auswählen

|= Headline |= a other\headline     |= the **big end**     |
| a cell    | a **big** cell        | **//bold italics//** |
| next\line | No == headline == or? |                      |
|           |                       | open end             |
Das Aufsplitten ist nun ein wenig komplizierter. Denn es soll besser mit zusätzlichen Leerzeichen umgegangen werden und ein Leerzeichen von und hinten ist auch nicht schlecht.

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Antworten