Как вы добавляете порядковые номера к несмежным абзацам в Google do c? - PullRequest
0 голосов
/ 11 июля 2020

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

Существует много языков, например, Engli sh (см. Пример 1), испанский (см. Пример 2 ), Дани sh (см. Пример 3). (1) Google Документы - это круто. (2) Los documentos google son geniales. (3) Google Dokumenter er seje.

Лингвистика - это научное c изучение языков, например, португальского (см. Пример 4): (4) O português é bom.

Языки, человеческие и компьютерные, завораживают.

Я знаю, что stati c текст может быть вставлен в курсор в Google Do c с:

function insertHelloWorld() {
  var cursor = DocumentApp.getActiveDocument().getCursor();
  cursor.insertText("Hello World!");
}

Мой вопрос: как я могу отслеживать числа, когда они вставляются, чтобы я мог обновлять все числа, когда новый пример вставляется в середину текста с уже существующими Примеры? Итак, если бы я вставил пример на немецком языке под номером (2) выше (между примерами на английском sh и испанском sh), я бы хотел обновить номера примеров, которые идут после недавно вставленного немецкого примера:

... (1) Google Документы - это круто. (2) Google Text и Tabellen - это круто. (3) Los documentos google son geniales. (4) Google Dokumenter er seje. ... (5) O português é bom. ...

1 Ответ

1 голос
/ 11 июля 2020

Пусть «ссылка» будет строкой «(см. Пример n)», где n - это число.

Пусть «примером» будет «(n) Пример текста ... "где n - число, и это всегда начало строки.

Это решение предполагает, что вы вручную заказали свои« ссылки »и« примеры ». Код не меняет порядок списка примеров. Следовательно, не имеет значения, каковы текущие значения n, нам просто нужно go через весь Do c и применить последовательные числа.

Это проще реализовать, если вы можете забыть все ваше форматирование при запуске обновления. В этом случае вы можете использовать обычный JavaScript и применить String.prototype.replace ко всему телу. Однако я предполагаю, что вы не хотите удалять свое форматирование, поэтому мы вынуждены использовать вместо этого модель DocumentApp.

В моем примере я использую body.findText до l oop через Do c. К сожалению, здесь используются регулярные выражения строки вместо обычных объектов RegExp, которым для поиска буквальных скобок требуются дополнительные обратные косые черты. Кроме того, я использую текстовые функции deleteText и insertText, а не String.prototype.replace, потому что использование replace будет воздействовать на весь элемент, а не на начальное и конечное смещения, найденные функцией findText.

function updateSequentialReferences() {
  const body = DocumentApp.getActiveDocument().getBody();
  replaceSequentially(body, "\\(see example \\d+\\)", count => `(see example ${count})`);
  replaceSequentially(body, "^\\(\\d+\\)(.*)$", (count, match) => match.replace(/^\(\d+\)/, `(${count})`));
}

function replaceSequentially(body, regexString, replacerFn) {
  let foundRef = body.findText(regexString);
  let count = 1;
  while (foundRef !== null) {
    const {element, end, start} = unwrapRangeElement(foundRef);
    const text = element.asText();
    const match = text.getText().slice(start, end + 1);
    text.deleteText(start, end);
    text.insertText(start, replacerFn(count, match));
    ++count;
    foundRef = body.findText(regexString, foundRef);
  }
}

function unwrapRangeElement(element) {
  return {
    element: element.getElement(),
    end: element.getEndOffsetInclusive(),
    start: element.getStartOffset(),
  }
}
...