2

作成時には Pandoc を使用し、より複雑なテーブルには HTML コードを貼り付けます。これにより、ファイルが乱雑に見える可能性があるため、Vim の foldexpr を使用して、正規表現を使用してこれらのテーブル要素を折り畳みたいと思います。この正規表現:

<table\b[^>]*>(?:(?=([^<]+))\1|<(?!table\b[^>]*>))*?</table>

Sublime Text と BBEdit でテーブル コードを強調表示するように機能しますが、Vim (非常に私の選択したエディター) で機能させることができないようです。

「Vim Scripting the Hardway」を見て、私は次のような単純な関数を書きたいと思っていました:

setlocal foldmethod=expr setlocal foldexpr=GetTableFold(v:lnum)

function! GetTableFold(lnum)
    if getline(a:lnum) =~? '\v<table\b[^>]*>(?:(?=([^<]+))\1|<(?!table\b[^>]*>))*?  </table>
    return '-1'
endif
return '0'
endfunction

ファイル内のテーブル要素を非表示にするために、機能しません。Vim で正規表現を簡単に検索しようとすると、「E64: ? follow nothing」というエラーも表示されます。

どんなアイデアでも大歓迎です!

4

1 に答える 1

3

これを行う方法にはいくつかの問題があります。1 つには、(Ingo が指摘したように) 正規表現に構文の問題があります。また、vim がフォールド レベルを計算する方法をよく理解していないと思います。Vim は、ファイル内のすべての行に対して関数「GetTableFold」を 1 回呼び出します。これにより、その特定の行の折りレベルが返されます。行番号以外のコンテキストがないため、行を複数の行にまたがる正規表現に一致させることはできません。代わりに、ラインがこの範囲内にあるかどうかを手動で計算する必要があります。

私はしばらくvimscriptを書いていないので、これは少しバグがあるかもしれませんが、私が試したいくつかの単純なケースではうまくいくようです. 少なくとも、どこから始めるべきかのベースを提供する必要があります。

function GetTableFold(lnum)
    let n = a:lnum
    while n > 0
        let currline = getline(n)
        let prevline = getline(n-1)
        if currline =~ '\v\<table\>|\<\/table\>'
            return '1'
        elseif currline =~ '\v^\s*$'
            " special case for blank lines
            return '-1'
        elseif prevline =~ '\v\<\/table\>'
            " special case for the line after </table>
            return '0'
        endif
        let n -= 1
    endwhile
    return '0'
endfunction

set foldmethod=expr
set foldexpr=GetTableFold(v:lnum)

<table>これは、あなたが決して持っていない</table>、同じ行にあるなど、いくつかの厄介な(合理的な?) 仮定を行います。pandoc ファイルに複雑なテーブルのみを配置するというユースケースを考えると、これは安全な仮定だと思います。テーブル内のテーブルをうまく処理できません。必要な場合は、これを少し調整する必要があります。

于 2012-09-23T13:08:36.033 に答える