简体   繁体   English

如何以编程方式格式化开始和结束标签之间的文本,然后删除标签

[英]How to programmatically format text between start and end tags and then remove the tags

Edit: the below endeavor is related to Google Apps Script to format text in a Google Doc.编辑:以下努力与 Google Apps Script 相关,用于格式化 Google Doc 中的文本。

I'm not familiar with JavaScript and really have only done some small bit of R coding and so this effort is a bit of parsing what I can google as well as some trial and error.我不熟悉 JavaScript 并且真的只做了一些 R 编码的一小部分,所以这项工作是解析我可以用谷歌搜索的内容以及一些试验和错误。 I've had some promising success, but I'm also having some trouble finding a complete answer to the following scenario.我取得了一些有希望的成功,但我也很难找到以下场景的完整答案。

Context语境

I have a google doc template that has embedded merge codes.我有一个嵌入了合并代码的谷歌文档模板。 A separate application is pulling data fields from objects and related objects and replacing those merge codes with unformatted text.一个单独的应用程序正在从对象和相关对象中提取数据字段,并将这些合并代码替换为未格式化的文本。 A side effect of this application is that I cannot format the merge codes ahead of time so that when replaced, the text is formatted appropriately.这个应用程序的一个副作用是我无法提前格式化合并代码,以便在替换时文本被适当地格式化。 Therefore I'm trying to create a script to run following text merge to programmatically apply some formatting.因此,我正在尝试创建一个脚本来运行以下文本合并以编程方式应用一些格式。

What I Need我需要的

I have three different styles I need to apply.我需要申请三个不同的 styles。 I am creating code to search for start tags and end tags and then format the text between.我正在创建代码来搜索开始标签和结束标签,然后格式化它们之间的文本。 In a perfect world the tags would also then be removed from the document leaving only the formatted text behind.在一个完美的世界中,标签也将从文档中删除,只留下格式化的文本。

Styled Item样式项目 Tags标签 Formatting to be applied要应用的格式
Requests要求 <req> </req> <req> </req> Roboto 10, Bold, #4a5356 Roboto 10,粗体,#4a5356
Citations引文 <cit> </cit> <cit> </cit> Lato 8, Bold, #4A5356拉托 8,粗体,#4A5356
Conclusions结论 <con> </con> <con> </con> Lato 8, Bold, #B38F00拉托 8,粗体,#B38F00

Code so Far到目前为止的代码

function onOpen() {
  DocumentApp.getUi().createMenu('Butler')
      .addItem('Format Headings', 'FormatRequests')

      .addToUi();
}

function FormatRequests() {
  var startTag = '<req>';
  var endTag = '</req>'
  var body = DocumentApp.getActiveDocument().getBody();
  var para = body.getParagraphs();
  for(var i in para){  
    var from = para[i].findText(startTag);
    var to =  para[i].findText(endTag,from);
    if((to != null && from != null) && ((to.getStartOffset()-1) - (from.getStartOffset()+startTag.length) > 0) ){
      para[i].editAsText().setBold(from.getStartOffset()+startTag.length, to.getStartOffset()-1, true);
    }
  }
}

So far I've succeeded in finding the tags and setting text between the tags to bold.到目前为止,我已经成功地找到了标签并将标签之间的文本设置为粗体。 But I don't know how to continue to apply the remainder of the formatting or how to remove the tags once the formatting has been applied.但是我不知道如何继续应用格式的其余部分,或者在应用格式后如何删除标签。

Any ideas?有任何想法吗?

So, what I've done is converted the data into an array and using that array I've made the desired formatting.所以,我所做的是将数据转换为一个数组,并使用该数组进行了所需的格式设置。

So, if this the data:所以,如果这是数据:

Hey! <req>My name is John</req> and I am a <cit>web developer</cit> from Canada. I love coding and solving problems. <con>Ping me if you want to talk code</con>.

I will convert this into the following nested array, where the first item at every index specifies the start index.我会将其转换为以下嵌套数组,其中每个索引的第一项指定起始索引。

[
  [ 0, 'Hey! ' ],
  [ 5, 'My name is John', '<req>' ],
  [ 20, ' and I am a ' ],
  [ 32, 'web developer', '<cit>' ],
  [ 45, ' from Canada. I love coding and solving problems. ' ],
  [ 95, 'Ping me if you want to talk code', '<con>' ],
  [ 127, '.' ]
]

NOTE: I've used ~ and ^ characters to split the data, hoping that these two characters don't appear in your data.注意:我使用~^字符来拆分数据,希望这两个字符不会出现在您的数据中。

Working Code Below:工作代码如下:

function myFunction() {
  const body = DocumentApp.getActiveDocument().getBody();

  const allText = body.editAsText();
  const arr = splitText(allText.getText())
  
  allText.deleteText(0, allText.getText().length - 1)

  for (let el of arr) {
    let someText = allText.appendText(el[1])
    let start = el[0];
    let end = el[0] + el[1].length - 1;

    if (el.length > 2) {
      if (el[2] === "<req>") {
        someText.setFontFamily(start, end, DocumentApp.FontFamily.ROBOTO);
        someText.setFontSize(start, end, 10);
        someText.setBold(start, end, true);
        someText.setForegroundColor(start, end, "#4a5356")
      }else if(el[2] === "<cit>") {
        someText.setFontFamily(start, end, DocumentApp.FontFamily.TIMES_NEW_ROMAN);
        someText.setFontSize(start, end, 8);
        someText.setBold(start, end, true);
        someText.setForegroundColor(start, end, "#4a5356")
      }else if (el[2] === "<con>") {
        someText.setFontFamily(start, end, DocumentApp.FontFamily.TIMES_NEW_ROMAN);
        someText.setFontSize(start, end, 8);
        someText.setBold(start, end, true);
        someText.setForegroundColor(start, end, "#b38f00")
      }
    } else {
      someText.setFontFamily(start, end, null);
        someText.setFontSize(start, end, null);
        someText.setBold(start, end, null);
        someText.setForegroundColor(start, end, null)
    }
  }
}

function splitText(data) {
  return data
  .replace(/<([a-z]{3})>/g, "~")
  .replace(/<\/([a-z]{3})>/g, "^<$1>~")
  .split("~")
  .map((s) => s.split("^"))
  .reduce((r, s, i, a) => (i === 0? r.push([0, ...s]): r.push([r[i - 1][0] + a[i - 1][0].length, ...s]), r), [])
}

Try this:尝试这个:

function main() {

  handle_tags(['<req>', '</req>'], "Roboto", 10, "Bold", "#4a5356");
  handle_tags(['<cit>', '</cit>'], "Lato", 8, "Bold", "#4a5356");
  handle_tags(['<con>', '</con>'], "Lato", 8, "Bold", "#B38F00");
  
}

function handle_tags(tags, family, size, style, color) {

  var body      = DocumentApp.getActiveDocument().getBody();
  var start_tag = tags[0];
  var end_tag   = tags[1];
  
  var found     = body.findText(start_tag);

  while (found) {
    var elem    = found.getElement();
    var start   = found.getEndOffsetInclusive();
    var end     = body.findText(end_tag, found).getStartOffset()-1;

    elem.setFontFamily(start, end, family);
    elem.setFontSize(start, end, size);
    elem.setForegroundColor(start, end, color);

    switch (style.toLowerCase()) {
      case 'bold': elem.setBold(start, end, true); break;
      case 'italic': elem.setItalic(start, end, true); break;
      case 'underline': elem.setUnderline(start, end, true); break;
    }

    found = body.findText(start_tag, found);
  }

  body.replaceText(start_tag, '');
  body.replaceText(end_tag, '');
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM