这篇文章严格意义上是写给有公众号且公众号文章需要贴代码的朋友们看的。

1 公众号编辑器真难用

自从入坑公众号以来,被公众号的这个编辑器简直折磨死了。我发的文章基本上是少不了贴代码的,可是每次贴上去的代码总是被公众号的编辑器无厘头的给我过滤掉换行符,简直气死人。

例如我编辑得好好的代码,

 Person person = new Person("benny", 27); System.out.println(person.getName() + " is " + person.age); //benny is 27 person.setName("andy"); person.age = 26; System.out.println(person.getName() + " is " + person.age); //andy is 26 

贴上去就成了这样:

 Person person = new Person("benny", 27);System.out.println(person.getName() + " is " + person.age); //benny is 27person.setName("andy");person.age = 26;System.out.println(person.getName() + " is " + person.age); //andy is 26 

每次一段代码一段代码的敲回车,简直敲到手抽筋。醉了。

这还不算,这个格式的代码发到手机上,还不能水平滚动,各种任性的折行,让本来清秀的代码看起来真是一坨一坨的。

2 分析下原因

查了一下,不少同行都在因为这个而感到苦恼,大家分析得出的结论是微信公众号的编辑器会对我们贴上去的内容进行处理,而处理的过程中又会对一些换行符进行过滤,导致本来排好的代码乱成一团。

3 几种常见的贴代码的方法

3.1 贴图法

对于这种情况,最直接的方法自然是用工具渲染好,然后截图贴到公众号的编辑器里面。也可以写一个工具把代码自动绘成图片。

  • 优点:简单直接,在找到更好的办法之前,我之前的几篇文章都是这么处理的。

  • 缺点:操作繁琐,除了生成图片或者截图,还要手动贴到公众号编辑器中,截图时对于代码的文字清晰度控制也不太容易,贴到编辑器之后,还会被压缩,导致代码不容易被看清楚。当然,另一个更大的硬伤就是读者阅读的时候会耗费比较多的流量,如果网速不好还会加载不出来。

3.2 Markdown Here

很多朋友都提到 Markdown Here,这是一个非常棒的 Chrome 插件,大家可以搜索并添加它,安装之后可以在 Options 当中选择自己喜欢的主题,之后只要在选中编辑框,贴入 Markdown 源码,再点击插件的按钮即可。

不过。。这个插件同样不能幸免于换行符的过滤,如果我们在微信公众号编辑器当中贴入 md 源码,按照上述操作渲染出漂亮的格式,保存之后预览,你就会发现这个办法其实并不怎么好用,或者说基本上不能用。

  • 优点:这插件真的很棒。

  • 缺点:因为渲染后的格式还是会惨遭微信公众号的编辑器的毒手,也就是说,你得自己手动处理一下换行的问题。

3.3 渲染好的格式直接贴

我们前面说,可以先把 md 源码渲染好,然后直接复制粘贴到公众号的编辑器当中,结果其实与 Markdown Here 的效果完全一样。说到底是换行符被过滤的问题。

我一直用的 md 工具是 MacDown,可以直接先用它编辑好文章,然后复制渲染结果贴到微信公众号当中,自行处理一下换行的问题即可。

  • 优点:本地编辑,方便快捷。

  • 缺点:一样,还是换行符的问题。

3.4 其他什么编辑器

当你在搜索引擎里面搜索这个问题的时候,大多数回答可能是推荐你用一些第三方的编辑器,比如 什么 135 编辑器之类的,这些编辑器对于不写代码的朋友来说,真的挺好用的,里面提供了各式各样的模板,大家只要把文字准备好,一套用就立马狂拽酷炫吊炸天。

可是,它们并不是为我们这些码农准备的啊,你想想公众号绝大多数的运营者都是编辑,而不是程序员,他们根本不需要关心什么是代码,更不需要关心怎么把代码排版好(我相信微信公众号编辑器的开发小伙伴大概也是这么想的吧,这么久了这编辑器还是这鬼样子)。

第三方编辑器很多,不过,当你一个一个去试的时候,你会发现这条路根本不通!!

  • 优点:适合编辑各种花哨的文字和图片。

  • 缺点:不支持代码的格式。

4 目前最优雅的方案诞生记

说实在的这个方案没有很高端。我们的痛点其实就是想个办法不让微信公众号编辑器对贴到里面的代码进行换行符的过滤。

有朋友提出把渲染后的结果每行都用 
替换 \n,这样过滤时,换行自然就不会被干掉了。

 <code class="hljs language-java" style="...">Person person = <span class="hljs-keyword" style="color: rgb(170, 13, 145);">new</span> Person(<span class="hljs-string" style="color: rgb(196, 26, 22);">"benny"</span>, <span class="hljs-number" style="color: rgb(28, 0, 207);">27</span>); System.out.println(person.getName() + <span class="hljs-string" style="color: rgb(196, 26, 22);">" is "</span> + person.age); <span class="hljs-comment" style="color: rgb(0, 106, 0);">//benny is 27</span> person.setName(<span class="hljs-string" style="color: rgb(196, 26, 22);">"andy"</span>); person.age = <span class="hljs-number" style="color: rgb(28, 0, 207);">26</span>; System.out.println(person.getName() + <span class="hljs-string" style="color: rgb(196, 26, 22);">" is "</span> + person.age); <span class="hljs-comment" style="color: rgb(0, 106, 0);">//andy is 26</span> </code> 

这就是 md 渲染后的结果,代码对应于文章开头的例子。我们发现所有的代码被放到 code 这个标签当中,如果我们在其中用 
替换 \n 会发生什么呢?

 Person person = new Person("benny", 27); System.out.println(person.getName() + " is " + person.age); //benny is 27 person.setName("andy");<br>person.age = 26; System.out.println(person.getName() + " is " + person.age); //andy is 26 

<br> 被直接显示出来了。根本不能用来换行。所以直接从结果入手好像没那么简单。那怎么办,我们干脆修改渲染方式吗?针对每行,用 <p /> 标签包起来不就可以换行了吗?

想法挺好啊。想到这里我就开始准备去修改 Markdown Here 的源码了。。。可,尼玛,我不是搞前端的,一片一片的 js 代码我该修改哪里呢?这下可尴尬了。

此路通,可能成本还是有点儿高了。于是我又回到原点,思考如何欺骗微信公众号编辑器那个换行符不能被过滤的问题。怎么骗呢?关键是,公众号的编辑器通过识别怎样的 pattern 来过滤换行符呢?如果我找到这个 pattern,然后把它破坏掉,不就可以了么?

经过一番尝试发现:

  • 每一行代码的前后各加一个空格,那么正常有内容的行末换行符就不会被过滤

  • 空行替换成“英文空格+中文空格+英文空格”,这样在微信公众号编辑器看起来似乎不是空行,不过在我们看来其实是空行

于是我动手写了一个简单的 python 脚本,那么后续我只要用 MacDown 编辑好我的文章,再用下面这个脚本自动为所有的代码加上空格、替换空行,那么我再把渲染好的文章贴到公众号的话,大功就告成了。

附上非常简单的脚本代码:

 #!/usr/local/bin/python # encoding=utf-8 # 微信公众号编辑器对代码支持的不好, 我们在贴代码之前需要在代码前后各加一个空格 # 并对空行做一下处理,主要随便搞几个空格和制表符 # 这样做可以防止公众号的编辑器过滤空行和换行符 import sys, re # 匹配 md 的代码起始块, 我习惯用 ```java 这样的形式, 也可以根据需求进行修改 CODE_PATTERN_START = r"^\s*```\s*\w*$" # 匹配代码块结束, ``` CODE_PATTERN_END = r"^\s*```\s*$" if len(sys.argv) < 2: print "参数不正确." exit() inputFile = open(sys.argv[1]) output = [] while True: line = inputFile.readline() if line: if re.match(CODE_PATTERN_START, line): output.append(line) while True: line = inputFile.readline() if re.match(CODE_PATTERN_END, line): output.append(line) break if line.strip(): # 代码行前后各加一个空格 line = " " + line line = line.replace("\n", " \n") print line else: print "空行" # 替换空行,下面的空格中有一个是中文空格 line = "   \n" output.append(line) else: output.append(line) else: break inputFile.close() outputFile = open(sys.argv[1], 'w+') outputFile.writelines(output) outputFile.close() 

5 小结

这种方法应该算不上一个最终的方案(最终方案应该是公众号编辑器的开发该考虑的事儿),但它成本比较低,输出效果也比较不错,希望能给大家带来帮助。

Kotlin, More Than a Better Java.

Kotlin

长按识别二维码,关注Kotlin

如何优雅的在微信公众号中编辑代码相关推荐

  1. php怎么添加会员卡,怎么在微信公众号中添加一个会员卡领取功能

    怎么在微信公众号中添加一个会员卡领取功能 发布时间:2020-12-09 16:06:27 来源:亿速云 阅读:129 作者:Leah 这篇文章将为大家详细讲解有关怎么在微信公众号中添加一个会员卡领取 ...

  2. php 微信开发 菜单,微信公众号中个性化菜单的开发实例

    微信公众号中个性化菜单的开发实例 个性化菜单让公众号的不同用户群体看到不一样的自定义菜单.该接口开放给已认证订阅号和已认证服务号,个性化菜单要求用户的微信客户端版本在iPhone6.2.2,Andro ...

  3. 基于WeX5平台开发微信公众号中的在线问卷调查

    在线调查问卷在我们的生活中应用的非常广泛,能够非常方便快捷的获取到我们需要的信息,统计分析出相关核心的数据,方便我们的决策.在微信发展迅速的时代,覆盖面非常的大,那么基于微信公众号去推送我们的在线问卷 ...

  4. 微信公众号中,怎么插入代码块?(微信公众号中,代码块怎么排版?)

    微信公众号代码编辑工具 步骤1.如上图所示,我们要点击复制; 步骤2.直接ctrl+v粘贴到微信公众号的编辑框中,如下图所示: 微信公众号排版工具(135编辑器) 135编辑器是一款很好的微信公众号编 ...

  5. python微信公众号翻译功能怎么用_Watson使用指南(七)在微信公众号中实现识图作诗功能...

    本文章主要是写一下这个项目开发的过程及之间遇到的问题,作为记录,也希望以此为契机认识志同道合的朋友,一起学习交流. 目录: 概述 环境准备及相关账号申请 部署Python Flask应用到Bluemi ...

  6. 微信公众号服务器端脑图,微信公众号中隐藏的思维导图工具,帮你随时随地高效思考...

    「有什么好用的思维导图工具推荐呢?」后台里收到了很多小伙伴类似的问题. 事实上,市面上的思维导图工具真的非常多.无论是老牌的 XMIND,还是在线版的 百度脑图或者 ProcessOn 都可以帮你制作 ...

  7. Vue 开发在微信公众号中如何文件下载

    通常我们调用下载接口时,我们需要根据后端提供的接口返回信息进行相应的处理操作. 1.接口返回 文件路径(部分). window.open('http://192.168.22.246:8080'+ f ...

  8. 微信公众号中的支付宝支付与微信支付 支付宝支付问题(微信bug)

    一般,在微信公众号中的商城都是需要支持微信支付和支付宝支付的,当然,较大的公司对于鹅厂和阿里的站队就不说了,所以这里简单记录一下支付宝支付和微信支付的主要流程.说是简单介绍,这是因为确实不难,因为前端 ...

  9. 如何把微信公众号中的图文复制出来

    如何把微信公众号中的图文复制出来 前言: 平时看到好的公众号文章的时候,想把它复制下来,保存在本地,或者进行编辑.转载等,转载可通过公众号留言,找公众号所有者进行审核,但该过程繁杂.如果直接ctrl+ ...

最新文章

  1. 李昱:百度产品登录协议介绍
  2. RIP 数据包类型 路由中毒
  3. 交叉熵代价函数——当我们用sigmoid函数作为神经元的激活函数时,最好使用交叉熵代价函数来替代方差代价函数,以避免训练过程太慢...
  4. mybatis一对多关联查询_一对一,一对多,多对多查询及延迟加载(N+1问题)分析
  5. boost::mp11::mp_map_keys相关用法的测试程序
  6. linux系统shell知识点,Linux 系统中shell知识点说明和常用的帮助命令简单介绍 | IT工程师的生活足迹...
  7. OpenSUSE下支持托盘的邮件客户端Sylpheed
  8. easyui datagrid reload后自动全选解决
  9. Activity详解(生命周期、以各种方式启动Activity、状态保存,完全退出等)
  10. 2020年上海将初步建成“泛在化、融合化、智敏化”智慧城市
  11. 如何把iphone 6s通讯录导入到诺基亚E72i内
  12. 网络营销的优势和劣势
  13. mac苹果安装百度网盘--日常工作记录
  14. 微信运动步数一键98800,最新方法来袭!11.01号更新
  15. java什么算垃圾代码,[把代码写成诗]Java美好的承诺,自动回收垃圾
  16. 图片动漫化 - 面部 - AnimeGAN
  17. Java保留两位小数的方法
  18. Python爬虫-Beautiful Soup-当当图书目录(1)
  19. Non-resolvable parent POM for com.example:demo:0.0.1-SNAPSHOT: Could not transfer artifact org.sprin
  20. SpringBoot整合支付宝付款(沙箱环境)

热门文章

  1. 重新审视PancakeSwap:Sushi之后又一个摘掉copycat帽子的成功者
  2. 转 | 禁忌搜索算法(Tabu Search)求解带时间窗的车辆路径规划问题详解(附Java代码)
  3. 基于Java的连连看游戏设计与实现
  4. Taro多端开发webview如何区分端,引入SDK,调用相应接口?
  5. 蚂蚁金服组件 ReferenceError: primordials is not defined
  6. 将Word文档转换为eReader或iBooks的ePub格式
  7. XP的楼梯(跳楼梯)
  8. python中pandas检索某一个具体值(具体到一个元素)
  9. 7300 LE显卡只能使用VGA模式
  10. 推动O2O快速发展的因素是什么 O2O模式的消费者有哪些类型?