c#解析markdown文档,实现替换图片链接操作(代码片段)

dotNET跨平台 dotNET跨平台     2023-03-09     213

关键词:

前言

又是好久没写博客了

其实也不是没写,是最近在「做一个博客」,从2月21日开始,大概一个多星期的时间,疯狂刷进度,边写代码边写了一整系列的博客开发笔记,目前为止已经写了16篇了,然后上3月之后工作有点忙加上有点沉迷原神,然后进度就暂时慢下来了

事实证明做什么事情一旦停下来就会产生惰性,于是停了这么久,我终于下定决心继续更新!

这次开发的博客用的是C#语言,搭配.netcore技术栈;前端继续用我比较熟悉的Bootstrap做布局,然后稍微折腾一下;管理端用的是Vue…… 过程中总能遇到一些技术问题,除了在博客开发笔记系列里记录,还是把一些普适性的解决方案单独拿出来。

我的博客采用程序员最爱的Markdown语法书写,而众所周知markdown有一个缺点就是关联图片资源麻烦

因为我的博客需要实现本地用Typora写的Markdown文档导入,所以解析markdown文档并处理导入图片资源是一个绕不过的坎。

如题,本文介绍的是C#解析Markdown文档。

Markdig库

之前我用Python实现过解析Markdown文档,Python生态里相关的库太多了,有很多很好的选择,之前我写的用Python实现解析Markdown的文章:python实现解析markdown文档中的图片,并且保存到本地~

然而C#这边基本没啥可选的,官方的Markdown库也标记为弃用状态,推荐迁移到Markdig这个库……

所以就没得选了,只能用这个Markdig。

官方介绍:

Markdig is a fast, powerful, CommonMark compliant, extensible Markdown processor for .NET.

其实这个库也不难用,但注意官方介绍里有这么一句话:

NOTE: The repository is under construction. There will be a dedicated website and proper documentation at some point!

喵的!就是完全没文档,用法基本靠猜和啃源码 ヽ(ー_ー)ノ

为了实现这个markdown图片导入,我只能硬着头皮搞起来

实现思路

Markdig有一个管道机制

举个例子的伪代码如下:

var pipeline = new MarkdownPipelineBuilder()
    .UseExt1()
    .UseExt2()
    .UseExt3()
    .Build();
var result = Markdown.ToHtml("This is a text with some *emphasis*", pipeline);

可以在解析Markdown过程中对Markdown文档做一些修饰处理

一开始我想到自己写一个管道来实现将Markdown里的图片链接做替换处理

然而(可能因为太菜)看了好几个官方的管道代码,也没琢磨出怎么实现我要的效果

直到我回想起官方介绍里的一个关键词:CommonMark compliant,就是说这玩意是兼容CommonMark

灵光一闪,Markdig因为是新项目还没文档,那作为老项目的CommonMark总有文档吧,于是我去找到了CommonMark.NET项目,一看果然有文档,虽然两者的API并不完全一致,但经过我的半蒙半猜的探索,终于是把要的功能搞定了~ ( ̄▽ ̄)~*

实现代码

终于上代码啦~

首先读取一个Markdown文档,得到MarkdownDocument对象

// 引入需要用到的命名空间
using Markdig;
using Markdig.Renderers.Normalize;
using Markdig.Syntax;
using Markdig.Syntax.Inlines;

var filepath = "temp/blog/机器学习/多个约束条件下的二维装箱问题——寻找《开罗拉面店》最优布局.md";
var md = File.ReadAllText(filepath);
var document = Markdown.Parse(md);

这个文档的部分内容如下:

## 前言
前段时间无聊回坑玩《开罗拉面店》,这是一款模拟经营类的小游戏,不管是画风还是游戏性都很对我胃口。

![](多个约束条件下的二维装箱问题——寻找《开罗拉面店》最优布局.assets/8869373-ea70bbc1e5c28b62.png)

![](多个约束条件下的二维装箱问题——寻找《开罗拉面店》最优布局.assets/8869373-3dd13511e9063800.png)

![](多个约束条件下的二维装箱问题——寻找《开罗拉面店》最优布局.assets/8869373-8fcc0475f92cfc84.png)

里面有一个玩法是拉面店布局,就给你一块地,还有几家店铺,你可以随便铺随便摆,当然肯定是摆的越多家店铺越好。

![](多个约束条件下的二维装箱问题——寻找《开罗拉面店》最优布局.assets/8869373-f2c6578cb8f77c31.png)

我一开始玩的时候也没想那么多,随便摆了摆就完事了,但玩到后期人气上不去,我就突发奇想,能不能把所有店铺摆进去?或者能不能尽可能多地去铺满这块地?

Markdig会把Markdown文档解析成一个文档树,接下来可以像DOM操作那样遍历文档节点了~

下面的代码是找出Markdown中的图片链接节点,并给图片链接加上前缀

foreach (var node in document.AsEnumerable()) 
    if (node is ParagraphBlock  Inline:    paragraphBlock) 
        foreach (var inline in paragraphBlock.Inline) 
            if (inline is LinkInline IsImage: true linkInline) 
                // 这里就是图片链接了
                // 实现给图片链接加上前缀
                linkInline.Url = $"http://127.0.0.1:5038/assets/blog/linkInline.Url";
                Console.WriteLine(linkInline.Url);
            
        
    

然后把修改完的Markdown文档重新输出:

using (var writer = new StringWriter()) 
    var render = new NormalizeRenderer(writer);
    render.Render(document);
    Console.WriteLine(writer.ToString());

最终实现的效果就是这样

## 前言

前段时间无聊回坑玩《开罗拉面店》,这是一款模拟经营类的小游戏,不管是画风还是游戏性都很对我胃口。

![](http://127.0.0.1:5038/assets/blog/多个约束条件下的二维装箱问题——寻找《开罗拉面店》最优布局.assets/8869373-ea70bbc1e5c28b62.png)

![](http://127.0.0.1:5038/assets/blog/多个约束条件下的二维装箱问题——寻找《开罗拉面店》最优布局.assets/8869373-3dd13511e9063800.png)

![](http://127.0.0.1:5038/assets/blog/多个约束条件下的二维装箱问题——寻找《开罗拉面店》最优布局.assets/8869373-8fcc0475f92cfc84.png)

里面有一个玩法是拉面店布局,就给你一块地,还有几家店铺,你可以随便铺随便摆,当然肯定是摆的越多家店铺越好。

后续

能实现把markdown文档里的图片链接拿出来,那后续的图片导入、链接替换就好办了,当然这是博客开发笔记里的内容,本文就不写了。

C#语言很不错,可惜第三方库的生态还是差了点,这个问题如果我用Python的话早就解决了,但C#的话就只能折腾,我甚至一度想要自己造个轮子来解析了……

其实应该不难,我想到的办法就是每一行遍历文档,然后用正则表达式把图片链接匹配出来,后续处理完成再用正则做替换,不过不太优雅就是了,在这个写代码靠copy的时代还是要有点追求,不然跟咸鱼有什么区别呢……

然后再唠一下最近在搞的好玩的东西:

  • 受俄乌战争警醒的「去Windows化」

  • 寻找国内的微信替代品「去腾讯化」

OK,接下来应该会开始更新博客开发笔记系列文章~(*^▽^*)

参考资料

  • CommonMark.NET Wiki:https://github.com/Knagis/CommonMark.NET/wiki

  • Markdig项目主页:https://github.com/xoofx/markdig

  • 相关issues:https://github.com/xoofx/markdig/issues/599

  • 相关源码:https://github.com/xoofx/markdig/blob/master/src/Markdig/Renderers/Normalize/NormalizeRenderer.cs

  • 微软文档:https://docs.microsoft.com/en-us/windows/communitytoolkit/parsers/markdownparser

  • https://www.songshizhao.com/blog/blogPage/1044.html

Markdown 文档中的书签链接

】Markdown文档中的书签链接【英文标题】:BookmarkletlinkinMarkdowndocument【发布时间】:2010-09-1705:16:20【问题描述】:如何在Markdown解析文档中包含书签?Markdown是否有任何“标签”,基本上说“不要解析这个”??例如,你可以有类... 查看详情

c#工具类:使用itextsharp操作pdf文档

...TextSharp组件提供出来的方法接口,我们可以实现很多与PDF文档有关的操作,如打开PDF文档对象、往PDF文档中添加段落、添加图片链接等等,功能非常的强大。这边简单对iTextSharp类进行了封装,提供一些常用的PDF操作方法。iTextS 查看详情

word文档中如何替换图片

在对文档进行编辑处理时,有时需要将文档中的图片转换为指定图片,如果逐张进行替换,如需要花费很多时间。使用word2013中的查找和替换功能,能够快速实现图片的替换,下面介绍具体的操作方法。1、在文档中选择图片,按... 查看详情

markdown-使用(代码片段)

...word中有特别多样式的设定,以满足用户的各种需求,而Markdown中的样式就要少很多,实现的样式必然少;但Markdown的优势在于让用户专注的点是在写作上,所以整体风格简单、整洁。Markdown适用于创作web文档的;Markdown的目标是易... 查看详情

java添加替换删除word中的图片

Java添加、替换、删除Word中的图片文档中,可以通过图文混排的方式来增加内容的可读性,相比纯文本文档,在内容展现方式上也更具美观性。在给文档添加图片时,可设置图片的文本环绕方式、旋转角度、图片高度/宽度等;另... 查看详情

前端小技巧:加载并解析markdown文档

参考技术A移步github作为程序猿,应该多多少少都用过Markdown,或者至少读过别人用Markdown语法写的一些文档,比如在GitHub有一个你要用的开源程序,而你又是第一回用它,那么你一般会在这个仓库的Readme里读一读开发者提供的工... 查看详情

markdown

简介:【易读易写】Markdown是一个Web上使用的文本到HTML的转换工具,可以通过简单、易读易写的文本格式生成结构化的HTML文档。Markdown语法标题#标题一##标题二###标题三粗体**粗体**斜体*斜体*链接文字(链接地址)图片![](图片链接... 查看详情

使用 C# 正则表达式替换 XML 元素内容

...文档中某些元素(例如密码)的内容。我宁愿不序列化和解析文档,因为我的代码将处理各种模式。输入文档示例:文档#1:<user><userid>j 查看详情

把htmlmarkdown之后怎么在页面正常显示出来

使用工具:jsparser操作方法:一、浏览器端进行渲染(markdown转html),比如ajax+marked 二、工具链接:参考技术AMarkDown只是一种文本编辑格式。用于快速编写文档。显示则是通过MarkDown编辑器转换为html代码来实现显示的。因为... 查看详情

新浪博客怎么写markdown

参考技术A关于markdown编辑编辑器有很多,这里推荐有道云笔记,它现在有markdown的窗口,左边编辑,右边显示编辑后的结果。关于上传图片有道云笔记的markdown可以用本地图片,但是更推荐使用带有网址的图片,这样一次编辑,... 查看详情

markdown基础语法整理

标题级别(一共六级)(建议在#后加一个空格比较标准)通过在文字下方添加“=”和“-”,他们分别表示一级标题和二级标题。在文字开头加上“#”,通过“#”数量表示几级标题。(共1~6级标题,级别越小字体越大)列表无序... 查看详情

[asp.netcore]c#解析markdown文档(代码片段)

C#解析Markdown文档通常我们写博客时候通常可以markdown类似写代码的方式又可以呈现HTML的效果。也很多离线的markdown编辑器然后写好之后导入到网站,或者在线markdown编写。C#如何解析markdown文档呢?1.什么时候Markdown;... 查看详情

[asp.netcore]c#解析markdown文档(代码片段)

C#解析Markdown文档通常我们写博客时候通常可以markdown类似写代码的方式又可以呈现HTML的效果。也很多离线的markdown编辑器然后写好之后导入到网站,或者在线markdown编写。C#如何解析markdown文档呢?1.什么时候Markdown;... 查看详情

如何在文本C#中用超链接/锚标记替换带有括号的url

】如何在文本C#中用超链接/锚标记替换带有括号的url【英文标题】:Howtoreplaceaurlhavingbracketswithhyperlink/anchortaginthetextC#【发布时间】:2019-02-2702:26:54【问题描述】:我正在尝试用锚标记替换所有出现的URL。我可以对大多数URL字符... 查看详情

求助关于java通过jacob操作word的问题

要实现以下功能:有a、b两个word文档,a中有文字“替换内容”,b中有文字、图片等,要实现用b文件的内容替换到a的“替换内容”部分,求实现代码?如能解决问题再加分!!!参考技术A呃。。。jacob要生成word文档不是很方便... 查看详情

markdown的入门教程,非常的使用(代码片段)

...的内容竟然没有图片,好气呦目录 概述简介官方文档Markdown编辑器初级语法标题粗体和斜体段落和换行分隔线引言列表无序列表有序列表代码行内代码块段落代码块链接网址链接图片链接指定图片宽高用图床获取外链进阶语... 查看详情

hexo中使用emoji和tasks(代码片段)

替换为markdown-it今天在迁移博客项目的时候,发现原来在hugo中可以使用的Emoji和tasks功能都不能正常使用了,查询了一下原因,主要是因为hexo默认的解析器是hexo-renderer-marked,这个默认的渲染器是不支持emoji功能的,但是支持tasks... 查看详情

C# - 解析网页的最佳方法?

】C#-解析网页的最佳方法?【英文标题】:C#-BestApproachtoParsingWebpage?【发布时间】:2010-09-2222:48:13【问题描述】:我已将整个网页的html保存为字符串,现在我想从链接中获取“href”值,最好能够稍后将它们保存为不同的字符串... 查看详情