且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

如何使用 Google Apps 脚本将 CSS 页面更改为具有内联样式的页面?

更新时间:2023-12-02 11:27:52

许多在线工具 可以进行这种转换,因此您可以利用 Google Apps 脚本中的一种.(如果您只需要偶尔执行一次,为什么不直接使用其中一项服务呢?)

There are numerous online tools that do this conversion, so you could leverage one of them from Google Apps Script. (If you only need to do this once in a while, why not just use one of those services?)

这是一个示例脚本,它基于 Google Apps 脚本是否有类似 getElementById 的东西?.

Here's an example script, that builds on the getElementByVal() function from Does Google Apps Script have something like getElementById?.

/**
 * Convert html containing <style> tags to instead have inline css.
 *
 * This example uses an online service from MailChimp Labs, but
 * the same principle could be used to leverage several other
 * online providers.
 *
 * @param  {Text}  htmlWstyle  A block of HTML text including
 *                             <style>..</style> tags.
 *
 * @returns {Text}             Same HTML, converted to inline css.
 */
function inline(htmlWstyle) {
  // Generate a POST request to inline css web tool.
  var payload =
  {
    "html" : htmlWstyle,
    "strip" : "checked"
  };

  // Because payload is a JavaScript object, it will be interpreted as
  // an HTML form. (We do not need to specify contentType; it will
  // automatically default to either 'application/x-www-form-urlencoded'
  // or 'multipart/form-data')

  var options =
  {
    "method" : "post",
    "payload" : payload,
    "muteHttpExceptions" : true
  };

  var url = "http://beaker.mailchimp.com/inline-css";
  var response = UrlFetchApp.fetch(url, options);

  // The html from this service is non-compliant, so we need
  // to massage it to satisfy the XmlService.
  var badlink = new RegExp('<link (.*?)[/]*>',"igm");
  var badmeta = new RegExp('<meta (.*?)[/]*>',"igm");
  var badinput = new RegExp('<input (.*?)[/]*>',"igm");
  var xml = response.getContentText()
                    .replace(badlink,"<link $1></link>" )
                    .replace(badinput,"<input $1></input>" )
                    .replace(badmeta,"<meta $1></meta>" )
                    .replace(/<br>/g,"<br/>");

  // So far, so good! Next, extract converted text from page. <textarea name="text" ...>
  // Put the receieved xml response into XMLdocument format
  var doc = XmlService.parse(xml);

  var inlineHTML = getElementByVal( doc, 'textarea', 'name', 'text' );
  return (inlineHTML == null) ? null : inlineHTML.getValue();
}

说明

那里似乎有一些黑魔法.previous answer 描述了如何使用旧的 Xml 服务检查网页的结构以找到您想要的位.它仍然是很好的阅读(和投票,提示,提示!),但该服务现在已经消失了,新的 XmlService 没有等效的探索性支持.

Explanation

There may appear to be some black magic in there. A previous answer described how to use the old Xml Service to examine the structure of a web page to find the bits you wanted. It's still good reading (and voting up, hint, hint!), but that service is now gone, and the new XmlService doesn't have equivalent exploratory support.

首先,我们发现一个网络服务 完成了我们感兴趣的工作,并使用 UrlFetch Service 模拟一个人将代码粘贴到服务中.理想情况下,我们想要一个只返回我们想要的结果的格式,我们可以在没有任何进一步工作的情况下使用.唉,我们拥有的是一个完整的网页,这意味着我们必须为我们的结果耕种它.那里的基本思想:使用 XmlService 解析和浏览页面,只提取我们想要的部分.

To start, we found a web service that did the job we were interested in, and used the UrlFetch Service to simulate a person pasting code into the service. Ideally, we'd like one that returned just the result we wanted, in a format we could use without any further work. Alas, what we had was a complete web page, and that meant that we'd have to farm it for our result. Basic idea there: Use the XmlService to parse and explore the page, extracting just the bit we wanted.

在选择的 Css Inline 服务中,Chrome 的Inspect Element"能力被用于确定标签类型()和唯一标识它的方法(名称=文本").有了这些知识,我们就拥有了使用 getElementByVal() 挖掘从 POST 请求返回的 HTML 所需的一切.(或者,您可以使用 String 方法来查找并提取您想要的文本.)

In the Css Inline service that was selected, Chrome's ability to "Inspect Element" was used to determine the tag type (<textarea>) and a way to uniquely identify it (name="text"). Armed with that knowledge, we had everything we needed to use getElementByVal() to dig through the HTML returned from a POST request. (Alternatively, you could use String methods to find and extract the text you want.)

但是当所有这些放在一起时,XmlService 一直在抱怨结果页面中 HTML 的格式 - 所以 JavaScript String &RegExp 方法用于在传递页面之前平衡格式错误的标签.

But when that was all put together, XmlService kept complaining about the format of the HTML in the result page - so JavaScript String & RegExp methods were used to balance the malformed tags before passing the page on.

这里有一个简单的例子来说明 inline() 函数的使用.请注意,样式信息是从外部 css 链接和标记样式中吸收的.

Here's a simple example illustrating use of the inline() function. Note that style information is absorbed from both the external css link AND the tagged styling.

function test_inline() {
  var myHtml =
    '<html>'
  +   '<head>'
  +     '<title>Example</title>'
  +     '<link rel="stylesheet" href="http://inlinestyler.torchboxapps.com/static/css/example.css" ></link>'
  +   '</head>'
  +   '<body>'
  +     '<style type="text/css">'
  +        'h1{'
  +             'color:yellow'
  +        '}'
  +     '</style>'
  +     '<h1>An example title</h1>'
  +     '<p>Paragraph 1</p>'
  +     '<p class="p2">Paragraph 2</p>'
  +   '</body>'
  + '</html>';

  var inlined = inline(myHtml);
  debugger;  // pause in debugger, have a look at "inlined"
}

结果

  <html>
    <head>
      <title>Example</title>
    </head>
    <body>
      <h1 style="color: yellow;">An example title</h1>
      <p style="margin: 0;padding: 0 0 10px 0;">Paragraph 1</p>
      <p class="p2" style="margin: 0;padding: 0 0 10px 0;">Paragraph 2</p>
    </body>
  </html>