Рубрики
Без рубрики

Как я образующуюся редактор HEMingway – популярное письмо – и построил свой собственный от пляжа в Таиланде

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

Автор оригинала: FreeCodeCamp Community Member.

Я использовал приложение HEMingway, чтобы попытаться улучшить мои посты. В то же время я пытался найти идеи для небольших проектов. Я пришел с идеей интеграции редактора стилей HEMINGWAYW в редактор Markown. Поэтому мне нужно было узнать, как работал Хемингуэй!

Получение логики

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

Открытие инструментов разработчиков в Chrome (Control + Shift + I или F12 в Windows/Linux, команда + опция + I на Mac) и навигация на Источники предоставил ответы Отказ Там я нашел файл, который я искал: hemingway3-web.js.

Этот код находится в доминированной форме, которая является болью читать и понимать. Чтобы решить это, я скопировал файл в VS-код и отформатировал документ ( Control + Shift + i for vs код). Это изменяет 3-строчный файл в файл 4859-линий со всем, что все отформатировано.

Исследуя код

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

!function(e) {
  function t(r) {
      if (n[r])
          return n[r].exports;
      var o = n[r] = {
          exports: {},
          id: r,
          loaded: !1
      };
...

Это продолжало около 200 строк, прежде чем я решил, что я, вероятно, читал код, чтобы заставить страницу пройти (реагировать?). Я начал снимать через остаток кода, пока я не нашел что-то, что я мог бы понять. (Я довольно много пропустил, что я бы позже нашел сквозь вызовы функций и смотрите на определение функции).

Первый бит кода, который я понял, был весь путь на линии 3496!

getTokens: function(e) {
  var t = this.getAdverbs(e), 
    n = this.getQualifiers(e),
    r = this.getPassiveVoices(e), 
    o = this.getComplexWords(e);
  return [].concat(t, n, r, o).sort(function(e, t) {
    return e.startIndex - t.startIndex
  })
}

И удивительно, все эти функции были определены прямо ниже. Теперь я знал, как приложение определило наречия, квалификаторы, пассивный голос и сложные слова. Некоторые из них очень просто. Приложение проверяет каждое слово против списков классификаторов, сложных слов и пассивных голосовых фраз. Это .getadverbs Фильтрует слова на основе того, заканчиваются ли они «LY», а затем проверяют, в списке нерешеных слов, заканчивающихся в «LY».

Следующий бит полезного кода был внедрение выделения слов или предложений. В этом коде есть строка:

e.highlight.hardSentences += h

«Хертик» было то, что я мог понять, что-то со смыслом. Затем я искал файл для Упорные препараты и получил 13 матчей. Это приводит к линии, которая рассчитала статистика читаемости:

n.stats.readability === i.default.readability.hard && (e.hardSentences += 1),
n.stats.readability === i.default.readability.veryHard && (e.veryHardSentences += 1)

Теперь я знал, что был читабельность Параметр в обоих Статистика и I.default Отказ Поиск файла, я получил 40 матчей. Один из этих матчей был GetReadabilityStyle Функция, где они оценивают ваше письмо.

Есть три уровня: нормальные, жесткие и очень тяжелые.

t = e.words;
n = e.readingLevel;
return t < 14
  ? i.default.readability.normal
  : n >= 10 && n < 14
    ? i.default.readability.hard
    : n >= 14 ? i.default.readability.veryHard 
      : i.default.readability.normal;

«Нормальный» – менее 14 слов, «жесткий» – это 10-14 слов, а «очень сложно» – более 14 слов.

Теперь, чтобы найти, как рассчитать уровень чтения.

Я провел некоторое время, пытаясь найти любое представление о том, как рассчитать уровень чтения. Я нашел его 4 строки над GetReadabilityStyle функция.

e = letters in paragraph;
t = words in paragraph;
n = sentences in paragraph;

getReadingLevel: function(e, t, n) {
  if (0 === t 
 0 === n) return 0;
  var r = Math.round(4.71 * (e / t) + 0.5 * (t / n) - 21.43);
  return r <= 0 ? 0 : r;
}

Это означает, что ваш счет составляет 4,71 * Среднее слово длина слова + 0,5 * Среднее длина предложения -21,43. Вот и все. Вот как классы Heamingway каждый из ваших предложений.

Другие интересные вещи, которые я нашел

  • Комментарий Highlight (информация о вашем письме с правой стороны) является большим оператором коммутатора. Темные операторы используются для изменения ответа на основе того, насколько хорошо вы написали.
  • Оценка идет до 16, прежде чем он классифицируется как «аспирантура».

Что я собираюсь сделать с этим

Я планирую сделать базовый веб-сайт и применить то, что я узнал из-за деконструирования приложения Hemingway. Ничто не нравится, больше как упражнение для реализации какой-то логики. Раньше я создал предварительный просмотр Markdown, поэтому я также мог попытаться создать приложение записи с помощью системы выделения и оценки.

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

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

Вызовы

1. Как обеспечить производительность. Спасание весь документ на каждой ключевой прессу может быть очень вычислительно дорогим. Это может привести к блокировке UX, которое, очевидно, не то, что мы хотим.

2. Как разделить текст в пункты, предложения и слова для выделения.

Возможные решения

  • Только сканирование абзацев, которые меняются. Сделайте это, подсчитав количество абзацев и сравниваем это до документа до изменения. Используйте это, чтобы найти абзац, который изменился или новый абзац и только сканирует, что один.
  • Есть кнопка для сканирования документа. Это массивно уменьшает вызовы функции сканирования.

2. Используйте то, что я узнал из Хемингуэя – каждый абзац – это

и любые предложения или слова, которые нуждаются в выделении, обернуты во внутреннем с нужным классом.

Создание приложения

Недавно я прочитал много статей о создании минимального жизнеспособного продукта (MVP), поэтому я решил, что я бы запустил этот маленький проект одинаково. Это означало, чтобы все было просто. Я решил пойти с коробкой ввода, кнопку для сканирования и вывода.

Это было очень легко настроить в моем файле index.html.


Fake Hemingway

Fake Hemingway

Теперь начать на интересной части. Теперь, чтобы получить работу JavaScript.

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

function format() {
    let inputArea = document.getElementById("text-area");
    let text = inputArea.value;
    let outputArea = document.getElementById("output");
    outputArea.innerHTML = text;
}

Далее является получение текста разделения в пункты. Это достигается путем разделения текста «\ N» и поместив каждый из них в тег

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

. Использование шаблонов строки делает это очень легко.

let paragraphs = text.split("\n");
let inParagraphs = paragraphs.map(paragraph => `

${paragraph}

`); outputArea.innerHTML = inParagraphs.join(" ");

Хотя я работал, хотя я стал раздраженным копированием и вставлять текст теста в текстовое поле. Чтобы решить это, я реализовал немедленно вызываемое выражение функции (IIFE), чтобы заполнить текстовое поле, когда веб-страница отображается.

(function start() {
    let inputArea = document.getElementById("text-area");
    let text = `The app highlights lengthy, …. compose something new.`;
    inputArea.value = text;
})();

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

Подсветка

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

Первый этап этого является петля по каждому абзацу и разделить их в массив предложений. Я сделал это, используя функцию «разделения ()», разделение на все полную остановку с пространством после него.

let sentences = paragraph.split('. ');

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

let words = sentence.split(" ").length;
let letters = sentence.split(" ").join("").length;

Используя эти цифры, я мог бы использовать уравнение, которое я нашел в приложении HEMingway.

let level = Math.round(4.71 * (letters / words) + 0.5 * words / sentences — 21.43);

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

if (words < 14) {
    return sentence;
} else if (level >= 10 && level < 14) {
    return `${sentence}`;
} else if (level >= 14) {
    return `${sentence}`;
} else {
    return sentence;
}

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

Файл CSS действительно прост; Он просто имеет каждый из классов (наречие, пассив, привлечение) и устанавливает свой цвет фона. Я взял точные цвета из приложения Hemingway.

Как только предложения были возвращены, я присоединяюсь к ним все вместе, чтобы сделать каждый из абзацев.

На данный момент я понял, что в моем коде возникли несколько проблем.

  • Там не было полных остановок. Когда я разделяю абзацы в предложения, я удалил все полные остановки.
  • Числа букв в предложении включали запятые, тире, колоны и полуобытия.

Мое первое решение было очень примитивным, но оно сработало. Я использовал разделенный («символ») и присоединиться («), чтобы удалить пунктуацию, а затем добавить». на конец. Whist это сработало, я искал лучшее решение. Хотя у меня нет большого опыта, используя Regex, я знал, что это будет лучшее решение. После некоторого гугула я нашел гораздо более элегантное решение.

let cleanSentence = sent.replace(/[^a-z0–9. ]/gi, "") + ".";

С этим сделано, у меня был частично рабочий продукт.

Следующее, что я решил справиться, это наречие. Чтобы найти наречие, HEMingway просто находит слова, которые заканчиваются в «LY», а затем проверяют, что он не в списке слов нереплеба «Ly». Было бы плохо, если «применить» или «Италию» были помечены как наречие.

Чтобы найти эти слова, я взял предложения и разделил их в массив слов. Я сопоставлен через этот массив и использовал его заявление.

if(word.match(/ly$/) &&, !lyWords[word] ){
    return `${word}`;
} else {
    return word
};

Whist это сработало большую часть времени, я нашел несколько исключений. Если последовало слово знаком пунктуации, то он не совпал заканчиваться «LY». Например, «крокодил элегантно скользил; это добыча, не знающая», будет иметь слово «элегантно»; в массиве. Решить это, я повторно использовал .replace (/^ a-z0-9.]/Gi, "") Функциональность для очистки каждого из слов.

Еще одним исключением было, если бы слово было капитализировано, которое было легко решено, позвонив Толкание () на строке.

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

Для этого я использовал .indexof () функция на предложениях. Если был индекс слова или фразы, я вставил метку промежутка открытия в этом индексе, а затем тег закрытия после длины ключа.

let qualifiers = getQualifyingWords();
let wordList = Object.keys(qualifiers);
wordList.forEach(key => {
    let index = sentence.toLowerCase().indexOf(key);
    if (index >= 0) {
    sentence =
        sentence.slice(0, index) +
        '' +
        sentence.slice(index, index + key.length) +
        "" +
        sentence.slice(index + key.length);
    }
});

С этой работой он начинает все больше выглядеть как редактор помингинга.

Последний кусок выделенной головоломки для реализации был пассивный голос. Хемингуэй использовал функцию 30 линий, чтобы найти все пассивные фразы. Я решил использовать большую часть логики, который реализован HEMINGWAY, но заказывает процесс по-разному. Они выглядели, чтобы найти любые слова, которые были в списке (есть, были, были, были, были, были, быть), а затем проверили, закончилось ли следующее слово «ed».

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

С этой работой у меня было приложение, которое подчеркивало все, что я хотел. Это мой MVP.

Тогда я ударил проблему

Как я писал этот пост, я понял, что в моем коде из моих огромных ошибок были две огромные ошибки.

// from getQualifier and getComplex
let index = sentence.toLowerCase().indexOf(key);
// from getPassive
let index = words.indexOf(match);

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

«Возможно» и «были отмечены» должны были быть выделены дважды каждый, но они не.

Чтобы исправить ошибку в GetQualifier и GetComplex, я решил использовать рекурсию. Я создал indandandspan Функция, которая использует. indexof () Чтобы найти первый случай слова или фразы. Он разбивает предложение на 3 части: перед фразой фраза, после фразы. Рекурсион работает, передавая строку «после фразы» обратно в функцию. Это будет продолжаться до тех пор, пока больше нет экземпляров фразы, где строка будет просто передаваться обратно.

function findAndSpan(sentence, string, type) {
    let index = sentence.toLowerCase().indexOf(key);
    if (index >= 0) {
        sentence =
            sentence.slice(0, index) +
            `` +
            sentence.slice(index, index + key.length) +
            "" +
            findAndSpan(
                sentence.slice(index + key.length), 
                key,
                type);
    }
    return sentence;
}

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

Счетчик статистики

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

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

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

data.sentences += sentence.length
or
data.adverbs += 1

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

С нужными значениями я должен был получить их рендеринг на экране. Я изменил структуру HTML-файла, чтобы входную коробку и выходную область находились в Div слева, оставив правый Div для счетчиков. Эти счетчики пустые Div с соответствующим идентификатором и классом, а также класс «счетчика».

С помощью этих Divs я использовал Document.Queryselector, чтобы установить внутренний HTML для каждого из счетчиков с использованием собранных данных. С небольшим количеством стайлинга класса «Counter» веб-приложение было завершено. Попробуйте здесь Или посмотри на Мой код здесь.