7

インデントされたコードをコードエディタで行うのと同じようにWebページでラップすることは可能ですか?私が何を意味するかをよりよく理解するには、以下のスクリーンショットの比較を参照してください。

pre-wrapWebページ:

スクリーンショット1

コードエディタでのインデントされた行の折り返し:

スクリーンショット2

私が示唆しているのは、インデントされた行は、折り返した後でもインデントを維持するということです。これはWebページでは発生しないようです。これを行うCSSプロパティはありますか?(JavaScriptも問題ありません。)

注:ここでは、コードの強調表示については話していません。折り返し線のインデントについてです。


これが重要な場合—これが私のWebページにコードブロックを表示する方法です。

<pre><code>if ( is_page() && $post->post_parent ) {
  return $post->post_parent;

} else {
  return false;
}
</code></pre>

...そしてwhite-space: pre-wrap;スタイルはpreタグに適用されます。

4

1 に答える 1

6

アルゴリズム

  1. 要素の内容を取得し、すべての行のリストを生成します。
  2. エレメントを使用して、スペース文字の幅を測定します。
  3. ドキュメントフラグメントを作成します(最適なパフォーマンスのために!)。
  4. すべての行をループします。各行について:
    • 先行する空白の数を数えます。
    • ブロック レベルの要素 ( など<div>) を作成します。
    • marginLeft(またはpaddingLeft、必要に応じて) プロパティを、1 つのスペースのサイズとプレフィックス付きスペースの数の積に設定します。
    • 追加 行の内容 (左トリム)。
  5. 実際の要素の内容をフラグメントに置き換えます。

コード (デモ: http://jsfiddle.net/YPnhX/ ):

/**
 * Auto-indent overflowing lines
 * @author Rob W http://stackoverflow.com/u/938089
 * @param code_elem HTMLCodeElement (or any element containing *plain text*)
 */
function autoindent(code_elem) {
    // Grab the lines
    var textContent = document.textContent === null ? 'textContent' : 'innerText';
    var lines = code_elem[textContent].split(/\r?\n/),
        fragment = document.createDocumentFragment(),
        dummy, space_width, i, prefix_len, line_elem;

    // Calculate the width of white space
    // Assume that inline element inherit styles from parent (<code>)
    dummy = document.createElement('span');
    code_elem.appendChild(dummy);
    // offsetWidth includes padding and border, explicitly override the style:
    dummy.style.cssText = 'border:0;padding:0;';
    dummy[textContent] = ' ';
    space_width = dummy.offsetWidth;
    // Wipe contents
    code_elem.innerHTML = '';

    for (i=0; i<lines.length; i++) {
        // NOTE: All preceeding white space (including tabs is included)
        prefix_len = /^\s*/.exec(lines[i])[0].length;
        line_elem = fragment.appendChild(document.createElement('div'));
        line_elem.style.marginLeft = space_width * prefix_len + 'px';
        line_elem[textContent] = lines[i].substring(prefix_len);
    }
    // Finally, append (all elements inside) the fragment:
    code_elem.appendChild(fragment);
}

ブラウザの互換性

  • IE8 + (IE7- はサポートしていませんwhite-space:pre-wrap)
  • クロム 1+
  • Firefox 3+
  • サファリ 3+
  • Opera 9+ (以前のバージョンは未テスト)

ノート

  • この例では、スペース (U+0020) 文字の幅を計算しました。他の空白文字に対して異なる値を計算する場合は、同様の方法が使用されます。
  • 前のメモのフォローアップ: タブを考慮に入れるには、ハード ルートを使用する必要があり、パフォーマンスが低下します。行ごとに、ダミーの内容 ( code_elem! に追加) をプレフィックス付きの空白に設定し、 を使用して幅を計算し.offsetWidthます。
    毎回、要素がレンダリングされます。数百行の場合、このメソッドは CPU 使用率のスパイクを引き起こす可能性があります。タブを使用して Web ページにコードを表示しないでください。
  • この関数は、要素の内容がプレーン テキストautoindentであることを前提としています。
于 2012-07-21T10:10:37.720 に答える