web-dev-qa-db-ja.com

HTMLからビジュアルエディタに切り替えるときに<pre> <code>でタブと改行を保持する

<pre><code></code></pre>ブロックに配置されたタブは取り除かれ、改行は取り除かれて一行のテキストが残ります。これは、HTMLからビジュアルエディタに切り替えると発生します。これを避けるためにTinyMCEに設定はありますか?

前:

enter image description here

後: enter image description here

ここでは、コードを文字化けし、その一部を<pre>..から吐き出します。

編集:

私は最善の選択肢は<code>タグを完全に削除してpreを残すことです。これはまだ重複した空白行を削除するという問題を抱えています、しかしそれはエディタを切り替えるときでさえも手付かずのままにします。

1
Aram Kocharyan

Function.phpに追加する

add_filter('tiny_mce_before_init', 'tiny_mce_before_init');

そして関数tiny_mce_before_init:

function tiny_mce_before_init($init) {
 $init['setup'] = "function(ed) {
     ed.onBeforeSetContent.add(function(ed, o) {
     if ( o.content.indexOf('<pre') != -1) {
     o.content = o.content.replace(/<pre[^>]*>[\\s\\S]+?<\\/pre>/g, function(a) {
     return a.replace(/(\\r\\n|\\n)/g, '<br />');
    });
   }
  });
 }";
 return $init;
}

http://core.trac.wordpress.org/ticket/19666 - これは既知のバグですが、回避策はありますがタブの改行は修正されません

3
OzzyCzech

また、HTMLからビジュアルエディタに切り替えるときに壊れることを避けるために、functions.phpにカスタムショートコードを追加しました。私は主にiFrameのためにこれを使いました、しかし多分それはここでも役に立つでしょう。

1
Donna

このプラグインは<pre>タグの間に空白を保存するようです。

コードフォーマットを維持する

0
Martin York

pastingで苦労したり、ビジュアルエディタフォーマット済みの<pre> codeで作業している人のためのものです。この解決法は何年もの間私のために働いています、そして私はそれが大好きです。このアプローチはエディタとwpautop()フロントエンドの間で正しい前コンテンツと文字を提供するために "ミドルハンド"を使います。

Functions.phpに貼り付けるだけ

それは重いように思えますが、それがなぜjQueryがtinMCE APIと話すときグローバルな範囲になければならないかの理由です。ドル記号$を使用することはできません。また、jQueryname__というテキストはコードを乱雑にしています。その大部分は HTML要素の作成 で、スペースをとります。

どのように動作するのか:非常に単純です、 それに「触れる」ことなく、-TinyMCEはそれをめちゃくちゃにしません 。試す価値があります。

/**
 * PRE Handler
 * Solves <pre> handle in Wordpress tinyMCE editor
 * TAB support
 * TAB support to TEXT editor
 * Simple cleanup with Undo
 * Push cleanup (experimental)
 * Moves empty code chunks to beginning
**/


function entex_tiny_mce_before_init(){
    add_filter('tiny_mce_before_init', function($mceInit){
        $mceInit['setup'] = 'ua_TinyMCE_setup_callback';
        return $mceInit;
    });
    add_action('before_wp_tiny_mce', 'entex_TinyMCE_javascript');
}
add_action('after_setup_theme', 'entex_tiny_mce_before_init');


function entex_TinyMCE_javascript() {

    echo '<script type="text/javascript">'."\n";
    ?>

    var ua_tinyMCE_invoked = 0;

    function ua_tinyMCE_focusbutton(){
        if(jQuery('ua-id-mce-focusbutton').get(0)) return;
        var jQueryE = jQuery('<a />').addClass('button ua-id-mce-focusbutton').css('float', 'right').on('click', function(){
            jQuery('html, body').stop().animate({ scrollTop: (jQuery('#wp-content-wrap').offset().top) - 20 }, 500);
            tinymce.activeEditor.focus();
            return false;
        }).attr('title', 'Scroll and focus the editor Toolbar in view').text('Toolbar focus').css('margin', '5px');
        jQuery('.mce-statusbar .mce-flow-layout').prepend(jQueryE);
    }

    function ua_TinyMCE_setup_callback(ed){

        if(ua_tinyMCE_invoked) return;
        ua_tinyMCE_invoked = 1;

        ed.on('init', function(e) {
            jQuery(ed.getBody()).on('click', 'pre', function() {
                ua_TinyMCE_edit_pre(ed, this);
                return false;
            });
            ua_tinyMCE_focusbutton();
        });
    }

    function ua_TinyMCE_helper_cleanBeginnings(str, find, replace){
        return str.replace(new RegExp(find, 'g'), replace);
    }

    function ua_TinyMCE_edit_pre(ed, obj) {
        var jQueryE = jQuery(obj); 
        var jQueryB = jQuery(ed.getBody());
        var content = jQuery('<textarea/>').html(jQueryE.html()).text();
        content = content.replace(/(<br>)/g, '');
        //content = content.replace(/   /g, '\t');
        var data = content;


        var jQueryL = jQuery('<div />').css({
            'position': 'fixed',
            'box-sizing': 'border-box',
            'background-color': 'rgba(255, 255, 255, 0.85',
            'border': '3px solid #ccc',
            'padding': '10px',
            'z-index': '9992',
            'height': 'auto',
            'width': '80%',
            'left': '50%',
            'margin-left': '-40%',
            'top': '5%'
        });

        var jQueryT = jQuery('<textarea />').keydown(function(e){

            if ( e.which != 9 ) return;
            var start = this.selectionStart;
            var end = this.selectionEnd;
            this.value = this.value.substr( 0, start ) + "\t" + this.value.substr( end );
            this.selectionStart = this.selectionEnd = start + 1;
            e.preventDefault();
            return false;

        }).attr('wrap', 'soft').css({
            'height': '98%',
            'width': '88%',
            'min-height': '300px',
            'tab-size': '3',
            'font-family': 'courier new',
            'box-sizing': 'border-box'
        });

        jQuery('#wpcontent').css('position', 'relative').append(jQueryL);
        jQueryL.append(jQueryT);
        jQueryL.append(
            jQuery('<div />').css({
                'width': '10%',
                'height': '100%',
                'position': 'absolute',
                'top': '0px',
                'right': '10px',
                'padding-top': '10px',
                'box-sizing': 'border-box'
            }).append(
                jQuery('<a />').attr('title', 'Send to element').click(function(){

                    var encodedStr = jQueryT.val().replace(/[\u00A0-\u9999<>\&]/gim, function(i) {
                        return '&#'+i.charCodeAt(0)+';';
                    });

                    jQueryE.html(encodedStr);
                    ed.focus();
                    jQueryL.remove();
                    return false;

                }).text('Send').addClass('button button-primary').css({
                    'display': 'block',
                    'width': '100%',
                    'margin-bottom': '5px',
                    'text-align': 'center',
                    'box-sizing': 'border-box'
                }), 

                jQuery('<a />').attr('title', 'Cleanup').click(function(){

                    var data = jQueryT.val();
                    var original = data;
                    data = data.replace(/(\r\n|\n|\r)/gm, "\r\n");
                    var workspace = data.replace(/(\r\n|\n|\r)/gm, '');

                    if(/^\s/.test(workspace)) {
                        var search_string = workspace.replace(/^\s+|\s+$/g, '');
                        if(search_string){
                            var firstChar = search_string[0];
                            var remove = workspace.substr(0, workspace.indexOf(firstChar));
                            remove = "\r\n" + remove;
                            data = ua_TinyMCE_helper_cleanBeginnings(data, remove, "\r\n");
                        }
                        data = data.replace(/   /g, "\t");
                        data = data.replace(/^\s+|\s+$/g, '');
                    } else {
                        data = data.replace(/^\s+|\s+$/g, '');
                    }
                    if(data != original){
                        jQueryT.data('original', original);
                        if(!jQuery('#ua-TinyMCE-btt-undo').get(0)){
                        jQuery(this).after(
                            jQuery('<a />').attr('title', 'Undo').click(function(){
                                jQueryT.val(jQueryT.data('original'));
                                jQuery(this).remove();
                                return false;

                            }).text('Undo').addClass('button').css({
                                'display': 'block',
                                'width': '100%',
                                'margin-bottom': '5px',
                                'text-align': 'center',
                                'box-sizing': 'border-box'
                            }).attr('id', 'ua-TinyMCE-btt-undo')
                        );
                        }
                    }
                    data = data.replace(/   /g, "\t");
                    jQueryT.val(data);
                    return false;

                }).text('Cleanup').addClass('button').css({
                    'display': 'block',
                    'width': '100%',
                    'margin-bottom': '5px',
                    'text-align': 'center',
                    'box-sizing': 'border-box'
                }),

                jQuery('<a />').attr('title', 'Close').click(function(){

                    ed.focus();
                    jQueryL.remove();
                    return false;

                }).text('Close').addClass('button').css({
                    'display': 'block',
                    'width': '100%',
                    'margin-bottom': '5px',
                    'text-align': 'center',
                    'box-sizing': 'border-box'
                }),

                jQuery('<a />').attr('title', 'Remove all data').click(function(){

                    jQueryT.val('').focus();
                    return false;

                }).text('Delete').addClass('button').css({
                    'display': 'block',
                    'width': '100%',
                    'margin-bottom': '0px',
                    'position': 'absolute',
                    'bottom': '10px',
                    'background-color': '#D54E21',
                    'color': '#fff',
                    'text-align': 'center',
                    'box-sizing': 'border-box'
                })
            )
        );
        jQueryT.val(content).focus();
        return false;
    }

    // WP EDITOR
    jQuery(document).ready(function($){
        if($('textarea#content').get(0)){
            $('textarea#content').on('keydown', function(e){
                if ( e.which != 9 ) return;
                var start = this.selectionStart;
                var end = this.selectionEnd;
                this.value = this.value.substr( 0, start ) + "\t" + this.value.substr( end );
                this.selectionStart = this.selectionEnd = start + 1;
                e.preventDefault();
                return false;
            }).css('tab-size', '3');
        }
    });

    <?php
    echo '</script>'."\n";
}

このアプローチは、ハックや厄介なプレッグマッチの解決策ではありません。これはデフォルトのAPIと同じ対話を生成します。

Push cleanupは、PHPクラスなどからコードを貼り付けたときに機能します。チャンクや切り出した関数の前に、スペースやタブがたくさんあります。最初の既存行に現れるスペースを計算します。

これになります:

                    if(search_string){
                        var firstChar = search_string[0];
                        var remove = workspace.substr(0, workspace.indexOf(firstChar));
                        remove = "\r\n" + remove;
                        data = ua_TinyMCE_helper_cleanBeginnings(data, remove, "\r\n");
                    }

これに:

if(search_string){
    var firstChar = search_string[0];
    var remove = workspace.substr(0, workspace.indexOf(firstChar));
    remove = "\r\n" + remove;
    data = ua_TinyMCE_helper_cleanBeginnings(data, remove, "\r\n");
}

B.T.Wには、便利なフォーカスボタンが付属しています。 エディタの右下に表示されます 。大量の<pre>コードチャンクを扱う場合に便利です。画面設定をオフにします。「フルハイトエディタと注意をそらさない機能を有効にする」より良いUIのために。

0
Jonas Lundman