2012-08-28 6 views
5

Ich bin ein Anfänger-Programmierer so diese Frage trivial klingen mag: Ich habe einige Textdateien containg getabulatortrennte Text wie haben:Konvertieren von Tabbed Text in HTML ungeordnete Liste?

A 
    B 
    C 
     D 
     E 

Jetzt möchte ich aus dieser ungeordneten .html Listen erzeugen, mit der Struktur :

<ul> 
<li>A 
<ul><li>B</li> 
<li>C 
<ul><li>D</li> 
<li>E</li></ul></li></ul></li> 
</ul> 

war meine Idee, einen Python-Skript zu schreiben, aber wenn es eine einfachere (automatisch) Art und Weise ist, das ist auch in Ordnung. Für die Einrückungsebene und Artikelnamen identifizieren würde ich versuchen, diesen Code zu verwenden:

import sys 
indent = 0 
last = [] 
for line in sys.stdin: 
    count = 0 
    while line.startswith("\t"): 
     count += 1 
     line = line[1:] 
    if count > indent: 
     indent += 1 
     last.append(last[-1]) 
    elif count < indent: 
     indent -= 1 
     last = last[:-1] 

Antwort

2

tokenize module versteht Ihr Eingabeformat: Zeilen enthalten gültige Python-IDs, die Einrückungsebene der Anweisungen ist signifikant. ElementTree module können Ihnen Baumstrukturen im Speicher zu manipulieren, so dass es mehr flexable sein könnte, einen Baum Schaffung von einem Rendering es als HTML zu trennen:

from tokenize import NAME, INDENT, DEDENT, ENDMARKER, NEWLINE, generate_tokens 
from xml.etree import ElementTree as etree 

def parse(file, TreeBuilder=etree.TreeBuilder): 
    tb = TreeBuilder() 
    tb.start('ul', {}) 
    for type_, text, start, end, line in generate_tokens(file.readline): 
     if type_ == NAME: # convert name to <li> item 
      tb.start('li', {}) 
      tb.data(text) 
      tb.end('li') 
     elif type_ == NEWLINE: 
      continue 
     elif type_ == INDENT: # start <ul> 
      tb.start('ul', {}) 
     elif type_ == DEDENT: # end </ul> 
      tb.end('ul') 
     elif type_ == ENDMARKER: # done 
      tb.end('ul') # end parent list 
      break 
     else: # unexpected token 
      assert 0, (type_, text, start, end, line) 
    return tb.close() # return root element 

Jede Klasse, die .start() bietet, .end(), .data() können .close() Methoden verwendet werden, a TreeBuilder zB könnten Sie einfach HTML on the fly schreiben anstatt einen Baum zu erstellen.

stdin zu analysieren und schreiben html Sie ElementTree.write() nutzen könnten, um stdout:

import sys 

etree.ElementTree(parse(sys.stdin)).write(sys.stdout, method='html') 

Ausgang:

<ul><li>A</li><ul><li>B</li><li>C</li><ul><li>D</li><li>E</li></ul></ul></ul> 

Sie eine beliebige Datei verwenden können, nicht nur sys.stdin/sys.stdout.

Hinweis: Um in stdout auf Python 3 zu schreiben, verwenden Sie sys.stdout.buffer oder encoding="unicode" aufgrund von Bytes/Unicode-Unterscheidung.

0

Ich denke, der Algorithmus so geht:

  • halte Spur der aktuellen Einzugsebene (durch die Zahl Zählen Laschen pro Zeile)

  • wenn die Einrückung Erhöhung: <ul> <li>current item</li>

  • wenn die indentati emittieren emittieren <li>current item</li>

Umsetzung in dem Code links an die OP als Übung

5

Try this (funktioniert auf Ihrem Test: <li>current item</li></ul>

  • wenn die Einrückungsebene bleibt gleich emittieren: auf Ebene sinkt Fall):

    import itertools 
    def listify(filepath): 
        depth = 0 
        print "<ul>"*(depth+1) 
        for line in open(filepath): 
         line = line.rstrip() 
         newDepth = sum(1 for i in itertools.takewhile(lambda c: c=='\t', line)) 
         if newDepth > depth: 
          print "<ul>"*(newDepth-depth) 
         elif depth > newDepth: 
          print "</ul>"*(depth-newDepth) 
         print "<li>%s</li>" %(line.strip()) 
         depth = newDepth 
        print "</ul>"*(depth+1) 
    

    hoffe, das hilft

  • -1

    Der Algorithmus ist einfach. Sie nehmen die Tiefe einer Linie, die mit einem Tab \ t angegeben ist, und verschieben das nächste Geschoss nach rechts \ t + \ t oder nach links \ t \ t- \ t oder lassen es auf der gleichen Ebene \ t stehen.

    Stellen Sie sicher, dass Ihre "in.txt" Tabs enthält oder ersetzen Sie die Einrückung durch Tabulatoren, wenn Sie es von hier kopieren. Wenn der Einzug aus Leerzeichen besteht, funktioniert nichts. Und das Trennzeichen ist eine Leerzeile am Ende. Sie können es im Code ändern, wenn Sie möchten.

    J.F. Sebastians Lösung ist in Ordnung, verarbeitet aber nicht Unicode.

    Erstellen einer Textdatei "in.txt" in UTF-8-Codierung:

    qqq 
        www 
        www 
         яяя 
         яяя 
        ыыы 
        ыыы 
    qqq 
    qqq 
    

    und das Skript "ul.py" laufen. Das Skript erstellt "out.html" und öffnet es in Firefox.

    #!/usr/bin/python 
    # -*- coding: utf-8 -*- 
    
    # The script exports a tabbed list from string into a HTML unordered list. 
    
    import io, subprocess, sys 
    
    f=io.open('in.txt', 'r', encoding='utf8') 
    s=f.read() 
    f.close() 
    
    #--------------------------------------------- 
    
    def ul(s): 
    
        L=s.split('\n\n') 
    
        s='<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">\n\ 
    <html><head><meta content="text/html; charset=UTF-8" http-equiv="content-type"><title>List Out</title></head><body>' 
    
        for p in L: 
         e='' 
         if p.find('\t') != -1: 
    
          l=p.split('\n') 
          depth=0 
          e='<ul>' 
          i=0 
    
          for line in l: 
           if len(line) >0: 
            a=line.split('\t') 
            d=len(a)-1 
    
            if depth==d: 
             e=e+'<li>'+line+'</li>' 
    
    
            elif depth < d: 
             i=i+1 
             e=e+'<ul><li>'+line+'</li>' 
             depth=d 
    
    
            elif depth > d: 
             e=e+'</ul>'*(depth-d)+'<li>'+line+'</li>' 
             depth=d 
             i=depth 
    
    
          e=e+'</ul>'*i+'</ul>' 
          p=e.replace('\t','') 
    
          l=e.split('<ul>') 
          n1= len(l)-1 
    
          l=e.split('</ul>') 
          n2= len(l)-1 
    
          if n1 != n2: 
           msg='<div style="color: red;">Wrong bullets position.<br>&lt;ul&gt;: '+str(n1)+'<br>&lt;&frasl;ul&gt;: '+str(n2)+'<br> Correct your source.</div>' 
           p=p+msg 
    
         s=s+p+'\n\n' 
    
        return s 
    
    #-------------------------------------  
    
    def detach(cmd): 
        process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True) 
        sys.exit() 
    
    s=ul(s) 
    
    f=io.open('out.html', 'w', encoding='utf8') 
    s=f.write(s) 
    f.close() 
    
    cmd='firefox out.html' 
    detach(cmd) 
    

    HTML wird:

    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> 
    <html><head><meta content="text/html; charset=UTF-8" http-equiv="content-type"><title>List Out</title></head><body><ul><li>qqq</li><ul><li>www</li><li>www</li><ul><li>яяя</li><li>яяя</li></ul><li>ыыы</li><li>ыыы</li></ul><li>qqq</li><li>qqq</li></ul> 
    
    Verwandte Themen