2

MarkdownのようなマークアップからHTMLへの翻訳者を書いています。順序付き/順序なしリストの翻訳を除いて、スクリプトを完了しました。重要な空白(別名オフサイドルール)に基づいてリストをフォーマットしたい。有効な入力の例は次のとおりです。

:: List item 
   top level
 :: List item level 2
 :: List item level 2
    :: List item level 3
      :: List item level 4
 :: List item level 2

:: List item top level

::リストアイテムを示します。インデントレベルは任意である可能性があります。タブは重要ではありません。私は紙の上の解決策に取り組んできましたが、実装する方法を見つけることができませんでした。これについてはどうすればよいですか?

PS:それが複数ある限り、任意のスペースの量は、Pythonのように新しいレベルを示します。

私はこれを実装するためにPythonを使用していますが、コードを探していません。やり方の説明が欲しいです。そしてできれば、ライブラリなしで完全なものを自分で実装したいと思います。このマークアップをjekyllブログに使用しますが、これは私にとっては小さなツールではありません。このプロジェクトから正規表現と構文解析についてできるだけ多くのことを学びたいと思います。前もって感謝します。

4

2 に答える 2

3

Pythonリファレンスへの@delnanのリンクは良いアプローチを提供しますが、(リファレンス自体が示唆するように)Pythonは正しいインデントを可能にします。

アプリケーションでは、異なるリスト レベルを示すためにインデント スペースの一意の数が必要な場合、ユーザーの混乱が少なくなる可能性があります。これらのセマンティクスについては、Python 3 のわずか 4 行でリストのレベルを見つけることができます。コードで解決策を見たいとは思わなかったでしょう (ただし、必要に応じて投稿したいと思います)。私のアプローチはおおよそ次のとおりでした:

  1. リストの各行の先頭にあるスペースの数を数えます (正規表現は必要ありません)。
  2. セットを作成し、それを並べ替えて、このリストの各レベルで使用されるインデント スペースの数のリストを最小から最大の順に並べます。
  3. それぞれのケースで使用されるインデント スペースの数をリスト レベルに関連付ける辞書を作成します。
  4. リストの各行の先頭にあるスペースの数を使用してその辞書を参照します。これにより、各行のリスト レベルが得られます。

(コードを含め、複数行のリスト項目を処理するために編集)

与えられた:

:: List item
   (this is the second line of the first list item)
 :: List item level 2
 :: List item level 2
    :: List item level 3
      :: List item level 4
 :: List item level 2
:: List item top leve

... 以下の関数はリストを生成します:

:: List item (this is the second line of the first list item)
 :: List item level 2
 :: List item level 2
  :: List item level 3
   :: List item level 4
 :: List item level 2
:: List item top level

... これは、このテスト ケースの意図した結果だと思います。

標準入力からリストを受け入れるように書かれたコードは次のとおりです。

import sys

def findIndent (lst):
    # given a list of text strings, returns a list containing the
    # indentation levels for each string
    spcCount = [len(s)-len(s.lstrip(' ')) for s in lst]
    indent = sorted(set(spcCount))
    levelRef = {indent[i]:i for i in range(len(indent))}
    return [levelRef[i]+1 for i in spcCount]

lst = []
for li in sys.stdin:
    if li.lstrip(' ').find('::') == 0:
        lst.append(li.rstrip())
    else:
        lst[-1] = lst[-1].rstrip() + ' ' + li.lstrip(' ').rstrip()

for i,li in zip(findIndent(lst),lst):
    print (' '*i + li.lstrip())
于 2013-03-03T04:53:42.787 に答える
0

答えではありませんが、ブロックの書式設定が必要です。

これはどのレベルのリストに解析する必要がありますか?

:: List item level 
  :: List item level ?
 :: List item level ?
    :: List item level ?
 :: List item level ?
   :: List item level ?

リストでは意味をなさないコーナーケースに対処しようとしていると思いますが、実際にはユーザーにもっと有効なものを書くように指示する必要があります。

于 2013-03-02T16:20:31.970 に答える