Уценка: отображать разрывы строк в элементах блока как <br> - PullRequest
0 голосов
/ 24 октября 2019

Я знаю, что это было задано ( Python Markdown nl2br расширение и т. Д.), Но ни один из этих ответов не делает это для меня.

Я хотел бы сделать уценку, чтобы произошли разрывы строкв элементе <p> будет отображаться как <br>. Пример: они набирают

Here is line one.
And line two.

New paragraph.

должны отображаться как

<p>Here is line one.<br>And line two.</p>
<p>New paragraph.</p>

Я знаю, что если вы хотите, вы должны ввести два пробела в конце строки, которую вы хотите <br>,Я пытаюсь сделать так, чтобы мои пользователи не должны были это делать, а вместо этого вводили текст, как будто они использовали пишущую машинку (для тех, кто знает, что это такое). Одно тяжелое возвращение, новая линия;два трудных возврата, новый абзац.

Я работал с https://parsedown.org/, а также экспериментировал с https://commonmark.thephpleague.com; также модулем разметки Python с расширением nl2br (попробовал их пример дословно,не работал для меня). Что бы я ни делал, я получаю слишком много или недостаточно разрывов строк, в зависимости.

Я попробовал то, что я думал, было бы умным и изящным: стиль моей уценки <p> с white-space: "pre" (также попытался pre-line). Это работает, если пользователь не сделал это "правильно" с двумя пробелами, и в этом случае вы получите нежелательный двойной эффект <br>.

Также попытался nl2br($markdown) с аналогично ненадежными результатами.

Я хочу, чтобы пользователи, не являющиеся техническими специалистами, могли как можно проще использовать базовое форматирование, и уценка, кажется, просто вещь, но для этой детали. Я не хочу писать CMS, просто чтобы обойти это. Например, я подумал о добавлении логического свойства markdown к сущности и разрешении ему выбирать, йадда йадда ... не хочу туда идти. Я думал о некоторой магии замены строк или регулярных выражений, либо во время записи в базу данных, либо непосредственно перед рендерингом. Но опять же, надеясь избежать слишком сложного. (Чтобы сделать его немного более сложным, мне также придется импортировать несколько тысяч устаревших записей, которые не относятся к уценке, и потенциально могут иметь дело с проблемами старых и новых).

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

Обновление: по многочисленным просьбам, примеры кода того, что не работает. Это приложение Zend MVC, которое включает сущности Doctrine, которые я называю MOTD и MOTW ( M essage O f T he D ay и M essage O f T he W eek соответственно);у них есть строковое свойство, называемое контентом. Обычно я рассматриваю эти объекты как Note s, и они реализуют NoteInterface. Когда я получаю их из базы данных (через класс NotesService, который использует собственный класс хранилища Doctrine), пришло время отобразить содержимое как уценку, прежде чем контроллер назначит его представлению:

// from NotesService.php

use Parsedown; 

// stuff omitted...
/**
 * gets MOT(D|W) by date
 *
 * @param  DateTime $date
 * @param  string   $type
 * @param boolean $render_markdown
 * @return NoteInterface|null
 */
public function getNoteByDate(DateTime $date, string $type, bool $render_markdown = true) :? NoteInterface
{
    $entity = $this->getRepository()->findByDate($date,$type);
    if ($entity && $render_markdown) {
        $content = $entity->getContent();
        $entity->setContent($this->parsedown($content));
    }

    return $entity;
}

Смысл логического $render_markdown - это когда нам нужна необработанная уценка, т. Е. Когда она собирается заполнить элемент textarea формы.

И метод parsedown(), довольно просто:

public function parsedown(string $content) : string
{
    if (! $this->parseDown) {
        $this->parseDown = new Parsedown();
    }
    // nope...
    // return nl2br($this->parseDown->text($content));
    return $this->parseDown->text($content);

}

Внутри видового сценария я просто иду, например,

if ($this->notes['motd']):
    // echo nl2br($this->notes['motd']->getContent());
    echo $this->notes['motd']->getContent();
else:
  ?><p class="font-italic no-note">no MOTD for this date</p><?php
endif;

Теперь, если в форме редактирования они вводят это как контент:

here is a line 
and here is another

now, new paragraph.

, а затем мы сохраняемв базе данных, когда вы выбираете его обратно и запускаете через $ parsedown-> text ($ content), вы получаете этот HTML:

<p>here is a line
and here is another</p>
<p>now, new paragraph.</p>

Обратите внимание, что в приведенном выше примере ввода нетпробелы, предшествующие переводу строки. Когда вы делаете два пробела перед переносом строки, да, это прекрасно работает. Но я не думаю, что мои пользователи хотят думать об этом. Поэтому использование nl2br() помогает, за исключением случаев, когда это приводит к слишком большому количеству последовательных <br> с в HTML.

Мое последнее мнение состоит в том, чтобы использовать решение CSS и фильтр ввода, который в конце удаляет <space><space>линий. Когда это сработает, я добавлю историю в свои мемуары. : -)

1 Ответ

0 голосов
/ 14 ноября 2019

Может быть более желательный способ добиться этого, но в конце концов я решил

(1) отфильтровать входные данные (при создании | время обновления) с подстановкой шаблона регулярного выражения, чтобы удалить завершающий '' (два последовательныхпробелы) из строк. Я случайно использую ZendFramework Zend\Filter\PregReplace, но это де-факто оболочка для preg_replace('/( {2,})(\R)/m',$2).

(2) Использовать CSS, чтобы при выводе этих объектов новые строки работали как <br>, например,

#motd .card-body p { white-space: pre-line }

Кажется, что работает для меня.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...