解决Markdig无法识别文件名带空格的图片问题

360影视 欧美动漫 2025-09-09 11:30 1

摘要:关于 StarBlog Publisher 工具,这是一款面向 StarBlog 的跨平台 Markdown 文章发布工具,内置多种主流大模型智能助手,支持即写即发和直观内容管理,助力高效创作。

昨天在发布那篇《[1]》的文章时

(使用 StarBlog Publisher 发布文章时)发现其中的 webp 图片都没法自动上传

一开始我以为是没法识别 webp 格式

关于 StarBlog Publisher 工具,这是一款面向 StarBlog 的跨平台 Markdown 文章发布工具,内置多种主流大模型智能助手,支持即写即发和直观内容管理,助力高效创作。

项目开源地址: https://github.com/star-blog/starblog-publisher

后来写了几个 demo 测试后才发现,是因为文件名里有空格,而 Markdig 很严格,不支持识别带空格的文件名,要么就是在插入图片时(Typora 里)先转义,要么就得自己处理图片解析。

文章里的图片是这样的格式

!(./2025-09-07-在鸡哥14x上安装使用Fedora42.assets/截图 2025-09-07 21-14-46.webp)

后面我修改了 starblog-publisher 分析图片的方法

做了以下改进:

使用正则表达式 匹配图片语法

支持路径中包含空格、中文字符等特殊字符

自动处理引号包围的路径和 URL 编码

话不多说,直接上代码吧

先看原来的图片解析代码,完全使用 Markdig 来实现

///
/// 从Markdown内容中提取所有图片路径
///
/// 图片路径数组
public string ExtractImagePaths {
if (post.Content == null) {
return Array.Emptystring>;
}

var document = Markdig.Markdown.Parse(post.Content);
var imagePaths = new Liststring>;
var baseDir = Path.GetDirectoryName(Filepath) ?? "";

foreach (var node in document.AsEnumerable) {
if (node is not ParagraphBlock { Inline: { } } paragraphBlock) continue;
foreach (var inline in paragraphBlock.Inline) {
if (inline is not LinkInline { IsImage: true } linkInline) continue;
if (string.IsNullOrWhiteSpace(linkInline.Url)) continue;

var imgUrl = Uri.UnescapeDataString(linkInline.Url);

// 如果是本地图片路径,转换为绝对路径
if (!imgUrl.StartsWith("http")) {
// 规范化路径
imgUrl = imgUrl.Replace('/', Path.DirectorySeparatorChar) // 统一路径分隔符
.Replace(".\\\\", "") // 移除相对路径前缀
.Replace("./", ""); // 移除相对路径前缀

imgUrl = Path.GetFullPath(Path.Combine(baseDir, imgUrl));
imagePaths.Add(imgUrl);
}
}
}

return imagePaths.ToArray;
}
自行实现图片解析

但 Markdig 实在是拉胯

那就只能我自己来实现解析了

也不难,用正则就可以了

///
/// 提取带空格的图片路径(Markdig 无法正确解析的情况)
///
/// Markdown 内容
/// 基础目录
/// 图片路径列表
private Liststring> ExtractImagePathsWithSpaces(string content, string baseDir) {
var imagePaths = new Liststring>;

// 使用正则表达式匹配图片语法:![alt](path)
// 支持路径中包含空格、中文字符等
var imagePattern =
var matches = System.Text.RegularExpressions.Regex.Matches(content, imagePattern);

foreach (System.Text.RegularExpressions.Match match in matches) {
if (match.Groups.Count >= 3) {
var imagePath = match.Groups[2].Value.Trim;

// 移除可能的引号
if ((imagePath.StartsWith('"') && imagePath.EndsWith('"')) ||
(imagePath.StartsWith('\'') && imagePath.EndsWith('\''))) {
imagePath = imagePath.Substring(1, imagePath.Length - 2);
}

// URL 解码
imagePath = Uri.UnescapeDataString(imagePath);

// 只处理本地路径
if (!imagePath.StartsWith("http")) {
// 规范化路径
imagePath = imagePath.Replace('/', Path.DirectorySeparatorChar)
.Replace(".\\\\", "")
.Replace("./", "");

var fullPath = Path.GetFullPath(Path.Combine(baseDir, imagePath));
imagePaths.Add(fullPath);
}
}
}

return imagePaths;
}
补充一下原方法

然后再补充一下原来 ExtractImagePaths 方法的代码

把底部的代码改成这样

// 添加自定义解析逻辑处理带空格的图片路径
// Markdig 无法正确解析带空格的图片路径,需要手动处理
var customPaths = ExtractImagePathsWithSpaces(post.Content, baseDir);
imagePaths.AddRange(customPaths);

// 去重并返回
return imagePaths.Distinct.ToArray;
image-20250908122447207 比如本文贴的代码里的// 使用正则表达式匹配图片语法:![alt](path)这一行注释,也会被识别到

就很烦,解决方法只能暂时是做成开关,由用户决定是否开启正则识别

只有当 Markdig 无法识别的情况下,才开启。然后再加一个忽略不存在的图片来解决。

开关

说干就干,我在设置里增加了一个开关


Border Classes="Card">
StackPanel Spacing="15" Margin="15">
StackPanel Orientation="Horizontal" Spacing="8">
i:Icon Value="fa-solid fa-image" Foreground="" />
TextBlock Text="图片解析设置" FontWeight="Bold" FontSize="16" />
StackPanel>

StackPanel Spacing="10">
ToggleSwitch OnContent="启用正则识别" OffContent="仅使用标准识别"
IsChecked="{Binding EnableRegexImageParsing}" />
TextBlock Text="启用后将使用正则表达式额外识别带空格的图片路径,但可能会过度识别。建议仅在需要处理特殊路径时开启。"
TextWrapping="Wrap"
FontSize="12"
Foreground="{DynamicResource SystemBaseMediumColor}"
Margin="0,5,0,0" />
StackPanel>
StackPanel>
Border>

效果是这样的

image-20250908124055845

不开启的情况下,识别出本文的图片就是这样的

image-20250908124224250

开启之后是这样,不存在的图片,我也加了标注

image-20250908124158289 跳过不存在的在 StarBlogPublisher/Services/MarkdownProcessor.cs 的MarkdownParse// 检查文件是否存在,跳过不存在的图片
if (!File.Exists(imgUrl)) {
Console.WriteLine($"跳过不存在的图片文件: {imgUrl}");
continue;
}

做一个好用的工具,就是得不断迭代优化

不过我还是得吐槽一下,Markdig 像个毛坯房一样

参考资料

[1]

在鸡哥14x上安装Linux:Fedora 42 上手体验:

[2]

StarBlog 番外篇 (3) StarBlog Publisher,跨平台一键发布,DeepSeek加持的文章创作神器:

[3]

StarBlog番外(4) 文章一键发布工具Publisher大升级,AI功能增强与界面优化:

[4]

AOT编译Avalonia应用:StarBlog Publisher项目实践与挑战:

《DeepSeek极速上手手册》24页干货:零基础3天玩转智能编码

清华独家课程三部曲:

❶《DeepSeek从入门到精通》104页精讲(附30+代码实例)

❷《职场效能革命指南》35页实战:7大行业应用场景深度拆解

❸《AI红利捕获手册》65页秘籍:普通人快速构建竞争壁垒的5种路径

与万千技术人共建智能开发新范式。

来源:opendotnet

相关推荐