Blogger/blogspot 引入 google 的 code-prettify 实现代码高亮 并保留手动设置的文字颜色

0 条回复
9 次浏览

前言

关于博客中的代码高亮, 最早我是  修改 blockquote 的 CSS 来实现 代码段 的显示效果

后来实验   引入 google 的 code-prettify 实现代码高亮 把 blockquote 转换为 pre code

最后 因为代码高亮会把我在代码段中设置的文字底色清除 , 换回了 修改 blockquote 的 CSS 来实现 代码段 的效果

现在我让  blogger 编辑器可以输入 pre 和 code 了 , 所以我用 blockquote 真的去表示引用, 引用我发送给 Agent 的自然语言, 这也确实是我最近几个月使用非常多的场景.

我也通过 Agent 操作 Blogger API 帮助我把历史博文中的 blockquote 换成了 pre

现在我重新考虑代码高亮的问题.

面向 Agent 开发

Hermes 对接 白嫖 公益站 agentrouter 的 deepseek-v4-flash

思路 1

我现在想把 google 的 code-prettify 代码高亮 功能加回来

但是, 还是面临 代码高亮会把我在代码段中设置的文字底色清除 的问题

我一开始的想法是, 

在 Blogger/blogspot 模板中, 加一个 script 用来给 pre 加 class="prettyprint".
那么这个脚本可以分析 pre 中是否有手动设置文字颜色 的情况.
如果有手动设置文字颜色, 那么就不给这个 pre 加 class="prettyprint"

我就是把上面这段话发给 Agent 修改 Blogger/blogspot 的 xml 模板

关键函数

复制
<!-- 为所有 pre 添加 class='prettyprint'(pre 内部已手动设置颜色/背景色的则不添加) -->
<script type='text/javascript'>
//<![CDATA[
(function(){
  /* 判断某个元素及其所有子孙元素是否设置了颜色或背景色 */
  function hasCustomColor(root){
    var elements=[root].concat(Array.prototype.slice.call(root.querySelectorAll('*')));
    for(var i=0;i<elements.length;i++){
      var el=elements[i];
      /* 1. 行内 style 中的 color / background-color / background */
      var styleAttr=el.getAttribute('style');
      if(styleAttr&&/(^|;|\s)(color|background-color|background)\s*:/i.test(styleAttr))return true;
      /* 2. 旧式 HTML 属性 bgcolor / color(如 <font color="red">) */
      if(el.hasAttribute('bgcolor')||el.hasAttribute('color'))return true;
    }
    return false;
  }
  function markPre(){
    document.querySelectorAll('pre').forEach(function(el){
      if(!hasCustomColor(el))el.classList.add('prettyprint');
    });
  }
  function run(){
    markPre();
    if(window.PR&&typeof PR.prettyPrint==='function')PR.prettyPrint();
  }
  if(document.readyState==='loading'){
    document.addEventListener('DOMContentLoaded',run);
  }else{
    run();
  }
  /* 兜底: run_prettify.js 异步就绪后一定能高亮 */
  window.addEventListener('load',function(){
    if(window.PR&&typeof PR.prettyPrint==='function')PR.prettyPrint();
  });
})();
//]]>
</script>

但是, 这样的话, 没有经过 prettify 处理的 pre 和经过了处理的 pre, 有了较大的不同.

image|479x500

思路 2

那么, 还有没有什么办法可以保留 pre 中手动设置的文字颜色呢?

我找到了 google 的 code-prettify 的源码 https://github.com/googlearchive/code-prettify 让 Agent 结合我的博客 html 一起分析.

分析结果是:

1. pre 中手动设置了文字的颜色, 再经过 prettify 处理, 会变成这样

复制
<span style="color:red"><span class="pun">红色文字</span></span>

2. 显色的原理
外层 style 设置为红色, 里层 class 根据 prettify 的 CSS 设置颜色

3. 解决方案
设置 CSS, 当 prettify 的 class 的父元素 是手动设置颜色的, 那么 prettify 的 class 颜色无效

复制
pre.prettyprinted :is(span[style*="color"], span[style*="background"], font[color], [bgcolor])
  :is(.pln,.kwd,.str,.com,.typ,.lit,.pun,.opn,.clo,.tag,.atn,.atv,.dec,.var,.fun) {
  color: inherit !important;
}

相应的, 给 pre 加 class="prettyprint" 的脚本也大大简化

复制
<!-- 为所有 pre 添加 class='prettyprint'; 手动颜色由 b:skin 中 CSS 保护 -->
<script type='text/javascript'>
//<![CDATA[
(function(){
  function run(){
    document.querySelectorAll('pre').forEach(function(el){el.classList.add('prettyprint')});
    if(window.PR&&typeof PR.prettyPrint==='function')PR.prettyPrint();
  }
  if(document.readyState==='loading')document.addEventListener('DOMContentLoaded',run);else run();
  /* 兜底: run_prettify.js 异步就绪后一定能高亮 */
  window.addEventListener('load',function(){if(window.PR&&typeof PR.prettyPrint==='function')PR.prettyPrint();});
})();
//]]>
</script>

总体效果
image|479x500

发表一个评论

R保持