Подтвердить что ты не робот

Как сохранить отступы в виде пробелов в тексте, заключенные в HTML <pre class="prettyprint-override"> tags excluding the current indentation level of the <pre class="prettyprint-override"> tag in the document?

Я пытаюсь отобразить свой код на веб-сайте, но у меня проблемы с сохранением отступов вправо.

Например, приведен следующий фрагмент:

<html>
 <body>
   Here is my code:
   <pre>
     def some_funtion
       return 'Hello, World!'
     end
   </pre>
 <body>
</html>

Это отображается в браузере как:

Here is my code:

     def some_funtion
       return 'Hello, World!'
     end

Когда я хочу, чтобы он отображался как:

Here is my code:

def some_funtion
 return 'Hello, World!'
end

Отличие заключается в том, что текущий уровень отступа HTML-тега добавляется к отступу кода. Я использую nanoc как статический генератор веб-сайтов, и я использую google prettify, чтобы добавить подсветку синтаксиса.

Кто-нибудь может предложить какие-либо предложения?

4b9b3361

Ответ 1

PRE предназначен для сохранения пробелов точно так, как он появляется (если не изменено white-space в CSS, что не имеет достаточной гибкости для поддержки кода форматирования).

До

Форматирование сохраняется, но так же все отступы вне тега PRE. Было бы неплохо сохранить пробелы, которые использовали местоположение тега в качестве отправной точки.

enter image description here

После

Содержимое по-прежнему форматируется как объявлено, но посторонние ведущие пробелы, вызванные положением тега PRE в документе, удаляются.

enter image description here

Я придумал следующий плагин, чтобы решить вопрос о необходимости удаления лишних пробелов, вызванных отступом контура документа. Этот код использует первую строку внутри тега PRE, чтобы определить, сколько было отступов, из-за отступов документа.

Этот код работает в IE7, IE8, IE9, Firefox и Chrome. Я кратко протестировал его с помощью библиотеки Prettify, чтобы объединить сохраненное форматирование с довольно печатной. Убедитесь, что первая строка внутри PRE фактически представляет базовый уровень отступов, который вы хотите игнорировать (или вы можете изменить плагин, чтобы быть более интеллектуальным).

Это грубый код. Если вы обнаружите ошибку или она не работает так, как вы хотите, пожалуйста, исправьте/комментарий; не просто вниз. Я написал этот код, чтобы исправить проблему, которая у меня была, и я активно ее использую, поэтому я хотел бы, чтобы она была как можно более прочной!

/*!
*** prettyPre ***/

(function( $ ) {

    $.fn.prettyPre = function( method ) {

        var defaults = {
            ignoreExpression: /\s/ // what should be ignored?
        };

        var methods = {
            init: function( options ) {
                this.each( function() {
                    var context = $.extend( {}, defaults, options );
                    var $obj = $( this );
                    var usingInnerText = true;
                    var text = $obj.get( 0 ).innerText;

                    // some browsers support innerText...some don't...some ONLY work with innerText.
                    if ( typeof text == "undefined" ) {
                        text = $obj.html();
                        usingInnerText = false;
                    }

                    // use the first line as a baseline for how many unwanted leading whitespace characters are present
                    var superfluousSpaceCount = 0;
                    var currentChar = text.substring( 0, 1 );

                    while ( context.ignoreExpression.test( currentChar ) ) {
                        currentChar = text.substring( ++superfluousSpaceCount, superfluousSpaceCount + 1 );
                    }

                    // split
                    var parts = text.split( "\n" );
                    var reformattedText = "";

                    // reconstruct
                    var length = parts.length;
                    for ( var i = 0; i < length; i++ ) {
                        // cleanup, and don't append a trailing newline if we are on the last line
                        reformattedText += parts[i].substring( superfluousSpaceCount ) + ( i == length - 1 ? "" : "\n" );
                    }

                    // modify original
                    if ( usingInnerText ) {
                        $obj.get( 0 ).innerText = reformattedText;
                    }
                    else {
                        // This does not appear to execute code in any browser but the onus is on the developer to not 
                        // put raw input from a user anywhere on a page, even if it doesn't execute!
                        $obj.html( reformattedText );
                    }
                } );
            }
        }

        if ( methods[method] ) {
            return methods[method].apply( this, Array.prototype.slice.call( arguments, 1 ) );
        }
        else if ( typeof method === "object" || !method ) {
            return methods.init.apply( this, arguments );
        }
        else {
            $.error( "Method " + method + " does not exist on jQuery.prettyPre." );
        }
    }
} )( jQuery );

Затем этот плагин можно применить с помощью стандартного селектора jQuery:

<script>
    $( function() { $("PRE").prettyPre(); } );
</script>

Ответ 2

Отступы с комментариями

Поскольку браузеры игнорируют комментарии, вы можете использовать их для отступов в содержимом тега pre.

Решение

<html>
  <body>
    <main>
      Here is my code with hack:
      <pre>
<!-- -->def some_funtion
<!-- -->  return 'Hello, World!'
<!-- -->end
      </pre>
      Here is my code without hack:
      <pre>
        def some_funtion
          return 'Hello, World!'
        end
      </pre>
    </main>
  <body>
</html>

Ответ 3

Удалось сделать это с помощью JavaScript. Он работает в Internet Explorer 9 и Chrome 15, я не тестировал более старые версии. Он должен работать в Firefox 11, когда добавляется поддержка outerHTML (см. здесь), между тем есть некоторые пользовательские реализации, доступные в Интернете. Упражнение для читателя состоит в том, чтобы избавиться от конечного отступа (пока я не успею закончить его и обновить этот ответ).

Я также отмечу это как сообщество wiki для удобного редактирования.

Обратите внимание, что вам придется переформатировать этот пример, чтобы использовать вкладки как отступы, или изменить регулярное выражение для работы с пробелами.

<!DOCTYPE html>
<html>
    <head>
        <title>Hello, World!</title>
    </head>
    <body>
        <pre>
            &lt;html&gt;
                &lt;head&gt;
                    &lt;title&gt;Hello World Example&lt;/title&gt;
                &lt;/head&gt;
                &lt;body&gt;
                    Hello, World!
                &lt;/body&gt;
            &lt;/html&gt;
        </pre>
        <pre>
            class HelloWorld
            {
                public static int Main(String[] args)
                {
                    Console.WriteLine(&amp;quot;Hello, World!&amp;quot;);
                    return 0;
                }
            }
        </pre>
        <script language="javascript">
            var pre_elements = document.getElementsByTagName('pre');

            for (var i = 0; i < pre_elements.length; i++)
            {
                var content = pre_elements[i].innerHTML;

                var tabs_to_remove = '';
                while (content.indexOf('\t') == '0')
                {
                  tabs_to_remove += '\t';
                  content = content.substring(1);
                }

                var re = new RegExp('\n' + tabs_to_remove, 'g');
                content = content.replace(re, '\n');
                pre_elements[i].outerHTML = '<pre>' + content + '</pre>';
            }
        </script>
    </body>
</html>

Ответ 4

Это можно сделать в четырех строках JavaScript:

var pre= document.querySelector('pre');

//insert a span in front of the first letter.  (the span will automatically close.)
pre.innerHTML= pre.textContent.replace(/(\w)/, '<span>$1');

//get the new span left offset:
var left= pre.querySelector('span').getClientRects()[0].left;

//move the code to the left, taking into account the body margin:
pre.style.marginLeft= (-left + pre.getClientRects()[0].left)+'px';
 <body>
   Here is my code:
   <pre>
     def some_funtion
       return 'Hello, World!'
     end
   </pre>
 <body>

Ответ 5

<script>
    $("pre[name='pre']").each(function () {
        var html = $(this).html()
        var blankLen = (html.split('\n')[0].match(/^\s+/)[0]).length
        $(this).html($.trim(html.replace(eval("/^ {" + blankLen + "}/gm"), "")))
    })
</script>
<div>
	<pre name="pre">
		1
			2
				3
	</pre>
</div>

Ответ 6

Я также обнаружил, что если вы используете haml, вы можете использовать метод preserve. Например:

preserve yield

Это сохранит пробел в выпуске yield, который обычно является уценкой, содержащей кодовые блоки.

Ответ 7

Я решил придумать нечто более конкретное, чем изменить способ работы pre или code. Поэтому я сделал некоторое регулярное выражение для получения первого символа новой строки \n (которому предшествуют возможные пробелы - \s* используется для очистки лишних пробелов в конце строки кода и перед символом новой строки (что, как я заметил, у вас было) ) и найдите за ним следующие вкладки или пробельные символы [\t\s]* (что означает символ табуляции, символ пробела (0 или больше) и установите это значение для переменной. Затем эта переменная используется в функции замены регулярных выражений, чтобы найти все экземпляры ее и замените его на \n (newline). Поскольку вторая строка (где pattern получает значение), не имеет глобального флага (a g после регулярного выражения), он найдет первый экземпляр \n newline и установите для переменной значение pattern. Таким образом, в случае новой строки, за которой следуют 2 символа табуляции, значение pattern будет технически соответствовать \n\t\t, которое будет заменено, где каждый \n символ находится в этом элементе pre code (так как он проходит через каждую функцию) и заменяется на \n

$("pre code").each(function(){
    var html = $(this).html();
    var pattern = html.match(/\s*\n[\t\s]*/);
    $(this).html(html.replace(new RegExp(pattern, "g"),'\n'));
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<body>
    Here is some code:

    <pre><code>
        Here is some fun code!
        More code
          One tab
            One more tab
            
            Two tabs and an extra newline character precede me
    </code></pre>
</body>

Ответ 8

Это громоздко, но оно работает, если для вас важна сводка кода:

        <pre>def some_funtion</pre>
        <pre>    return 'Hello, World!'</pre>
        <pre>end</pre>

В вашем css

    pre { margin:0 }

В vim, обычно записывая свой код, а затем выполняйте:

    :s/\t\t\([^\n]\+\)/<pre>\1<\/pre>/

для каждой строки будет работать.

Ответ 9

Если вы используете это на блоке кода, например:

<pre>
  <code>
    ...
  </code>
</pre>

Вы можете просто использовать css, как это, чтобы компенсировать это большое количество белого пространства спереди.

pre code {
  position: relative;
  left: -95px; // or whatever you want
}

Ответ 10

Тэг pre сохраняет все пробелы, которые вы использовали во время записи в теле. Где, как обычно, если вы не используете pre, он будет отображать текст нормально... (HTML заставит браузер игнорировать эти пробелы). Попробуйте это, я использовал тег абзаца. Выход: -

Вот мой код:

def some_function

  return 'Hello, World!'

конец

<html> <body> Here is my code: <p> def some_function<br> <pre> return 'Hello, World!'<br></pre> end </p> </body> </html>