编程开源技术交流,分享技术与知识

网站首页 > 开源技术 正文

MarkWord - 可发布博客的 Markdown编辑器 代码开源

wxchong 2025-03-12 21:23:03 开源技术 17 ℃ 0 评论

因为前一段时间看到 NetAnalyzer 在Windows10系统下UI表现惨不忍睹,所以利用一段时间为了学习一下WPF相关的内容,于是停停写写,用了WPF相关的技术,两个星期做了一个Markdown编辑器,并且集成了:编辑时与网页同步,博客发布,PDF导出等功能。也主要是不忿某款外国软件收费,故有此作。

展示与说明

代码同步编辑

博客发布

代码说明

博客发布

MarkWord支持博客园和CSDN博客发布,并且可以进行图片同步(无论是本地图片还是网上的图片,都可以同步到博客服务器)。 该功能使用了MetaWeblog技术。使用方法如下:

/// 
/// 文档上传,包括新增与更新
/// 
public static string UploadBlogs(string apiUrl, string BlogId, string userId, string password, string 
BlogsModel, string postId, string title, string Markdown, bool publish)
{

    int procIndex = 1;

    SendMsg(5, procIndex, "准备数据中……");
    //转换为html
    string Blogs = string.Format("\r\n{0}", 
    CommonMark.CommonMarkConverter.Convert(Markdown));
    metaTools.Url = apiUrl;


    Post blogsPost = new Post;

    //分类
    List tmpCategories = new List;
    tmpCategories.Add("");//添加空分类,是因为部分博客(如csdn)字段这部分为必填字段不添加会产生异常
    blogsPost.categories = tmpCategories.ToArray;

    //添加时间
    blogsPost.dateCreated = DateTime.Now.ToLocalTime;

    //添加标题
    blogsPost.title = title;


    //指定文章编号
    blogsPost.postid = postId;

    //内容
    blogsPost.description = BlogsModel.Contains("{0}") ?//必须使用{0}占位符
        string.Format(BlogsModel, Blogs) : //根据模板生成数据 主要是为了制定Markdown模板
        BlogsModel + Blogs; //通过前缀方式添加

    //开始查找图片并更新到服务器
    HtmlDocument htmlDoc = new HtmlDocument;
    WebClient webClient = new WebClient;
    htmlDoc.LoadHtml(blogsPost.description);
    var ImgList = htmlDoc.DocumentNode.Descendants("img");

    int procCount = 3 + ImgList.Count;

    SendMsg(procCount, procIndex++, string.Format("数据分析完成,总共需要上传{0}张图片", ImgList.Count));
    int imgErr = 0;//图片上传错误数量
    foreach (var i in ImgList)
    {
        SendMsg(procCount, procIndex++, "正在上传图片数据……");
        //获取图片文件字符串
        string ImgUrl = i.GetAttributeValue("src", "");
        if (string.IsNullOrEmpty(ImgUrl))
        {
 imgErr++;
 continue;
        }
        try
        {
 var imgeData = webClient.DownloadData(ImgUrl);//下载文件

 FileData fd = default(FileData);
 fd.bits = imgeData;//图片数据
 fd.name = Path.GetExtension(ImgUrl);//文件名
 fd.type = string.Format("image/{0}", fd.name.Substring(1));

 UrlData obj = metaTools.newMediaObject(BlogId, userId, password, fd);
 blogsPost.description = blogsPost.description.Replace(ImgUrl, obj.url);
        }
        catch
        {
 imgErr++;
 continue;
        }
    }
    try
    {
        if (string.IsNullOrWhiteSpace(postId))
        {
 SendMsg(procCount, procIndex++, "开始发布文章……");
 postId = metaTools.newPost(BlogId, userId, password, blogsPost, publish);
        }
        else
        {
 SendMsg(procCount, procIndex++, "正在更新文章……");
 metaTools.editPost(postId, userId, password, blogsPost, publish);
        }
    }
    catch (Exception ex)
    {
        Common.ShowMessage("博客发送失败");
        return postId;
    }

    if (imgErr == 0)
    {
        Common.ShowMessage("博客发送成功");
    }
    else
    {
        Common.ShowMessage(string.Format("博客发送成功了,但是有{0}张图片发送失败", imgErr));
    }
    SendMsg(procCount, procCount, "完成");
    return postId;

}

具体API实现方法见代码中的BlogsAPI项目

PDF导出

PDF导出功能,使用了HTML转PDF方法 相关DLL已经包含在项目当中了

//html to Pdf
public static void HtmlToPdf(string filePath, string html, bool isOrientation = false)
{
    if (string.IsNullOrEmpty(html))
        html = "Null";
    // 创建全局信息
    GlobalConfig gc = new GlobalConfig;
    gc.SetMargins(new Margins(50, 50, 60, 60))
        .SetDocumentTitle("MarkWord")
        .SetPaperSize(PaperKind.A4)
        .SetPaperOrientation(isOrientation)
        .SetOutlineGeneration(true);

 
    //页面信息
    ObjectConfig oc = new ObjectConfig;
    oc.SetCreateExternalLinks(false)
        .SetFallbackEncoding(Encoding.UTF8)
        .SetLoadImages(true)
        .SetScreenMediaType(true)
        .SetPrintBackground(true);
    //.SetZoomFactor(1.5);

    var pechkin = new SimplePechkin(gc);
    pechkin.Finished += Pechkin_Finished;
    pechkin.Error += Pechkin_Error;
    pechkin.ProgressChanged += Pechkin_ProgressChanged;
    var buf = pechkin.Convert(oc, html);

    if (buf == null)
    {
        Common.ShowMessage("导出异常");
        return;
    }

    try
    {
        string fn = filePath; //Path.GetTempFileName + ".pdf";
        FileStream fs = new FileStream(fn, FileMode.Create);
        fs.Write(buf, 0, buf.Length);
        fs.Close;

        //Process myProcess = new Process;
        //myProcess.StartInfo.FileName = fn;
        //myProcess.Start;
    }
    catch { }
}

CommonMark使用

最后就Markdown的转换,在这里我使用了CommonMark,使用方法比较简单

 CommonMark.CommonMarkConverter.Convert("### test")

如有疑问欢迎交流!!!

最后来一发小广告

NetAnalyzer2016网络协议分析软件源码开放购买,可以分析80多种协议,支持http数据还原(包含chunked和gzip数据) ,欢迎大家可以支持一下!!

如有疑问欢迎QQ联系:470200051

祝大家周末愉快

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表