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
Moderator
Beiträge: 8461
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Freitag 28. November 2008, 17:42

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???

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

Samstag 29. November 2008, 11:14

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

Samstag 29. November 2008, 20:00

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
Moderator
Beiträge: 8461
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Samstag 29. November 2008, 20:37

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...

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

Samstag 29. November 2008, 20:38

@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

Sonntag 30. November 2008, 00:52

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

Sonntag 30. November 2008, 10:37

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

Montag 1. Dezember 2008, 14:22

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
Administrator
Beiträge: 16024
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Montag 1. Dezember 2008, 15:32

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 Modvoice
lunar

Montag 1. Dezember 2008, 16:17

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

Mittwoch 3. Dezember 2008, 14:46

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

Mittwoch 3. Dezember 2008, 18:14

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.

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