实验笔记是个好东西。如果你做了一堆研究,最后发现以前做过的东西忘记放在哪里了,或者说代码已经被你修改得面目全非了,你想对比一下当下的结果和当时的结果,这可能会给你带来无尽的烦恼。 Python的Jupyter确实可以解决上述的问题,它可以将代码,结果,备注(说明,公式等)展示在同一个文件中,打开速度也很快,如果没有别的需求,这应该是最完美的工具。 但是我对Matlab依赖比较强,想用Matlab实现同样的功能,该怎么办呢? Matlab的确提供了相关的功能,即实时脚本(live script),具体使用方法建议参考官网的帮助文档,文档的扩展名是.mlx。
不过,文档需要在Matlab中打开,Matlab的启动速度的非常慢,所以为了快速查阅实验笔记,我们可以将其导出为.html格式。
给文件起个名字,假设为'实验笔记20200630.html', 用浏览器打开,效果如下。可以看出展示效果还是很棒的,但是网页的Title和文件名不符。这就带来了很大的麻烦,如果我们保存了很多实验笔记,并且同时打开了很多文件,我们如何通过Title来区别文件呢?
下面就是本文的重点:我特意研究了,发现无法通过设置修改保存的html文件的title (官方程序员肯定是偷懒了,希望官方可以修理这个bug),所以我只能通过撸代码强行修改html源代码里的Title了。html的源代码长这样:
源代码的编码为UTF-8, 我保存的文件名有中文字符,所以这就涉及到编码转换的问题,这是麻烦1;麻烦2就是说如果为了修改Title而把整个文件都修改了则会极大降低效率,得不偿失。分析发现:上图红色框框内的内容是无用的,可以将其改写掉,所以红线框+绿线框内的内容就是我需要替换掉的部分;而假如文档标题长度小于框框内的长度,我们可以在修改后的第二行后面插入多余的换行符,这样就不会影响到第三行及之后的内容。
经过加班加点加调试,终于搞定这个问题,Matlab代码如下。它的主要功能就是修改当前路径下html文件的title(Matlab Live Script导出的html文件)
function Html_ChangeTitle
%% 获取当前的工作路径
path = cd;
%% 获取当前文件夹下的所有.html文件
fileExt = '*.html';
files = dir(fullfile(path,fileExt));
len = size(files,1);
fprintf('[Tips] -- 开始更改文件名-------------------\n');
for i=1:len
fileName = files(i,1).name;
fileName(end-4:end) = []; % 去除.html字符
fileFullName = strcat(path,'\',files(i,1).name);
fid = fopen(fileFullName,'r+','n','UTF-8');
% 'r+' 打开后先读后写。该文件必须已存在
% 'UTF-8' 读写的编码格式 UTF-8
% 更改文件名
changename(fid,fileName);
fclose(fid);
end
% 提示更改完毕
fprintf('[Tips] -- 文件名更改完毕-------------------\n');
end
function changename(fid,fileName)
while 1
line = fgetl(fid); % 从文件中读取“下一行”,并且移除换行符(\n)
if ~ischar(line) %判断是否为字符,如果不是则中断
warning('[ERROR] -- line非字符');
break;
end
% 寻找k1的位置, 比较特殊
k1 = strfind(line,'<meta name="generator"');
% contains(line,'<meta name="generator"'); % 18才有此功能
if isempty(k1)
k1 = strfind(line,'<title>');
end
k2 = strfind(line,'</title>');
if ~isempty(k1) && ~isempty(k2)
% 文件名已经更改好, 无需更改
flag = strfind(line,['<title>',fileName,'</title>']);
% contains(line,['<title>',fileName,'</title>'])
if ~isempty(flag)
fprintf('[Tips] -- 已忽略,无需更改, %s.html \n',fileName);
break;
end
% 移动插入点(从插入点覆盖写入文件)
offset = length(unicode2native(line,'UTF-8')) + 2 - length(unicode2native(line(1:k1),'UTF-8'));
% 每行结尾有LF,所以要加2(Windows)
fseek(fid, -offset, 'cof'); % 向前偏移, 所以要加负号
% 写入的内容
% chip1 = line(1:k1+6);
chip3 = line(k2:end); % chip3后面可能有制表符
newline = ['<title>',fileName,strrep(chip3,' ','')];
% 判断文件名是否过长(在UTF-8编码中,一个汉字的长度是3)
L0 = length(unicode2native(line(k1:end),'UTF-8'));
L1 = length(unicode2native(newline, 'UTF-8'));
if L1 > L0
fprintf('[Tips] -- 已忽略,名字过长, %s.html \n',fileName);
break; % 文件名已经更改好, 无需更改
else
% fprintf(fid,['%s',repmat('\t',1,(L0-L1))],native2unicode(newline,'UTF-8'));
fprintf(fid,['%s',repmat('\t',1,(L0-L1))],newline);
% 如果文件名过短, 将剩余部分全部用换行符覆盖
fprintf('[Tips] -- 已更改,更改完毕, %s.html \n',fileName);
end
% 不用加换行符和回车符 '\r\n'
% count = fwrite(fid,native2unicode(newline,'UTF-8'),'char');
break;
else
continue;
end
end
end
将代码保存为Html_ChangeTitle.m,放在Matlab的path(默认路径)中,然后将其添加到快速访问工具栏,过程如下
在浏览器中打开更改了Title的实验笔记,效果如下。
至此搞定,心里的石头也落地了😂。