# 我的终极文章打印方案：不靠插件、软件，只用小书签！

> 本文公开全文。

原文：https://utgd.net/article/21181

之前我读过不少站内关于 PDF 打印的文章，一开始为了格式清爽，而选择了剪藏到 Obsidian，再导出为 PDF 打印。我写成文分享后，还是觉得流程繁琐，况且需要借助 Obsidian，就能拦掉一批人，费时又费力。

今天我就思考，有没有更好的解决方法。一开始我折腾 Microsoft Edge 的阅读模式，又下载插件，换浏览器，最后逛 UTGD 时，看到了一个完美的解决思路：借助小书签（Bookmarklet）来调整文章格式！

我简要介绍一下小书签，它是一种特殊的浏览器书签，点击后就执行 JavaScript 代码，能直接对当前页面进行操作。它的优势是，支持几乎所有主流浏览器，无需下载，比插件更方便，还能自行修改，满足需求。

使用方法很简单：直接复制小书签，随后在浏览器随便添加一个网页书签，把网址替换成 javascript 代码即可。如果觉得不需要，刷新网页就能恢复原状。

理论说到这里，下面说解决方案。

## 1、把网页文章调整成纯净阅读模式。

```
javascript:(function()%7Bjavascript%3A(function()%7Bjavascript%3A(function()%7Bconsole.log('start')%3Bvar jsCode%3Ddocument.createElement('script')%3BjsCode.setAttribute('src'%2C'https%3A%2F%2Fgcore.jsdelivr.net%2Fgh%2Fmozilla%2Freadability%2FReadability.js')%3Bwindow.cleanHtml%3D(function()%7Bvar loc%3Ddocument.location%3Bvar uri%3D%7Bspec%3Aloc.href%2Chost%3Aloc.host%2CprePath%3Aloc.protocol%2B'%2F%2F'%2Bloc.host%2Cscheme%3Aloc.protocol.substr(0%2Cloc.protocol.indexOf('%3A'))%2CpathBase%3Aloc.protocol%2B'%2F%2F'%2Bloc.host%2Bloc.pathname.substr(0%2Cloc.pathname.lastIndexOf('%2F')%2B1)%7D%3Bvar article%3Dnew Readability(uri%2Cdocument).parse()%3Bvar titleElement%3Ddocument.createElement('h1')%3BtitleElement.textContent%3Darticle.title%3BtitleElement.style.textAlign%3D'center'%3BtitleElement.style.margin%3D'20px 0'%3BtitleElement.style.backgroundColor%3D'transparent'%3BtitleElement.style.border%3D'none'%3BtitleElement.style.padding%3D'0'%3Bvar metadataElement%3Ddocument.createElement('p')%3BmetadataElement.style.textAlign%3D'center'%3BmetadataElement.style.color%3D'%23555'%3BmetadataElement.style.fontSize%3D'12px'%3BmetadataElement.style.margin%3D'-15px 0 25px 0'%3BmetadataElement.style.lineHeight%3D'1.6'%3BmetadataElement.style.wordBreak%3D'break-word'%3Bvar metadataParts%3D%5B%5D%3Bif(article.byline)%7BmetadataParts.push('作者%3A '%2Barticle.byline)%3B%7Dvar linkHTML%3D'原文%3A <a href%3D"'%2Bloc.href%2B'" target%3D"_blank" style%3D"color%3A%23007bff%3Btext-decoration%3Aunderline%3B">'%2Bloc.href%2B'<%2Fa>'%3BmetadataParts.push(linkHTML)%3BmetadataElement.innerHTML%3DmetadataParts.join('<span style%3D"margin%3A0 1em%3B">%7C<%2Fspan>')%3Bvar contentDiv%3Ddocument.createElement('div')%3BcontentDiv.innerHTML%3Darticle.content%3Bdocument.head.innerHTML%3D''%3Bvar cleanStyle%3Ddocument.createElement('link')%3BcleanStyle.setAttribute('href'%2C'https%3A%2F%2Fgcore.jsdelivr.net%2Fgh%2Frunningcheese%2FAwesome-Bookmarklets%2Flibs%2Fclean.css')%3BcleanStyle.setAttribute('rel'%2C'stylesheet')%3Bdocument.head.appendChild(cleanStyle)%3Bvar customStyles%3Ddocument.createElement('style')%3BcustomStyles.type%3D'text%2Fcss'%3Bvar styleText%3D'blockquote %7B color%3A %23666%3B display%3A block%3B margin%3A 0 0 16px%3B padding%3A 0 20px%3B border-left%3A %23ddd solid 4px%3B %7D h1%2C h2%2C h3%2C h4%2C h5%2C h6 %7B color%3A %23000000 !important%3B %7D body %7B color%3A %23000000 !important%3B font-size%3A 18px !important%3B line-height%3A 1.7 !important%3B %7D'%3BcustomStyles.appendChild(document.createTextNode(styleText))%3Bdocument.head.appendChild(customStyles)%3Bdocument.body.innerHTML%3D''%3Bdocument.body.appendChild(titleElement)%3Bdocument.body.appendChild(metadataElement)%3Bdocument.body.appendChild(contentDiv)%3B%7D)%3BjsCode.onload%3DcleanHtml%3Bdocument.body.appendChild(jsCode)%3B%7D)()%7D)()%7D)()
```

作用：文章开启阅读模式，有标题和文章来源，字号为 18px，美化引用样式。

我以前保存了一个【阅读模式】小书签，但它开启后，不显示正文标题。我借助 AI 完善后，发现不少需要改善的地方：

- 标题下我希望显示作者和原文链接，方便打印后溯源；

- 文字颜色比较淡，导致打印出后来字迹不清；

- 文章字号较小，打印在 A5 小册子上阅读比较费眼；

- 引用样式只是两段缩进字符，但不够醒目；

- 小书签无法应用在公众号文章上（因其封闭、自成一体的设计）。

中间我跟 AI 对话了几十次，遇到许多问题，最后完美解决了上述问题（除了公众号文章），再导出为 PDF 即可。

现在你把上面 javascript 开头的小书签，添加到浏览器后，点开一篇文章，也就拥有了一个纯净的阅读模式，无需借助插件和 Obsidian。

应用前与应用后（但放弃了banner图）

## 2、公众号的解决方案：字体调大、颜色为黑。

```
javascript:(function()%7Bjavascript%3A(function()%7Bvar id%3D'font-styler-bookmarklet'%3Bif(document.getElementById(id))%7Balert('样式已调整！')%3Breturn%3B%7Dvar css%3D%60%23js_content%2C%23js_content p%2C%23js_content span%7Bfont-size%3A18px !important%3Bcolor%3A%23000000 !important%3B%7D%60%3Bvar style%3Ddocument.createElement('style')%3Bstyle.id%3Did%3Bstyle.appendChild(document.createTextNode(css))%3Bdocument.head.appendChild(style)%3Balert('正文样式已调整！')%3B%7D)()%7D)()
```

作用：网页文字全部变成黑色，字号为 18px。

上述提到，由于公众号的封闭，小书签无法应用。我最后想到，许多时候公众号文章需要调整，是因为原文排版字体不是纯黑色，导致打印出来字迹不清，而且字号太小，无法调整。

那问题就简单了，我只需要小书签能帮我把所有文字改为黑色，字号设置为 18px 就够了。应用之后，文章格式就会自动调整。

应用前与应用后

下图为打印对比：

如此一来，公众号文章打印后更适合纸质阅读，也不劳烦其他工具来帮忙了。

## 3、点击就能缩小网页图片。

```
javascript:(function()%7Bjavascript%3A(function() %7B if (window.imgShrinkActive) %7B alert('图片缩小模式已激活！')%3B return%3B %7D window.imgShrinkActive %3D true%3B function shrinkImg(e) %7B e.preventDefault()%3B e.stopPropagation()%3B const img %3D e.target%3B const minWidth %3D 50%3B let curWidth %3D img.offsetWidth%3B let newWidth %3D curWidth * 0.9%3B if (newWidth < minWidth) %7B newWidth %3D minWidth%3B %7D img.style.setProperty('width'%2C newWidth %2B 'px'%2C 'important')%3B img.style.setProperty('height'%2C 'auto'%2C 'important')%3B if (newWidth %3D%3D%3D minWidth) %7B alert('图片已缩小到最小尺寸')%3B %7D %7D document.querySelectorAll('img').forEach(img %3D> %7B img.style.cursor %3D 'pointer'%3B img.addEventListener('click'%2C shrinkImg%2C true)%3B %7D)%3B alert('图片缩小模式已开启，点击任意图片即可逐步缩小！')%3B %7D)()%7D)()
```

作用：启用后，每点击一次图片，就会缩小 10%，直到 50px 最小尺寸。

目前，格式问题解决了，但图片还是个难题。因为不少文章图片比较大，打印出来很占地方，之前就有朋友问有没有方法。

今天我想到也能用小书签来解决，于是让 AI 来协助完成，中间也遇到点击图片后，因为原有设计，自动铺满全屏的情况，接着优化几次，总算解决了。

## 4、字体调整为「思源宋体 CN」。

```
javascript:(function()%7Bjavascript%3A(function()%7Bvar style %3D document.createElement('style')%3Bstyle.innerHTML %3D %60%40import url('https%3A%2F%2Ffonts.googleapis.com%2Fcss2%3Ffamily%3DNoto%2BSerif%2BSC%3Awght%40500%3B900%26display%3Dswap')%3Bbody%2C p%2C div%2C span%2C a%2C li%2C td%2C th %7Bfont-family%3A 'Noto Serif SC'%2C serif !important%3Bfont-weight%3A 500 !important%3B%7Dh1%2C h2%2C h3%2C h4%2C h5%2C h6%2C b%2C strong %7Bfont-family%3A 'Noto Serif SC'%2C serif !important%3Bfont-weight%3A 900 !important%3B%7D%60%3Bdocument.head.appendChild(style)%3B%7D)()%7D)()
```

作用：将网页正文字体设置为「思源宋体 CN Medium」，标题及粗体为「思源宋体 CN Heavy」，需要提前安装字体。

这是个人偏好，我觉得思源宋体比较耐看，以及我之前打印 UTGD 文章时，就发现粗体和标题的字重都没有变化，因此额外增添一条，诸君自取。

## 5、删除多余元素。

```
javascript: (function%20()%20%7B%20%20%20var%20isIe%20%3D%20false%3B%20%20%2F*%40cc_on%20isIe%3Dtrue%3B%20%40*%2F%20%20function%20fe(a%2C%20fn)%20%7B%20%20%20%20%20var%20i%2C%20l%20%3D%20a.length%3B%20%20%20%20%20for%20(i%20%3D%200%3B%20i%20%3C%20l%3B%20i%2B%2B)%20%7B%20fn(a%5Bi%5D)%3B%20%7D%20%20%20%7D%3B%20%20%20function%20ae(el%2C%20n%2C%20fn%2C%20ix)%20%7B%20%20%20%20%20function%20wfn(ev)%20%7B%20%20%20%20%20%20%20var%20el%20%3D%20(isIe%20%3F%20window.event.srcElement%20%3A%20ev.target)%3B%20%20%20%20%20%20%20if%20(n%20%3D%3D%20%27click%27)%20%7B%20%20%20%20%20%20%20%20ev.stopPropagation()%3B%20%20%20%20%20%20%20%20ev.preventDefault()%3B%20%20%20%20%20%20%20%7D%20%20%20%20%20%20if%20(ix%20%7C%7C%20!el.xmt)%20%7Bfn(el)%3B%7D%20%20%20%20%20%7D%20%20%20%20%20if%20(isIe)%20%7B%20%20%20%20%20%20%20n%20%3D%20%27on%27%20%2B%20n%3B%20el.attachEvent(n%2C%20wfn)%3B%20%20%20%20%20%7D%20else%20%7B%20%20%20%20%20%20%20var%20isUseCapture%20%3D%20(n%20%3D%3D%20%27click%27)%3B%20%20%20%20%20%20el.addEventListener(n%2C%20wfn%2C%20isUseCapture)%3B%20%7D%20%20%20%20%20if%20(!el.es)%20el.es%20%3D%20%5B%5D%3B%20%20%20%20%20el.es.push(%20%20%20%20%20%20function%20()%20%7B%20%20%20%20%20%20%20%20%20if%20(isIe)%20%7B%20el.detachEvent(n%2C%20wfn)%3B%20%7D%20%20%20%20%20%20%20%20%20else%20%7B%20el.removeEventListener(n%2C%20wfn%2C%20isUseCapture)%3B%20%7D%20%20%20%20%20%20%20%7D)%3B%20%20%20%20%20el.re%20%3D%20function%20()%20%7B%20fe(el.es%2C%20function%20(f)%20%7B%20f()%20%7D)%3B%20%7D%3B%20%20%20%7D%3B%20%20function%20sce(el)%20%7B%20%20%20%20%20var%20oldclick%20%3D%20el.onclick%2C%20oldmu%20%3D%20el.onmouseup%2C%20oldmd%20%3D%20el.onmousedown%3B%20%20%20%20%20el.onclick%20%3D%20function%20()%20%7B%20return%20false%3B%20%7D%3B%20%20%20%20%20el.onmouseup%20%3D%20function%20()%20%7B%20return%20false%3B%20%7D%3B%20%20%20%20%20el.onmousedown%20%3D%20function%20()%20%7B%20return%20false%3B%20%7D%3B%20%20%20%20%20el.rce%20%3D%20function%20()%20%7B%20el.onclick%20%3D%20oldclick%3B%20el.onmouseup%20%3D%20oldmu%3B%20el.onmousedown%20%3D%20oldmd%3B%20%7D%3B%20%20%20%7D%20%20%20if%20(!window.r_)%20window.r_%20%3D%20%5B%5D%3B%20%20%20var%20r%20%3D%20window.r_%3B%20%20%20var%20D%20%3D%20document%3B%20%20%20ae(D.body%2C%20%27mouseover%27%2C%20function%20(el)%20%7B%20el.style.backgroundColor%20%3D%20%27%23ffff99%27%3B%20sce(el)%20%7D)%3B%20%20%20ae(D.body%2C%20%27mouseout%27%2C%20function%20(el)%20%7B%20el.style.backgroundColor%20%3D%20%27%27%3B%20if%20(el.rce)%20el.rce()%3B%20%7D)%3B%20%20%20ae(D.body%2C%20%27click%27%2C%20function%20(el)%20%7B%20%20%20%20el.style.display%20%3D%20%27none%27%3B%20%20%20%20%20r.push(el)%3B%20%20%20%7D)%3B%20%20%20function%20ac(p%2C%20tn%2C%20ih)%20%7B%20var%20e%20%3D%20D.createElement(tn)%3B%20%20%20%20%20if%20(ih)%20e.innerHTML%20%3D%20ih%3B%20%20%20%20%20p.appendChild(e)%3B%20%20%20%20%20return%20e%3B%20%20%20%7D%20%20%20var%20p%20%3D%200%3B%20%20%20var%20bx%20%3D%20ac(D.body%2C%20%27div%27)%3B%20%20%20bx.style.cssText%20%3D%20%27position%3A%27%20%2B%20(isIe%20%3F%20%27absolute%27%20%3A%20%27fixed%27)%20%2B%20%27%3Bpadding%3A2px%3Bbackground-color%3A%2399FF99%3Bborder%3A1px%20solid%20green%3Bz-index%3A9999%3Bfont-family%3Asans-serif%3Bfont-size%3A10px%27%3B%20%20%20function%20sp()%20%7B%20%20%20%20%20bx.style.top%20%3D%20(p%20%26%202)%20%3F%20%27%27%20%3A%20%2710px%27%3B%20%20%20%20%20bx.style.bottom%20%3D%20(p%20%26%202)%20%3F%20%2710px%27%20%3A%20%27%27%3B%20%20%20%20%20bx.style.left%20%3D%20(p%20%26%201)%20%3F%20%27%27%20%3A%20%2710px%27%3B%20%20%20%20%20bx.style.right%20%3D%20(p%20%26%201)%20%3F%20%2710px%27%20%3A%20%27%27%3B%20%20%20%7D%20sp()%3B%20%20%20var%20ul%20%3D%20ac(bx%2C%20%27a%27%2C%20%27%20Undo%20%7C%27)%3B%20%20%20ae(ul%2C%20%27dblclick%27%2C%20function%20()%20%7B%20var%20e%20%3D%20r.pop()%3B%20if%20(e)%20e.style.display%20%3D%20%27%27%3B%20%7D%2C%20true)%3B%20%20%20var%20ual%20%3D%20ac(bx%2C%20%27a%27%2C%20%27%20Undo%20All%20%7C%27)%3B%20%20%20ae(ual%2C%20%27dblclick%27%2C%20function%20()%20%7B%20var%20e%3B%20while%20(e%20%3D%20r.pop())%20e.style.display%20%3D%20%27%27%3B%20%7D%2C%20true)%3B%20%20%20var%20ml%20%3D%20ac(bx%2C%20%27a%27%2C%20%27%20Move%20%7C%27)%3B%20%20%20ae(ml%2C%20%27dblclick%27%2C%20function%20()%20%7B%20p%2B%2B%3B%20sp()%3B%20%7D%2C%20true)%3B%20%20%20var%20xl%20%3D%20ac(bx%2C%20%27a%27%2C%20%27%20Exit%20%27)%3B%20%20%20ae(xl%2C%20%27dblclick%27%2C%20function%20()%20%7B%20D.body.re()%3B%20bx.parentNode.removeChild(bx)%3B%20%7D%2C%20true)%3B%20%20%20fe(%5Bbx%2C%20ul%2C%20ml%2C%20xl%2C%20ual%5D%2C%20function%20(e)%20%7B%20e.style.cursor%20%3D%20%27pointer%27%3B%20e.xmt%20%3D%201%3B%20%7D)%3B%20%7D)()
```

源于 Minja 的文章《剪藏网页到本地的轻量化思路》，由网友 Flez 提供的优化版本。

作用：启用后，就能任意删除网页元素。

简单一用，鼠标点点，就能删掉文章里的无用元素，比如二维码、自我介绍、多余图片，最后留下干净清爽的页面。

## 最后

我迭代了十几个版本，最后形成了这套打印前的简化流程。这么操作下来，不管是阅读模式，还是调整图片，删改元素，都不需要任何插件。

而且你想修改哪里，随时能让 AI 来帮你，比如字号、颜色、字体等、总能调整到满意为止。

这时打印出来的文章，格式也跟我之前用 Obsidian 导出打印没什么两样，甚至更加快速简单。

至此，文章打印格式的折腾，也能暂且告一段落，希望这篇文章对你有用，少点折腾，一步到位。

---

[前往标准阅读页](https://utgd.net/article/21181?audience=web)
