关注领域建模

追随UML,学会思考

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);
        }
    }
}

 

posted on 2025-03-10 12:42  Beewolf  阅读(65)  评论(0)    收藏  举报

导航