我正在使用puppeteer
(无头Chrome)将RMarkdown脚本生成的.html呈现为.pdf。 (有关为什么我不简单使用output: pdf_document
的信息,请参见下文。)但是,puppeteer
似乎并没有尊重我的color
和background-color
样式设置。如下所示,在网络上渲染页面时不存在该问题。因此,我很确定这是puppeteer
和RMarkdown
之间的相互作用,但是我对knitr
的了解还不足以确定此问题的确切原因。
考虑以下test.Rmd
脚本:
---
title: "Testing colors"
output: html_document
---
<style>
html {
-webkit-print-color-adjust: exact;
}
h4 {color: blue;}
</style>
#### Blue heading
<div style="color:red">This text is red</div>
<div style="background-color:red">This text has red background</div>
我们可以通过在R中调用test.html
将其呈现为rmarkdown::render( "test.Rmd", output_file="test.html" )
。注意-webkit-print-color-adjust
设置;通常建议使用它作为解决与颜色有关的问题的方法,但我发现它对我而言没有任何作用。
在puppeteer tutorials之后,我整理了以下render.js
:
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.setViewport({width: 400, height: 200});
await page.goto('file:///home/sokolov/test/puppeteer/test.html');
await page.screenshot({path: 'test.png'});
await page.pdf({path: 'test.pdf', printBackground: true});
await browser.close();
})();
从命令行运行node render.js
会生成test.png
和test.pdf
。前者看起来完全符合您的期望:
但是,.pdf
失去了所有颜色规格:
如果我将render.js
中的网址替换为外部页面(例如https://www.w3schools.com/css/css_background.asp
),则该页面会以.png
和.pdf
格式正确显示。指定printBackground: true
是使其适用于此外部页面的关键,但似乎对我的本地test.html
无效。
关于如何使颜色起作用的任何想法?
P.S。为了简要说明为什么我不简单地在output: pdf_document
中使用.Rmd
的问题,我想指出,我正在使用的真实RMarkdown文档使用flexdashboard
布局,其中{ {3}}。我阅读的大多数教程都建议使用无头浏览器将最终的.html
渲染为.png
/ .pdf
。该解决方案对我来说效果很好,除了失去颜色样式。
答案 0 :(得分:1)
为什么不尝试删除所有!important
标签?我们的目标是rmarkdown:render
嵌入的CSS。只需运行一些搜索并替换代码,puppeteer即可正确着色由test.html制成的pdf。在安装了vim的shell中运行它:
echo "%s/%21important// | w!" | vim -e test.html
就是这样!在下面,我仅记录解决该问题的第一次尝试,并解释为什么它可能不是最佳解决方案。其他人可能会发现它有用。
在安装了vim的shell中运行它:
echo "%s/%40media%20print%7B.\{-}%7D// | w!" | vim -e test.html
上面的命令将test.html
样式部分删除而覆盖@media print{}
。尽管@media print{}
样式没有完全或干净地删除,但是新的test.html
具有所需的效果。
我们正在使用url编码的CSS,因此当我真的想编写此代码时,需要%s/%40media%20print%7B.\{-}%7D//
:
%s/@media print{.\{-}}//
目标是完全删除以下语句:@media print {a: ""}
。我没有正确处理嵌套的括号,因此此脚本仅部分删除了@media print {.a{a: ""};b{}...}
这样的语句,而第一个右括号之后的所有内容都保持不变。那是一个错误。由于与.\{-}
的非贪婪匹配而不是与.*
的贪婪匹配,我删除的内容太少了。
为了便于阅读,我在test.html
中URL decoded是实际的CSS。您可以看到我删除了不匹配的花括号。可能实际上没有删除有问题的css,但是只要检测到@media print
,删除这些行就会充分破坏css从而禁用有问题的css。无论如何,删除这6个匹配项即可解决问题。
@media print{*,:after,:before{color:#000!important;text-
shadow:none!important;background:0 0!important;-webkit-box-
shadow:none!important;box-shadow:none!important}
@media print{.visible-print{display:block!important}
@media print{.visible-print-block{display:block!important}
@media print{.visible-print-inline{display:inline!important}
@media print{.visible-print-inline-block{display:inline-block!important}
@media print{.hidden-print{display:none!important}