Может ли CodeMirror отображать разрывы строк Markdown?

Можно ли заставить CodeMirror в режиме Markdown показывать разрывы строк?

Пример: здесь следует строка Markdown с двумя завершающими пробелами, что означает «Я хочу здесь новую строку». А затем еще одна строка без пробелов в конце, что означает «Нет новой строки, пожалуйста». Однако, поскольку конечные пробелы невидимы, было бы полезно, если бы можно было нарисовать или , чтобы указать, что будет вставлена ​​новая строка.

Roses are flowers  ↵
Violets are also flowers
and wise mice slice rice

Это будет отображаться как:

Roses are flowers
Violets are also flowers and wise mice slice rice

person KajMagnus    schedule 04.04.2013    source источник
comment
ну, вы можете отредактировать режим уценки, чтобы сделать это. используй источник, Люк.   -  person Eliran Malka    schedule 05.04.2013
comment
@EliranMalka В конце концов я написал аддон CodeMirror. Смотрите мой ответ на этой странице. Возможно, лучше не трогать сам режим Markdown — мне пришлось объединить изменения из основного репозитория @ Github, чтобы поддерживать его в актуальном состоянии.   -  person KajMagnus    schedule 18.06.2013
comment
звучит как хорошая идея. вы внесли его обратно?   -  person Eliran Malka    schedule 18.06.2013
comment
@EliranMalka Я отправил письмо в группу Google-mail со ссылками на исходный код (под лицензией MIT) и демо, так что да, я полагаю, что сделал.   -  person KajMagnus    schedule 18.06.2013


Ответы (2)


Вот простое наложение, которое будет стилизовать завершающие пробелы:

editorInstance.addOverlay({
  token: function(stream) {
    if (stream.match(/^\s+$/)) return "trailing-whitespace";
    stream.match(/^\s*\S*/);
    return null;
  }
});

Затем добавьте подобное правило CSS, чтобы сделать его действительно видимым:

.cm-trailing-whitespace { color: #f80; text-decoration: underline; }
person Marijn    schedule 09.04.2013
comment
Спасибо Марин! Я проверю это, как только перейду на CodeMirror 3 (кажется, .addOverlay отсутствует в моей версии, какая-то старая версия 2.x). - person KajMagnus; 15.04.2013
comment
Сейчас я обновился до 3.13 и протестировал [наложение, которое стилизует завершающие пробелы]. Однако я подумал, что довольно сложно определить, было ли 1 или 2 завершающих пробела, поэтому вместо этого я написал еще одно наложение, которое стилизует каждое пространство с помощью выделенного токена — см. мой собственный ответ на этой странице. (Оверлей завершающих пробелов обертывал все завершающие пробелы одним ‹span›, что затрудняло стилизацию каждого пробела по отдельности) - person KajMagnus; 18.06.2013

Я написал оверлей MarkDown, который визуализирует новые строки с помощью: · ↵ (знак '·' для первого пробела и '↵' для второго пробела). Пример:

Violets are flowers·↵
Roses are also flowers

(в первой строке 2 пробела в конце.)

Вот демонстрация и ссылки на самые последние файлы исходного кода: (лицензия: MIT)
http://www.debiki.com/-1c250-visualizing-markdown-double-space-line-breaks


Пример использования. Включите вышеуказанные файлы JS и CSS и:

var codeMirrorEditor = CodeMirror.fromTextArea(some-textarea, {
  mode: "markdown",
  showMarkdownLineBreaks: true,   // <---
  ...
});


Исходный код на сегодняшний день: сначала CSS, затем JS:

------------ CSS:

/**
 * Makes the CodeMirror editor show newlines, in Markdown mode.
 *
 * Copyright (C) 2013 Kaj Magnus Lindberg (born 1979)
 *
 * Licensed under the MIT license.
 */

.cm-markdown-single-trailing-space-odd:before,
.cm-markdown-single-trailing-space-even:before,
.cm-markdown-line-break:before {
  font-weight: bold;
  color: hsl(30, 100%, 50%); /* a dark orange */
  position: absolute;
}


.cm-markdown-single-trailing-space-odd:before,
.cm-markdown-single-trailing-space-even:before {
  content: '·';
}

.cm-markdown-line-break:before {
  content: '↵';
}

------------ JS:

/**
 * Shows trailing Markdown spaces and line breaks, like so:·↵
 *
 * Copyright (C) 2013 Kaj Magnus Lindberg (born 1979)
 *
 * License: (MIT)
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */


CodeMirror.defineOption("showMarkdownLineBreaks", false,
    function(codeMirror, newValue, oldValue) {

  if (oldValue == CodeMirror.Init) {
    oldValue = false;
  }
  if (oldValue && !newValue) {
    codeMirror.removeOverlay("show-markdown-line-breaks");
  }
  else if (!oldValue && newValue) {
    codeMirror.addOverlay({
      name: "show-markdown-line-breaks",
      token: markMarkdownTrailingSpaces
    });
  }
});


function markMarkdownTrailingSpaces(stream) {

  // Possible stream.string:s and how they're handled: (`n` is text
  // with no trailing spaces)
  // ""
  // "n"    case 1
  // "_"    case 3
  // "n_"   case 1, case 3
  // "__"   case 2, case 3
  // "n__"  case 1, case 2, case 3
  // "___"  case 2, case 3
  // "n___" case 1, case 2, case 3

  // Returns separate CSS classes for each trailing space;
  // otherwise CodeMirror merges contiguous spaces into
  // one single <span>, and then I don't know how to via CSS
  // replace each space with exact one '·'.
  function singleTrailingSpace() {
    return stream.pos % 2 == 0 ?
      "markdown-single-trailing-space-even" :
      "markdown-single-trailing-space-odd";
  };

  if (!stream.string.length) // can this happen?
    return null;

  // Case 1: Non-space characters. Eat until last non-space char.
  var eaten = stream.match(/.*[^ ]/);
  if (eaten)
    return null;

  // Case 2, more than one trailing space left before end-of-line.
  // Match one space at a time, so each space gets its own
  // `singleTrailingSpace()` CSS class. Look-ahead (`(?=`) for more spaces.
  if (stream.match(/ (?= +$)/))
    return singleTrailingSpace();

  // Case 3: the very last char on this line, and it's a space.
  // Count num trailing spaces up to including this last char on this line.
  // If there are 2 spaces (or more), we have a line break.
  var str = stream.string;
  var len = str.length;
  var twoTrailingSpaces = len >= 2 && str[len - 2] == ' ';
  stream.eat(/./);
  if (twoTrailingSpaces)
    return "markdown-line-break";
  return singleTrailingSpace();
};


// vim: et ts=2 sw=2 list
person KajMagnus    schedule 18.06.2013
comment
пожалуйста, приложите краткий пример (или часть кода, которая действительно делает волшебство), чтобы получить самодостаточный ответ. - person Eliran Malka; 18.06.2013
comment
@EliranMalka Я добавил пример использования. - person KajMagnus; 18.06.2013