下面是我根据我的部分需求和想法想让该插件实现的功能。只可惜我对这些没有经验,但会试着学习来实现这些功能,更希望能有感兴趣的道友一起实现这些功能。
类似该插件支持的 markdown 导出之后仍然支持调用 MathJax 的功能。插件介绍说本身已经支持本地 MathJax 解析功能,但是我按照介绍的方法生成的 html 没有被渲染。可以选择调用本地的 MathJax 还是远程的 MathJax。
修改了代码使 html 中支持脚本后,发现 MathJax 还是不能显示。提示: File failed to load: /extensions/TeX/noUndefined.js
和 File failed to load: file:////D:/Mydocuments/My%20Knowledge/temp/eeb22476-2d48-4faf-a78a-26aa088a2566/36/index_files/extensions/TeX/noUndefined.js
,路径是我的安装目录的 temp 文件夹,说明有些时候加载远程下载到本地 temp 的 MathJax,但是网速问题下载是不会成功的,导致 MathJax 加载失败。有些时候直接加载本地的 MathJax,但是就是找不到文件位置,我已经放好了文件了,不知道为什么找不到,或者没权限执行。
为知会自动把 html 中的 mathjax online 路径中的 MathJax 下载,然后自动把 html 文件中的 MathJax 路径设置为本地一个 index_files/MathJax 的文件夹,导致加载失败。还发现直接使用完整 Emacs 导出和使用 emacs -q 命令行调用导出和为知中文档的 html 版本这三者都不相同。前两者不同的原因是我设置了变量 org-html-mathjax-options
和 org-html-mathjax-template
。‘
因此,应该是为知本身对于 MathJax 路径的处理,或者是 nFlags 的取值造成的后果(需要测试)。
修改好了 emacs -q 命令导致的 MathJax 路径未设置问题,cmd 和 shell 中的字符转义问题搞的好头大,作为 newbee 真心顶不住。但是我没有对 %
转义就已经正常了,这里记录一下,以后出问题好有个参考。(20160715)
终于把导出 html 时设置 MathJax 的本地路径的部分能做的事情做完了,现在可以设置三种方式:第一种是不使用 MathJax,这种情况为知会自动调用 MathJax 来做渲染,不在 html 中显示,但是这种渲染速度非常慢,感觉应该是为知从自己服务器拖下来的;第二种是使用远程 CDN 的 MathJax,但是导入为知之后会被强行替换为本地的 index_files/MathJax.js
的路径,但是又会提示该路径下不存在有几个 js 文件,导致无法渲染;第三种是使用本地的 MathJax,需要把 MathJax 的包下载到本地,同样导入为知之后会被强行替换为本地的 index_files/MathJax.js
的路径,同样也会导致无法渲染。只能跟为知的技术人员进一步沟通再说了,我能做的已经做完了,还需要做一点收尾工作(用个选项设置选择哪种 MathJax 渲染方式,具体逻辑还需要根据为知的回复再作考虑)。(20160716)
在工具菜单下用选项来设置 Org2Wiz 默认需要添加的标签,设置 Org2Wiz 使用 MathJax 的哪一种渲染方式。(20160717)
- 添加各种选项设置
- 读取写入 ini 文件
//从ini文件读取一个字符串。bstrFileName:ini文件名;bstrSection:ini里面的section;bstrKey:key;返回值:读取到的值
[id(21), helpstring(“method GetValueFromIni”)] HRESULT GetValueFromIni([in] BSTR bstrFileName, [in] BSTR bstrSection, [in] BSTR bstrKey, [out,retval] BSTR* pbstrValue);
//向ini文件写入一个字符串。bstrFileName:ini文件名;bstrSection:ini里面的section;bstrKey:key;bstrValue:写入的值 [id(22), helpstring(“method SetValueToIni”)] HRESULT SetValueToIni([in] BSTR bstrFileName, [in] BSTR bstrSection, [in] BSTR bstrKey, [in] BSTR bstrValue);
- 给文档添加一个标签(这个标签可能已经存在,也可能不存在)
- 现在实现的添加完标签之后,还需要切换一下文档才可以看到添加好的标签,后续想办法解决。
- 暂时只能添加一个默认标签,以后会考虑设置多个(只需要在 ini 文件中用分号分开即可)
- IWizTagCollection | 为知笔记 Windows 插件开发文档 里面的枚举接口我不会用
- JavaScript Array forEach() Method
- IWizDatabase | 为知笔记 Windows 插件开发文档
- IWizTag | 为知笔记 Windows 插件开发文档
- IWizTagCollection | 为知笔记 Windows 插件开发文档
- IWizDocument | 为知笔记 Windows 插件开发文档
- 读取写入 ini 文件
//从ini文件读取一个字符串。bstrFileName:ini文件名;bstrSection:ini里面的section;bstrKey:key;返回值:读取到的值
[id(21), helpstring(“method GetValueFromIni”)] HRESULT GetValueFromIni([in] BSTR bstrFileName, [in] BSTR bstrSection, [in] BSTR bstrKey, [out,retval] BSTR* pbstrValue);
- 参考
- Yet Another Org-Mode Configuration MathJax CDN 章节
- Math formatting in HTML export - The Org Manual
- GNU Emacs Lisp Reference Manual: Shell Arguments
- GNU Emacs Lisp Reference Manual: Syntax for Strings
- GNU Emacs Manual: Action Arguments
- GNU Emacs Manual: Initial Options
- bat、cmd 批处理中(或 DOS 环境)的特殊字符 - jinsen - 博客园
- html 语言注释-CSDN 论坛
- html 和 CSS 注释-CSDN 论坛
- XML CDATA
- JavaScript Number toString() Method
- MessageBox function (Windows)
- appendChild method (Internet Explorer)
- IHTMLDocument2 interface (Windows)
- scripts Property (IHTMLDocument2)
- item method (Preliminary)
- script element | script object (Internet Explorer)
- text property (Internet Explorer)
- 待参考
附件中有时候不会只放置所需的 org 文件,有时候会加入一些其他附件,这个时候附件的自动排序会导致插件的导入 org 功能失效。此时必须手动修改 org 文件名,很不方便,也不智能。
我的想法是:如果附件中只有一个 org 文件,就让该插件自动识别已添加的附件,并找出所需的 org 文件,然后进行 Org2Wiz 操作;如果有多个 org 文件会让使用者选择需要导出的 org 文件,否则就导出默认的那个文件(该功能还需要进行更周全的考虑)。
现在已经实现的是找到附件中的一个 org 文件,然后导出。后续再想办法实现遇到多个 org 文件弹出窗口提示选择一个。(20160713)
- State “CANCELLED” from “TODO” [2016-07-15 Fri 16:18]
为知不提供相关 API
为知支持 pdf 导入,但是好像知道只可以导入到新笔记中 ,需要更仔细的调研 。经过咨询为知官方人员,回复说暂不提供导入文件的 API,这一个功能暂时没办法实现了。参考:为知笔记导入 pdf 文件的 API 是什么呢_为知笔记吧_百度贴吧 二楼官方回复。
- State “DONE” from “TODO” [2016-07-17 Sun 17:49]
现在有个问题: Emacs 中 org 文件在中文文件夹直接导出 pdf 会出问题,但是 org 导出 tex 和 tex 导出 pdf 在中文文件夹都没有问题,正在想办法解决。
还需要找到为知直接在当前笔记导入 pdf 文件(覆盖原笔记)的 API。
- 参考
- JavaScript Number 对象
- How do I convert a string into an integer in JavaScript? - Stack Overflow
- javascript对象类型判断 - big军 的个人空间 - 开源中国社区
- javascript - 如何正确判断 js 数据类型 - SegmentFault
- undefined 与 null 的区别 - 阮一峰的网络日志
- js 中去掉文件的后缀名正则表达式 - js 教程 - 网页制作 - 壹聚教程网
- Javascript 函数返回多个值的方法介绍_javascript 入门教程 - 脚本学堂
- 在 JS 方法中返回多个值的三种方法 - oec2003 - 博客园
- 现在还不知道怎么判断某个本地文件是否存在
- State “DONE” from “TODO” [2016-07-17 Sun 02:58]
- State “DONE” from “TODO” [2016-09-18 Sun 19:03]
- 设置好默认的文件编码格式(默认 UTF-8)或者自己提前准备好一个文件,到需要的时候复制过去然后改名。打算采用后一种方式。
- UTF-8
- UTF-8-DOS
- GBK
- 判断后缀
- 判断是否有 org 附件
- 如何新建文件(如果无法新建,说明文件名不合适,或者权限问题)
- 新建文件之后把该文件添加到 Document 的附件中(按照设置好的编码格式)
- 怎么样只用批处理命令就实现 ANSI-UTF8 的互换 | 人生の宝物を探しにいこう 这篇文章最有参考价值,关于编码转换
- 在 CMD 创建文件 - bits00 - ITeye 技术网站 建立空文件的方法
- 如何在 CMD 下更改文本文件的编码格式 - CSDN 论坛 - CSDN.NET - 中国最大的 IT 技术社区
- Unicode 字符与 GB2312 的相互转换 - 软件开发程序员博客文章收藏网
- 如何在 cmd 下建立文件夹、删除文件、重命名文件?_百度知道
- cmd ren命令 重命名文件(夹)_DOS/BAT_脚本之家
推荐一个 org 导出 html 的好 css:thomasf/solarized-css
- 可以使用 Chrome 开发工具来调试了。
- 对于全局插件的调试,可以启用 Wiz 的 debug 模式。
- 对于 Type,除了 HtmlDialog 类型外,其他的类型,都必须指定 ScriptFileName,来指定脚本文件(必须是 js 文件)。
- Plugin_x,则代表某一个插件的描述部分,x 从 0 开始,到插件数量 - 1。如果有多个插件功能,每一个插件功能有一个独立的 Plugin_x section,例如 [Plugin_0], [Plugin_1] 等等
- MenuType:插件菜单的类型,这个菜单应该先是在哪一个菜单里面。
- 我们增加了 [Strings] 部分,并且对 html 对话框里面的资源进行了本地化。
- Html 对话框里面,所有的语言,我们都用了英文,这样在没有进行本地化支持的时候,全部显示成英文。 首先,我们给 HelloWorld 外边增加了一个 span,并且给了他一个 id
- 为知笔记提供了一种在程序运行期间,一直可以运行并且响应 Wiz 消息的一种插件。例如在 wiz 运行期间,设定一个定时器,每隔半个小时就可以提醒用户休息眼睛。
- 就像一个网页,里面内置了很多脚本,在网页打开的状态下,这些脚本一直都是可以运行的。
- 而对于直接执行脚本的插件 (ExecuteScript) 或者 html 对话框插件 (HtmlDialog),他们只有在用户点击菜单,调用插件的时候,才会被加载执行,当脚本执行完毕,或者用户关闭对话框的时候,插件将会被清除出内存。
- 给全局插件进行国际化
- 避免全局脚本命名冲突 :为了避免这个问题,我们需要给自己的变量和函数名,加上前缀或者后缀,例如我们给所有的变量增加一个前缀,叫做 HelloWorld,这样就可以有效避免这个问题了。
- 内部对象 IWizExplorerApp:为知笔记主程序运行的时候,对外暴露的一个内部对象,通过 IWizExplorerApp,可以获得为知笔记正在打开的账户数据,主窗口各种控件等等。在三种插件里面,都提供了脚本直接访问这个对象的方法。
- 为知笔记在运行插件脚本之前,也内置了一个对象:WizExplorerApp,类型同样是 IWizExplorerApp。另外, Global 类型插件,在运行的时候,也与定义了 objApp 对象,同样是 IWizExplorerApp。在 全局插件 里面,我们直接使用了 objApp,而没有进行定义,是因为全局插件已经帮我们定义好了。
- 通过 IWizExplorerApp 来获得其他的对象:获得当前打开的账户数据库 (IWizDatabase), 注意:在全局插件中,已经直接定义了 objDatabase 对象,在插件脚本中可以直接使用。 ;获得为知笔记主窗口对象 (IWizExplorerWindow), 注意:在全局插件中,一定直接定义了 objWindow 对象,在插件脚本中可以直接使用。 ;一些常用的功能的对象 (IWizCommonUI),这个对象提供了大量辅助性的功能,例如 ini 文件读写,注册表文件读写,文本文件读写等等, 注意:在全局插件中,一定直接创建了 objCommon 对象,在插件脚本中可以直接使用。 。
- 关于各种对象的描述,请参看接口描述部分。
- 全局插件的初始化:从前面的介绍可以看出,全局插件有一个初始化过程,而这个初始化,实际上就是执行了一段脚本。该脚本保存在为知笔记安装路径下面的 plugins 文件夹,文件名是 global_plugin_share.js。定义了几个对象:objApp, objDatabase, objWindow 以及 objCommon;定义了两个函数,提供了 javascript 里面的 alert, confirm 这两个函数的功能,在全局插件脚本里面可以直接使用 WizAlert 来代替 alert, WizConfirm 来代替 confirm;实现了监听为知笔记一些消息的功能,简单描述了如何在插件脚本中响应这些事件。
- 有关 为知对于事件的响应 可以看这里:全局插件深入 | 为知笔记 Windows 插件开发文档
- MathJax 是一个开源的基于 Ajax 的数学公式显示的解决方案,结合多种先进的 Web 技术,支持主流的浏览器。MathJax 根据页面中定义的 LaTex 数据,生成对应的数学公式。
- 首先,如果一个笔记中包含 LaTeX 或者 MathML 编写的公式,那么在浏览的时候,我们可以动态加入 MathJax 渲染引擎,这样就可以将渲染笔记里面的公式了。
- 我们将会在笔记 HTML 完成的时候,来判断当前笔记是否需要使用 MatjJax 来渲染,如果需要,则动态插入一行脚本,来渲染公式。
- 和帐号相关的配置
- 和帐号无关的配置
- 注册表读写
- ini 文件读写
- 为知笔记 Windows 客户端开放了大量的 API,其中绝大部分,都通过 COM 提供,可以在 javascript, C#, C++, Delphi 等语言中使用。
- 接口通过 IDL(Interface description language) 语言描述。
- IWizDocument 是 WizKMCore.dll 包含的一个 COM 对象。文档对象必须隶属于一个数据库,因此您不能直接创建这个对象,而是需要通过 IWizDatabase 对象来获得数据库中的文档对象。 通过 IWizDatabase.GetAllDocuments,获得 IWizFolder.Documents 等等方法,可以获得数据库的文档信息。
- //获得/设置文档的类型,例如document,note,journal,contact等等 [propget, id(11), helpstring(“property Type”)] HRESULT Type([out, retval] BSTR* pVal); [propput, id(11), helpstring(“property Type”)] HRESULT Type([in] BSTR newVal);
- //更改文档数据,通过一个HTML文件名和对应的URL来更新。 [id(55), helpstring(“method UpdateDocument6”)] HRESULT UpdateDocument6([in] BSTR bstrHtmlFileName, [in] BSTR bstrURL, [in] LONG nFlags);
- nFlags 的取值 //更改文档数据,通过一个html文件来更新文档。 //wizUpdateDocumentSaveSel = 0x0001 保存选中部分,仅仅针对UpdateDocument2有效 //wizUpdateDocumentIncludeScript = 0x0002 包含html里面的脚本 //wizUpdateDocumentShowProgress = 0x0004 显示进度 //wizUpdateDocumentSaveContentOnly = 0x0008 只保存正文 //wizUpdateDocumentSaveTextOnly = 0x0010 只保存文字内容,并且为纯文本 //wizUpdateDocumentDonotDownloadFile = 0x0020 不从网络下载html里面的资源 //wizUpdateDocumentAllowAutoGetContent = 0x0040 如果只保存正文,允许使用自动获得正文方式
- IWizDocumentAttachment 对象,文档的附件。
- 获得附件的GUID
- 获得/设置附件的名称
- 获得/设置附件的描述
- 获得/设置附件的原始URL
- 获得/设置附件的文件大小,单位是字节。
- 获得附件的信息修改日期
- 获得附件的信息md5值
- 获得附件的数据修改日期
- 获得附件的数据md5值
- 获得附件所属的文档
- 获得附件所属的文档GUID
- 获得附件的磁盘文件名
- 获得附件的版本,用于同步,保留
- 删除附件
- 重新从数据库中获得附件信息
- 更新附件的数据md5值。
- 获得/设置附件数据已经是否已经被下载到本地
- 检查附件数据是否被下载,如果没有,则自动下载。
- 获取/设置附件数据,IStream类型
- 获取/设置笔记的服务器版本号,内部使用
- 获取本地一些属性,内部使用
- 设置服务器的一些属性,内部使用
- IWizDocumentAttachmentCollection 是 IWizDocumentAttachment 的集合
- 生成一个新的IEnumXXXX类型的接口,可以在某些语言内使用for_each类型的语法。
- 获得某一个对象。Index:索引值,以0开始;返回值:IWizDocumentAttachment对象
- 获得集合内元素的数量
- 添加一个附件对象,类型为IWizDocumentAttachment
- IWizDocumentAttachmentListCtrl 是 WizKMControls.dll 所包含的一个 ActiveX 控件,利用这个控件,可以显示 Wiz 的文档列表,以便用户选择一个或者多个 Wiz 文档。同时,这个控件还包含了各种用户操作,用户通过右键菜单,可以实现多种操作。
- 您可以在网页里面直接使用这个控件,也可以在其它的高级语言里面使用,例如 C++,VB,C#,Delphi 等等。
- 设置/获取事件监听消息
- 设置/获取主程序APP
- 获得/设置数据库对象,类型为IWizDatabase
- 获得/设置附件列表所属的文档对象,类型为IWizDocument
- 获得/设置用户选中的附件对象,类型为IWizDocumentAttachmentCollection
- 获得/设置是否显示边框,已经无效
- 执行添加附件命令。
- 执行添加附件命令,可以传入一个文件名数组,直接添加某些文件作为附件
- 或者最小高度
MathJax 在 Wiz 中的实现方法可以参考 Wiz.Editor.md 和 Notes.Markdown 等笔记编辑器。主要参考 MathJax 在 html 中需要加什么。
- 之前一直认为为知会对所有文件进行 MathJax 渲染,现在发现是我的代码少注释一句话,导致这种现象出现的。
eventsHtmlDocumentComplete.add(OM_onHtmlDocumentCompleted);
这句话导致所有的文件都在打开时被动态加上了 MathJax.js ,导致如果原本没有 MathJax 渲染的就会自动被渲染,造成了我的错觉。(20160721) - 为知的文件的 html 中是不包含 MathJax 渲染的,在 PC 平台只有使用 F12 可以看到动态的 html,会发现为知对笔记进行了动态渲染,添加了 MathJax.js。可以想象在其他平台应该也实现了动态渲染的功能(但是我只做 PC 的插件,是没有办法直接做到全平台动态加载的)。
- 发现为知把笔记中涉及的 js 文件都直接从网络上下载下来,放在笔记 ziw 压缩包目录下的 index_files 文件夹下面,方便在各平台都可以正常加载,使每一个 ziw 文件包含了所有笔记需要用到的文件(除了附件),也保证了各平台的兼容性。
- 如果我想在我的插件中对 org 文件实现 MathJax 渲染的话,要考虑各平台的兼容性,也就是保证各平台都可以被正常渲染。但是我只能开发 PC 的插件,所以最好向 md 文件靠拢(还要思考到底该怎么实现。最好是向为知提建议,添加一个 flag 针对每个文档进行标记,这样可以在 PC 端添加修改是否使用 MathJax 的选项,从而实现在全平台渲染)。如果只考虑 PC 平台,不管其他平台是否使用 MathJax 渲染的话,可以直接使用动态渲染的方法,添加本地或者在线 MathJax.js 渲染文件。
- 参考:为知笔记应用中心-笔记编辑
- MathJax 本地文件如果使用
unpacked
文件夹的部分,最终渲染出来是以字符形式显示。如果直接使用 MathJax 最外面的几个文件夹(config
,extensions
,fonts
,jax
,localization
),最终渲染出来是以 Math 对象形式显示(fonts
文件夹似乎可以不要)。