次のような 1 行のみを含む html ソース ファイルがあります。
<html><head>test</head><body>wow</body></html>
、そして次のようにフォーマットしたい:
<html>
<head>
test
</head>
<body>
wow
</body>
</html>
、次のコマンドを使用しました: Edit-> Line-> Reindent ですが、機能しません。
次のような 1 行のみを含む html ソース ファイルがあります。
<html><head>test</head><body>wow</body></html>
、そして次のようにフォーマットしたい:
<html>
<head>
test
</head>
<body>
wow
</body>
</html>
、次のコマンドを使用しました: Edit-> Line-> Reindent ですが、機能しません。
崇高なテキストでこれを試してください:
>
"Find
> Quick Add Next
( Mac ではCommand+ 、PC では +)を使用します。DCtrlD複数の選択ですべての出現箇所が強調表示され、キャレットをタグの最後に移動し、Return キーを押して必要なすべての新しい行を挿入します。
幸運を
Sublime もこの機能を提供しているという印象を受けました。そうではないことがわかったとき、正規表現を使用するという考えが浮かびました。通常、正規表現は XML/HTML の解析には不適切であると考えられていますが、この場合はこのアプローチが受け入れられることがわかりました。Sublimeはプラグインによるカスタマイズ性が高いとも言われているので、その方法はあると思います。
正直なところ、tidy
あなたの問題に対処するプラグインがそこにあるに違いないと考えるか、少なくとも疑うことができました. 代わりに、最初の崇高なプラグインを作成することになりました。私はあなたの入力と期待される出力でテストしただけですが、それは満足していますが、確実に動作するにはほど遠いです. ただし、私が学んだことを共有するためにここに投稿しますが、それでも問題に対する答えです。
Ctrl+n新しいバッファ ( ) を開き、メニューの [ツール] で [新しいプラグイン... ] エントリを選択すると、 「Hello World!」という小さなメッセージが気前よく生成されます。サブクラスを実装するための優れたテンプレートを提供するプラグインの例 (Python モジュールとして) 。TextCommand は、アクティブなバッファー/現在開いているファイルへのアクセスを提供します。親類の や と同様に、run-method を上書きする必要があります。sublime_plugin.TextCommand
WindowCommand
ApplicationCommand
公式のAPI リファレンスでは、Sublime ビルドと共に配布され、Packages/Default
Sublime 構成パスに関連する場所にあるサンプル ソースを読んで学習することを提案しています。その他の例は、 Web サイトで見つけることができます。インターネットにはもっと あります。
View
問題を解決するには、主にアクティブなテキスト バッファを表すオブジェクトにアクセスする必要があります。幸いなことに、TextCommand
実装しようとしているサブクラスにはサブクラスがあり、現在選択されている領域とその選択内容を簡単に要求し、必要に応じて選択したテキストを処理し、後で選択したテキストを好みのものに置き換えることができます。
文字列操作を要約すると、次のようになります。 4 つの正規表現があり、それぞれが要素クラス<start-tag>
、<empty-tag/>
、</close-tag>
およびのいずれかに一致しtext-node
ます。すべてのマークアップ テキストがこれらでカバーされていると仮定して、選択の各行を一致する部分文字列にしました。これらは、1 行に 1 つずつ再配置されます。これを行った後、前の行に開始タグが含まれるすべての行をインデントすることを忘れずに、単純なインデントを適用します。終了タグを含む行はすぐにインデント解除されます。
Python 正規表現のグループ アドレス指定機能を使用して、すべての行のインデントを決定し、それに応じて次の行を揃えることができます。これにより、余計な手間をかけずに、内部的に一貫性のあるインデントされたマークアップが得られますが、選択範囲外の行は考慮されません。選択範囲を囲み要素に拡張するか、少なくとも隣接する行のインデント レベルに準拠することで、結果を簡単に改善できます。デフォルトのコマンドを使用することは常に可能です。
もう 1 つ気を付けなければならないことは、キーをプラグイン コマンドにバインドし、メニュー エントリを提供することです。おそらく何らかの形で可能であり、デフォルト.sublime-menu
と.sublime-commands
ファイルはPackages/Default
少なくともアイデアを提供します。とにかく、ここにいくつかのコードがあります。以下に保存する必要があり、次のように Sublime Python コンソール ( )Packages/User/whatever.py
から呼び出すことができます。Ctrl+`
view.run_command('guess_indentation')
import sublime
import sublime_plugin
import re
class GuessIndentationCommand(sublime_plugin.TextCommand):
def run(self, edit):
view = self.view
#view.begin_edit()
# patterns
start_tag = '<\w+(?:\s+[^>\/]+)*\s*>' # tag_start
node_patterns = [start_tag,
start_tag[:-1]+'\/\s*>', # tag_empty
'<\/\s?\w+\s?>', # tag_close
'[^>\s][^<>]*[^<\s]'] # text_node
patterns = '(?:{0})'.format('|'.join(node_patterns))
indentors = re.compile('[ \t]*({0})'.format('|'.join(node_patterns[:1])))
unindentors=re.compile('[ \t]*({0})'.format(node_patterns[2]))
# process selected text
for region in view.sel():
# if selection contains text:
if not region.empty():
selection = view.substr(region)
expanded = []
# divide selected lines into XML elements, if it contains more than one
for line in selection.split('\n'):
elements = re.findall(patterns, line)
if len(elements)>0:
expanded += elements
else:
expanded.append(line)
# indent output
indent=0
indented = []
for line in expanded:
match = unindentors.match(line)
if match:
indent = max(0, indent-1)
# append line to output, unindented if closing tag
indented.append('\t'*indent+line)
if match:
continue
# test for possible indentation candidate
# indentation applies to the NEXT line
match = indentors.match(line)
if match:
indent+=1
# replace selection with aligned output
view.replace(edit, region, '\n'.join(indented))
簡単なものであれば、タグをインデントするマクロを記録し(ツール - >マクロの記録)、保存してこのマクロを再利用することができました。それが役立つかどうかはわかりません。