将选项卡式文本转换为html无序列表?

Eli*_*lip 5 html python

我是初学程序员,所以这个问题可能听起来微不足道:我有一些文本文件包含制表符分隔的文本,如:

A
    B
    C
        D
        E
Run Code Online (Sandbox Code Playgroud)

现在我想生成无序的.html列表,结构如下:

<ul>
<li>A
<ul><li>B</li>
<li>C
<ul><li>D</li>
<li>E</li></ul></li></ul></li>
</ul>
Run Code Online (Sandbox Code Playgroud)

我的想法是写一个Python脚本,但如果有一个更容易(自动)的方式,那也没关系.为了识别缩进级别和项目名称,我将尝试使用此代码:

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]
Run Code Online (Sandbox Code Playgroud)

ins*_*get 5

试试这个(适用于你的测试用例):

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)
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助


jfs*_*jfs 2

tokenize模块理解您的输入格式:行包含有效的Python标识符,语句的缩进级别很重要。ElementTree模块允许您操作内存中的树结构,因此将树的创建与将其呈现为 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
Run Code Online (Sandbox Code Playgroud)

任何提供.start().end().data().close()方法的类都可以用作例如TreeBuilder,您可以即时编写 html,而不是构建树。

要解析标准输入并将 html 写入标准输出,您可以使用ElementTree.write()

import sys

etree.ElementTree(parse(sys.stdin)).write(sys.stdout, method='html')
Run Code Online (Sandbox Code Playgroud)

输出:

<ul><li>A</li><ul><li>B</li><li>C</li><ul><li>D</li><li>E</li></ul></ul></ul>
Run Code Online (Sandbox Code Playgroud)

您可以使用任何文件,而不仅仅是sys.stdin/sys.stdout.

注意:要在 Python 3 上写入 stdout,请使用sys.stdout.bufferencoding="unicode"由于字节/Unicode 的区别。