PrismJS без разрывов строк

Не уверен, что кто-нибудь сталкивался с этим. Я использую подсветку синтаксиса PrismJS для выделения кода. Приложение написано на Reactjs, и я пытаюсь сделать это в редакторе WYSIWYG. Я обертываю выбранный пользователем текст с пре + кодом, когда пользователь хочет вставить блок кода. PrismJS, кажется, правильно маркирует элементы, как и следовало ожидать:

Но, как вы, вероятно, можете видеть из изображения выше, все помещено в одну строку. Скорее хороший блок кода:

Я не уверен, что не так, используя css с сайта prismjs:

code[class*="language-"],
pre[class*="language-"] {
    color: black;
    background: none;
    text-shadow: 0 1px white;
    font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
    text-align: left;
    white-space: pre;
    word-spacing: normal;
    word-break: normal;
    word-wrap: normal;
    line-height: 1.5;

    -moz-tab-size: 4;
    -o-tab-size: 4;
    tab-size: 4;

    -webkit-hyphens: none;
    -moz-hyphens: none;
    -ms-hyphens: none;
    hyphens: none;
}

pre[class*="language-"]::-moz-selection,
pre[class*="language-"] ::-moz-selection,
code[class*="language-"]::-moz-selection,
code[class*="language-"] ::-moz-selection {
    text-shadow: none;
    background: #b3d4fc;
}

pre[class*="language-"]::selection,
pre[class*="language-"] ::selection,
code[class*="language-"]::selection,
code[class*="language-"] ::selection {
    text-shadow: none;
    background: #b3d4fc;
}

@media print {
    code[class*="language-"],
    pre[class*="language-"] {
        text-shadow: none;
    }
}

/* Code blocks */
pre[class*="language-"] {
    padding: 1em;
    margin: .5em 0;
    overflow: auto;
}

:not(pre) > code[class*="language-"],
pre[class*="language-"] {
    background: #f5f2f0;
}

/* Inline code */
:not(pre) > code[class*="language-"] {
    padding: .1em;
    border-radius: .3em;
    white-space: normal;
}

.token.comment,
.token.prolog,
.token.doctype,
.token.cdata {
    color: slategray;
}

.token.punctuation {
    color: #999;
}

.namespace {
    opacity: .7;
}

.token.property,
.token.tag,
.token.boolean,
.token.number,
.token.constant,
.token.symbol,
.token.deleted {
    color: #905;
}

.token.selector,
.token.attr-name,
.token.string,
.token.char,
.token.builtin,
.token.inserted {
    color: #690;
}

.token.operator,
.token.entity,
.token.url,
.language-css .token.string,
.style .token.string {
    color: #9a6e3a;
    background: hsla(0, 0%, 100%, .5);
}

.token.atrule,
.token.attr-value,
.token.keyword {
    color: #07a;
}

.token.function,
.token.class-name {
    color: #dd4a68;
}

.token.regex,
.token.important,
.token.variable {
    color: #e90;
}

.token.important,
.token.bold {
    font-weight: bold;
}
.token.italic {
    font-style: italic;
}

.token.entity {
    cursor: help;
}

Здесь выводится HTML:

РЕДАКТИРОВАТЬ:

Если добавить перенос слов: пре-перенос это результат:

6 ответов

У меня была аналогичная проблема при инициализации элемента вручную. Я наткнулся на это обсуждение, в котором было исправление, которое помогло мне: https://github.com/PrismJS/prism/issues/1764

HTML - Загрузить скрипт с флагом data-manual:

<script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.20.0/prism.min.js" data-manual></script>

JS - Добавьте следующий хук:

Prism.hooks.add("before-highlight", function (env) {
    env.code = env.element.innerText;
});
Prism.highlightElement(code);

Рабочий пример:https://codepen.io/Ukmasmu/pen/xxZLwxG?editors=1010

Попробуйте обновить файл CSS:

white-space: pre-wrap

https://github.com/PrismJS/prism/issues/1237

Если это кому-то поможет, у меня есть textarea который обновляет блок кода по мере ввода, и это сработало для меня:

<textarea onkeyup="this.onchange();" onchange="document.getElementById('query-highlighted').textContent = this.value; Prism.highlightAll();"></textarea>
<pre><code class="language-sql" id="query-highlighted"></code></pre>

А именно я использовал .textContent = вместо того .innerText = (последний не сохранил разрывы строк, как ожидалось).

Мне помогли ответ Севера ван Снагга и проблема, которую он связал.

1. Активируйте плагин нормализации пробелов.

Я предлагаю вам активировать плагин нормализации пробелов и установить свойство вместо того, чтобы манипулировать файлом prism.css, чтобы использовать как это:

      Prism.plugins.NormalizeWhitespace.setDefaults({
            'remove-trailing': true,
            'remove-indent': true,
            'left-trim': true,
            'right-trim': true,
            'break-lines': 60, //max number of characters in each line before break
});

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

2. Вставьте тег разрыва строки, чтобы разбить строку по желанию.

Теперь, когда вы установили свойство после определенного максимального количества символов, вы, вероятно, захотите разбить некоторые строки по своему желанию для более чистого кода. Для этого вам нужно вставить тег там, где вы хотите сделать линию разрыва.

ПРИМЕЧАНИЕ: если вы используете синтаксический анализатор HTML для анализа динамического содержимого с помощью призмы

Если вы используете синтаксический анализатор для синтаксического анализа динамически сгенерированного html-кода в виде строки (например, из базы данных), а prims не анализирует ваши теги, вам придется использовать призматический крючок вот так:

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

Я пытался смешать Markdown и Prismjs, трюк состоит в том, чтобы заменить «\ n» на «\ r\n», чтобы сохранить линии разрыва.

          from bs4 import BeautifulSoup
    ...
    code_tag = soup.new_tag('code class="lang-%s"' % lang)
    code_tag.string = code.string.replace('\n','\r\n')
    code.replaceWith(code_tag)

Подобно ответу Севера ван Снагга, я использую следующее решение, в котором цикл forEach выделяет все узлы кода в соответствии с правилами стиля используемой таблицы стилей Prism CSS (поскольку у меня есть несколько тегов кода на одной странице). Я нахожу эти скрипты в нижней части моего HTML-кода:

      <script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.27.0/prism.min.js" data-manual></script>

<script>
    Prism.hooks.add("before-highlight", function (env) {
        env.code = env.element.innerText;
    });

    code = document.getElementsByTagName('code');
    Array.from(code).forEach(el => { Prism.highlightElement(el) });
</script>
Другие вопросы по тегам