公众号:理念世界的影子

文不可无观点,观点不可无论据。

转载请注明出处

结果简单,重在过程

有时将彩色Matlab代码拷贝到Word中,可能出现彩色消失、中文乱码、没有行号、字体不佳等问题。已有的措施包括但不限于:

先将代码拷贝到Word,手动修改乱码,适用于中文字符不多的场合。

先将代码拷贝到PowerPoint,然后再拷贝回Word。

在Word中增加行号,但有时颜色会消失。

将代码拷贝到notepad++或某网站,调整好格式后再拷贝到Word。

拷贝彩色代码本就是编程问题。对于强大的编程语言Matlab,如采用以上措施,无异于衣锦夜行。

但怎么编程实现一键彩色代码拷贝,还真是个问题。直至有次笔者发现在主菜单中,点击File/Publish,弹出了Matlab浏览器,并显示了彩色代码,于是有了思路,并一步一步地形成了最终的方法。

方法为:在Matlab中选中代码,按Alt+Z键,切换到Word,按Ctrl+V,即可拷贝带行号的彩色代码。参见如下视频:

图 拷贝代码示意图

下面是方法研究过程。

第一步:点击菜单发布.m文件+手动操作IE

+

点击File/Publish,直接从弹出的Matlab浏览器选中文字,拷贝到Word,但没有颜色信息。具体如下图

图 直接从MATLAB浏览器拷贝后黏贴,没有颜色信息

看来是浏览器问题,好在浏览器中有网址,用IE/Edge/Chrome打开再复制,可在Word中黏贴彩色文本。如下图:

图 用其它浏览器打开复制后黏贴,有颜色信息,无乱码

第二步:编程发布.m文件+手动操作IE

+

在第一步中,每次复制代码,都要点击Publish再切换到浏览器,非常麻烦。

笔者坚信,任何Matlab的界面操作,都能找到指令代替。

譬如菜单的Publish操作就有publish函数,再加上调用IE的命令,形成如下两条命令:

editorhtml2clipboard.m

file=publish(

'test.m'

,

'html'

);

eval(['!"c:\\ProgramFiles\\Internet Explorer\\iexplore.exe" "' file '"'])

这次可以直接弹出IE供拷贝了。(Win10中可能没有安装iexplorer,可以将打开程序更换为Edge,或打开控制面板/程序/启用或关闭Windows功能, 勾选Internet Explorer 11,然后重启计算机)。

图 在Windows功能中启用Internet Explorer 11

第三步:编程发布.m文件+COM操作IE

+

第二步中需要切换到浏览器再复制比较麻烦,可以利用COM接口调用浏览器。代码如下:

editorhtml2clipboard.m

file=publish('test.m', struct('format', 'html', 'useNewFigure', false)); % 发布,不弹出figure界面

app=actxserver('internetexplorer.application'); % 打开ie组件

app.Navigate(file); % 打开文件

while(~strcmpi(app.ReadyState,'READYSTATE_COMPLETE')) end

%OLECMDID_COPY = 12, OLECMDID_SELECTALL = 17,见docobj.h

app.ExecWB(17, 0); % 全选

app.ExecWB(12, 0); % 拷贝

app.Quit; %退出

这里为了使用COM,需要关闭IE的保护模式。

图 在IE中关闭启动保护模式

现在不用切换到浏览器就可以直接拷贝彩色代码了。

第四步:剪贴板获取代码+编程发布+COM操作IE

+

第三步中拷贝代码停留在文件级,使用起来还是不方便。我们希望能选中代码后直接输出,可以利用Matlab的剪贴板函数clipboard。

editorhtml2clipboard.m

tic

str = clipboard('paste'); % 从剪贴板获取

mfile='buffer.m'; % 临时文件

fp=fopen(mfile, 'w'); fprintf(fp, '%s',str);fclose(fp); % 写文件

file=publish(mfile, struct('format', 'html', 'useNewFigure', false));

app=actxserver('internetexplorer.application');

app.Navigate(file); % 打开文件

while(~strcmpi(app.ReadyState,'READYSTATE_COMPLETE')) end

% OLECMDID_COPY = 12,OLECMDID_SELECTALL = 17,见docobj.h

app.ExecWB(17, 0); % 全选

app.ExecWB(12, 0); % 拷贝

app.Quit; %退出

toc

每次使用时,先按Ctrl+C键将代码复制到剪贴板,然后再运行此程序,就可以得到彩色代码。

可能有些机器上用不了IE,用Word也行,相关代码如下:

editorhtml2clipboard.m

app=actxserver('word.application');

do=app.Documents;

do.Open(file);

sel=app.Selection;

sel.WholeStory;

sel.Copy;

do.Close;

app.Quit;

delete(file);

但使用时,每次都需要复制代码,再运行程序,有点不方便。有没有快捷键可以运行程序?这样,选中代码,按Ctrl+C后再按一次快捷键就可以了。

Matlab的界面是用java实现的,理论上只要获取编辑器界面的java对象,就可以增加键盘监听函数。

但笔者不熟悉java,更搞不清楚com.mathworks.mde的结构,于是网上一通搜索,还真找到了这个程序:

EditorMacro.m

(https://www.mathworks.com/matlabcentral/fileexchange/24615)

在命令窗口运行命令:

>>  EditorMacro('Alt Z', 'worked')

>>  EditorMacro('Alt Z',@editorhtml2clipboard, 'run')

其中第一句测试快捷键是否可用,第二句将函数绑定到快捷键上。现在只要选中代码,按Ctrl+C,再按Alt+Z就可以输出彩色代码。

第五步:选区获取代码+编程发布+COM操作IE

+

目前需要按两次键输出彩色代码,有没有可能合并?EditorMacro的帮助里说,第二个参数macro有两个输入参数:editorPane 对象和事件数据。

界面相关对象有没有可能获取选区?改写一下程序进行测试:

editorhtml2clipboard.m

function editorhtml2clipboard(obj, event)

methodsview(obj) % 查看obj对象属性

h=obj.getSelectedText()

whos h

按下Alt+Z,在弹出的对象方法查看窗口中,果然有获取选区的函数,对象返回了java.lang.String类型数据。

图 EditorMacro的Macro函数第一个参数的方法

现在十分简单,将原来的editorhtml2clipboard.m中,从剪贴板获取命令

str = clipboard('paste'); %从剪贴板获取

改为从选区获取

str = char(obj.getSelectedText());%从选区获取

这时,只要按一次Alt+Z就可以拷贝彩色代码了。

但还有些瑕疵,拷贝的代码最后都有“Published with MATLAB® 7.11”字样。

在publish函数设置断点跟踪进去,发现尽管publish程序有800多行,但与生成彩色代码html相关的仅三行:

[dom,cellBoundaries] =m2mxdom(code);

xslt(dom,options.stylesheet,outputAbsoluteFilename);

styleSheet = fullfile(codepadDir,'private','mxdom2simplehtml.xsl');

原来publish使用的是XML。三行代码中,一行调用m2mxdom函数将代码解析成XML的DOM结构,一行用XSLT将之翻译为html,还有一行指明这个翻译文件是mxdom2simplehtml.xsl。

发现了这个,立刻改造代码,将

mfile='buffer.m'; % 临时文件

fp=fopen(mfile, 'w'); fprintf(fp, '%s',str);fclose(fp); % 写文件

file=publish(mfile, struct('format', 'html', 'useNewFigure', false));

改为:

dom=m2mxdom(str);

file=xslt(dom, 'mxdom2simplehtml.xsl');

此时程序变为:

editorhtml2clipboard.m

function editorhtml2clipboard(obj, event)  tic  str = char(obj.getSelectedText());% 从选区获取  dom=m2mxdom(str);  file=xslt(dom, 'mxdom2simplehtml.xsl');  app=actxserver('internetexplorer.application');  app.Navigate(file); % 打开文件  while(~strcmpi(app.ReadyState,'READYSTATE_COMPLETE')) end  % OLECMDID_COPY = 12,OLECMDID_SELECTALL = 17,见docobj.h  app.ExecWB(17, 0); % 全选

app.ExecWB(12, 0); % 拷贝

app.Quit; %退出

delete(file);

toc

这里的m2mxdom.m文件和mxdom2simplehtml.xsl文件均在私有文件夹:MATLAB安装目录的\toolbox\matlab\codetools\private里,需要将它拷贝到可访问的文件夹下(如当前文件夹)。

“Published with MATLAB® 7.11”字样就来自mxdom2simplehtml.xsl文件,只要把文件中这句

删除或注释()掉即可

此外,还可以在此文件里定制代码的字体、大小等。譬如在

pre.codeinput {

background: #EEEEEE;

padding: 10px;

}

增加字体和字号:

pre.codeinput {

background: #EEEEEE;

padding: 10px;

font-family: calibri;

font-size: 10pt;

}

第六步:优化

+

现在程序可以正确工作了,但拷贝的没有行号,而且彩色代码生成时间较长,达1~3秒。

行号非常好解决,要么在mxdom2simplehtml.xsl中修改CSS,要么直接更改字符串str,将回车改为回车+行号。输出自带型号的缺点是从Word中回拷到Matlab会无法运行,为解决这个问题,可以在Word中按住Ctrl键直接拖选代码,或者在Matlab中写个滤除开头字节的语句并注册一个快捷键。

01  nret=[0 find(str==char(10))]; % 开头或回车

02  for i=length(nret):-1:1 % 从后向前替换

03      j=nret(i);  % 开头或回车

04      str=[str(1:j)  sprintf('%02d ', i)  str(j+1:end)]; % 从回车处断开,并插入行号

05  end

程序运行时间主要消耗在actxserver创建COM对象上。而且每次按一下快捷键,就需要创建COM对象,然后再销毁,太浪费时间且无必要。优化的方法包括将COM对象设置为persistent变量,或者在调用editorhtml2clipboard前就创建好。

即在调用之前生成COM对象:

existapp=actxserver('internetexplore.application') % 创建IE的COM对象

editorhtml2clipboard([],[],existapp) % 打开IE的

再将editorhtml2clipboard.m中的生成COM对象改为:

bappfromcaller=false; % 是否已传入IE对象

if(~strcmpi(class(app), 'com.internetexplorer_application'))% 如果是IE

% 如果调用程序没有传入,则打开IE

app=actxserver('internetexplorer.application');

else

bappfromcaller=true;

end

利用此方法,能将复制彩色代码时间降到0.3秒。

有没有更好的办法呢?网上搜索发现,Windows在剪贴板中定义了CF_HTML类型

(https://docs.microsoft.com/en-us/windows/win32/dataxchg/html-clipboard-format)

只要在html字符串前增加:

Version:0.9

StartHTML:71

EndHTML:170

StartFragment:140

EndFragment:160

其中几个数值含义为:

StartHTML的数值为的开头位置

EndHTML的数值为结束位置

StartFragment的数值为的开头位置

EndFragment的数值为的开头位置

最后设置剪贴板第一个参数为如下字符串,第二个参数设置为HTML类型。

图 CF_HTML类型

.Net的System.Windows.Forms中有这个API,于是可以采用如下代码进行复制:

htmltext=['Version:0.9' char(10)...

'StartHTML:00000000' char(10)...

'EndHTML:00000000' char(10)...

'StartFragment:00000000' char(10)...

'EndFragment:00000000' char(10)...

htmltext];

NET.addAssembly('System.Windows.Forms');

clip=System.Windows.Forms.Clipboard;

clip.SetText(htmltext,System.Windows.Forms.TextDataFormat.Html);

在代码测试中发现,其实并不需要设置StartHTML的位置,也不需要在html中加和,就可完成拷贝。

综上形成的editorhtml2clipboard.m程序如下,执行时间降低到0.03秒。

editorhtml2clipboard.m

01  function editorhtml2clipboard(obj,event)

02  % EDITORHTML2CLIPBOARD 将matlab代码拷贝为彩色HTML

03  %  Note: EDITORHTML2CLIPBOARD requires .Net or COM and java on allplatforms.

04  %

05  %  Example:

06  %  editorhtml2clipboard(); % 显示'%abc'的彩色代码

07  %  EditorMacro('Alt Z', @editorhtml2clipboard, 'run');

08  %

09  %  使用方法为:

10  %         1) 在命令窗口输入editorhtml2clipboard,测试程序是否正确;

11  %         2) 将MATLAB安装目录的\toolbox\matlab\codetools\private中的mxdom2simplehtml.xsl和m2mxdom.m拷贝到当前文件夹或其它matlab可访问的文件夹。其中mxdom2simplehtml.xsl可根据格式需要适当修改。

12  %        3) 下载EditorMacro.m(https://www.mathworks.com/matlabcentral/fileexchange/24615)放置到当前文件夹或matlab可访问的文件夹。

13  %         4) 在命令窗口输入EditorMacro('Alt Z',@editorhtml2clipboard, 'run')。可以先运行EditorMacro('Alt Z', ‘test’),然后按Alt+Z看是否有字符输出,如果没有输出就更换快捷键重试。此外,每次重启Matlab时,EditorMacro都会失效,因此可将这句放到我的文档/Matlab/Startup.m中,这样启动Matlab时就自动注册了快捷键。

14  %         5) 在选中代码中按快捷键,就可以将彩色代码拷贝到word中。

15  %

16  %  See also REGEXP, XSLT, M2MXDOM

17  %

18  %  Copyright 2020 "Space Odyssey" 公众号: 理念世界的影子.

19  %  $Date: 2020/03/01 $

20

21  tic

22  % 方法1:CF_HTML法,最快,需.Net支持。特征格式只能复制到word等,不能复制到notepad中

23  % 方法2: 需IE COM服务支持

24  % 方法3:需Word COM服务支持

25  method=1;

26  if(nargin==0)

27      str=sprintf('%%test中文\n2\n3');

28  else

29      str =char(obj.getSelectedText()); % 从选区获取

30  end

31  if(isempty(str)) return;end

32  nret=[0 find(str==char(10))]; % 开头或回车

33  fori=length(nret):-1:1 % 从后向前替换

34      j=nret(i);  % 开头或回车

35      str=[str(1:j)  sprintf('%02d ', i)  str(j+1:end)]; % 从回车处断开,并插入行号

36  end

37  % m2mxdom将m文件格式转换为XML格式

38  % xslt引擎通过mxdom2simplehtml.xsl描述文件,将XML转换为带颜色的html文件

39  htmltext=xslt(m2mxdom(str), 'mxdom2simplehtml.xsl', '-tostring');

40  if(method==1)

41      % 方法1:CF_HTML法

42      htmltext=['Version:0.9' char(10)...

43          'StartHTML:00000000' char(10)...

44          'EndHTML:00000000' char(10)...

45          'StartFragment:00000000' char(10)...

46          'EndFragment:00000000' char(10)...

47          htmltext];

48

% NET.addAssembly('System.Windows.Forms');

49      clip=System.Windows.Forms.Clipboard;

50      clip.SetText(htmltext, System.Windows.Forms.TextDataFormat.Html);

51  elseif(method==2)

52      % 方法2:IE COM法。为了加快运行,可以提前生成app,然后作为参数传入

53      app=actxserver('internetexplorer.application');

54      app.Navigate('about:blank');

55      while(~strcmpi(app.ReadyState,'READYSTATE_COMPLETE')) end

56     app.Document.documentElement.innerHTML=htmltext;

57      % OLECMDID_COPY = 12,OLECMDID_SELECTALL = 17,见docobj.h

58      app.ExecWB(17, 0);

59      app.ExecWB(12, 0);

60      app.Quit;

61  elseif(method==3)

62      % 方法3:WORD COM法。为了加快运行,可以提前生成app,然后作为参数传入

63      app=actxserver('word.application');

64      do=app.Documents;

65      file=tempname;

66      fp=fopen(file, 'w'); fprintf(fp, '%s', htmltext);fclose(fp);

67      do.Open(file);

68      sel=app.Selection;

69      sel.WholeStory;

70      sel.Copy;

71      do.Close;

72      app.Quit;

73      delete(file);

74  end

75  toc

使用方法为:

1) 在命令窗口输入editorhtml2clipboard,测试程序是否正确;

2) 将MATLAB安装目录的\toolbox\matlab\codetools\private中的mxdom2simplehtml.xsl和m2mxdom.m拷贝到当前文件夹或其它matlab可访问的文件夹。其中mxdom2simplehtml.xsl可根据格式需要适当修改。

3) 下载EditorMacro.m,放置到当前文件夹或matlab可访问的文件夹。

(https://www.mathworks.com/matlabcentral/fileexchange/24615)

4) 在命令窗口输入EditorMacro('Alt Z', @editorhtml2clipboard, 'run')。可以先运行EditorMacro('Alt Z', ‘test’),然后按Alt+Z看是否有字符输出,如果没有就更换快捷键重试。此外,每次重启Matlab时,EditorMacro都会失效,因此可将这句放到我的文档/Matlab/Startup.m中,这样启动Matlab时就自动注册了快捷键。

5) 在选中代码中按快捷键,就可以将彩色代码拷贝到word中。

最后,1)~3)的四个文件可在留言中找到地址并下载。

editorhtml2clipboard.m

mxdom2simplehtml.xsl

m2mxdom.m

EditorMacro.m

往期文章:MATLAB

《天遇---地球在宇宙流浪,人类在地球流浪---天体力学的几个图像切片》

《MATLAB小游戏---牛顿法中的分形》

《MATLAB程序设计语言(3.3)---一切皆为数组3(结构体和元胞数组的底层实现)》

《用圆搞定FBB---FBB、Matlab与航天》

《MATLAB程序设计语言(3)---一切皆为数组2(MATLAB的底层实现)》

《MATLAB程序设计语言(3.1)---一切皆为数组1》

《MATLAB程序设计语言(2.1)---变量的作用域》

《MATLAB程序设计语言(2)---help的see also与六度空间理论》

《MATLAB程序设计语言(1)---入门》

微信扫一扫

关注“理念世界的影子”

版权声明:本文是"洞穴之外"作者原创文章,欢迎转载,须署名并注明来自“理念世界的影子”公众号。

彩色matlab代码拷贝到word研究,matlab编辑器合并_彩色MATLAB代码拷贝到WORD研究相关推荐

  1. 苹果电脑拷贝文件到u盘很慢_电脑文件需要拷贝到另外一台电脑,U盘太慢怎么办?一根网线解决你的烦恼...

    我们平时可以因为各种原因,如电脑重装.高清电影分享.更换电脑等),需要将大文件拷贝至另一台电脑.我们采用U盘拷贝的话很浪费时间,且不一定能找到大的U盘使用.那该怎么办呢? 这里我们采用局域网进行拷贝就 ...

  2. blob显示在word编辑器中_你最头疼pdf转word,这里有最全面的转换方法,让工作更轻松...

    我们在工作中经常要涉及到格式转换,特别涉及到文档格式之间的转换,为难了很多工作中的职场人士.俗话说"书到用时方恨少".我们平常多积累一些职场中的小技巧,自然在工作中就不会发难. 在 ...

  3. matlab中右三角形方向,《有限元基础教程》_【MATLAB算例】4.7.1(2) 基于3节点三角形单元的矩形薄板分析(Triangle2D3Node)...

    [MATLAB 算例]4.7.1(2) 基于3节点三角形单元的矩形薄板分析(T riangle2D3Node) 如图4-20所示为一矩形薄平板,在右端部受集中力100 000F N =作用,材料常数为 ...

  4. matlab中如何清空文本框中的值_在MATLAB的命令窗口中执行()命令,将命令窗口的显示内容清空。...

    [单选题]已知 x = [3, 5, 7],那么执行语句 x[1:] = [2]之后,x的值为___________.(3.0分) [判断题]Python集合中的元素可以是整型(3.0分) [判断题] ...

  5. python生成word文档的表格_说说如何使用 Python 在 word 中创建表格

    我们可以使用 python-docx 模块,实现在 word 中创建表格. 请看下面这段代码: table = doc.add_table(rows=1, cols=len(titles)) # 设置 ...

  6. dataframe两个表合并_史上代码最少的工作表拆分,仅需5行,不可思议

    工作中,很多小伙伴都会遇到一些需求,将一份Excel文档按照部门进行拆分,每个部门是一个单独的工作表,或者每个部门整理的工作表汇总为一份总的工作表.读者需要注意的是,多个工作表的拆分与合并,始终在一个 ...

  7. word文档怎么一分为二_微信文章怎么转成word文档,这个强大工具可以帮你搞定...

    现在每个人微信里都会订阅自己喜欢的公众号,小编也是这样,初略统计下,微信里关注的公众号不下60个,工作的.生活的.新闻资讯.娱乐八卦.美容养生等等,太多太多了. 这些公众号每天都会推送许多内容精致的文 ...

  8. 如何用word制作英语答题卡_考研英语答题卡模板(word打印版).doc

    考研英语答题卡模板(word打印版) 考 生 姓 名 报 考 单 位 考生编号(左对齐) [ 0 ] [ 0 ] [ 0 ] [ 0 ] [ 0 ] [ 0 ] [ 0 ] [ 0 ] [ 0 ] [ ...

  9. word中将空格替换为_如何在Office 2007中将Word保存为PDF

    word中将空格替换为 How to save a Word document to be a PDF in Office 2007? 如何在Office 2007中将Word 文档保存为PDF? I ...

最新文章

  1. 分享如何在Ubuntu 16.04下CUDA8.0
  2. Java实现红包随机金额算法
  3. 利用ASP.netCore自带DI(DependencyInjection)实现批量依赖注入
  4. ACdream1157 Segments(CDQ分治 + 线段树)
  5. 【安全测试】:某系统短信修改密码,绕过逻辑漏洞
  6. @Scheduled定时任务不生效的原因
  7. 怎么在ASP.NET 2.0中使用Membership (转载)
  8. Android Multimedia框架总结(十四)Camera框架初识及自定义相机案例
  9. Windowserver2012部署always on
  10. SetWindowsHookEx全局钩子
  11. 邮箱登录入口官网是哪个?域名邮箱登录入口展示
  12. 电商erp软件有哪些好处?
  13. ★追风的牛★添翼圈Moto Droid玩家手册(感谢原作者,只是做个备份而已,如果牵扯到越劝,我会立即删掉)
  14. 【Matplotlib绘制图像目录】Python数据可视化之美
  15. outlook邮箱收到的附件(excel, word, ppt)不能正常打开的解决办法
  16. 如何做一个基于python校园运动场地预约系统毕业设计毕设作品(Django框架)
  17. C# Md5与AES加密解密源码记录
  18. File `xx.sty‘ not found——LaTex解决方案
  19. app表白 生日 小游戏 表白
  20. swustoj木材加工(0436)

热门文章

  1. 一个简单的B站视频抽奖小程序
  2. Java 常用内置对象
  3. LeetCode 1-10 题 3、4、5、7、9、10
  4. 解决方案之Android 国际化资源完美兼容6.0,7.0,8.0
  5. php一点通,编程一点通下载-编程一点通最新安卓版下载-99wo下载站
  6. stream流、数学类、String类的常用方法、date、密码等
  7. 美国签证经历(完善中)
  8. 原神改文件换服务器,原神B服怎么转成官服
  9. 今天在5460同学录的留言
  10. java中父类创建子类的语法_Java 语言中,所创建的子类都应有一个父类。( )_学小易找答案...