尝试更优雅的写作
May 10, 2016虽然用markdown写作确实感到前所未有的简洁和优雅,但是我表示对markdown的分栏显示非常的不舒适。某天朋友推荐了Typora,一个真正的所见即所得的markdown编辑器。
Typora编辑器界面
真正的所见即所得,所以当我第一次使用Typora的时候,就不再使用typecho自带的编辑器了。虽然装了个小插件可以分栏显示,但是分栏显示并不是真正意义上的markdown所见即所得。
Typora区别于其他markdown编辑器的优势
- 单栏即时显示,真正的所见即所得
- 非常友好的表格及公式编辑
- 类似Office的快捷键
- 本地图片直接拖拽到编辑器即可插入
不方便的地方
用Typora写完文章再复制到博客上,会有很多麻烦的地方。比如
- 每次写完都要登陆博客去发表。略麻烦。
- 图片上传问题。由于写文章的时候偶尔需要用到的图片都是本地的,所以拖拽到Typora后的图片地址是本地的地址,复制到博客后还得重新上传一下图片。很麻烦且本身typecho后台传图片就不友好。
所以要解决以上问题,得自己写个程序,即能很方便的把文章发出去,也能很友好的传图片。用C#写了个简单的程序来解决自己的问题。
- 用Typora编辑好的文章拖拽到这里后,直接提交到博客上
- 把本地的图片找出来传到服务器并把文章中的图片地址给替换掉。
实现更优雅的操作
本地读取文件,提取图片或者附件,上传到服务器,返回url替换到本地的文章,上传文章到博客。
1.友好的拖拽读取文件
实现这个在C#窗体程序并不难。只需要给对应的panel添加DragDro()和DragEnter()事件。如:
private void panel1_DragEnter(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent(DataFormats.FileDrop))
e.Effect = DragDropEffects.Link;
else
{
e.Effect = DragDropEffects.None;
}
}
private void panel1_DragDrop(object sender, DragEventArgs e)
{
//文件路径
String pathStr = ((System.Array)e.Data.GetData(DataFormats.FileDrop)).GetValue(0).ToString();
fileManage.setTextFilePath(pathStr);
}
2.找文本中的图片
Markdown的图片格式如
即"叹号"[名称](地址)
表达式:!\[(?<name>.*?)\]\((?<path>.*?)\)
可匹配到对应的字符串。
”!”符号不能省,用于区别于超链接[名称](地址)
的写法
在C#中,可以用regex.Matches() 匹配多个,如
Regex regex = new Regex(@"!\[(?<name>.*?)\]\((?<path>.*?)\)");
MatchCollection matches = regex.Matches(fileManage.getTextFileText());
foreach (Match match in matches)
{
}
在foreach中遍历处理匹配的name 和path即可。
3.上传图片并替换url
由于typecho使用的是php,所以能想到的方法便是在服务器端挂个php脚本,接收图片。
- 服务端
在服务器端新建一个脚本放在 usr/upload_QoiuernRsjk2345Iffj.php
<?php
if ($_FILES["file"]["error"] > 0)
{
echo "error";
}
else
{
$url = "http://539go.com/usr/";
$path = "uploads/".date("Y/m-d/");
creatdir($path);
if (file_exists($path . $_FILES["file"]["name"]))
{
echo "exists";
}
else
{
move_uploaded_file($_FILES["file"]["tmp_name"],
$path . $_FILES["file"]["name"]);
echo $url . $path . $_FILES["file"]["name"];
}
}
function creatdir($path)
{
if(!is_dir($path))
{
if(creatdir(dirname($path)))
{
mkdir($path,0777);
return true;
}
}
else
{
return true;
}
}
?>
其中$url = "http://539go.com/usr/";
是php文本所放置的地址。
$path = "uploads/".date("Y/m-d/");
是保存图片的格式,比如这里我要保存到 uploads/年份/月-日/
这样的格式下。
- 客户端
C#
public string SendFile(string fileName, Uri uri, string encodingType = "UTF-8")
{
WebClient myWebClient = new WebClient();
byte[] responseArray = myWebClient.UploadFile(uri, "POST", fileName);
return Encoding.GetEncoding(encodingType).GetString(responseArray);
}
String str = SendFile(imgItem.path, new Uri("http://http://539go.com/usr/upload_QoiuernRsjk2345Iffj.php"));
这里只是提供一个示例,调用senFile()后,str会接收php返回的内容,比如没有文件时返回error,文件存在时返回返回 exists,否则返回对应的url。都需要做对应的处理。
没有学过php,所以加密码什么的暂时不做了。
4.提交到博客
这个相对来说简单,分析一下typecho数据库的字段然后编写sql语句就行了。
contents表就是typecho保存文章内容的表了。
cid是自增的,其他的都好理解,其中created和modified字段是创建日期和修改日期的,是int类型的时间戳格式。所以需要在添加日期的时候转换一下。
/// <summary>
/// 时间戳转为C#格式时间
/// </summary>
/// <param name="timeStamp"></param>
/// <returns></returns>
private DateTime StampToDateTime(string timeStamp)
{
DateTime dateTimeStart = TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1));
long lTime = long.Parse(timeStamp + "0000000");
TimeSpan toNow = new TimeSpan(lTime);
return dateTimeStart.Add(toNow);
}
/// <summary>
/// DateTime时间格式转换为Unix时间戳格式
/// </summary>
/// <param name="time"></param>
/// <returns></returns>
private int DateTimeToStamp(System.DateTime time)
{
System.DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new System.DateTime(1970, 1, 1));
return (int)(time - startTime).TotalSeconds;
}
/// <summary>
/// 获取时间戳(现在)
/// </summary>
/// <returns></returns>
static public int getDateStampNow()
{
System.DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new System.DateTime(1970, 1, 1));
return (int)(System.DateTime.Now - startTime).TotalSeconds;
}
另外,在C#上使用mysql需要引用MySql.Data.dll,不然是没办法使用MySqlConnection的。
插入文章的Sql:
insert into typecho_contents (title,slug,created,modified,text,authorId,allowComment,allowPing,allowFeed)
values(@title,@slug,@created,@modified,@text,@authorId,@allowComment,@allowPing,@allowFeed)
有的字段不用添加,因为有默认值。
另外,由于没有插入cid,slug字段在typecho上是默认和cid相同的,所以,当执行完sql后,需要根据得到的cid修改slug字段
update typecho_contents set slug=@slug where cid=@cid;
4.完成后
提交后的界面只能待会儿上传了后再上传了。因为暂时没有做修改的功能。
时间匆忙,还有很多不足的地方需要有空慢慢实现,仅仅完整了暂时的需求。
需要完善的地方
- php加个密码
- 上传后最好可以修改文章
- 中文问题
- 界面太丑
提交后的界面