2012-08-28 13 views
5

Jestem początkujący programista więc to pytanie może wydawać się trywialna: Mam kilka plików tekstowych zawierajacego tabulatorami tekstu jak:Konwertuj tekst z kartami na nieuporządkowaną listę html?

A 
    B 
    C 
     D 
     E 

Teraz chcę generować nieuporządkowane listy .html się z tego, ze strukturą :

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

Mój pomysł był napisać skrypt Pythona, ale jeśli jest łatwiejsze (automatyczny) sposób, który też jest w porządku. Identyfikacji nazwę poziomu wcięcia i artykuł chciałbym spróbować użyć tego kodu:

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] 

Odpowiedz

2

tokenize module Rozumie twój format wejściowy: linie zawierają poprawne identyfikatory Pythona, poziom wcięcia instrukcji jest znaczący. ElementTree module pozwala manipulować struktury drzewa w pamięci, więc może to być więcej flexable aby oddzielić tworzenie drzewie od czyniąc go jako HTML:

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 

Każda klasa, która zapewnia .start(), .end(), .data(), .close() metody mogą być stosowane jako TreeBuilder np. można po prostu napisać html w locie zamiast budować drzewo.

do analizowania stdin i stdout napisać HTML można użyć ElementTree.write():

import sys 

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

wyjściowa:

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

Można użyć dowolnego pliku, a nie tylko sys.stdin/sys.stdout.

Uwaga: Aby napisać do stdout na Pythonie 3, użyj sys.stdout.buffer lub encoding="unicode" z powodu rozróżnienia bajtów/znaków Unicode.

0

myślę, że algorytm jest tak:

  • śledzić na obecnym poziomie wcięcia (licząc liczbę zakładek w linii)

  • jeśli wzrost poziomu wcięcia: emitują <ul> <li>current item</li>

  • Jeśli natomiast indentati na poziom spada: emitują <li>current item</li></ul>

  • jeśli poziom wcięcia pozostaje taka sama: emitują <li>current item</li>

Wyrażając to w kodzie jest pozostawiony PO jak ćwiczenia

5

Spróbuj tego (działa na badania przypadek):

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) 

Nadzieja to pomaga

-1

Algorytm jest prosty. Bierzesz poziom głębokości linii oznaczonej tabulatorem \ ti przesuwasz następny punkt w prawo \ t + \ t lub w lewo \ t \ t \ \ t lub pozostawiasz go na tym samym poziomie \ t.

Upewnij się, że twój "in.txt" zawiera zakładki lub zastąp wcięcie zakładkami, jeśli skopiujesz je stąd. Jeśli wcięcie zostało wykonane z pustych pól, nic nie działa. A separator to pusty wiersz na końcu. Możesz go zmienić w kodzie, jeśli chcesz.

J.F. rozwiązanie Sebastiana jest w porządku, ale nie przetwarza Unicode.

Utwórz plik tekstowy "in.txt" w kodowaniu UTF-8:

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

i uruchom skrypt "ul.py". Skrypt utworzy "out.html" i otworzy go w Firefoksie.

#!/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 będą:

<!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> 
Powiązane problemy