免費論壇 繁體 | 簡體
Sclub交友聊天~加入聊天室當版主
分享
返回列表 发帖

记录一回写油猴

其实之前也写过一次,不过那时有 tan9p 帮忙,这次是自己鼓捣。

话说最近在知乎撸了些题,今晚有空本来打算把我的回答存个档,却发现直接复制内容粘贴出来是这样的:
令 [公式] ,则 [公式] 且

[公式]

可见 ...
难道要进入编辑界面逐个公式点开来复制代码?那也太麻烦了……

查看网页源码,发现其实代码是在的:
QQ截图20210305010436.png
2021-3-5 02:57

于是想到一个办法:把这整块 html 代码复制到 winedt 上,用正则表达式把 <img ... data-formula="代码"> 替换为代码,再把多余的 <p> </p> &amp; 之类的替换好就基本上可以了,不过这种操作还是稍微有点麻烦。

然后去问 86鱼,他说的两种方法据说效率也不高,其实我也没去试,因为他提到了油猴,我就想到:把替换操作交给油猴不就得了?而且还更简单,把代码放进 alt 里,复制的就是代码,整块复制也不会有多余的东西,正是我最初以为会有的效果!

然而实现的过程并没那么顺利,按这想法写好的脚本死活没效果,各种怀疑写错语法(毕竟我没有系统地学过),改来改去改到我就对 <p> 里的逗号换成顿号都不行,几乎想放弃时忽然某次刷新好像看到逗号变了一下,再刷新看清楚,真的有变过顿号,只是很快又变回逗号,于是终于发现原来是脚本运行得太早,知乎的页面大概不像一般网页那样一下加载完,当然具体是怎样我也不懂,反正马上查延时的方法,用了个 setTimeout 设成 10 秒后运行,果然好了。
分享到: QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
$\href{https://kuingggg.github.io/}{\text{About Me}}$

目前脚本:
// ==UserScript==
// @name         zihu_ltx_cpy
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  zihu_ltx_cpy
// @author       kk
// @match        https://www.zhihu.com/question/*
// @grant        none
// ==/UserScript==

(function() {
    'use strict';
  window.setTimeout(function(){
    var j;
    var temp;
    var classDom = document.getElementsByClassName('RichContent-inner');
    for (j = 0; j < classDom.length; j++)
    {
        temp = classDom[j].innerHTML;
        temp = temp.replace(/alt="\[公式\]" eeimg="1" data-formula="([^"]+)"/g,'eeimg="1" alt="`$1`"');
        classDom[j].innerHTML = temp;
    }
  },7000);
})();
在 zhihu.com/question 页面有效,7 秒后运行应该够了,运行时会看到公式闪一下,就可以直接整块复制了,代码两边是我在这里喜欢用的 ` (左引号,KaTeX 渲染)
$\href{https://kuingggg.github.io/}{\text{About Me}}$

TOP

测试一下,把这帖 https://www.zhihu.com/question/446548234/answer/1753611863 的回答整块复制过来:
kuing
谢邀@sea
7 人赞同了该回答
令 `\sqrt {y+z}=a,\sqrt {z+x}=b,\sqrt {x+y}=c` ,则 `a^2+b^2+c^2=2` 且

`T=\sum \frac {b^2-c^2}a=\frac {(a-b)(a-c)(b-c)(a+b+c)}{abc},`

可见只需考虑 `a>b>c` 的情况,另外注意 `c^2\geqslant a^2-b^2` ,然后齐次化去条件,问题变成:

已知 `a>b>c\geqslant\sqrt{a^2-b^2}` ,求下式的最大值:

`F=\frac {\sqrt 2(a-b)(a-c)(b-c)(a+b+c)}{abc\sqrt {a^2+b^2+c^2}}.`

固定 a, b, c 之间的距离,则 `\frac 1{ab\sqrt {a^2+b^2+c^2}}` 关于 c 递减,`\frac {a+b+c}c=\frac {a-c+b-c}c+3` 也关于 c 递减,故 F 关于 c 递减,所以 F 取最大值时必然有 `c=\sqrt{a^2-b^2}` ,这就意味着换元之前的 T 只需考虑 x=0 的情况即可,此时

`T=2z-1-\sqrt{z}+\sqrt{1-z},`

求导可以算出其最大值为 `\frac 14\sqrt {\frac {71-17\sqrt {17}}2}\approx 0.168` 。

编辑于 02-27
​ 修改
​赞同 7
​2 条评论
​分享
​收藏

​设置

TOP

当然有些地方还是需要处理一下的,因为那边不分行内公式与行间公式,放到这里之后,
  1. 需要行间的得自己把 ` 改成 \[ ,像楼上的那个 T= 和 F= 就应该改改,多行公式如 align 环境前后的 ` 也要去掉……
复制代码

TOP

方案二:不弄延时,而是做一个按钮,点击才做替换操作。
最新见 44#,这里就不改了,留个印。
网上搜索到创建悬浮按钮的方法 https://blog.csdn.net/qq_41298974/article/details/108434838,学习完引入这里,变成:
// ==UserScript==
// @name         zihu_ltx_cpy
// @namespace    http://tampermonkey.net/
// @version      0.4
// @description  for zihu ltx cpy
// @author       kk
// @match        https://www.zhihu.com/*
// @grant        none
// ==/UserScript==

(function() {
    'use strict';
    //按钮部分来自https://blog.csdn.net/qq_41298974/article/details/108434838
    var mybutton,beasetag;
    mybutton = document.createElement("div");
    beasetag = document.querySelector("body");
    beasetag.appendChild(mybutton);
    mybutton.innerHTML = "$代码$";
    mybutton.style = "position:fixed;bottom:30px;left:30px;width:100px;height:100px;background:black;opacity:0.5;color:white;text-align:center;line-height:100px;cursor:pointer;";
    mybutton.onclick = function(){
      let classDom = document.getElementsByClassName('RichContent-inner');
      for (let item of classDom)
      {
        item.innerHTML = item.innerHTML.replace(/ loading="lazy"/g,'').replace(/alt="\[公式\]" eeimg="1" data-formula="([^"]+)"/g,'eeimg="1" alt="$$$1$"');
      };
      let classDom2 = document.getElementsByClassName('QuestionRichText QuestionRichText--expandable');
      for (let item of classDom2)
      {
        item.innerHTML = item.innerHTML.replace(/ loading="lazy"/g,'').replace(/alt="\[公式\]" eeimg="1" data-formula="([^"]+)"/g,'eeimg="1" alt="$$$1$"');
      };
    };
})();
这样的话,就可以等网页加载完再点按钮,不用担心长帖子 7 秒够不够的问题。
对于自己的回答列表,也可以全部展开内容再点按钮,就可以一次过复制一堆,这是之前做不到的,所以这次网址就不限于 question 了。
2

评分人数

    • isee: 坛主维护ing威望 + 1
    • hbghlyj: 感谢分享威望 + 1
$\href{https://kuingggg.github.io/}{\text{About Me}}$

TOP

本帖最后由 abababa 于 2021-3-14 14:37 编辑

回复 5# kuing

这个是不是等几秒,好像是有其它方法能用。因为这个katex没有右键菜单,就一直不能复制,然后去年maven网友给我做了一个,就可以复制了,是得安装一个插件,不过我的是opera浏览器,就安装的Tampermonkey这个,可能是通用的吧,在火狐里也能用?我看他是引用了jquery这个,我把jquery也升级了几次,现在是3.6.0版本的,还有他那个默认是居中的,就是text-align:left;这个他没有,我给加上了,变成居左的,其它的我没改。
忘了说了,使用时是先按住ctrl键,然后左键点那个katex的显示部分,就有弹出来的源代码内容了。
  1. // ==UserScript==
  2. // @name         katex_cp
  3. // @namespace    http://tampermonkey.net/
  4. // @version      0.1
  5. // @author       You
  6. // @match        http://kuing.orzweb.net/*
  7. // @require      https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js
  8. // ==/UserScript==


  9. (function() {
  10.     'use strict';
  11.     $(document).ready(function(){
  12.         $('.katex').each(function(index,element){
  13.             var visual = $(element).find(".katex-html")[0];
  14.             var code = $(element).find("annotation")[0].innerHTML;
  15.             $(visual).mouseup(function(event){
  16.                 if(event.ctrlKey && event.which == 1){
  17.                     var x = event.clientX;
  18.                     var y = event.clientY;
  19.                     var close_btn = document.createElement('button');
  20.                     close_btn.innerHTML='close';
  21.                     var cp2clp = document.createElement('div');
  22.                     var title = document.createElement('p');
  23.                     var code_body = document.createElement('div');
  24.                     var body = document.body;
  25.                     close_btn.onclick = function(){
  26.                         body.removeChild(cp2clp);
  27.                     };
  28.                     title.appendChild(close_btn);
  29.                     cp2clp.appendChild(title);
  30.                     code_body.innerHTML = code;
  31.                     cp2clp.appendChild(code_body);
  32.                     cp2clp.style = 'text-align:left; border: 1px solid black; position:fixed;background-color:white;width:300px; height:200px;top:'+y+'px;left:'+x+'px;';
  33.                     body.appendChild(cp2clp);
  34.                 }
  35.             });
  36.         });
  37.     });
  38. })();
复制代码

TOP

回复 6# abababa

又问了网友,原来是能直接把所有东西都复制回来,不用自己拖鼠标,是用到一个叫“clipboard”的工具。然后又帮我写了一个知乎的复制,感觉还行,就是有图的时候复制不了,不过图本来也不能用鼠标右键的那个复制吧。
然后打开网页以后,只要一点那个按钮,就复制到剪贴板了,到记事本里一粘贴就都出来了。
  1. // ==UserScript==
  2. // @name         zhihu_cp
  3. // @namespace    http://tampermonkey.net/
  4. // @version      0.1
  5. // @author       You
  6. // @match        https://www.zhihu.com/*
  7. // @require      https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.0/jquery.min.js
  8. // @require      https://cdn.jsdelivr.net/npm/clipboard@2.0.8/dist/clipboard.min.js
  9. // @grant        none
  10. // ==/UserScript==

  11. (function() {
  12.     'use strict';
  13.     $(document).ready(function(){
  14.         var cp_btn = $('<button>');
  15.         cp_btn.attr('class','copy');
  16.         cp_btn.text("cp_ans");
  17.         cp_btn.attr('style',"position:fixed;top:50px;left:50px;width:50px;height:30px;background-color:gray;");
  18.         var cp_texts = '';
  19.         cp_btn.click(function(){
  20.             var articles = $('.RichContent-inner');
  21.             articles.each(function(index, article) {
  22.                 var cp_text = article.innerHTML.replace(/<img.*?(data-formula="(.*?)")?>/ig, '\$$2\$')
  23.                 .replace(/<sup (data-text="(.*?)")?.*?>.*?<\/sup>/,'【$2】')
  24.                 .replace(/<(span|ol|li|h2|b|div|p).*?>|<\/(span|ol|li|h2|b|div)>/ig,'')
  25.                 .replace(/<figure.*?>.*?<\/figure>/ig,'[图占位符]')
  26.                 .replace('$','')
  27.                 .replace(/<svg.*?>.*?<\/svg>/ig,'')
  28.                 .replace(/<noscript>.*?<\/noscript>/ig,'')
  29.                 .replace(/<a.*?href="(.*?)".*?>(.*?)<\/a>/ig,'\\href{$1}{$2}')
  30.                 .replace(/&amp;/g,'&')
  31.                 .replace(/&lt;/g,'<')
  32.                 .replace(/&gt;/g,'>')
  33.                 .replace(/<\/p>|<br>/ig, '\n');
  34.                 cp_texts += '\n\n'+cp_text;
  35.             });
  36.             $(cp_btn).attr('data-clipboard-text',cp_texts);
  37.             var clipboard = new ClipboardJS('.copy');
  38.         });
  39.         $('body').append(cp_btn);
  40.     });
  41. })();
复制代码
1

评分人数

    • hbghlyj: 测试可用.真好!谢谢威望 + 1

TOP

太复杂,看不懂了暂时还是用我5#自己写就够用的

TOP

回复 7# abababa
我怎么觉得不太一样呢,仔细检查之后发现是少了一些$符号,是不是有什么转义之类的东西然后就发不上来呀。
我发一个附件在这里: zhihu_cp.txt (1.78 KB)

TOP

回复 9# hbghlyj

我也不怎么懂,这都是请网友做的,我大致能看明白一些功能,比如那个replace就是把字符替换出来的意思吧,但细节我可不明白了。

TOP

TOP

回复 12# kuing

原来如此。发完了又看了一下就觉得不一样,他那个里有一处是好几个$,这里的就没有了,一检查还确实少了。

TOP

回复 13# abababa

就是这行:
var cp_text = article.innerHTML.replace(/<img.*?(data-formula="(.*?)")?>/ig, '\$$$2\$$')
$\href{https://kuingggg.github.io/}{\text{About Me}}$

TOP

回复 14# kuing

对,就这个,大致能猜出来是替换图片(显示成代码的那种图,不是插入的图片)的,然后后面是把代码放到$之间吧,但细节可就弄不明白了。

TOP

这个插件好像不适用于知乎专栏的公式的复制

TOP

回复 16# hbghlyj

是指我的还是他的?
如果是我那个那就是正常的,因为我弄这个只是为了复制自己的回答,没考虑专栏

TOP

请问,如何导出微信公众号的数学公式呢

TOP

回复 18# hbghlyj

应该得看他是用什么来编辑的吧……你得举几个栗子。

TOP

本帖最后由 hbghlyj 于 2021-4-25 23:36 编辑

比如这一系列的文章
如何导出微信公众号的数学公式呢
我一般是用正则表达式替换
Find What:
  1. \<span style*formula="(*)"*\<\/span\>\<\/span\>
复制代码
Replace with:
  1. $\1$
复制代码
有没有更快捷的方法呢?

TOP

布理雷恩特(才华横溢)网的LaTeX代码可以拷贝吗?
https://brilliant.org/discussion ... st-season-3-part-2/

TOP

返回列表 回复 发帖