MarkdownToMediaWiki AI时代开发的开发流程
目标:当前ollama回答的问题,采用的格式是Markdown的,而我常用的是Mediawiki,所以想把这个格式转换一下。
方法:采用豆包的AI编程,一步一步的来实现。
遇到的问题:
1,表格没有实现,因为Markdig无法识别table模块,我发现在table前面增加一个换行符号就可以,然后问豆包。豆包给我一个正则表达式,但匹配上出现错误,多次询问后得到正确答案。
2,发现回答中漏掉了代码的功能,询问后增加成功。
用了2个小时,不停地问豆包,终于搞定了。\
感叹一下:新的开发时代真的来临了。
主要代码如下:
using Markdig; using Markdig.Extensions.Tables; using Markdig.Helpers; using Markdig.Syntax; using Markdig.Syntax.Inlines; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Text.RegularExpressions; namespace MarkdownToMediaWiki { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { //读取 Markdown.txt 文件内容到字符串 string markdownFilePath = "Markdown.txt"; string markdown = ReadMarkdownFromFile(markdownFilePath); // string markdown = @"#### **3. 研究内容与技术路线** //- **研究框架图** // 用Visio绘制包含""基础研究→关键技术→集成验证""三阶段的鱼骨图 //- **技术参数表** // | 技术难点 | 解决方案 | 预期指标 | 验证方法 | // |----------|----------|----------|----------| // | 界面缺陷 | 原子层钝化 | 缺陷密度<0.1/cm² | TEM观测 | "; // 在表格前插入换行符 markdown = InsertNewlinesBeforeTables(markdown); tbxMarkdown.Text = markdown; } private void btnChange_Click(object sender, EventArgs e) { tbxMediawiki.Text = ConvertMarkdownToMediaWiki(tbxMarkdown.Text); // 将 TextBox 的文本复制到剪贴板 if (tbxMediawiki.Text != "") { Clipboard.SetText(tbxMediawiki.Text); MessageBox.Show("文本已复制到剪贴板!"); } } static string InsertNewlinesBeforeTables(string markdown) { // 正则表达式匹配表格的起始行(表头行) //string tableStartPattern = @"^\s*\|.*\|$"; // 优化后的正则表达式匹配表格的起始行(表头行) string tableStartPattern = @"^\s*\|[^|]+(\|[^|]+)+\|\s*$"; var lines = markdown.Split(new[] { '\n', '\r' }, StringSplitOptions.RemoveEmptyEntries); var newLines = new List<string>(); bool inTable = false; for (int i = 0; i < lines.Length; i++) { if (Regex.IsMatch(lines[i], tableStartPattern, RegexOptions.Multiline)) { if (!inTable && i > 0) { // 如果当前行是表格起始行且不是第一行,且不在表格内,则插入换行符 newLines.Add(""); } inTable = true; } else if (inTable && !Regex.IsMatch(lines[i], @"^\s*\|[-: ]+\|$", RegexOptions.Multiline)) { // 如果在表格内,且当前行不是分隔行,则判断表格结束 inTable = false; } newLines.Add(lines[i]); } return string.Join(Environment.NewLine, newLines); } static string ReadMarkdownFromFile(string filePath) { try { // 读取文件的所有文本内容 return File.ReadAllText(filePath); } catch (Exception ex) { Console.WriteLine($"读取文件时发生错误: {ex.Message}"); return null; } } static string ConvertMarkdownToMediaWiki(string markdown) { var pipeline = new MarkdownPipelineBuilder(); pipeline.Extensions.Add(new PipeTableExtension()); // 手动添加表格扩展 var builtPipeline = pipeline.Build(); var document = Markdown.Parse(markdown, builtPipeline); //var document = Markdown.Parse(markdown, pipeline); var result = new StringBuilder(); ProcessBlock(result, document); return result.ToString(); } static void ProcessBlock(StringBuilder result, MarkdownObject block) { switch (block) { case HeadingBlock heading: result.Append('='.Repeat(heading.Level)); result.Append(' '); ProcessInline(result, heading.Inline); result.Append(' '); result.Append('='.Repeat(heading.Level)); result.AppendLine(); break; case ParagraphBlock paragraph: ProcessInline(result, paragraph.Inline); result.AppendLine(); break; case ListBlock list: foreach (ListItemBlock listItem in list) { result.Append("* "); ProcessBlock(result, listItem); } break; case Table table: result.Append("{| class=\"wikitable\" style=\"text-align: left;\""); result.AppendLine(); bool isFirstRow = true; foreach (TableRow row in table) { if (!isFirstRow) { result.Append("|-"); result.AppendLine(); } isFirstRow = false; for (int i = 0; i < row.Count; i++) { TableCell cell = (TableCell)row[i]; result.Append(row.IsHeader ? "! " : "| "); var cellContent = new StringBuilder(); foreach (var child in cell) { ProcessBlock(cellContent, child); } result.Append(cellContent.ToString().Trim()); if (i < row.Count - 1) { result.AppendLine(); } } result.AppendLine(); } result.Append("|}"); result.AppendLine(); break; case CodeBlock codeBlock: if (codeBlock is FencedCodeBlock fencedCodeBlock) { string language = fencedCodeBlock.Info; result.Append("<syntaxhighlight"); if (!string.IsNullOrEmpty(language)) { result.Append($" lang=\"{language}\""); } result.Append(">"); result.AppendLine(); foreach (var line in fencedCodeBlock.Lines) { result.Append(line.ToString()); result.AppendLine(); } result.Append("</syntaxhighlight>"); result.AppendLine(); } else { result.Append("<pre>"); result.AppendLine(); foreach (var line in codeBlock.Lines) { result.Append(line.ToString()); result.AppendLine(); } result.Append("</pre>"); result.AppendLine(); } break; case ContainerBlock container: foreach (var child in container) { ProcessBlock(result, child); } break; } } static void ProcessInline(StringBuilder result, Inline inline) { if (inline == null) return; switch (inline) { case LiteralInline literal: result.Append(literal.Content.ToString()); break; case EmphasisInline emphasis: string emphasisMark = emphasis.DelimiterCount == 2 ? "'''" : "''"; result.Append(emphasisMark); foreach (var child in emphasis) { ProcessInline(result, child); } result.Append(emphasisMark); break; case CodeInline codeInline: result.Append("<code>"); result.Append(codeInline.Content.ToString()); result.Append("</code>"); break; case ContainerInline container: foreach (var child in container) { ProcessInline(result, child); } break; } } private void btnCopy_Click(object sender, EventArgs e) { // 将 TextBox 的文本复制到剪贴板 Clipboard.SetText(tbxMediawiki.Text); MessageBox.Show("文本已复制到剪贴板!"); } private void btnClean_Click(object sender, EventArgs e) { tbxMarkdown.Text = ""; tbxMediawiki.Text = ""; } } public static class StringExtensions { public static string Repeat(this char c, int count) { return new string(c, count); } } }
浙公网安备 33010602011771号