├── .gitignore ├── md2visio ├── obj │ ├── Debug │ │ ├── net8.0 │ │ │ ├── md2visio.csproj.Up2Date │ │ │ ├── md2visio.csproj.BuildWithSkipAnalyzers │ │ │ ├── apphost.exe │ │ │ ├── md2visio.AssemblyInfoInputs.cache │ │ │ ├── md2visio.dll │ │ │ ├── md2visio.genruntimeconfig.cache │ │ │ ├── md2visio.pdb │ │ │ ├── md2visio.csproj.CoreCompileInputs.cache │ │ │ ├── ref │ │ │ │ └── md2visio.dll │ │ │ ├── refint │ │ │ │ └── md2visio.dll │ │ │ ├── md2visio.assets.cache │ │ │ ├── md2visio.csproj.AssemblyReference.cache │ │ │ ├── md2visio.sourcelink.json │ │ │ ├── .NETCoreApp,Version=v8.0.AssemblyAttributes.cs │ │ │ ├── md2visio.GlobalUsings.g.cs │ │ │ ├── md2visio.GeneratedMSBuildEditorConfig.editorconfig │ │ │ ├── md2visio.AssemblyInfo.cs │ │ │ └── md2visio.csproj.FileListAbsolute.txt │ │ └── md2visio.1.0.0.nuspec │ ├── x64 │ │ └── Debug │ │ │ └── net8.0 │ │ │ ├── md2visio.csproj.Up2Date │ │ │ ├── md2visio.csproj.BuildWithSkipAnalyzers │ │ │ ├── apphost.exe │ │ │ ├── md2visio.AssemblyInfoInputs.cache │ │ │ ├── md2visio.genruntimeconfig.cache │ │ │ ├── md2visio.csproj.CoreCompileInputs.cache │ │ │ ├── md2visio.dll │ │ │ ├── md2visio.pdb │ │ │ ├── ref │ │ │ └── md2visio.dll │ │ │ ├── refint │ │ │ └── md2visio.dll │ │ │ ├── md2visio.assets.cache │ │ │ ├── md2visio.csproj.AssemblyReference.cache │ │ │ ├── md2visio.sourcelink.json │ │ │ ├── .NETCoreApp,Version=v8.0.AssemblyAttributes.cs │ │ │ ├── md2visio.GlobalUsings.g.cs │ │ │ ├── md2visio.GeneratedMSBuildEditorConfig.editorconfig │ │ │ ├── md2visio.AssemblyInfo.cs │ │ │ └── md2visio.csproj.FileListAbsolute.txt │ ├── md2visio.csproj.nuget.g.targets │ ├── md2visio.csproj.nuget.g.props │ ├── project.nuget.cache │ └── md2visio.csproj.nuget.dgspec.json ├── md2visio.vssx ├── test │ ├── .space │ │ └── context.mdb │ ├── pie.md │ ├── packet.md │ ├── journey.md │ ├── xy.md │ └── graph.md ├── bin │ ├── Debug │ │ ├── net8.0 │ │ │ ├── OFFICE.DLL │ │ │ ├── stdole.dll │ │ │ ├── md2visio.dll │ │ │ ├── md2visio.exe │ │ │ ├── md2visio.pdb │ │ │ ├── YamlDotNet.dll │ │ │ ├── Microsoft.Vbe.Interop.dll │ │ │ ├── System.Drawing.Common.dll │ │ │ ├── Microsoft.Win32.SystemEvents.dll │ │ │ ├── System.Private.Windows.Core.dll │ │ │ ├── Microsoft.VisualStudio.Interop.dll │ │ │ ├── Interop.Microsoft.Office.Interop.Visio.dll │ │ │ ├── Microsoft.VisualStudio.Imaging.Interop.14.0.DesignTime.dll │ │ │ ├── runtimes │ │ │ │ └── win │ │ │ │ │ └── lib │ │ │ │ │ └── net8.0 │ │ │ │ │ └── Microsoft.Win32.SystemEvents.dll │ │ │ └── md2visio.runtimeconfig.json │ │ └── md2visio.1.0.0.nupkg │ └── x64 │ │ └── Debug │ │ └── net8.0 │ │ ├── OFFICE.DLL │ │ ├── stdole.dll │ │ ├── YamlDotNet.dll │ │ ├── md2visio.dll │ │ ├── md2visio.exe │ │ ├── md2visio.pdb │ │ ├── Microsoft.Vbe.Interop.dll │ │ ├── System.Drawing.Common.dll │ │ ├── System.Private.Windows.Core.dll │ │ ├── Microsoft.VisualStudio.Interop.dll │ │ ├── Microsoft.Win32.SystemEvents.dll │ │ ├── Interop.Microsoft.Office.Interop.Visio.dll │ │ ├── runtimes │ │ └── win │ │ │ └── lib │ │ │ └── net8.0 │ │ │ └── Microsoft.Win32.SystemEvents.dll │ │ ├── Microsoft.VisualStudio.Imaging.Interop.14.0.DesignTime.dll │ │ └── md2visio.runtimeconfig.json ├── default │ ├── class.yaml │ ├── block.yaml │ ├── pie.yaml │ ├── mindmap.yaml │ ├── kanban.yaml │ ├── architecture.yaml │ ├── packet.yaml │ ├── sankey.yaml │ ├── requirement.yaml │ ├── flowchart.yaml │ ├── er.yaml │ ├── gantt.yaml │ ├── gitGraph.yaml │ ├── state.yaml │ ├── default.yaml │ ├── quadrantChart.yaml │ ├── journey.yaml │ ├── timeline.yaml │ ├── sequence.yaml │ └── xyChart.yaml ├── struc │ ├── graph │ │ ├── GBorderNode.cs │ │ ├── GLabel.cs │ │ ├── GSubgraph.cs │ │ └── GEdge.cs │ ├── figure │ │ ├── Edge.cs │ │ ├── IConfig.cs │ │ ├── FigureBuilder.cs │ │ ├── INode.cs │ │ ├── GrowthDirection.cs │ │ ├── Figure.cs │ │ ├── Empty.cs │ │ ├── FigureBuilderFactory.cs │ │ ├── ConfigDefaults.cs │ │ ├── Container.cs │ │ └── Config.cs │ ├── packet │ │ ├── Packet.cs │ │ ├── PacBuilder.cs │ │ └── PacBlock.cs │ ├── pie │ │ ├── Pie.cs │ │ ├── PieDataItem.cs │ │ └── PieBuilder.cs │ ├── journey │ │ ├── Journey.cs │ │ ├── JoTask.cs │ │ ├── JoSection.cs │ │ └── JoBuilder.cs │ └── xy │ │ ├── XyChart.cs │ │ ├── XyAxis.cs │ │ └── XyBuilder.cs ├── vsdx │ ├── @base │ │ ├── VDrawerException.cs │ │ ├── VDrawerAssert.cs │ │ ├── VShapeBoundary.cs │ │ ├── VFigureBuilder.cs │ │ ├── VFigureDrawer.cs │ │ ├── VBuilder.cs │ │ └── VBoundary.cs │ ├── VBuilderPie.cs │ ├── VBuilderG.cs │ ├── VBuilderJo.cs │ ├── VBuilderPac.cs │ └── @tool │ │ ├── VColorGenerator.cs │ │ ├── VHSLColor.cs │ │ ├── FileTool.cs │ │ ├── VRGBColor.cs │ │ └── VColor.cs ├── mermaid │ ├── @cmn │ │ ├── SttEmpty.cs │ │ ├── SttFinishFlag.cs │ │ ├── SttComment.cs │ │ ├── SttKeywordParam.cs │ │ ├── SttPercent.cs │ │ ├── SttWordFlag.cs │ │ ├── SttCtxChar.cs │ │ ├── SttQuoted.cs │ │ ├── SttMermaidStart.cs │ │ ├── CompoValue.cs │ │ ├── SttFrontMatter.cs │ │ ├── SttMermaidClose.cs │ │ ├── SttFigureType.cs │ │ ├── SttIterator.cs │ │ ├── SttIntro.cs │ │ ├── ValueAccessor.cs │ │ ├── SynException.cs │ │ ├── CompoDict.cs │ │ ├── TypeMap.cs │ │ ├── MmdPaired.cs │ │ └── SynState.cs │ ├── journey │ │ ├── JoSttKeywordParam.cs │ │ ├── JoSttWord.cs │ │ ├── JoSttKeyword.cs │ │ ├── JoSttChar.cs │ │ └── JoSttTriple.cs │ ├── graph │ │ ├── internal │ │ │ ├── GSttBackQuote.cs │ │ │ ├── GSttTilde.cs │ │ │ ├── GSttWord.cs │ │ │ ├── GSttEqual.cs │ │ │ ├── GSttWordFlag.cs │ │ │ ├── GSttMinus.cs │ │ │ └── GSttChar.cs │ │ ├── GSttQuoted.cs │ │ ├── GSttAmp.cs │ │ ├── GSttExtendShape.cs │ │ ├── GSttPipedLinkText.cs │ │ ├── GSttText.cs │ │ ├── GSttLinkStart.cs │ │ ├── GSttLinkEnd.cs │ │ ├── GSttKeyword.cs │ │ ├── GSttLinkLabel.cs │ │ ├── GSttNoLabelLink.cs │ │ ├── GSttPaired.cs │ │ └── GSttKeywordParam.cs │ ├── xy │ │ ├── XySttWord.cs │ │ ├── XySttChar.cs │ │ ├── XySttKeyword.cs │ │ └── XySttKeywordParam.cs │ ├── pie │ │ ├── PieSttWord.cs │ │ ├── PieSttKeyword.cs │ │ ├── PieSttChar.cs │ │ ├── PieSttTuple.cs │ │ └── PieSttKeywordParam.cs │ └── packet │ │ ├── PacSttKeyword.cs │ │ ├── PacSttChar.cs │ │ └── PacSttTuple.cs ├── Properties │ └── launchSettings.json ├── md2visio - Backup.csproj ├── md2visio.csproj.user ├── main │ ├── Program.cs │ ├── AppTest.cs │ └── AppConfig.cs └── md2visio.csproj ├── example.png ├── .gitattributes ├── LICENSE ├── md2visio.sln └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | .vs/* 3 | /TODO.md 4 | -------------------------------------------------------------------------------- /md2visio/obj/Debug/net8.0/md2visio.csproj.Up2Date: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /md2visio/obj/x64/Debug/net8.0/md2visio.csproj.Up2Date: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /md2visio/obj/Debug/net8.0/md2visio.csproj.BuildWithSkipAnalyzers: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /md2visio/obj/x64/Debug/net8.0/md2visio.csproj.BuildWithSkipAnalyzers: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Megre/md2visio/HEAD/example.png -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /md2visio/md2visio.vssx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Megre/md2visio/HEAD/md2visio/md2visio.vssx -------------------------------------------------------------------------------- /md2visio/test/.space/context.mdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Megre/md2visio/HEAD/md2visio/test/.space/context.mdb -------------------------------------------------------------------------------- /md2visio/bin/Debug/net8.0/OFFICE.DLL: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Megre/md2visio/HEAD/md2visio/bin/Debug/net8.0/OFFICE.DLL -------------------------------------------------------------------------------- /md2visio/bin/Debug/net8.0/stdole.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Megre/md2visio/HEAD/md2visio/bin/Debug/net8.0/stdole.dll -------------------------------------------------------------------------------- /md2visio/bin/Debug/md2visio.1.0.0.nupkg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Megre/md2visio/HEAD/md2visio/bin/Debug/md2visio.1.0.0.nupkg -------------------------------------------------------------------------------- /md2visio/bin/Debug/net8.0/md2visio.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Megre/md2visio/HEAD/md2visio/bin/Debug/net8.0/md2visio.dll -------------------------------------------------------------------------------- /md2visio/bin/Debug/net8.0/md2visio.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Megre/md2visio/HEAD/md2visio/bin/Debug/net8.0/md2visio.exe -------------------------------------------------------------------------------- /md2visio/bin/Debug/net8.0/md2visio.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Megre/md2visio/HEAD/md2visio/bin/Debug/net8.0/md2visio.pdb -------------------------------------------------------------------------------- /md2visio/obj/Debug/net8.0/apphost.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Megre/md2visio/HEAD/md2visio/obj/Debug/net8.0/apphost.exe -------------------------------------------------------------------------------- /md2visio/obj/Debug/net8.0/md2visio.AssemblyInfoInputs.cache: -------------------------------------------------------------------------------- 1 | 3303f9560aa09d36277f72ea2f50635b6556a53aa2b8a54db58964c1c793a45b 2 | -------------------------------------------------------------------------------- /md2visio/obj/Debug/net8.0/md2visio.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Megre/md2visio/HEAD/md2visio/obj/Debug/net8.0/md2visio.dll -------------------------------------------------------------------------------- /md2visio/obj/Debug/net8.0/md2visio.genruntimeconfig.cache: -------------------------------------------------------------------------------- 1 | 8cd9969f5e45f022b8ba145f14b942cbab9fc3f4ea971bfb39099dcc02351f23 2 | -------------------------------------------------------------------------------- /md2visio/obj/Debug/net8.0/md2visio.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Megre/md2visio/HEAD/md2visio/obj/Debug/net8.0/md2visio.pdb -------------------------------------------------------------------------------- /md2visio/bin/Debug/net8.0/YamlDotNet.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Megre/md2visio/HEAD/md2visio/bin/Debug/net8.0/YamlDotNet.dll -------------------------------------------------------------------------------- /md2visio/bin/x64/Debug/net8.0/OFFICE.DLL: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Megre/md2visio/HEAD/md2visio/bin/x64/Debug/net8.0/OFFICE.DLL -------------------------------------------------------------------------------- /md2visio/bin/x64/Debug/net8.0/stdole.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Megre/md2visio/HEAD/md2visio/bin/x64/Debug/net8.0/stdole.dll -------------------------------------------------------------------------------- /md2visio/obj/x64/Debug/net8.0/apphost.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Megre/md2visio/HEAD/md2visio/obj/x64/Debug/net8.0/apphost.exe -------------------------------------------------------------------------------- /md2visio/obj/x64/Debug/net8.0/md2visio.AssemblyInfoInputs.cache: -------------------------------------------------------------------------------- 1 | 3303f9560aa09d36277f72ea2f50635b6556a53aa2b8a54db58964c1c793a45b 2 | -------------------------------------------------------------------------------- /md2visio/obj/x64/Debug/net8.0/md2visio.genruntimeconfig.cache: -------------------------------------------------------------------------------- 1 | 8cd9969f5e45f022b8ba145f14b942cbab9fc3f4ea971bfb39099dcc02351f23 2 | -------------------------------------------------------------------------------- /md2visio/bin/x64/Debug/net8.0/YamlDotNet.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Megre/md2visio/HEAD/md2visio/bin/x64/Debug/net8.0/YamlDotNet.dll -------------------------------------------------------------------------------- /md2visio/bin/x64/Debug/net8.0/md2visio.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Megre/md2visio/HEAD/md2visio/bin/x64/Debug/net8.0/md2visio.dll -------------------------------------------------------------------------------- /md2visio/bin/x64/Debug/net8.0/md2visio.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Megre/md2visio/HEAD/md2visio/bin/x64/Debug/net8.0/md2visio.exe -------------------------------------------------------------------------------- /md2visio/bin/x64/Debug/net8.0/md2visio.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Megre/md2visio/HEAD/md2visio/bin/x64/Debug/net8.0/md2visio.pdb -------------------------------------------------------------------------------- /md2visio/default/class.yaml: -------------------------------------------------------------------------------- 1 | config: 2 | # mermaid.mermaidAPI.defaultConfig.class 3 | class: 4 | hideEmptyMembersBox: false -------------------------------------------------------------------------------- /md2visio/obj/Debug/net8.0/md2visio.csproj.CoreCompileInputs.cache: -------------------------------------------------------------------------------- 1 | 6db1187423a154c595b947fb46adf65877b8d4312beef413302f53f11a02c3b4 2 | -------------------------------------------------------------------------------- /md2visio/obj/Debug/net8.0/ref/md2visio.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Megre/md2visio/HEAD/md2visio/obj/Debug/net8.0/ref/md2visio.dll -------------------------------------------------------------------------------- /md2visio/obj/x64/Debug/net8.0/md2visio.csproj.CoreCompileInputs.cache: -------------------------------------------------------------------------------- 1 | fe24d07ba4e63b07a7625607a646f2744e86200bb601916f82e19c927706daf5 2 | -------------------------------------------------------------------------------- /md2visio/obj/x64/Debug/net8.0/md2visio.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Megre/md2visio/HEAD/md2visio/obj/x64/Debug/net8.0/md2visio.dll -------------------------------------------------------------------------------- /md2visio/obj/x64/Debug/net8.0/md2visio.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Megre/md2visio/HEAD/md2visio/obj/x64/Debug/net8.0/md2visio.pdb -------------------------------------------------------------------------------- /md2visio/obj/Debug/net8.0/refint/md2visio.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Megre/md2visio/HEAD/md2visio/obj/Debug/net8.0/refint/md2visio.dll -------------------------------------------------------------------------------- /md2visio/obj/x64/Debug/net8.0/ref/md2visio.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Megre/md2visio/HEAD/md2visio/obj/x64/Debug/net8.0/ref/md2visio.dll -------------------------------------------------------------------------------- /md2visio/obj/Debug/net8.0/md2visio.assets.cache: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Megre/md2visio/HEAD/md2visio/obj/Debug/net8.0/md2visio.assets.cache -------------------------------------------------------------------------------- /md2visio/obj/x64/Debug/net8.0/refint/md2visio.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Megre/md2visio/HEAD/md2visio/obj/x64/Debug/net8.0/refint/md2visio.dll -------------------------------------------------------------------------------- /md2visio/bin/Debug/net8.0/Microsoft.Vbe.Interop.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Megre/md2visio/HEAD/md2visio/bin/Debug/net8.0/Microsoft.Vbe.Interop.dll -------------------------------------------------------------------------------- /md2visio/bin/Debug/net8.0/System.Drawing.Common.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Megre/md2visio/HEAD/md2visio/bin/Debug/net8.0/System.Drawing.Common.dll -------------------------------------------------------------------------------- /md2visio/default/block.yaml: -------------------------------------------------------------------------------- 1 | config: 2 | # mermaid.mermaidAPI.defaultConfig.block 3 | block: 4 | useMaxWidth: true 5 | padding: 8 -------------------------------------------------------------------------------- /md2visio/obj/x64/Debug/net8.0/md2visio.assets.cache: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Megre/md2visio/HEAD/md2visio/obj/x64/Debug/net8.0/md2visio.assets.cache -------------------------------------------------------------------------------- /md2visio/bin/x64/Debug/net8.0/Microsoft.Vbe.Interop.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Megre/md2visio/HEAD/md2visio/bin/x64/Debug/net8.0/Microsoft.Vbe.Interop.dll -------------------------------------------------------------------------------- /md2visio/bin/x64/Debug/net8.0/System.Drawing.Common.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Megre/md2visio/HEAD/md2visio/bin/x64/Debug/net8.0/System.Drawing.Common.dll -------------------------------------------------------------------------------- /md2visio/bin/Debug/net8.0/Microsoft.Win32.SystemEvents.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Megre/md2visio/HEAD/md2visio/bin/Debug/net8.0/Microsoft.Win32.SystemEvents.dll -------------------------------------------------------------------------------- /md2visio/bin/Debug/net8.0/System.Private.Windows.Core.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Megre/md2visio/HEAD/md2visio/bin/Debug/net8.0/System.Private.Windows.Core.dll -------------------------------------------------------------------------------- /md2visio/bin/Debug/net8.0/Microsoft.VisualStudio.Interop.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Megre/md2visio/HEAD/md2visio/bin/Debug/net8.0/Microsoft.VisualStudio.Interop.dll -------------------------------------------------------------------------------- /md2visio/bin/x64/Debug/net8.0/System.Private.Windows.Core.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Megre/md2visio/HEAD/md2visio/bin/x64/Debug/net8.0/System.Private.Windows.Core.dll -------------------------------------------------------------------------------- /md2visio/bin/x64/Debug/net8.0/Microsoft.VisualStudio.Interop.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Megre/md2visio/HEAD/md2visio/bin/x64/Debug/net8.0/Microsoft.VisualStudio.Interop.dll -------------------------------------------------------------------------------- /md2visio/bin/x64/Debug/net8.0/Microsoft.Win32.SystemEvents.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Megre/md2visio/HEAD/md2visio/bin/x64/Debug/net8.0/Microsoft.Win32.SystemEvents.dll -------------------------------------------------------------------------------- /md2visio/default/pie.yaml: -------------------------------------------------------------------------------- 1 | config: 2 | # mermaid.mermaidAPI.defaultConfig.pie 3 | pie: 4 | useMaxWidth: true 5 | textPosition: 0.75 6 | useWidth: 984 -------------------------------------------------------------------------------- /md2visio/obj/Debug/net8.0/md2visio.csproj.AssemblyReference.cache: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Megre/md2visio/HEAD/md2visio/obj/Debug/net8.0/md2visio.csproj.AssemblyReference.cache -------------------------------------------------------------------------------- /md2visio/bin/Debug/net8.0/Interop.Microsoft.Office.Interop.Visio.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Megre/md2visio/HEAD/md2visio/bin/Debug/net8.0/Interop.Microsoft.Office.Interop.Visio.dll -------------------------------------------------------------------------------- /md2visio/default/mindmap.yaml: -------------------------------------------------------------------------------- 1 | config: 2 | # mermaid.mermaidAPI.defaultConfig.mindmap 3 | mindmap: 4 | useMaxWidth: true 5 | padding: 10 6 | maxNodeWidth: 200 -------------------------------------------------------------------------------- /md2visio/obj/x64/Debug/net8.0/md2visio.csproj.AssemblyReference.cache: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Megre/md2visio/HEAD/md2visio/obj/x64/Debug/net8.0/md2visio.csproj.AssemblyReference.cache -------------------------------------------------------------------------------- /md2visio/struc/graph/GBorderNode.cs: -------------------------------------------------------------------------------- 1 | namespace md2visio.struc.graph 2 | { 3 | internal class GBorderNode : GNode 4 | { 5 | public GBorderNode() { } 6 | 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /md2visio/bin/x64/Debug/net8.0/Interop.Microsoft.Office.Interop.Visio.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Megre/md2visio/HEAD/md2visio/bin/x64/Debug/net8.0/Interop.Microsoft.Office.Interop.Visio.dll -------------------------------------------------------------------------------- /md2visio/obj/md2visio.csproj.nuget.g.targets: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /md2visio/obj/Debug/net8.0/md2visio.sourcelink.json: -------------------------------------------------------------------------------- 1 | {"documents":{"C:\\Users\\TR\\文档\\GitHub\\md2visio\\*":"https://raw.githubusercontent.com/Megre/md2visio/5f48c97e9cdd2ac78444a3401aa393be779a5f48/*"}} -------------------------------------------------------------------------------- /md2visio/obj/x64/Debug/net8.0/md2visio.sourcelink.json: -------------------------------------------------------------------------------- 1 | {"documents":{"C:\\Users\\TR\\文档\\GitHub\\md2visio\\*":"https://raw.githubusercontent.com/Megre/md2visio/5f48c97e9cdd2ac78444a3401aa393be779a5f48/*"}} -------------------------------------------------------------------------------- /md2visio/bin/Debug/net8.0/Microsoft.VisualStudio.Imaging.Interop.14.0.DesignTime.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Megre/md2visio/HEAD/md2visio/bin/Debug/net8.0/Microsoft.VisualStudio.Imaging.Interop.14.0.DesignTime.dll -------------------------------------------------------------------------------- /md2visio/bin/Debug/net8.0/runtimes/win/lib/net8.0/Microsoft.Win32.SystemEvents.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Megre/md2visio/HEAD/md2visio/bin/Debug/net8.0/runtimes/win/lib/net8.0/Microsoft.Win32.SystemEvents.dll -------------------------------------------------------------------------------- /md2visio/default/kanban.yaml: -------------------------------------------------------------------------------- 1 | config: 2 | # mermaid.mermaidAPI.defaultConfig.kanban 3 | kanban: 4 | useMaxWidth: true 5 | padding: 8 6 | sectionWidth: 200 7 | ticketBaseUrl: '' -------------------------------------------------------------------------------- /md2visio/bin/x64/Debug/net8.0/runtimes/win/lib/net8.0/Microsoft.Win32.SystemEvents.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Megre/md2visio/HEAD/md2visio/bin/x64/Debug/net8.0/runtimes/win/lib/net8.0/Microsoft.Win32.SystemEvents.dll -------------------------------------------------------------------------------- /md2visio/default/architecture.yaml: -------------------------------------------------------------------------------- 1 | config: 2 | # mermaid.mermaidAPI.defaultConfig.architecture 3 | architecture: 4 | useMaxWidth: true 5 | padding: 40 6 | iconSize: 80 7 | fontSize: 16 -------------------------------------------------------------------------------- /md2visio/bin/x64/Debug/net8.0/Microsoft.VisualStudio.Imaging.Interop.14.0.DesignTime.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Megre/md2visio/HEAD/md2visio/bin/x64/Debug/net8.0/Microsoft.VisualStudio.Imaging.Interop.14.0.DesignTime.dll -------------------------------------------------------------------------------- /md2visio/struc/figure/Edge.cs: -------------------------------------------------------------------------------- 1 | namespace md2visio.struc.figure 2 | { 3 | internal interface Edge 4 | { 5 | string LineType { get; set; } 6 | string StartTag { get; set; } 7 | string EndTag { get; set; } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /md2visio/vsdx/@base/VDrawerException.cs: -------------------------------------------------------------------------------- 1 | namespace md2visio.vsdx.@base 2 | { 3 | internal class VDrawerException: Exception 4 | { 5 | public VDrawerException(string message) : base(message) 6 | { 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /md2visio/obj/Debug/net8.0/.NETCoreApp,Version=v8.0.AssemblyAttributes.cs: -------------------------------------------------------------------------------- 1 | // 2 | using System; 3 | using System.Reflection; 4 | [assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETCoreApp,Version=v8.0", FrameworkDisplayName = ".NET 8.0")] 5 | -------------------------------------------------------------------------------- /md2visio/mermaid/@cmn/SttEmpty.cs: -------------------------------------------------------------------------------- 1 | namespace md2visio.mermaid.cmn 2 | { 3 | internal class SttEmpty : SynState 4 | { 5 | public override SynState NextState() 6 | { 7 | throw new NotImplementedException(); 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /md2visio/obj/x64/Debug/net8.0/.NETCoreApp,Version=v8.0.AssemblyAttributes.cs: -------------------------------------------------------------------------------- 1 | // 2 | using System; 3 | using System.Reflection; 4 | [assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETCoreApp,Version=v8.0", FrameworkDisplayName = ".NET 8.0")] 5 | -------------------------------------------------------------------------------- /md2visio/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "profiles": { 3 | "md2visio": { 4 | "commandName": "Project", 5 | "commandLineArgs": "/Y /D /V /I \"$(ProjectDir)\\test\\graph.md\" /O \"$(HOMEPATH)\\Desktop\"", 6 | "workingDirectory": "$(ProjectDir)" 7 | } 8 | } 9 | } -------------------------------------------------------------------------------- /md2visio/default/packet.yaml: -------------------------------------------------------------------------------- 1 | config: 2 | # mermaid.mermaidAPI.defaultConfig.packet 3 | packet: 4 | useMaxWidth: true 5 | rowHeight: 32 6 | bitWidth: 32 7 | bitsPerRow: 32 8 | showBits: true 9 | paddingX: 5 10 | paddingY: 5 -------------------------------------------------------------------------------- /md2visio/struc/figure/IConfig.cs: -------------------------------------------------------------------------------- 1 | namespace md2visio.struc.figure 2 | { 3 | internal interface IConfig 4 | { 5 | bool GetDouble(string keyPath, out double d); 6 | bool GetInt(string keyPath, out int i); 7 | bool GetString(string keyPath, out string val); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /md2visio/default/sankey.yaml: -------------------------------------------------------------------------------- 1 | config: 2 | # mermaid.mermaidAPI.defaultConfig.sankey 3 | sankey: 4 | useMaxWidth: true 5 | width: 600 6 | height: 400 7 | linkColor: gradient 8 | nodeAlignment: justify 9 | showValues: true 10 | prefix: '' 11 | suffix: '' -------------------------------------------------------------------------------- /md2visio/struc/packet/Packet.cs: -------------------------------------------------------------------------------- 1 | using md2visio.struc.figure; 2 | using md2visio.vsdx; 3 | 4 | namespace md2visio.struc.packet 5 | { 6 | internal class Packet : Figure 7 | { 8 | public override void ToVisio(string path) 9 | { 10 | new VBuilderPac(this).Build(path); 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /md2visio/vsdx/@base/VDrawerAssert.cs: -------------------------------------------------------------------------------- 1 | 2 | namespace md2visio.vsdx.@base 3 | { 4 | public static class VDrawerAssert 5 | { 6 | public static void Assert(this T obj, bool assert, string message) where T : class 7 | { 8 | if(!assert) throw new VDrawerException(message); 9 | } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /md2visio/bin/Debug/net8.0/md2visio.runtimeconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "runtimeOptions": { 3 | "tfm": "net8.0", 4 | "framework": { 5 | "name": "Microsoft.NETCore.App", 6 | "version": "8.0.0" 7 | }, 8 | "configProperties": { 9 | "System.Runtime.Serialization.EnableUnsafeBinaryFormatterSerialization": false 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /md2visio/bin/x64/Debug/net8.0/md2visio.runtimeconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "runtimeOptions": { 3 | "tfm": "net8.0", 4 | "framework": { 5 | "name": "Microsoft.NETCore.App", 6 | "version": "8.0.0" 7 | }, 8 | "configProperties": { 9 | "System.Runtime.Serialization.EnableUnsafeBinaryFormatterSerialization": false 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /md2visio/obj/Debug/net8.0/md2visio.GlobalUsings.g.cs: -------------------------------------------------------------------------------- 1 | // 2 | global using global::System; 3 | global using global::System.Collections.Generic; 4 | global using global::System.IO; 5 | global using global::System.Linq; 6 | global using global::System.Net.Http; 7 | global using global::System.Threading; 8 | global using global::System.Threading.Tasks; 9 | -------------------------------------------------------------------------------- /md2visio/md2visio - Backup.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net8.0 6 | enable 7 | enable 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /md2visio/obj/x64/Debug/net8.0/md2visio.GlobalUsings.g.cs: -------------------------------------------------------------------------------- 1 | // 2 | global using global::System; 3 | global using global::System.Collections.Generic; 4 | global using global::System.IO; 5 | global using global::System.Linq; 6 | global using global::System.Net.Http; 7 | global using global::System.Threading; 8 | global using global::System.Threading.Tasks; 9 | -------------------------------------------------------------------------------- /md2visio/mermaid/journey/JoSttKeywordParam.cs: -------------------------------------------------------------------------------- 1 | using md2visio.mermaid.cmn; 2 | 3 | namespace md2visio.mermaid.journey 4 | { 5 | internal class JoSttKeywordParam : SttKeywordParam 6 | { 7 | public override SynState NextState() 8 | { 9 | return Save(ExpectedGroups["param"].Value).Forward(); 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /md2visio/vsdx/VBuilderPie.cs: -------------------------------------------------------------------------------- 1 | using md2visio.struc.pie; 2 | using md2visio.vsdx.@base; 3 | 4 | namespace md2visio.vsdx 5 | { 6 | internal class VBuilderPie(Pie figure) : VFigureBuilder(figure) 7 | { 8 | protected override void ExecuteBuild() 9 | { 10 | new VDrawerPie(figure, VisioApp).Draw(); 11 | } 12 | 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /md2visio/vsdx/VBuilderG.cs: -------------------------------------------------------------------------------- 1 | using md2visio.struc.graph; 2 | using md2visio.vsdx.@base; 3 | 4 | namespace md2visio.vsdx 5 | { 6 | internal class VBuilderG(Graph figure) : VFigureBuilder(figure) 7 | { 8 | override protected void ExecuteBuild() 9 | { 10 | new VDrawerG(figure, VisioApp).Draw(); 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /md2visio/vsdx/VBuilderJo.cs: -------------------------------------------------------------------------------- 1 | using md2visio.struc.journey; 2 | using md2visio.vsdx.@base; 3 | 4 | namespace md2visio.vsdx 5 | { 6 | internal class VBuilderJo(Journey figure) : VFigureBuilder(figure) 7 | { 8 | protected override void ExecuteBuild() 9 | { 10 | new VDrawerJo(figure, VisioApp).Draw(); 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /md2visio/mermaid/@cmn/SttFinishFlag.cs: -------------------------------------------------------------------------------- 1 | using md2visio.mermaid.graph.@internal; 2 | 3 | namespace md2visio.mermaid.cmn 4 | { 5 | internal class SttFinishFlag : SynState 6 | { 7 | public override SynState NextState() 8 | { 9 | // \n or ; 10 | return Save(Take().Buffer).ClearBuffer().Forward(); 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /md2visio/struc/figure/FigureBuilder.cs: -------------------------------------------------------------------------------- 1 | using md2visio.mermaid.cmn; 2 | 3 | namespace md2visio.struc.figure 4 | { 5 | internal abstract class FigureBuilder 6 | { 7 | protected SttIterator iter; 8 | 9 | public FigureBuilder(SttIterator iter) 10 | { 11 | this.iter = iter; 12 | } 13 | 14 | abstract public void Build(string outputFile); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /md2visio/md2visio.csproj.user: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ProjectDebugger 5 | 6 | 7 | md2visio 8 | 9 | -------------------------------------------------------------------------------- /md2visio/default/requirement.yaml: -------------------------------------------------------------------------------- 1 | config: 2 | # mermaid.mermaidAPI.defaultConfig.requirement 3 | requirement: 4 | useMaxWidth: true 5 | rect_fill: '#f9f9f9' 6 | text_color: '#333' 7 | rect_border_size: 0.5px 8 | rect_border_color: '#bbb' 9 | rect_min_width: 200 10 | rect_min_height: 200 11 | fontSize: 14 12 | rect_padding: 10 13 | line_height: 20 -------------------------------------------------------------------------------- /md2visio/default/flowchart.yaml: -------------------------------------------------------------------------------- 1 | config: 2 | flowchart: 3 | useMaxWidth: true 4 | titleTopMargin: 25 5 | subGraphTitleMargin: 6 | top: 0 7 | bottom: 0 8 | diagramPadding: 8 9 | htmlLabels: true 10 | nodeSpacing: 50 11 | rankSpacing: 50 12 | curve: basis 13 | padding: 15 14 | defaultRenderer: dagre-wrapper 15 | wrappingWidth: 200 -------------------------------------------------------------------------------- /md2visio/mermaid/graph/internal/GSttBackQuote.cs: -------------------------------------------------------------------------------- 1 | using md2visio.mermaid.cmn; 2 | 3 | namespace md2visio.mermaid.graph.@internal 4 | { 5 | internal class GSttBackQuote : SynState 6 | { 7 | public override SynState NextState() 8 | { 9 | if (SttMermaidClose.IsMermaidClose(Ctx)) return Forward(); 10 | 11 | return Take().Forward(); 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /md2visio/mermaid/graph/internal/GSttTilde.cs: -------------------------------------------------------------------------------- 1 | using md2visio.mermaid.cmn; 2 | 3 | namespace md2visio.mermaid.graph.@internal 4 | { 5 | internal class GSttTilde : SynState 6 | { 7 | public override SynState NextState() 8 | { 9 | if (GSttNoLabelLink.IsEmptyLink(Ctx)) return Forward(); 10 | 11 | throw new SynException("unexpected '~'", Ctx); 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /md2visio/default/er.yaml: -------------------------------------------------------------------------------- 1 | config: 2 | # mermaid.mermaidAPI.defaultConfig.er 3 | er: 4 | useMaxWidth: true 5 | titleTopMargin: 25 6 | diagramPadding: 20 7 | layoutDirection: TB 8 | minEntityWidth: 100 9 | minEntityHeight: 75 10 | entityPadding: 15 11 | nodeSpacing: 140 12 | rankSpacing: 80 13 | stroke: gray 14 | fill: honeydew 15 | fontSize: 12 -------------------------------------------------------------------------------- /md2visio/mermaid/@cmn/SttComment.cs: -------------------------------------------------------------------------------- 1 | using md2visio.mermaid.graph; 2 | 3 | namespace md2visio.mermaid.cmn 4 | { 5 | internal class SttComment : SynState 6 | { 7 | public override SynState NextState() 8 | { 9 | if (Expect(@"(?s)(?%%[^\n]+?(%%)?(?=\n))")) 10 | return Save(ExpectedGroup("cmnt")).Forward(); 11 | 12 | return Take(2).Forward(); 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /md2visio/struc/figure/INode.cs: -------------------------------------------------------------------------------- 1 | using md2visio.struc.graph; 2 | using Microsoft.Office.Interop.Visio; 3 | 4 | namespace md2visio.struc.figure 5 | { 6 | internal interface INode 7 | { 8 | string ID { get; set; } 9 | string Label { get; set; } 10 | Shape? VisioShape { get; set; } 11 | Container Container { get; set; } 12 | List InputEdges { get; } 13 | List OutputEdges { get; } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /md2visio/test/pie.md: -------------------------------------------------------------------------------- 1 | ```mermaid 2 | --- 3 | config: 4 | theme: 'dark' 5 | themeVariables: 6 | pieOuterStrokeWidth: "1px" 7 | --- 8 | %%{init: {"pie": {"textPosition": 0.8}, "themeVariables": {"pieOuterStrokeWidth": "5px"}} }%% 9 | pie showData title Pets adopted by volunteers 10 | %% pie: test 11 | title Key elements in Product X 12 | "Calcium:" : 42.96 13 | "Potassium" : 50.05 14 | "Magnesium" : 10.01 15 | "Iron" : 5 16 | ``` 17 | 18 | -------------------------------------------------------------------------------- /md2visio/mermaid/xy/XySttWord.cs: -------------------------------------------------------------------------------- 1 | using md2visio.mermaid.cmn; 2 | 3 | namespace md2visio.mermaid.xy 4 | { 5 | internal class XySttWord : SynState 6 | { 7 | public override SynState NextState() 8 | { 9 | if (string.IsNullOrEmpty(Buffer)) return SlideSpaces().Forward(); 10 | 11 | if (XySttKeyword.IsKeyword(Ctx)) return Forward(); 12 | return Take().Forward(); 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /md2visio/mermaid/@cmn/SttKeywordParam.cs: -------------------------------------------------------------------------------- 1 | using md2visio.mermaid.cmn; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace md2visio.mermaid.cmn 9 | { 10 | internal abstract class SttKeywordParam: SynState 11 | { 12 | public static bool HasParam(SynContext ctx) 13 | { 14 | return ctx.Expect(@"[^\S\n]*(?\S.+?)\s*(?=\n)"); 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /md2visio/mermaid/journey/JoSttWord.cs: -------------------------------------------------------------------------------- 1 | using md2visio.mermaid.cmn; 2 | 3 | namespace md2visio.mermaid.journey 4 | { 5 | internal class JoSttWord : SynState 6 | { 7 | public override SynState NextState() 8 | { 9 | if (string.IsNullOrEmpty(Buffer)) return SlideSpaces().Forward(); 10 | 11 | if(JoSttKeyword.IsKeyword(Ctx)) return Forward(); 12 | return Take().Forward(); 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /md2visio/mermaid/pie/PieSttWord.cs: -------------------------------------------------------------------------------- 1 | using md2visio.mermaid.cmn; 2 | 3 | namespace md2visio.mermaid.pie 4 | { 5 | internal class PieSttWord : SynState 6 | { 7 | public override SynState NextState() 8 | { 9 | if (string.IsNullOrEmpty(Buffer)) return SlideSpaces().Forward(); 10 | 11 | if (PieSttKeyword.IsKeyword(Ctx)) return Forward(); 12 | return Take().Forward (); 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /md2visio/mermaid/@cmn/SttPercent.cs: -------------------------------------------------------------------------------- 1 | using md2visio.mermaid.graph.@internal; 2 | 3 | namespace md2visio.mermaid.cmn 4 | { 5 | internal class SttPercent : SynState 6 | { 7 | public override SynState NextState() 8 | { 9 | if (string.IsNullOrWhiteSpace(Buffer)) 10 | { 11 | if (Expect("%%")) return Restore(2).Forward(); 12 | } 13 | 14 | return Take().Forward(); 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /md2visio/mermaid/@cmn/SttWordFlag.cs: -------------------------------------------------------------------------------- 1 | using md2visio.mermaid.graph; 2 | using md2visio.mermaid.graph.@internal; 3 | 4 | namespace md2visio.mermaid.cmn 5 | { 6 | internal class SttWordFlag : SynState 7 | { 8 | public override SynState NextState() 9 | { 10 | if (!string.IsNullOrWhiteSpace(Buffer)) return Forward(); 11 | if(Peek() == "\n") return Forward(); 12 | 13 | return SlideSpaces().Forward(); 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /md2visio/test/packet.md: -------------------------------------------------------------------------------- 1 | ```mermaid 2 | --- 3 | title: "TCP 数据包" 4 | config: 5 | theme: 'forest' 6 | --- 7 | packet-beta 8 | 192-252: "数据 (可变长度)" 9 | 0-15: "源端口" 10 | 16-31: "目的端口" 11 | 32-63: "序列号" 12 | 64-95: "确认号" 13 | 96-99: "数据偏移" 14 | 100-105: "保留" 15 | 106: "URG" 16 | 107: "ACK" 17 | 108: "PSH" 18 | 109: "RST" 19 | 110: "SYN" 20 | 111: "FIN" 21 | 112-127: "窗口" 22 | 128-143: "校验和" 23 | 144-159: "紧急指针" 24 | 160-191: "(选项和填充)" 25 | 253-289: "test" 26 | ``` -------------------------------------------------------------------------------- /md2visio/default/gantt.yaml: -------------------------------------------------------------------------------- 1 | config: 2 | # mermaid.mermaidAPI.defaultConfig.gantt 3 | gantt: 4 | useMaxWidth: true 5 | titleTopMargin: 25 6 | barHeight: 20 7 | barGap: 4 8 | topPadding: 50 9 | rightPadding: 75 10 | leftPadding: 75 11 | gridLineStartPadding: 35 12 | fontSize: 11 13 | sectionFontSize: 11 14 | numberSectionStyles: 4 15 | axisFormat: '%Y-%m-%d' 16 | topAxis: false 17 | displayMode: '' 18 | weekday: sunday -------------------------------------------------------------------------------- /md2visio/default/gitGraph.yaml: -------------------------------------------------------------------------------- 1 | config: 2 | # mermaid.mermaidAPI.defaultConfig.gitGraph 3 | gitGraph: 4 | useMaxWidth: true 5 | titleTopMargin: 25 6 | diagramPadding: 8 7 | nodeLabel: 8 | width: 75 9 | height: 100 10 | x: -25 11 | 'y': 0 12 | mainBranchName: main 13 | mainBranchOrder: 0 14 | showCommitLabel: true 15 | showBranches: true 16 | rotateCommitLabel: true 17 | parallelCommits: false 18 | arrowMarkerAbsolute: false -------------------------------------------------------------------------------- /md2visio/mermaid/@cmn/SttCtxChar.cs: -------------------------------------------------------------------------------- 1 | using md2visio.mermaid.graph.@internal; 2 | using md2visio.mermaid.pie; 3 | 4 | namespace md2visio.mermaid.cmn 5 | { 6 | internal class SttCtxChar : SynState 7 | { 8 | Dictionary typeMap = TypeMap.CharMap; 9 | 10 | public override SynState NextState() 11 | { 12 | (bool success, string graph) = Ctx.FindContainerFrag(SttFigureType.Supported); 13 | if (success) return Forward(typeMap[graph]); 14 | else return Forward(); 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /md2visio/mermaid/packet/PacSttKeyword.cs: -------------------------------------------------------------------------------- 1 | using md2visio.mermaid.cmn; 2 | using System.Text.RegularExpressions; 3 | 4 | namespace md2visio.mermaid.packet 5 | { 6 | internal class PacSttKeyword : SynState 7 | { 8 | public override SynState NextState() 9 | { 10 | Save(Buffer).ClearBuffer(); 11 | return Forward(); 12 | } 13 | 14 | public static bool IsKeyword(SynContext ctx) 15 | { 16 | return Regex.IsMatch(ctx.Cache.ToString(), "^(packet-data|packet)$"); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /md2visio/default/state.yaml: -------------------------------------------------------------------------------- 1 | config: 2 | # mermaid.mermaidAPI.defaultConfig.state 3 | state: 4 | useMaxWidth: true 5 | titleTopMargin: 25 6 | dividerMargin: 10 7 | sizeUnit: 5 8 | padding: 8 9 | textHeight: 10 10 | titleShift: -15 11 | noteMargin: 10 12 | forkWidth: 70 13 | forkHeight: 7 14 | miniPadding: 2 15 | fontSizeFactor: 5.02 16 | fontSize: 24 17 | labelHeight: 16 18 | edgeLengthFactor: '20' 19 | compositTitleSize: 35 20 | radius: 5 21 | defaultRenderer: dagre-wrapper -------------------------------------------------------------------------------- /md2visio/mermaid/graph/internal/GSttWord.cs: -------------------------------------------------------------------------------- 1 | using md2visio.mermaid.cmn; 2 | using md2visio.mermaid.graph; 3 | using System.Text.RegularExpressions; 4 | 5 | namespace md2visio.mermaid.graph.@internal 6 | { 7 | internal class GSttWord : SynState 8 | { 9 | public override SynState NextState() 10 | { 11 | // keyword or text 12 | if (string.IsNullOrWhiteSpace(Buffer)) throw new SynException("syntax error", Ctx); 13 | 14 | if (GSttKeyword.IsKeyword(Buffer)) return Forward(); 15 | else return Forward(); 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /md2visio/vsdx/@base/VShapeBoundary.cs: -------------------------------------------------------------------------------- 1 | using md2visio.struc.figure; 2 | using Microsoft.Office.Interop.Visio; 3 | 4 | namespace md2visio.vsdx.@base 5 | { 6 | internal class VShapeBoundary : VBoundary 7 | { 8 | Shape? shape; 9 | 10 | public Shape? Shape { get => shape; } 11 | 12 | public VShapeBoundary() { } 13 | 14 | public VShapeBoundary(Shape shape) : base(VShapeDrawer.PinX(shape), 15 | VShapeDrawer.PinY(shape), 16 | VShapeDrawer.Width(shape), 17 | VShapeDrawer.Height(shape)) 18 | { 19 | this.shape = shape; 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /md2visio/vsdx/@base/VFigureBuilder.cs: -------------------------------------------------------------------------------- 1 | using md2visio.struc.figure; 2 | 3 | namespace md2visio.vsdx.@base 4 | { 5 | internal abstract class VFigureBuilder : 6 | VBuilder where T : Figure 7 | { 8 | protected T figure; 9 | 10 | public VFigureBuilder(T figure) 11 | { 12 | this.figure = figure; 13 | } 14 | 15 | public void Build(string outputFile) 16 | { 17 | ExecuteBuild(); 18 | 19 | Console.WriteLine($"Output: {outputFile}"); 20 | SaveAndClose(outputFile); 21 | } 22 | 23 | protected abstract void ExecuteBuild(); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /md2visio/mermaid/journey/JoSttKeyword.cs: -------------------------------------------------------------------------------- 1 | using md2visio.mermaid.cmn; 2 | using System.Text.RegularExpressions; 3 | 4 | namespace md2visio.mermaid.journey 5 | { 6 | internal class JoSttKeyword : SynState 7 | { 8 | public override SynState NextState() 9 | { 10 | Save(Buffer).ClearBuffer(); 11 | if (JoSttKeywordParam.HasParam(Ctx)) return Forward(); 12 | else return Forward(); 13 | } 14 | 15 | public static bool IsKeyword(SynContext ctx) 16 | { 17 | return Regex.IsMatch(ctx.Cache.ToString(), "^(journey|title|section)$"); 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /md2visio/mermaid/packet/PacSttChar.cs: -------------------------------------------------------------------------------- 1 | using md2visio.mermaid.cmn; 2 | 3 | namespace md2visio.mermaid.packet 4 | { 5 | internal class PaSttChar : SynState 6 | { 7 | public override SynState NextState() 8 | { 9 | string? next = Ctx.Peek(); 10 | if (next == null) return EndOfFile; 11 | 12 | if (next == "%") return Forward(); 13 | if (next == ":") return Forward(); 14 | if (next == "\n") return Forward(); 15 | if (next == "`") return Forward(); 16 | 17 | return Take().Forward(); 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /md2visio/mermaid/@cmn/SttQuoted.cs: -------------------------------------------------------------------------------- 1 | using System.Text; 2 | 3 | namespace md2visio.mermaid.cmn 4 | { 5 | internal abstract class SttQuoted : SynState 6 | { 7 | public static bool TestQuoted(SynContext ctx) 8 | { 9 | return ctx.Test(@"^(?s)""(?[^""]*)"""); 10 | } 11 | 12 | public static string TrimQuote(string quoted) 13 | { 14 | StringBuilder sb = new StringBuilder(quoted.Trim()); 15 | if (sb[0] == '"') sb.Remove(0, 1); 16 | if (sb.Length > 0 && sb[sb.Length - 1] == '"') sb.Remove(sb.Length - 1, 1); 17 | 18 | return sb.ToString(); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /md2visio/default/default.yaml: -------------------------------------------------------------------------------- 1 | config: 2 | # mermaid.mermaidAPI.defaultConfig 3 | theme: default 4 | look: classic 5 | handDrawnSeed: 0 6 | layout: dagre 7 | maxTextSize: 50000 8 | maxEdges: 500 9 | logLevel: 5 10 | securityLevel: strict 11 | startOnLoad: true 12 | arrowMarkerAbsolute: false 13 | secure: 14 | - secure 15 | - securityLevel 16 | - startOnLoad 17 | - maxTextSize 18 | - suppressErrorRendering 19 | - maxEdges 20 | legacyMathML: false 21 | forceLegacyMathML: false 22 | deterministicIds: false 23 | 24 | markdownAutoWrap: true 25 | suppressErrorRendering: false 26 | elk: 27 | mergeEdges: false 28 | nodePlacementStrategy: BRANDES_KOEPF -------------------------------------------------------------------------------- /md2visio/struc/pie/Pie.cs: -------------------------------------------------------------------------------- 1 | using md2visio.struc.figure; 2 | using md2visio.vsdx; 3 | 4 | namespace md2visio.struc.pie 5 | { 6 | internal class Pie : Figure 7 | { 8 | public bool ShowData { get; set; } = false; 9 | 10 | public Pie() { 11 | } 12 | 13 | public double TotalNum() 14 | { 15 | double total = 0; 16 | foreach (INode item in InnerNodes.Values) 17 | { 18 | total += ((PieDataItem)item).Data; 19 | } 20 | return total; 21 | } 22 | 23 | public override void ToVisio(string path) 24 | { 25 | new VBuilderPie(this).Build(path); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /md2visio/mermaid/@cmn/SttMermaidStart.cs: -------------------------------------------------------------------------------- 1 | namespace md2visio.mermaid.cmn 2 | { 3 | internal class SttMermaidStart : SynState 4 | { 5 | public override SynState NextState() 6 | { 7 | return Run(Ctx); 8 | } 9 | 10 | public static SynState Run(SynContext ctx) 11 | { 12 | if (!ctx.Until(@"^\s*(?`{3,})\s*mermaid\s*(?=\n)")) 13 | return EndOfFile; 14 | 15 | SynState state = new SttMermaidStart(); 16 | state.Ctx = ctx; 17 | state.Fragment = ctx.ExpectedGroups["bquote"].Value; 18 | ctx.AddState(state); 19 | 20 | return state.Forward(); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /md2visio/struc/pie/PieDataItem.cs: -------------------------------------------------------------------------------- 1 | using md2visio.struc.figure; 2 | using md2visio.struc.graph; 3 | using Microsoft.Office.Interop.Visio; 4 | 5 | namespace md2visio.struc.pie 6 | { 7 | internal class PieDataItem : INode 8 | { 9 | public string ID { get; set; } = string.Empty; 10 | public string Label { get => ID; set => ID = value; } 11 | public Shape? VisioShape { get; set; } 12 | public Container Container { get; set; } = Empty.Get(); 13 | public double Data { get; set; } 14 | 15 | public List InputEdges => throw new NotImplementedException(); 16 | 17 | public List OutputEdges => throw new NotImplementedException(); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /md2visio/mermaid/xy/XySttChar.cs: -------------------------------------------------------------------------------- 1 | using md2visio.mermaid.cmn; 2 | 3 | namespace md2visio.mermaid.xy 4 | { 5 | internal class XySttChar : SynState 6 | { 7 | public override SynState NextState() 8 | { 9 | string? next = Ctx.Peek(); 10 | if (next == null) return EndOfFile; 11 | 12 | if (next == "%") return Forward(); 13 | if (next == " ") return Forward(); 14 | if (next == "\t") return Forward(); 15 | if (next == "\n") return Forward(); 16 | if (next == "`") return Forward(); 17 | 18 | return Take().Forward(); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /md2visio/test/journey.md: -------------------------------------------------------------------------------- 1 | ## Journey 2 | 3 | `````mermaid 4 | --- 5 | config: 6 | theme: "base" 7 | --- 8 | journey 9 | %% journey : test 10 | title My working day 11 | section Go to work 1 12 | Make tea: 5: Me 13 | Go upstairs: 3: Me 14 | Do work: 1: Me, Cat 15 | section Go home 2 16 | Go downstairs: 5: Me 17 | Sit down: 5: Me 18 | section Go home 3 19 | Make tea: 3: Me 20 | section Go home 4 21 | Make tea: 3: Me 22 | section Go home 5 23 | Make tea: 3: Me 24 | section Go home 6 25 | Make tea: 3: Me 26 | section Go home 7 27 | Make tea: 3: Me 28 | section Go home 8 29 | Make tea: 3: Me 30 | section Go home 9 31 | Make tea: 3: Me 32 | ````` 33 | -------------------------------------------------------------------------------- /md2visio/default/quadrantChart.yaml: -------------------------------------------------------------------------------- 1 | config: 2 | # mermaid.mermaidAPI.defaultConfig.quadrantChart 3 | quadrantChart: 4 | useMaxWidth: true 5 | chartWidth: 500 6 | chartHeight: 500 7 | titleFontSize: 20 8 | titlePadding: 10 9 | quadrantPadding: 5 10 | xAxisLabelPadding: 5 11 | yAxisLabelPadding: 5 12 | xAxisLabelFontSize: 16 13 | yAxisLabelFontSize: 16 14 | quadrantLabelFontSize: 16 15 | quadrantTextTopPadding: 5 16 | pointTextPadding: 5 17 | pointLabelFontSize: 12 18 | pointRadius: 5 19 | xAxisPosition: top 20 | yAxisPosition: left 21 | quadrantInternalBorderStrokeWidth: 1 22 | quadrantExternalBorderStrokeWidth: 2 -------------------------------------------------------------------------------- /md2visio/struc/journey/Journey.cs: -------------------------------------------------------------------------------- 1 | using md2visio.struc.figure; 2 | using md2visio.vsdx; 3 | 4 | namespace md2visio.struc.journey 5 | { 6 | internal class Journey : Figure 7 | { 8 | public Journey() { } 9 | 10 | public HashSet JoinerSet() 11 | { 12 | HashSet set = new HashSet(); 13 | foreach (INode section in innerNodes.Values) 14 | { 15 | foreach (string joiner in ((JoSection)section).JoinerSet()) 16 | set.Add(joiner); 17 | } 18 | return set; 19 | } 20 | 21 | public override void ToVisio(string path) 22 | { 23 | new VBuilderJo(this).Build(path); 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /md2visio/mermaid/@cmn/CompoValue.cs: -------------------------------------------------------------------------------- 1 | namespace md2visio.mermaid.cmn 2 | { 3 | internal class CompoValue 4 | { 5 | string key = string.Empty; 6 | string value = string.Empty; 7 | public string Key { get { return key; } set { key = value; } } 8 | public string Value { get { return value; } set { this.value = value; } } 9 | 10 | public CompoValue(string key, string value) 11 | { 12 | this.key = key; 13 | this.value = value; 14 | } 15 | 16 | public bool IsQuoted() { return key == "\""; } 17 | public bool IsPaired() { return key == "["; } 18 | public bool IsText() { return key == "T"; } 19 | public bool IsList() { return key == ","; } 20 | 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /md2visio/main/Program.cs: -------------------------------------------------------------------------------- 1 | // See https://aka.ms/new-console-template for more information 2 | 3 | using md2visio.main; 4 | using md2visio.mermaid.cmn; 5 | using md2visio.struc.figure; 6 | 7 | AppConfig config = AppConfig.Instance; 8 | if (!config.ParseArgs(args)) return; 9 | if (config.Test) { new AppTest().Test(); return; } 10 | 11 | try 12 | { 13 | SynContext synContext = new(config.InputFile); 14 | SttMermaidStart.Run(synContext); 15 | if(config.Debug) Console.Write(synContext.ToString()); 16 | 17 | FigureBuilderFactory factory = new(synContext.NewSttIterator()); 18 | factory.Build(config.OutputPath); 19 | factory.Quit(); 20 | } 21 | catch(Exception ex) 22 | { 23 | if (config.Debug) throw; 24 | else Console.Error.WriteLine(ex.Message); 25 | } 26 | -------------------------------------------------------------------------------- /md2visio/mermaid/graph/GSttQuoted.cs: -------------------------------------------------------------------------------- 1 | using md2visio.mermaid.cmn; 2 | using md2visio.mermaid.graph.@internal; 3 | 4 | namespace md2visio.mermaid.graph 5 | { 6 | internal class GSttQuoted : SttQuoted 7 | { 8 | 9 | public override SynState NextState() 10 | { 11 | // e.g. "..." 12 | string? pre = Peek(-1), next = Peek(1); 13 | if (Buffer.Length > 0 && !string.IsNullOrWhiteSpace(Buffer.Last().ToString())) // e.g. D" 14 | return Take().Forward(); 15 | 16 | if (Expect(@"(?s)""(?[^""]*)""")) 17 | return ClearBuffer().Save(ExpectedGroup("quote")).Forward(); 18 | 19 | throw new SynException("syntax error", Ctx); 20 | } 21 | 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /md2visio/obj/Debug/net8.0/md2visio.GeneratedMSBuildEditorConfig.editorconfig: -------------------------------------------------------------------------------- 1 | is_global = true 2 | build_property.TargetFramework = net8.0 3 | build_property.TargetPlatformMinVersion = 4 | build_property.UsingMicrosoftNETSdkWeb = 5 | build_property.ProjectTypeGuids = 6 | build_property.InvariantGlobalization = 7 | build_property.PlatformNeutralAssembly = 8 | build_property.EnforceExtendedAnalyzerRules = 9 | build_property._SupportedPlatformList = Linux,macOS,Windows 10 | build_property.RootNamespace = md2visio 11 | build_property.ProjectDir = C:\Users\TR\文档\GitHub\md2visio\md2visio\ 12 | build_property.EnableComHosting = 13 | build_property.EnableGeneratedComInterfaceComImportInterop = 14 | build_property.EffectiveAnalysisLevelStyle = 8.0 15 | build_property.EnableCodeStyleSeverity = 16 | -------------------------------------------------------------------------------- /md2visio/mermaid/xy/XySttKeyword.cs: -------------------------------------------------------------------------------- 1 | using md2visio.mermaid.cmn; 2 | using System.Text.RegularExpressions; 3 | 4 | namespace md2visio.mermaid.xy 5 | { 6 | internal class XySttKeyword : SynState 7 | { 8 | public override SynState NextState() 9 | { 10 | if (!IsKeyword(Ctx)) throw new SynException($"unknown keyword '{Buffer}'", Ctx); 11 | 12 | Save(Buffer).ClearBuffer(); 13 | if (XySttKeywordParam.HasParam(Ctx)) return Forward(); 14 | else return Forward(); 15 | } 16 | 17 | public static bool IsKeyword(SynContext ctx) 18 | { 19 | return Regex.IsMatch(ctx.Cache.ToString(), "^(xychart-beta|xychart|title|x-axis|y-axis|line|bar)$"); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /md2visio/obj/x64/Debug/net8.0/md2visio.GeneratedMSBuildEditorConfig.editorconfig: -------------------------------------------------------------------------------- 1 | is_global = true 2 | build_property.TargetFramework = net8.0 3 | build_property.TargetPlatformMinVersion = 4 | build_property.UsingMicrosoftNETSdkWeb = 5 | build_property.ProjectTypeGuids = 6 | build_property.InvariantGlobalization = 7 | build_property.PlatformNeutralAssembly = 8 | build_property.EnforceExtendedAnalyzerRules = 9 | build_property._SupportedPlatformList = Linux,macOS,Windows 10 | build_property.RootNamespace = md2visio 11 | build_property.ProjectDir = C:\Users\TR\文档\GitHub\md2visio\md2visio\ 12 | build_property.EnableComHosting = 13 | build_property.EnableGeneratedComInterfaceComImportInterop = 14 | build_property.EffectiveAnalysisLevelStyle = 8.0 15 | build_property.EnableCodeStyleSeverity = 16 | -------------------------------------------------------------------------------- /md2visio/mermaid/@cmn/SttFrontMatter.cs: -------------------------------------------------------------------------------- 1 | namespace md2visio.mermaid.cmn 2 | { 3 | /** 4 | * --- 5 | * title: This is title 6 | * config: 7 | * ... 8 | * --- 9 | */ 10 | internal class SttFrontMatter : SynState 11 | { 12 | public override SynState NextState() 13 | { 14 | if (!IsConfig(Ctx)) return Take().Forward(); 15 | if (!Until(@"(?s)---\s*(?.*?)\n\s*---\s*(?=\n)")) throw new SynException("expected '---'", Ctx); 16 | 17 | Save(ExpectedGroup("cfg")); 18 | return ClearBuffer().Forward(); 19 | } 20 | 21 | public static bool IsConfig(SynContext ctx) 22 | { 23 | return ctx.Test(@"^(?---\s*\n)"); 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /md2visio/mermaid/pie/PieSttKeyword.cs: -------------------------------------------------------------------------------- 1 | using md2visio.mermaid.cmn; 2 | using md2visio.mermaid.journey; 3 | using System.Text.RegularExpressions; 4 | 5 | namespace md2visio.mermaid.pie 6 | { 7 | internal class PieSttKeyword : SynState 8 | { 9 | public override SynState NextState() 10 | { 11 | if (!IsKeyword(Ctx)) throw new SynException($"unknown keyword '{Buffer}'", Ctx); 12 | 13 | Save(Buffer).ClearBuffer(); 14 | if (PieSttKeywordParam.HasParam(Ctx)) return Forward(); 15 | else return Forward(); 16 | } 17 | 18 | public static bool IsKeyword(SynContext ctx) 19 | { 20 | return Regex.IsMatch(ctx.Cache.ToString(), "^(pie|title)$"); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /md2visio/mermaid/pie/PieSttChar.cs: -------------------------------------------------------------------------------- 1 | using md2visio.mermaid.cmn; 2 | 3 | namespace md2visio.mermaid.pie 4 | { 5 | internal class PieSttChar : SynState 6 | { 7 | public override SynState NextState() 8 | { 9 | string? next = Ctx.Peek(); 10 | if (next == null) return EndOfFile; 11 | 12 | if (next == "%") return Forward(); 13 | if (next == ":") return Forward(); 14 | if (next == " ") return Forward(); 15 | if (next == "\t") return Forward(); 16 | if (next == "\n") return Forward(); 17 | if (next == "`") return Forward(); 18 | 19 | return Take().Forward(); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /md2visio/struc/journey/JoTask.cs: -------------------------------------------------------------------------------- 1 | namespace md2visio.struc.journey 2 | { 3 | internal class JoTask 4 | { 5 | string name; 6 | int score = 5; 7 | HashSet joiners = new HashSet(); 8 | 9 | public JoSection? Section { get; set; } = null; 10 | public string Name { get => name; } 11 | public int Score { get => score; } 12 | public HashSet Joiners { get => joiners; } 13 | 14 | public JoTask(string name, string score, string partners) 15 | { 16 | this.name = name; 17 | if (int.TryParse(score, out int number)) this.score = number; 18 | 19 | foreach (string joiner in partners.Split(",")) 20 | { 21 | joiners.Add(joiner); 22 | } 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /md2visio/mermaid/graph/GSttAmp.cs: -------------------------------------------------------------------------------- 1 | using md2visio.mermaid.cmn; 2 | using md2visio.mermaid.graph.@internal; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | 9 | namespace md2visio.mermaid.graph 10 | { 11 | internal class GSttAmp : SynState 12 | { 13 | public override SynState NextState() 14 | { 15 | string? pre = Peek(-1), next2 = Peek(2); 16 | if (!string.IsNullOrWhiteSpace(pre)) return Take().Forward(); 17 | if ("&" != next2?.Trim()) return Take().Forward(); 18 | 19 | if (Ctx.LastNonFinishState() is not GSttText) throw new SynException("syntax error", Ctx); 20 | 21 | return Save("&").Slide(2).Forward(); 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /md2visio/mermaid/graph/GSttExtendShape.cs: -------------------------------------------------------------------------------- 1 | using md2visio.mermaid.cmn; 2 | using md2visio.mermaid.graph.@internal; 3 | using System.Text.RegularExpressions; 4 | 5 | namespace md2visio.mermaid.graph 6 | { 7 | internal class GSttExtendShape : SynState 8 | { 9 | public override SynState NextState() 10 | { 11 | string? pre = Peek(-1); 12 | if (string.IsNullOrWhiteSpace(pre)) throw new SynException("syntax error", Ctx); 13 | if (!Expect(@"@\{")) throw new SynException("expected @{...}", Ctx); 14 | 15 | Restore(); 16 | if (!GSttPaired.IsPaired("{", Ctx)) throw new SynException("expected @{...}", Ctx); 17 | 18 | Group pair = Ctx.TestGroups[0]; 19 | return Save(pair.Value).Slide(pair.Length).Forward(); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /md2visio/mermaid/journey/JoSttChar.cs: -------------------------------------------------------------------------------- 1 | using md2visio.mermaid.cmn; 2 | 3 | namespace md2visio.mermaid.journey 4 | { 5 | internal class JoSttChar : SynState 6 | { 7 | public override SynState NextState() 8 | { 9 | string? next = Ctx.Peek(); 10 | if (next == null) return EndOfFile; 11 | 12 | if (next == "%") return Forward(); 13 | if (next == ":") return Restore(Buffer.Length).Forward(); 14 | if (next == " ") return Forward(); 15 | if (next == "\t") return Forward(); 16 | if (next == "\n") return Forward(); 17 | if (next == "`") return Forward(); 18 | 19 | return Take().Forward(); 20 | } 21 | 22 | 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /md2visio/mermaid/packet/PacSttTuple.cs: -------------------------------------------------------------------------------- 1 | using md2visio.mermaid.cmn; 2 | using System.Text; 3 | 4 | namespace md2visio.mermaid.packet 5 | { 6 | internal class PacSttTuple : SynState 7 | { 8 | public override SynState NextState() 9 | { 10 | if (Buffer.Length > 0) Restore(Buffer.Length).ClearBuffer(); 11 | if (!IsTupleLine(Ctx)) throw new SynException("expected a tuple"); 12 | 13 | AddCompo("bits", ExpectedGroups["bits"].Value); 14 | AddCompo("name", ExpectedGroups["name"].Value); 15 | 16 | return ClearBuffer().Save(ExpectedGroups[0].Value.Trim()).Forward(); 17 | } 18 | 19 | public static bool IsTupleLine(SynContext ctx) 20 | { 21 | return ctx.Expect(@"^\s*(?\d+(\s*-\s*\d+)?)\s*:\s*""(?.+)""\s*(?=\n)"); 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /md2visio/struc/xy/XyChart.cs: -------------------------------------------------------------------------------- 1 | using md2visio.struc.figure; 2 | using md2visio.vsdx; 3 | 4 | namespace md2visio.struc.xy 5 | { 6 | internal class XyChart : Figure 7 | { 8 | public XyAxis XAxis { get; set; } = Empty.Get(); 9 | public XyAxis YAxis { get; set; } = Empty.Get(); 10 | public List<(MmdJsonArray, string type)> Contents { get; set; } = new(); 11 | 12 | public bool IsVertical 13 | { 14 | get 15 | { 16 | Config.GetString("config.xyChart.chartOrientation", out string ori); 17 | return !ori.ToLower().Equals("horizontal"); 18 | } 19 | } 20 | 21 | public XyChart() { 22 | 23 | } 24 | 25 | public override void ToVisio(string path) 26 | { 27 | new VBuilderXy(this).Build(path); 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /md2visio/mermaid/@cmn/SttMermaidClose.cs: -------------------------------------------------------------------------------- 1 | using System.Text.RegularExpressions; 2 | 3 | namespace md2visio.mermaid.cmn 4 | { 5 | internal class SttMermaidClose : SynState 6 | { 7 | public override SynState NextState() 8 | { 9 | if (!IsMermaidClose(Ctx)) throw new SynException($"expected mermaid close", Ctx); 10 | 11 | string closeTag = Ctx.TestGroups["bquote"].Value; 12 | return Save(closeTag).Slide(Ctx.TestGroups[0].Value.Length).Forward(); 13 | } 14 | 15 | public static bool IsMermaidClose(SynContext ctx) 16 | { 17 | (bool success, SynState mermaidStart) = ctx.FindContainerType("SttMermaidStart"); 18 | if (!success) return false; 19 | 20 | int L = mermaidStart.Fragment.Length; 21 | return ctx.Test($@"^\s*(?`{{{L},}})\s*(?=\n|$)"); 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /md2visio/mermaid/graph/GSttPipedLinkText.cs: -------------------------------------------------------------------------------- 1 | using md2visio.mermaid.cmn; 2 | using md2visio.mermaid.graph.@internal; 3 | using System.Text.RegularExpressions; 4 | 5 | namespace md2visio.mermaid.graph 6 | { 7 | internal class GSttPipedLinkText : SynState 8 | { 9 | public override SynState NextState() 10 | { 11 | if (!IsPipedLinkText(Ctx)) throw new SynException("expected piped link text", Ctx); 12 | 13 | Group textGroup = Ctx.TestGroups["text"]; 14 | string text = textGroup.Value.Trim(); 15 | return Save(text).Slide(Ctx.TestGroups[0].Length).Forward(); 16 | } 17 | 18 | public static bool IsPipedLinkText(SynContext ctx) 19 | { 20 | if (!ctx.Test(@"(?s)^\s*\|")) return false; 21 | if (!ctx.Test(@"(?s)^\s*\|(?.+?)\|")) return false; 22 | return true; 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /md2visio/mermaid/graph/GSttText.cs: -------------------------------------------------------------------------------- 1 | using md2visio.mermaid.cmn; 2 | using md2visio.mermaid.graph.@internal; 3 | using System.Text.RegularExpressions; 4 | 5 | namespace md2visio.mermaid.graph 6 | { 7 | internal class GSttText : SynState 8 | { 9 | Regex regNodeString = new(@"^[\^=\|><]|~{1,2}$", RegexOptions.Compiled); 10 | 11 | public override SynState NextState() 12 | { 13 | if (!Ctx.FindContainerFrag("graph|flowchart|subgraph").Success) 14 | throw new SynException("syntax error", Ctx); 15 | 16 | string text = Buffer; 17 | ClearBuffer().SlideSpaces(); 18 | if (string.IsNullOrWhiteSpace(text)) return Forward(); 19 | 20 | if (regNodeString.IsMatch(text)) 21 | throw new SynException("unexpected node string", Ctx); 22 | 23 | return Save(text).Forward(); 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /md2visio/mermaid/journey/JoSttTriple.cs: -------------------------------------------------------------------------------- 1 | using md2visio.mermaid.cmn; 2 | 3 | namespace md2visio.mermaid.journey 4 | { 5 | internal class JoSttTriple : SynState 6 | { 7 | public override SynState NextState() 8 | { 9 | if(!IsTripleLine(Ctx)) throw new SynException("expected a triple", Ctx); 10 | 11 | string triple = ExpectedGroups[0].Value.Trim(); 12 | foreach (string s in triple.Split(":")) 13 | { 14 | string trimed = s.Trim(); 15 | if (string.IsNullOrEmpty(trimed)) throw new SynException("task item can't be empty", Ctx); 16 | AddCompo(trimed); 17 | } 18 | 19 | return Save(triple).Forward(); 20 | } 21 | 22 | public static bool IsTripleLine(SynContext ctx) 23 | { 24 | return ctx.Expect(@"([^:\n]+:){2}[^:\n]+(?=\n)"); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /md2visio/struc/figure/GrowthDirection.cs: -------------------------------------------------------------------------------- 1 | namespace md2visio.struc.figure 2 | { 3 | internal class GrowthDirection 4 | { 5 | public int H { get; set; } = 1; 6 | public int V { get; set; } = 0; 7 | public bool Positive { get => V > 0 || H > 0; } 8 | 9 | public GrowthDirection(Container figure) 10 | { 11 | Decide(figure); 12 | } 13 | 14 | public void Decide(Container figure) 15 | { 16 | if (figure.Direction == "RL") 17 | { H = -1; V = 0; } 18 | else if (figure.Direction == "TD" || figure.Direction == "TB") 19 | { H = 0; V = -1; } 20 | else if (figure.Direction == "BT") 21 | { H = 0; V = 1; } 22 | else // LR 23 | { H = 1; V = 0; } 24 | } 25 | 26 | public override string ToString() 27 | { 28 | return $"H: {H}, V: {V}"; 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /md2visio/mermaid/graph/internal/GSttEqual.cs: -------------------------------------------------------------------------------- 1 | using md2visio.mermaid.cmn; 2 | 3 | namespace md2visio.mermaid.graph.@internal 4 | { 5 | internal class GSttEqual : SynState 6 | { 7 | public override SynState NextState() 8 | { 9 | // left 10 | if (Buffer.Length > 0) 11 | { 12 | if (GSttLinkStart.IsLinkStart(Ctx)) 13 | return Restore(Buffer.Length).ClearBuffer().Forward(); 14 | if (GSttNoLabelLink.IsNoLabelLink(Ctx)) 15 | return Restore(Buffer.Length).ClearBuffer().Forward(); 16 | 17 | throw new SynException("unexpected '='", Ctx); 18 | } 19 | 20 | // right 21 | if (GSttLinkStart.IsLinkStart(Ctx)) return Forward(); 22 | else if (GSttNoLabelLink.IsNoLabelLink(Ctx)) return Forward(); 23 | 24 | throw new SynException("unexpected '='", Ctx); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /md2visio/obj/Debug/net8.0/md2visio.AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // 此代码由工具生成。 4 | // 运行时版本:4.0.30319.42000 5 | // 6 | // 对此文件的更改可能会导致不正确的行为,并且如果 7 | // 重新生成代码,这些更改将会丢失。 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | using System; 12 | using System.Reflection; 13 | 14 | [assembly: System.Reflection.AssemblyCompanyAttribute("md2visio")] 15 | [assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")] 16 | [assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")] 17 | [assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+5f48c97e9cdd2ac78444a3401aa393be779a5f48")] 18 | [assembly: System.Reflection.AssemblyProductAttribute("md2visio")] 19 | [assembly: System.Reflection.AssemblyTitleAttribute("md2visio")] 20 | [assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")] 21 | 22 | // 由 MSBuild WriteCodeFragment 类生成。 23 | 24 | -------------------------------------------------------------------------------- /md2visio/struc/figure/Figure.cs: -------------------------------------------------------------------------------- 1 | namespace md2visio.struc.figure 2 | { 3 | internal abstract class Figure : Container 4 | { 5 | string title = string.Empty; 6 | Config config; 7 | 8 | public string Title 9 | { 10 | get => title; 11 | set => title = value.Trim(); 12 | } 13 | public MmdFrontMatter FrontMatter { get => config.UserFrontMatter; } 14 | public MmdJsonObj Directive { get => config.UserDirective; } 15 | public Config Config { get => config; } 16 | 17 | public Figure() 18 | { 19 | config = new Config(this); 20 | } 21 | 22 | public abstract void ToVisio(string path); 23 | } 24 | 25 | class EmptyFigure : Figure 26 | { 27 | public static EmptyFigure Instance = new EmptyFigure(); 28 | public EmptyFigure() { } 29 | 30 | public override void ToVisio(string path) 31 | { 32 | throw new NotImplementedException(); 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /md2visio/obj/x64/Debug/net8.0/md2visio.AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // 此代码由工具生成。 4 | // 运行时版本:4.0.30319.42000 5 | // 6 | // 对此文件的更改可能会导致不正确的行为,并且如果 7 | // 重新生成代码,这些更改将会丢失。 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | using System; 12 | using System.Reflection; 13 | 14 | [assembly: System.Reflection.AssemblyCompanyAttribute("md2visio")] 15 | [assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")] 16 | [assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")] 17 | [assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+5f48c97e9cdd2ac78444a3401aa393be779a5f48")] 18 | [assembly: System.Reflection.AssemblyProductAttribute("md2visio")] 19 | [assembly: System.Reflection.AssemblyTitleAttribute("md2visio")] 20 | [assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")] 21 | 22 | // 由 MSBuild WriteCodeFragment 类生成。 23 | 24 | -------------------------------------------------------------------------------- /md2visio/main/AppTest.cs: -------------------------------------------------------------------------------- 1 | using md2visio.mermaid.cmn; 2 | using md2visio.struc.figure; 3 | using md2visio.vsdx.@base; 4 | 5 | namespace md2visio.main 6 | { 7 | internal class AppTest 8 | { 9 | string testDir = @"test"; 10 | string[] files = ["graph", "journey", "packet", "pie"]; 11 | string outputPath = @$"{Environment.GetEnvironmentVariable("HOMEPATH")}\Desktop\TestOutput"; 12 | 13 | public void Test() 14 | { 15 | if(!Path.Exists(outputPath)) 16 | Directory.CreateDirectory(outputPath); 17 | 18 | AppConfig config = AppConfig.Instance; 19 | foreach (string file in files) 20 | { 21 | SynContext synContext = new(@$"{testDir}\{file}.md"); 22 | SttMermaidStart.Run(synContext); 23 | Console.Write(synContext.ToString()); 24 | 25 | new FigureBuilderFactory(synContext.NewSttIterator()).Build(outputPath); 26 | } 27 | VBuilder.VisioApp.Quit(); 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /md2visio/mermaid/graph/GSttLinkStart.cs: -------------------------------------------------------------------------------- 1 | using md2visio.mermaid.cmn; 2 | using md2visio.struc.figure; 3 | 4 | namespace md2visio.mermaid.graph 5 | { 6 | internal class GSttLinkStart : SynState 7 | { 8 | public override SynState NextState() 9 | { 10 | SynState state = Create(Ctx); 11 | if (!state.IsEmpty()) 12 | return state.Forward(); 13 | 14 | return Forward(); 15 | } 16 | 17 | public static SynState Create(SynContext ctx) 18 | { 19 | if (!IsLinkStart(ctx)) return EmptyState.Instance; 20 | 21 | SynState state = new GSttLinkStart(); 22 | state.Ctx = ctx; 23 | state.Save(ctx.TestGroups["estart"].Value); 24 | 25 | return state.Slide(state.Fragment.Length); 26 | } 27 | 28 | public static bool IsLinkStart(SynContext ctx) 29 | { 30 | return ctx.Test("^(?[xo<]?(--(?![-ox>])|==(?![=ox>])))"); // -- or == 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /md2visio/mermaid/graph/GSttLinkEnd.cs: -------------------------------------------------------------------------------- 1 | using md2visio.mermaid.cmn; 2 | using md2visio.mermaid.graph.@internal; 3 | using md2visio.struc.figure; 4 | 5 | namespace md2visio.mermaid.graph 6 | { 7 | internal class GSttLinkEnd : SynState 8 | { 9 | public override SynState NextState() 10 | { 11 | if (!IsLinkEnd(Ctx)) throw new SynException("syntax error", Ctx); 12 | 13 | return Create(Ctx); 14 | } 15 | 16 | public static SynState Create(SynContext ctx) 17 | { 18 | if (!IsLinkEnd(ctx)) return EmptyState.Instance; 19 | 20 | SynState state = new GSttLinkEnd(); 21 | state.Ctx = ctx; 22 | state.Save(ctx.TestGroups["edgeEnd"].Value); 23 | 24 | return state.Slide(state.Fragment.Length).Forward(); 25 | } 26 | 27 | public static bool IsLinkEnd(SynContext ctx) 28 | { 29 | return ctx.Test("^(?[])") || 30 | ctx.Test("^(?[])"); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /md2visio/default/journey.yaml: -------------------------------------------------------------------------------- 1 | config: 2 | # mermaid.mermaidAPI.defaultConfig.journey 3 | journey: 4 | useMaxWidth: true 5 | diagramMarginX: 50 6 | diagramMarginY: 10 7 | leftMargin: 150 8 | width: 150 9 | height: 50 10 | boxMargin: 10 11 | boxTextMargin: 5 12 | noteMargin: 10 13 | messageMargin: 35 14 | messageAlign: center 15 | bottomMarginAdj: 1 16 | rightAngles: false 17 | taskFontSize: 14 18 | taskFontFamily: '"Open Sans", sans-serif' 19 | taskMargin: 50 20 | activationWidth: 10 21 | textPlacement: fo 22 | actorColours: 23 | - '#8FBC8F' 24 | - '#7CFC00' 25 | - '#00FFFF' 26 | - '#20B2AA' 27 | - '#B0E0E6' 28 | - '#FFFFE0' 29 | sectionFills: 30 | - '#191970' 31 | - '#8B008B' 32 | - '#4B0082' 33 | - '#2F4F4F' 34 | - '#800000' 35 | - '#8B4513' 36 | - '#00008B' 37 | sectionColours: 38 | - '#fff' -------------------------------------------------------------------------------- /md2visio/default/timeline.yaml: -------------------------------------------------------------------------------- 1 | config: 2 | # mermaid.mermaidAPI.defaultConfig.timeline 3 | timeline: 4 | useMaxWidth: true 5 | diagramMarginX: 50 6 | diagramMarginY: 10 7 | leftMargin: 150 8 | width: 150 9 | height: 50 10 | boxMargin: 10 11 | boxTextMargin: 5 12 | noteMargin: 10 13 | messageMargin: 35 14 | messageAlign: center 15 | bottomMarginAdj: 1 16 | rightAngles: false 17 | taskFontSize: 14 18 | taskFontFamily: '"Open Sans", sans-serif' 19 | taskMargin: 50 20 | activationWidth: 10 21 | textPlacement: fo 22 | actorColours: 23 | - '#8FBC8F' 24 | - '#7CFC00' 25 | - '#00FFFF' 26 | - '#20B2AA' 27 | - '#B0E0E6' 28 | - '#FFFFE0' 29 | sectionFills: 30 | - '#191970' 31 | - '#8B008B' 32 | - '#4B0082' 33 | - '#2F4F4F' 34 | - '#800000' 35 | - '#8B4513' 36 | - '#00008B' 37 | sectionColours: 38 | - '#fff' 39 | disableMulticolor: false -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2025 Megre 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /md2visio/struc/xy/XyAxis.cs: -------------------------------------------------------------------------------- 1 | using md2visio.mermaid.cmn; 2 | using md2visio.struc.figure; 3 | using System.Drawing; 4 | 5 | namespace md2visio.struc.xy 6 | { 7 | internal class XyAxis 8 | { 9 | public string Title { get; set; } = string.Empty; 10 | public SizeF Range { get; set; } = SizeF.Empty; 11 | public MmdJsonArray Ticks { get; set;} = new MmdJsonArray(); 12 | 13 | public XyAxis() { } 14 | 15 | public XyAxis(CompoDict dict) 16 | { 17 | Title = dict["title"] ?? string.Empty; 18 | string s = "rangeStart", e = "rangeEnd"; 19 | if (dict.ContainsKey(s) && dict.ContainsKey(e)) 20 | InitRange(dict.Get(s), dict.Get(e)); 21 | if (dict.ContainsKey("vals")) 22 | Ticks.Load(dict.Get("vals")); 23 | } 24 | 25 | 26 | void InitRange(string rangeStart, string rangeEnd) 27 | { 28 | float start, end; 29 | if(float.TryParse(rangeStart, out start) && 30 | float.TryParse(rangeEnd, out end)) 31 | Range = new SizeF(start, end); 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /md2visio/vsdx/VBuilderPac.cs: -------------------------------------------------------------------------------- 1 | using md2visio.struc.figure; 2 | using md2visio.struc.packet; 3 | using md2visio.vsdx.@base; 4 | 5 | namespace md2visio.vsdx 6 | { 7 | internal class VBuilderPac(Packet figure) : VFigureBuilder(figure) 8 | { 9 | protected override void ExecuteBuild() 10 | { 11 | VDrawerPac drawer = new VDrawerPac(figure, VisioApp); 12 | drawer.SortedNodes = OrderInnerNodes(); 13 | drawer.Draw(); 14 | } 15 | 16 | List OrderInnerNodes() 17 | { 18 | List nodes = figure.InnerNodes.Values.ToList(); 19 | IComparer comparer = new PacBitsComparer(); 20 | nodes.Sort(comparer); 21 | 22 | return nodes; 23 | } 24 | } 25 | 26 | class PacBitsComparer : IComparer 27 | { 28 | public int Compare(INode? x, INode? y) 29 | { 30 | if(x == null || y == null) return 0; 31 | PacBlock bitsx = (PacBlock) x, 32 | bitsy = (PacBlock) y; 33 | 34 | return bitsx.BitStart - bitsy.BitStart; 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /md2visio/struc/packet/PacBuilder.cs: -------------------------------------------------------------------------------- 1 | using md2visio.mermaid.cmn; 2 | using md2visio.mermaid.packet; 3 | using md2visio.struc.figure; 4 | 5 | namespace md2visio.struc.packet 6 | { 7 | internal class PacBuilder(SttIterator iter) : FigureBuilder(iter) 8 | { 9 | readonly Packet packet = new(); 10 | 11 | public override void Build(string outputFile) 12 | { 13 | while (iter.HasNext()) 14 | { 15 | SynState cur = iter.Next(); 16 | if (cur is SttMermaidStart) { } 17 | if (cur is SttMermaidClose) { packet.ToVisio(outputFile); break; } 18 | if (cur is PacSttTuple) { BuildBits((PacSttTuple) cur); } 19 | if (cur is SttComment) { packet.Config.LoadUserDirectiveFromComment(cur.Fragment); } 20 | if (cur is SttFrontMatter) { packet.Config.LoadUserFrontMatter(cur.Fragment); } 21 | } 22 | } 23 | 24 | void BuildBits(PacSttTuple tuple) 25 | { 26 | PacBlock bits = new(tuple.GetPart("bits"), tuple.GetPart("name")); 27 | packet.AddInnerNode(bits); 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /md2visio/test/xy.md: -------------------------------------------------------------------------------- 1 | ```mermaid 2 | --- 3 | config: 4 | xyChart: 5 | width: 900 6 | height: 900 7 | chartOrientation: horizontal 8 | xAxis: 9 | showLabel: true 10 | yAxis: 11 | showTitle: true 12 | themeVariables: 13 | xyChart: 14 | titleColor: "#ff0000" 15 | --- 16 | xychart-beta 17 | title "Sales Revenue" 18 | x-axis X 2-->10 19 | y-axis Y 1 -->100 20 | bar [10, 20, 30,40,50,60,70,80,100] 21 | line [10, 20, 30,40,50,60,70,80] 22 | ``` 23 | 24 | 25 | ```mermaid 26 | --- 27 | config: 28 | xyChart: 29 | width: 900 30 | height: 600 31 | chartOrientation: vertical 32 | xAxis: 33 | showLabel: true 34 | yAxis: 35 | showTitle: false 36 | themeVariables: 37 | xyChart: 38 | titleColor: "#ff0000" 39 | --- 40 | xychart-beta 41 | title "Sales Revenue" 42 | x-axis X [jan, feb, mar, apr, may, jun] 43 | y-axis Y 6000--> 12000 44 | bar [5000, 6000, 7500, 8200, 9500, 10500, 12000] 45 | line [5000, 6000, 7500, 8200, 9500] 46 | line [5500, 6200, 7600, 6500] 47 | ``` 48 | 49 | -------------------------------------------------------------------------------- /md2visio/vsdx/@tool/VColorGenerator.cs: -------------------------------------------------------------------------------- 1 | using md2visio.vsdx.@tool; 2 | 3 | internal static class VColorGenerator 4 | { 5 | public static readonly Random random = new(); 6 | 7 | // Method to generate a list of unique and distinguishable background colors 8 | public static List Generate(int count) 9 | { 10 | var colors = new HashSet(); 11 | 12 | while (colors.Count < count) 13 | { 14 | int r = random.Next(0, 256); 15 | int g = random.Next(0, 256); 16 | int b = random.Next(0, 256); 17 | 18 | // Ensure the brightness is sufficient for readability with black text 19 | if (CalculateBrightness(r, g, b) > 128) // Adjust this threshold as needed 20 | { 21 | colors.Add(new VRGBColor(r, g, b)); 22 | } 23 | } 24 | 25 | // Convert HashSet to List to return 26 | return colors.ToList(); 27 | } 28 | 29 | // Method to calculate the brightness of a color 30 | private static double CalculateBrightness(int r, int g, int b) 31 | { 32 | return 0.299 * r + 0.587 * g + 0.114 * b; 33 | } 34 | } -------------------------------------------------------------------------------- /md2visio/default/sequence.yaml: -------------------------------------------------------------------------------- 1 | config: 2 | # mermaid.mermaidAPI.defaultConfig.sequence 3 | sequence: 4 | useMaxWidth: true 5 | hideUnusedParticipants: false 6 | activationWidth: 10 7 | diagramMarginX: 50 8 | diagramMarginY: 10 9 | actorMargin: 50 10 | width: 150 11 | height: 65 12 | boxMargin: 10 13 | boxTextMargin: 5 14 | noteMargin: 10 15 | messageMargin: 35 16 | messageAlign: center 17 | mirrorActors: true 18 | forceMenus: false 19 | bottomMarginAdj: 1 20 | rightAngles: false 21 | showSequenceNumbers: false 22 | actorFontSize: 14 23 | actorFontFamily: '"Open Sans", sans-serif' 24 | actorFontWeight: 400 25 | noteFontSize: 14 26 | noteFontFamily: '"trebuchet ms", verdana, arial, sans-serif' 27 | noteFontWeight: 400 28 | noteAlign: center 29 | messageFontSize: 16 30 | messageFontFamily: '"trebuchet ms", verdana, arial, sans-serif' 31 | messageFontWeight: 400 32 | wrap: false 33 | wrapPadding: 10 34 | labelBoxWidth: 50 35 | labelBoxHeight: 20 -------------------------------------------------------------------------------- /md2visio/obj/Debug/md2visio.1.0.0.nuspec: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | md2visio 5 | 1.0.0 6 | md2visio 7 | Package Description 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /md2visio/mermaid/@cmn/SttFigureType.cs: -------------------------------------------------------------------------------- 1 | using md2visio.mermaid.graph; 2 | using System.Text.RegularExpressions; 3 | 4 | namespace md2visio.mermaid.cmn 5 | { 6 | internal class SttFigureType : SynState 7 | { 8 | public static readonly string Supported = 9 | "graph|flowchart|sequenceDiagram|classDiagram|stateDiagram|stateDiagram-v2|" + 10 | "erDiagram|journey|gantt|pie|quadrantChart|requirementDiagram|gitGraph|C4Context|mindmap|" + 11 | "timeline|zenuml|sankey|sankey-beta|xychart|xychart-beta|block|block-beta|packet|packet-beta|" + 12 | "kanban|architecture|architecture-beta"; 13 | 14 | Dictionary typeMap = TypeMap.KeywordMap; 15 | 16 | public override SynState NextState() 17 | { 18 | string kw = Buffer.Trim(); 19 | if (!IsFigure(kw)) throw new SynException($"unknown graph type {kw}", Ctx); 20 | if (!typeMap.ContainsKey(kw)) throw new NotImplementedException($"keyword '{kw}' not implemented"); 21 | 22 | return Forward(typeMap[kw]); 23 | } 24 | 25 | public static bool IsFigure(string word) 26 | { 27 | return Regex.IsMatch(word, $"^({Supported})$"); 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /md2visio/mermaid/graph/GSttKeyword.cs: -------------------------------------------------------------------------------- 1 | using md2visio.mermaid.cmn; 2 | using md2visio.mermaid.graph.@internal; 3 | using System.Text.RegularExpressions; 4 | 5 | namespace md2visio.mermaid.graph 6 | { 7 | internal class GSttKeyword : SynState 8 | { 9 | public override SynState NextState() 10 | { 11 | if (!IsKeyword(Buffer)) throw new SynException("syntax error", Ctx); 12 | if (Buffer == "direction") 13 | { 14 | if (!GSttKeywordParam.HasParam(Ctx)) return Forward(); 15 | } 16 | 17 | Save(Buffer).ClearBuffer().SlideSpaces(); 18 | if (GSttKeywordParam.HasParam(Ctx)) return Forward(); 19 | 20 | return Forward(); 21 | } 22 | 23 | static Regex regKW = 24 | new("^(graph|flowchart|subgraph|end|style|linkStyle|class|classDef|direction|click)$", RegexOptions.Compiled); 25 | public static bool IsKeyword(string word) 26 | { 27 | return regKW.IsMatch(word); 28 | } 29 | 30 | static Regex regDir = 31 | new("^(LR|RL|TD|TB|BT)$", RegexOptions.Compiled); 32 | public static bool IsDirection(string word) 33 | { 34 | return regDir.IsMatch(word); 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /md2visio/obj/md2visio.csproj.nuget.g.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | True 5 | NuGet 6 | $(MSBuildThisFileDirectory)project.assets.json 7 | $(UserProfile)\.nuget\packages\ 8 | C:\Users\TR\.nuget\packages\;D:\Program Files (x86)\Microsoft Visual Studio\Shared\NuGetPackages 9 | PackageReference 10 | 6.14.1 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /md2visio/struc/graph/GLabel.cs: -------------------------------------------------------------------------------- 1 | using System.Text.RegularExpressions; 2 | 3 | namespace md2visio.struc.graph 4 | { 5 | internal class GLabel 6 | { 7 | string content = string.Empty; 8 | string markdown = string.Empty; 9 | 10 | protected GLabel() { } 11 | 12 | public GLabel(string content) 13 | { 14 | Content = content; 15 | } 16 | 17 | public string Content 18 | { 19 | get { return content; } 20 | set 21 | { 22 | if (value?.Length > 0) 23 | { 24 | content = value; 25 | ParseQuote(); 26 | ParseMarkdown(); 27 | } 28 | } 29 | } 30 | 31 | private void ParseQuote() 32 | { 33 | Match match = Regex.Match(content, @"(^""(?.+)""$)|(^'(?.+)')$"); 34 | if (match.Success) content = match.Groups["ct"].Value; 35 | } 36 | 37 | private void ParseMarkdown() 38 | { 39 | Match match = Regex.Match(content, @"""?`([^`]+)`""?"); 40 | if (match.Success) markdown = match.Groups[1].Value; 41 | } 42 | 43 | public override string ToString() 44 | { 45 | if (markdown.Length == 0) return content; 46 | return markdown; 47 | } 48 | 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /md2visio/mermaid/@cmn/SttIterator.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace md2visio.mermaid.cmn 8 | { 9 | internal class SttIterator 10 | { 11 | SynContext ctx; 12 | int stateIndex = -1; 13 | 14 | public int Pos { get { return stateIndex; } } 15 | public SynContext Context { get { return ctx; } } 16 | 17 | public SttIterator(SynContext ctx) 18 | { 19 | this.ctx = ctx; 20 | } 21 | 22 | public SynState Current 23 | { 24 | get 25 | { 26 | return ctx.StateList[stateIndex]; 27 | } 28 | } 29 | 30 | public bool HasNext() 31 | { 32 | return ctx.StateList.Count > stateIndex + 1; 33 | } 34 | 35 | public SynState Next() 36 | { 37 | return ctx.StateList[++stateIndex]; 38 | } 39 | 40 | public SynState PeekNext() 41 | { 42 | return ctx.StateList[stateIndex + 1]; 43 | } 44 | 45 | public bool HasPre() 46 | { 47 | return stateIndex - 1 >= 0 && 48 | stateIndex - 1 < ctx.StateList.Count; 49 | } 50 | 51 | public SynState PeekPre() 52 | { 53 | return ctx.StateList[stateIndex - 1]; 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /md2visio/mermaid/graph/internal/GSttWordFlag.cs: -------------------------------------------------------------------------------- 1 | using md2visio.mermaid.cmn; 2 | 3 | namespace md2visio.mermaid.graph.@internal 4 | { 5 | internal class GSttWordFlag : SynState 6 | { 7 | public override SynState NextState() 8 | { 9 | // a word flag may make a node string 10 | // left 11 | if (!string.IsNullOrWhiteSpace(Buffer)) { return Forward(); } 12 | 13 | // right 14 | string? next = Peek(); 15 | if (next == "\n") { return Forward(); } 16 | 17 | next = SlideSpaces().Peek(); 18 | if (next == ";") { return Forward(); } 19 | if (next == "`") { return Forward(); } 20 | if (next == "=") { return Forward(); } 21 | if (next == ">") { return Forward(); } 22 | if (next == "<") { return Forward(); } 23 | if (next == "{") { return Forward(); } 24 | if (next == "[") { return Forward(); } 25 | if (next == "(") { return Forward(); } 26 | if (next == "@") { return Forward(); } 27 | if (next == "%") { return Forward(); } 28 | if (next == "~") { return Forward(); } 29 | 30 | return Forward(); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /md2visio/obj/project.nuget.cache: -------------------------------------------------------------------------------- 1 | { 2 | "version": 2, 3 | "dgSpecHash": "KdAvhiH+/Eo=", 4 | "success": true, 5 | "projectFilePath": "C:\\Users\\TR\\文档\\GitHub\\md2visio\\md2visio\\md2visio.csproj", 6 | "expectedPackageFiles": [ 7 | "C:\\Users\\TR\\.nuget\\packages\\microsoft.visualstudio.imaging.interop.14.0.designtime\\17.13.40008\\microsoft.visualstudio.imaging.interop.14.0.designtime.17.13.40008.nupkg.sha512", 8 | "C:\\Users\\TR\\.nuget\\packages\\microsoft.visualstudio.interop\\17.13.40008\\microsoft.visualstudio.interop.17.13.40008.nupkg.sha512", 9 | "C:\\Users\\TR\\.nuget\\packages\\microsoft.win32.systemevents\\9.0.1\\microsoft.win32.systemevents.9.0.1.nupkg.sha512", 10 | "C:\\Users\\TR\\.nuget\\packages\\stdole\\17.13.40008\\stdole.17.13.40008.nupkg.sha512", 11 | "C:\\Users\\TR\\.nuget\\packages\\system.drawing.common\\9.0.1\\system.drawing.common.9.0.1.nupkg.sha512", 12 | "C:\\Users\\TR\\.nuget\\packages\\wondercircuits.microsoft.office.core\\15.0.0\\wondercircuits.microsoft.office.core.15.0.0.nupkg.sha512", 13 | "C:\\Users\\TR\\.nuget\\packages\\wondercircuits.microsoft.office.interop.visio\\15.0.0\\wondercircuits.microsoft.office.interop.visio.15.0.0.nupkg.sha512", 14 | "C:\\Users\\TR\\.nuget\\packages\\wondercircuits.microsoft.vbe.interop\\15.0.0\\wondercircuits.microsoft.vbe.interop.15.0.0.nupkg.sha512", 15 | "C:\\Users\\TR\\.nuget\\packages\\yamldotnet\\16.3.0\\yamldotnet.16.3.0.nupkg.sha512" 16 | ], 17 | "logs": [] 18 | } -------------------------------------------------------------------------------- /md2visio/mermaid/@cmn/SttIntro.cs: -------------------------------------------------------------------------------- 1 | namespace md2visio.mermaid.cmn 2 | { 3 | internal class SttIntro: SynState 4 | { 5 | public override SynState NextState() 6 | { 7 | string? next = Ctx.Peek(); 8 | if (next == null) return EndOfFile; 9 | 10 | if (next == "-") { return Forward(); } 11 | if (next == "%") { return Forward(); } 12 | if (next == " ") { return Forward(); } 13 | if (next == "\t") { return Forward(); } 14 | if (next == "\n") { return Forward(); } 15 | 16 | if (Unexpected(next)) throw new SynException($"unexpected '{next}'", Ctx); 17 | 18 | return Take().Forward(); 19 | } 20 | 21 | bool Unexpected(string next) 22 | { 23 | switch(next) 24 | { 25 | case ";": 26 | case "@": 27 | case "~": 28 | case "{": 29 | case "[": 30 | case "(": 31 | case "<": 32 | case "`": 33 | case "\"": 34 | case "=": 35 | case "&": 36 | case "|": 37 | case ")": 38 | case "}": 39 | case "]": 40 | case ">": return true; 41 | } 42 | return false; 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /md2visio/struc/journey/JoSection.cs: -------------------------------------------------------------------------------- 1 | using md2visio.struc.figure; 2 | using md2visio.struc.graph; 3 | using Microsoft.Office.Interop.Visio; 4 | 5 | namespace md2visio.struc.journey 6 | { 7 | internal class JoSection : INode 8 | { 9 | string Title { get; set; } = string.Empty; 10 | public string ID { get; set; } = string.Empty; 11 | public string Label { get => ID; set => ID = value; } 12 | public Shape? VisioShape { get; set; } 13 | public Container Container { get; set; } = Empty.Get(); 14 | public List Tasks { get => joTasks; } 15 | 16 | public List InputEdges => throw new NotImplementedException(); 17 | 18 | public List OutputEdges => throw new NotImplementedException(); 19 | 20 | List joTasks = new List(); 21 | 22 | public JoSection() { } 23 | public JoSection(string title) { Title = title.Trim(); } 24 | 25 | public void AddTask(JoTask joTask) 26 | { 27 | joTask.Section = this; 28 | joTasks.Add(joTask); 29 | } 30 | 31 | public HashSet JoinerSet() 32 | { 33 | HashSet set = new HashSet(); 34 | foreach (JoTask joTask in joTasks) 35 | { 36 | foreach (string joiner in joTask.Joiners) 37 | set.Add(joiner); 38 | } 39 | return set; 40 | } 41 | 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /md2visio/mermaid/pie/PieSttTuple.cs: -------------------------------------------------------------------------------- 1 | using md2visio.mermaid.cmn; 2 | using System.Text; 3 | 4 | namespace md2visio.mermaid.pie 5 | { 6 | internal class PieSttTuple : SynState 7 | { 8 | public override SynState NextState() 9 | { 10 | if(Buffer.Length > 0) Restore(Buffer.Length).ClearBuffer(); 11 | if (!IsTupleLine(Ctx)) throw new SynException("expected a tuple"); 12 | 13 | string tuple = ExpectedGroups[0].Value.Trim(); 14 | int index = tuple.LastIndexOf(':'); 15 | AddToCompo(tuple.Substring(0, index)); 16 | AddToCompo(tuple.Substring(index + 1, tuple.Length - index - 1)); 17 | 18 | return ClearBuffer().Save(tuple).Forward(); 19 | } 20 | 21 | void AddToCompo(string compo) 22 | { 23 | string trimed = TrimItem(compo); 24 | if (string.IsNullOrEmpty(trimed)) throw new SynException("data item can't be empty", Ctx); 25 | AddCompo(trimed); 26 | } 27 | 28 | string TrimItem(string item) 29 | { 30 | StringBuilder sb = new StringBuilder(item.Trim()); 31 | if (sb[0] == '"') sb.Remove(0, 1); 32 | if (sb.Length > 0 && sb[sb.Length - 1] == '"') sb.Remove(sb.Length-1, 1); 33 | 34 | return sb.ToString(); 35 | } 36 | 37 | public static bool IsTupleLine(SynContext ctx) 38 | { 39 | return ctx.Expect(@"[^\n]+:[^:\n""]+(?=\n)"); 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /md2visio/mermaid/pie/PieSttKeywordParam.cs: -------------------------------------------------------------------------------- 1 | using md2visio.mermaid.cmn; 2 | using Microsoft.Office.Interop.Visio; 3 | using System.Text; 4 | 5 | namespace md2visio.mermaid.pie 6 | { 7 | internal class PieSttKeywordParam : SttKeywordParam 8 | { 9 | public override SynState NextState() 10 | { 11 | return Save(ExpectedGroups["param"].Value).Forward(); 12 | } 13 | 14 | public Dictionary ParsePieParam() 15 | { 16 | Dictionary dict = new Dictionary(); 17 | string[] items = Fragment.Split(" "); 18 | for (int i=0; i dict, string[] items, int index) 34 | { 35 | StringBuilder title = new StringBuilder(); 36 | while (index < items.Length) 37 | { 38 | string item = items[index++]; 39 | title.Append(item).Append(' '); 40 | } 41 | dict.Add("title", title.ToString().Trim()); 42 | } 43 | 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /md2visio.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.10.35013.160 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "md2visio", "md2visio\md2visio.csproj", "{5C8AB8F5-F4CE-4DA5-BFD5-DB26E21D3583}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Debug|x64 = Debug|x64 12 | Release|Any CPU = Release|Any CPU 13 | Release|x64 = Release|x64 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {5C8AB8F5-F4CE-4DA5-BFD5-DB26E21D3583}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 17 | {5C8AB8F5-F4CE-4DA5-BFD5-DB26E21D3583}.Debug|Any CPU.Build.0 = Debug|Any CPU 18 | {5C8AB8F5-F4CE-4DA5-BFD5-DB26E21D3583}.Debug|x64.ActiveCfg = Debug|x64 19 | {5C8AB8F5-F4CE-4DA5-BFD5-DB26E21D3583}.Debug|x64.Build.0 = Debug|x64 20 | {5C8AB8F5-F4CE-4DA5-BFD5-DB26E21D3583}.Release|Any CPU.ActiveCfg = Release|Any CPU 21 | {5C8AB8F5-F4CE-4DA5-BFD5-DB26E21D3583}.Release|Any CPU.Build.0 = Release|Any CPU 22 | {5C8AB8F5-F4CE-4DA5-BFD5-DB26E21D3583}.Release|x64.ActiveCfg = Release|x64 23 | {5C8AB8F5-F4CE-4DA5-BFD5-DB26E21D3583}.Release|x64.Build.0 = Release|x64 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | GlobalSection(ExtensibilityGlobals) = postSolution 29 | SolutionGuid = {03E65BEF-D3FE-4DD4-9421-DD40E2A70F38} 30 | EndGlobalSection 31 | EndGlobal 32 | -------------------------------------------------------------------------------- /md2visio/mermaid/graph/GSttLinkLabel.cs: -------------------------------------------------------------------------------- 1 | using md2visio.mermaid.cmn; 2 | using md2visio.struc.figure; 3 | using System.Text.RegularExpressions; 4 | 5 | namespace md2visio.mermaid.graph 6 | { 7 | internal class GSttLinkLabel : SynState 8 | { 9 | public override SynState NextState() 10 | { 11 | // [(); 29 | } 30 | 31 | public static bool IsLinkText(SynContext ctx) 32 | { 33 | if (ctx.LastState() is not GSttLinkStart) return false; 34 | 35 | string tag = ctx.LastState().Fragment.Substring(1, 1); 36 | if (!ctx.Test(@$"(?s)^(?.+?)(?=[])")) 37 | return false; 38 | 39 | Group textGroup = ctx.TestGroups["text"]; 40 | string text = textGroup.Value.Trim(); 41 | if (text.Length == 0) return false; 42 | 43 | return true; 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /md2visio/mermaid/@cmn/ValueAccessor.cs: -------------------------------------------------------------------------------- 1 | using System.Text; 2 | 3 | namespace md2visio.mermaid.cmn 4 | { 5 | internal abstract class ValueAccessor 6 | { 7 | abstract public T? GetValue(string keyPath) where T : class; 8 | abstract public void SetValue(string key, object value); 9 | 10 | virtual public bool GetString(string keyPath, out string s) 11 | { 12 | s = GetValue(keyPath) ?? string.Empty; 13 | return s != string.Empty; 14 | } 15 | 16 | virtual public bool GetInt(string keyPath, out int i) 17 | { 18 | string? val = GetValue(keyPath); 19 | bool success = int.TryParse(val, out i); 20 | return success; 21 | } 22 | 23 | virtual public bool GetDouble(string keyPath, out double d) 24 | { 25 | string? val = GetValue(keyPath); 26 | bool success = double.TryParse(val, out d); 27 | return success; 28 | } 29 | 30 | protected void AppendKey(StringBuilder path, string key) 31 | { 32 | if (path.Length > 0) path.Append("."); 33 | path.Append(key); 34 | } 35 | 36 | protected void UnappendKey(StringBuilder path) 37 | { 38 | int dotIndex = path.Length - 1; 39 | for (; dotIndex >= 0; --dotIndex) 40 | { 41 | if (path[dotIndex] == '.') break; 42 | } 43 | if(dotIndex >= 0) path.Remove(dotIndex, path.Length - dotIndex); 44 | else path.Clear(); 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /md2visio/default/xyChart.yaml: -------------------------------------------------------------------------------- 1 | config: 2 | # mermaid.mermaidAPI.defaultConfig.xyChart 3 | xyChart: 4 | backgroundColor: white 5 | titleColor: '#131300' 6 | xAxisTitleColor: '#131300' 7 | xAxisLabelColor: '#131300' 8 | xAxisTickColor: '#131300' 9 | xAxisLineColor: '#131300' 10 | yAxisTitleColor: '#131300' 11 | yAxisLabelColor: '#131300' 12 | yAxisTickColor: '#131300' 13 | yAxisLineColor: '#131300' 14 | plotColorPalette: >- 15 | #ECECFF,#8493A6,#FFC3A0,#DCDDE1,#B8E994,#D1A36F,#C3CDE6,#FFB6C1,#496078,#F8F3E3 16 | useMaxWidth: true 17 | width: 700 18 | height: 500 19 | titleFontSize: 20 20 | titlePadding: 10 21 | showTitle: true 22 | xAxis: 23 | $ref: '#/$defs/XYChartAxisConfig' 24 | showLabel: true 25 | labelFontSize: 14 26 | labelPadding: 5 27 | showTitle: true 28 | titleFontSize: 16 29 | titlePadding: 5 30 | showTick: true 31 | tickLength: 5 32 | tickWidth: 2 33 | showAxisLine: true 34 | axisLineWidth: 2 35 | yAxis: 36 | $ref: '#/$defs/XYChartAxisConfig' 37 | showLabel: true 38 | labelFontSize: 14 39 | labelPadding: 5 40 | showTitle: true 41 | titleFontSize: 16 42 | titlePadding: 5 43 | showTick: true 44 | tickLength: 5 45 | tickWidth: 2 46 | showAxisLine: true 47 | axisLineWidth: 2 48 | chartOrientation: vertical 49 | plotReservedSpacePercent: 50 -------------------------------------------------------------------------------- /md2visio/mermaid/graph/internal/GSttMinus.cs: -------------------------------------------------------------------------------- 1 | using md2visio.mermaid.cmn; 2 | using System.Text.RegularExpressions; 3 | 4 | namespace md2visio.mermaid.graph.@internal 5 | { 6 | internal class GSttMinus : SynState 7 | { 8 | public override SynState NextState() 9 | { 10 | // left 11 | if (Buffer.Length > 1) return Forward(); 12 | else if (Buffer.Length == 1) 13 | { 14 | if (Regex.IsMatch(Buffer, "^[xo]$")) 15 | { 16 | if (GSttLinkStart.IsLinkStart(Ctx)) 17 | return ClearBuffer().Restore(1).Forward(); 18 | else if (GSttNoLabelLink.IsNoLabelLink(Ctx)) 19 | return ClearBuffer().Restore(1).Forward(); 20 | return Take().Forward(); 21 | } 22 | else if (GSttLinkStart.IsLinkStart(Ctx) || 23 | GSttNoLabelLink.IsNoLabelLink(Ctx)) 24 | { 25 | return Forward(); 26 | } 27 | else 28 | { 29 | return Take().Forward(); 30 | } 31 | } 32 | 33 | // right 34 | if (SttFrontMatter.IsConfig(Ctx)) return Forward(); 35 | if (GSttLinkStart.IsLinkStart(Ctx)) return Forward(); 36 | else if (GSttNoLabelLink.IsNoLabelLink(Ctx)) 37 | return Forward(); 38 | 39 | return Take().Forward(); 40 | } 41 | 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /md2visio/mermaid/@cmn/SynException.cs: -------------------------------------------------------------------------------- 1 | using System.Text; 2 | 3 | namespace md2visio.mermaid.cmn 4 | { 5 | internal class SynException : Exception 6 | { 7 | public SynException(string message) : base(message) { } 8 | 9 | public SynException(string message, SynContext context) : 10 | base(ContextMessage(message, context)) 11 | { 12 | 13 | } 14 | 15 | public SynException(string message, SttIterator iter) : 16 | base(ContextMessage(message, iter)) 17 | { 18 | 19 | } 20 | 21 | static string ContextMessage(string message, SttIterator iter) 22 | { 23 | return $"{message} near {iter.PeekPre().ToString()} {iter.PeekNext().ToString()}"; 24 | } 25 | 26 | static string ContextMessage(string message, SynContext context) 27 | { 28 | return $"{message} at line {context.LineNum} near {CurrentLine(context)}"; 29 | } 30 | 31 | static string CurrentLine(SynContext context) 32 | { 33 | StringBuilder sb = new StringBuilder(); 34 | for(int i = context.Consumed.Length-1; i>=0; --i) 35 | { 36 | char c = context.Consumed[i]; 37 | if (c == '\n') break; 38 | sb.Insert(0, c); 39 | } 40 | int column = sb.Length; 41 | for (int i = 0; i < context.Incoming.Length; ++i) 42 | { 43 | char c = context.Incoming[i]; 44 | if (c == '\n') break; 45 | sb.Append(c); 46 | } 47 | return $"'{sb.ToString()}' (column {column})"; 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /md2visio/mermaid/graph/GSttNoLabelLink.cs: -------------------------------------------------------------------------------- 1 | using md2visio.mermaid.cmn; 2 | using md2visio.mermaid.graph.@internal; 3 | using md2visio.struc.figure; 4 | 5 | namespace md2visio.mermaid.graph 6 | { 7 | internal class GSttNoLabelLink : SynState 8 | { 9 | public override SynState NextState() 10 | { 11 | SynState edge = Create(Ctx); 12 | if (edge.IsEmpty()) throw new SynException("syntax error", Ctx); 13 | 14 | return edge; 15 | } 16 | 17 | public static SynState Create(SynContext ctx) 18 | { 19 | if (!IsNoLabelLink(ctx)) 20 | return EmptyState.Instance; 21 | 22 | SynState state = new GSttNoLabelLink(); 23 | state.Ctx = ctx; 24 | state.Save(ctx.TestGroups["edge"].Value); 25 | 26 | return state.Slide(state.Fragment.Length).Forward(); 27 | } 28 | 29 | public static bool IsNoLabelLink(SynContext context) 30 | { 31 | return IsSolidSingleLine(context) 32 | || IsDashedSingleLine(context) 33 | || IsEmptyLink(context); 34 | } 35 | 36 | public static bool IsDashedSingleLine(SynContext ctx) 37 | { 38 | return ctx.Test(@"^(?[]?)"); 39 | } 40 | 41 | public static bool IsSolidSingleLine(SynContext ctx) 42 | { 43 | return ctx.Test(@"^(?[])") || 44 | ctx.Test(@"^(?[])"); 45 | } 46 | 47 | public static bool IsEmptyLink(SynContext ctx) 48 | { 49 | return ctx.Test("^(?~{3,})"); 50 | } 51 | 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /md2visio/mermaid/graph/internal/GSttChar.cs: -------------------------------------------------------------------------------- 1 | using md2visio.mermaid.cmn; 2 | 3 | namespace md2visio.mermaid.graph.@internal 4 | { 5 | internal class GSttChar : SynState 6 | { 7 | public override SynState NextState() 8 | { 9 | string? next = Ctx.Peek(); 10 | if (next == null) return EndOfFile; 11 | 12 | if (next == ";") { return Forward(); } 13 | if (next == "\n") { return Forward(); } 14 | if (next == "\t") { return Forward(); } 15 | if (next == " ") { return Forward(); } 16 | if (next == "@") { return Forward(); } 17 | if (next == "~") { return Forward(); } 18 | if (next == "{") { return Forward(); } 19 | if (next == "[") { return Forward(); } 20 | if (next == "(") { return Forward(); } 21 | if (next == "<") { return Forward(); } 22 | if (next == "`") { return Forward(); } 23 | if (next == "\"") { return Forward(); } 24 | if (next == "-") { return Forward(); } 25 | if (next == "=") { return Forward(); } 26 | if (next == "&") { return Forward(); } 27 | if (next == "%") { return Forward(); } 28 | if (next == "|") { return Forward(); } 29 | if (next == ")") { throw new SynException("unexpected ')'", Ctx); } 30 | if (next == "}") { throw new SynException("unexpected '}'", Ctx); } 31 | if (next == "]") { throw new SynException("unexpected ']'", Ctx); } 32 | if (next == ">") { throw new SynException("unexpected '>'", Ctx); } 33 | 34 | return Take().Forward(); 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /md2visio/struc/packet/PacBlock.cs: -------------------------------------------------------------------------------- 1 | using md2visio.struc.figure; 2 | using md2visio.struc.graph; 3 | using Microsoft.Office.Interop.Visio; 4 | 5 | namespace md2visio.struc.packet 6 | { 7 | internal class PacBlock : INode 8 | { 9 | public string ID { get; set; } = string.Empty; 10 | public string Label { get; set; } = string.Empty; 11 | public Shape? VisioShape { get; set; } 12 | public Container Container { get; set; } = Empty.Get(); 13 | public int BitStart { get; set; } = 0; 14 | public int BitEnd { get; set; } = 0; 15 | public int BitNum { get => BitEnd - BitStart + 1; } 16 | 17 | public PacBlock(string bits, string label) { 18 | string[] arr = bits.Split('-'); 19 | (bool success, int val) = ParseInt(arr[0]); 20 | if(success && val >= 0) BitStart = BitEnd = val; 21 | 22 | if(arr.Length > 1) { 23 | (success, val) = ParseInt(arr[1]); 24 | if(success && val >= BitStart) BitEnd = val; 25 | } 26 | 27 | ID = bits; 28 | Label = label; 29 | } 30 | 31 | public PacBlock Split(int headingBitNum) 32 | { 33 | if(headingBitNum >= BitNum) return this; 34 | 35 | int total = BitNum; 36 | BitEnd = BitStart + headingBitNum - 1; 37 | 38 | string bits = $"{BitEnd + 1}-{BitEnd + (total - headingBitNum)}"; 39 | return new PacBlock(bits, Label); 40 | } 41 | 42 | public List InputEdges => throw new NotImplementedException(); 43 | 44 | public List OutputEdges => throw new NotImplementedException(); 45 | 46 | (bool success, int val) ParseInt(string str) 47 | { 48 | int result = 0; 49 | bool success = int.TryParse(str.Trim(), out result); 50 | return (success, result); 51 | } 52 | 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /md2visio/md2visio.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net8.0 6 | enable 7 | enable 8 | AnyCPU;x64 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /md2visio/vsdx/@base/VFigureDrawer.cs: -------------------------------------------------------------------------------- 1 | using md2visio.struc.figure; 2 | using md2visio.vsdx.@tool; 3 | using Microsoft.Office.Interop.Visio; 4 | 5 | namespace md2visio.vsdx.@base 6 | { 7 | internal abstract class VFigureDrawer : 8 | VShapeDrawer where T : Figure 9 | { 10 | protected T figure = Empty.Get(); 11 | protected Config config; 12 | 13 | public VFigureDrawer(T figure, Application visioApp) : base(visioApp) 14 | { 15 | this.figure = figure; 16 | config = figure.Config; 17 | } 18 | 19 | public abstract void Draw(); 20 | 21 | public void SetFillForegnd(Shape shape, string configPath) 22 | { 23 | if (config.GetString(configPath, out string sColor)) 24 | { 25 | SetFillForegnd(shape, VColor.Create(sColor)); 26 | } 27 | } 28 | 29 | public void SetFillForegnd(Shape shape, VColor color) 30 | { 31 | SetShapeSheet(shape, "FillPattern", "1"); 32 | SetShapeSheet(shape, "FillForegnd", $"THEMEGUARD({color.RGB()})"); 33 | } 34 | 35 | public void SetLineColor(Shape shape, string configPath) 36 | { 37 | if(config.GetString(configPath, out string color)) { 38 | SetShapeSheet(shape, "LineColor", $"THEMEGUARD({VColor.Create(color).RGB()})"); 39 | } 40 | } 41 | 42 | public void SetTextColor(Shape shape, string configPath) 43 | { 44 | if (config.GetString(configPath, out string color)) { 45 | shape.CellsU["Char.Color"].FormulaU = $"THEMEGUARD({VColor.Create(color).RGB()})"; 46 | } 47 | } 48 | 49 | public List GetStringList(string prefix, int maxCount = 13) 50 | { 51 | List list = figure.Config.GetStringList(prefix, maxCount); 52 | if(list.Count == 0) 53 | list = figure.Config.GetStringListFromMultipleKeys(prefix); 54 | 55 | return list; 56 | } 57 | 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /md2visio/struc/figure/Empty.cs: -------------------------------------------------------------------------------- 1 | namespace md2visio.struc.figure 2 | { 3 | using System; 4 | using System.Collections.Concurrent; 5 | 6 | public static class Empty 7 | { 8 | private static readonly ConcurrentDictionary emptyInstances = new(); 9 | 10 | public static T Get() where T : class 11 | { 12 | return (T) emptyInstances.GetOrAdd(typeof(T), type => 13 | { 14 | try 15 | { 16 | #pragma warning disable CS8603 17 | return Activator.CreateInstance(type); 18 | #pragma warning restore CS8603 19 | } 20 | catch (Exception ex) 21 | { 22 | throw new InvalidOperationException( 23 | $"Can't create empty instance of {type.Name}. " + 24 | "Please ensure that the type has a public parameterless constructor, " + 25 | "or manually register the instance.", ex); 26 | } 27 | }); 28 | } 29 | 30 | private static object Get(Type type) 31 | { 32 | return emptyInstances.GetOrAdd(type, t => 33 | { 34 | try 35 | { 36 | #pragma warning disable CS8603 37 | return Activator.CreateInstance(t); 38 | #pragma warning restore CS8603 39 | } 40 | catch (Exception ex) 41 | { 42 | throw new InvalidOperationException( 43 | $"Can't create empty instance of {t.Name}. " + 44 | "Please ensure that the type has a public parameterless constructor, " + 45 | "or manually register the instance.", ex); 46 | } 47 | }); 48 | } 49 | 50 | public static bool IsEmpty(this T obj) where T : class 51 | { 52 | var objType = obj.GetType(); 53 | return obj == Get(objType); 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /md2visio/vsdx/@tool/VHSLColor.cs: -------------------------------------------------------------------------------- 1 | using System.Text.RegularExpressions; 2 | 3 | namespace md2visio.vsdx.@tool 4 | { 5 | internal class VHSLColor: VColor 6 | { 7 | public VHSLColor(float H, float S, float L, float a) 8 | { 9 | (this.H, this.S, this.L, this.a) = (H, S, L, a); 10 | (r, g, b) = HSL2RGB(H, S, L); 11 | Clamp(); 12 | } 13 | 14 | public static new VColor Create(string color) 15 | { 16 | (float H, float S, float L, float a) = ParseColor(color); 17 | return new VHSLColor(H, S, L, a); 18 | } 19 | 20 | protected static readonly Regex regHSL = new Regex(@"^\s*hsla?\s*\(\s*(?(?:-\s*)?\d*(.\d*)?)\s*,\s*(?\d*(.\d*)?\s*%?)\s*,\s*(?\d*(.\d*)?\s*%?)\s*(?\d*(.\d*)?)\s*\)\s*$", RegexOptions.Compiled); 21 | public static bool IsHSL(string color) 22 | { 23 | return regHSL.IsMatch(color.Trim().ToLower()); 24 | } 25 | 26 | protected static (float H, float S, float L, float a) ParseColor(string color) 27 | { 28 | color = color.Trim().ToLower(); 29 | (float H, float S, float L, float a) = (0, 0, 0, 1); 30 | 31 | Match match; 32 | if ((match = regHSL.Match(color)).Success) 33 | { 34 | float.TryParse(match.Groups["h"].Value, out H); 35 | TryParsePercent(match.Groups["s"].Value, out S); 36 | TryParsePercent(match.Groups["l"].Value, out L); 37 | if (match.Groups["a"].Success) 38 | TryParsePercent(match.Groups["a"].Value, out a); 39 | } 40 | 41 | return (H, S, L, a); 42 | } 43 | 44 | static bool TryParsePercent(string percent, out float f) 45 | { 46 | if (percent.EndsWith('%')) 47 | { 48 | bool success = float.TryParse(percent.TrimEnd('%').Trim(), out float r); 49 | f = success ? r / 100 : 0; 50 | return success; 51 | } 52 | else 53 | return float.TryParse(percent.Trim(), out f); 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /md2visio/mermaid/xy/XySttKeywordParam.cs: -------------------------------------------------------------------------------- 1 | using md2visio.mermaid.cmn; 2 | using System.Text.RegularExpressions; 3 | 4 | namespace md2visio.mermaid.xy 5 | { 6 | internal class XySttKeywordParam : SttKeywordParam 7 | { 8 | public override SynState NextState() 9 | { 10 | string keyword = Ctx.StateList.Last().Fragment; 11 | string param = ExpectedGroups["param"].Value; 12 | ParseParam(keyword, param); 13 | 14 | return Save(param).Forward(); 15 | } 16 | 17 | void ParseParam(string keyword, string param) 18 | { 19 | if(keyword == "x-axis") ParseXAxis(param); 20 | else if(keyword == "y-axis") ParseYAxis(param); 21 | } 22 | 23 | void ParseXAxis(string param) 24 | { 25 | Match match = Regex.Match(param, 26 | "^(\"?(?[^\\[\\n\"]+?)\"?)?[^\\S\\n]*((?<vals>\\[[^]]+\\])|(?<range>(?<s>\\d+)[^\\S\\n]*-->[^\\S\\n]*(?<e>\\d+)))?[^\\S\\n]*(?=\\n|$)"); 27 | if (!match.Success) throw new SynException("expected x-axis parameters", Ctx); 28 | 29 | if (match.Groups["title"].Success) AddCompo("title", match.Groups["title"].Value); 30 | if (match.Groups["vals"].Success) AddCompo("vals", match.Groups["vals"].Value); 31 | if (match.Groups["range"].Success) { 32 | AddCompo("rangeStart", match.Groups["s"].Value); 33 | AddCompo("rangeEnd", match.Groups["e"].Value); 34 | } 35 | } 36 | 37 | void ParseYAxis(string param) 38 | { 39 | Match match = Regex.Match(param, 40 | "^(\"?(?<title>[^\\[\\n\"]+?)\"?)?[^\\S\\n]*(?<range>(?<s>\\d+)[^\\S\\n]*-->[^\\S\\n]*(?<e>\\d+))?[^\\S\\n]*(?=\\n|$)"); 41 | if (!match.Success) throw new SynException("expected y-axis parameters", Ctx); 42 | 43 | if (match.Groups["title"].Success) AddCompo("title", match.Groups["title"].Value); 44 | if (match.Groups["range"].Success) { 45 | AddCompo("rangeStart", match.Groups["s"].Value); 46 | AddCompo("rangeEnd", match.Groups["e"].Value); 47 | } 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /md2visio/mermaid/@cmn/CompoDict.cs: -------------------------------------------------------------------------------- 1 | using System.Text; 2 | 3 | namespace md2visio.mermaid.cmn 4 | { 5 | internal class CompoDict 6 | { 7 | public static CompoDict Empty = new CompoDict(); 8 | string entire = "entire"; 9 | List<CompoValue> valueList = new List<CompoValue>(); // key the order of added values ([0]: Entire) 10 | Dictionary<string, CompoValue> dict = new Dictionary<string, CompoValue>(); 11 | 12 | public string Entire { get { return valueList[0].Value; } set { valueList[0].Value = value; } } 13 | 14 | public CompoDict() 15 | { 16 | Add(entire, string.Empty); 17 | } 18 | 19 | public void Add(string key, string value) 20 | { 21 | if (dict.ContainsKey(key)) dict[key].Value = value; 22 | else 23 | { 24 | CompoValue pv = new CompoValue(key, value); 25 | valueList.Add(pv); 26 | dict.Add(key, pv); 27 | } 28 | } 29 | 30 | public void Add(string value) 31 | { 32 | Add($"{valueList.Count}", value); 33 | } 34 | 35 | public bool ContainsKey(object key) 36 | { 37 | return dict.ContainsKey($"{key}"); 38 | } 39 | 40 | public string Get(string key) 41 | { 42 | return dict[key].Value; 43 | } 44 | 45 | public string Get(object key) 46 | { 47 | return Get($"{key}"); 48 | } 49 | 50 | public string? this[object key] 51 | { 52 | get 53 | { 54 | if (!ContainsKey(key)) return null; 55 | return Get($"{key}"); 56 | } 57 | } 58 | 59 | public List<CompoValue> Values() 60 | { 61 | return valueList; 62 | } 63 | 64 | public string MakeWhole() 65 | { 66 | StringBuilder sb = new StringBuilder(); 67 | foreach (var item in valueList) 68 | { 69 | if (item.Key == entire) continue; 70 | sb.Append(item.Value).Append(' '); 71 | } 72 | return sb.ToString(); 73 | } 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /md2visio/vsdx/@tool/FileTool.cs: -------------------------------------------------------------------------------- 1 | using md2visio.main; 2 | using md2visio.struc.figure; 3 | 4 | namespace md2visio.vsdx._tool 5 | { 6 | internal class FileTool 7 | { 8 | public static string ExtendPath(string path) 9 | { 10 | string? fullpath = Path.GetFullPath(path); 11 | if (!Path.Exists(fullpath)) 12 | fullpath = Path.Combine(ExeDir()??"", path); 13 | 14 | if (!Path.Exists(fullpath)) 15 | fullpath = Path.Combine(WorkDir()??"", path); 16 | 17 | if (!Path.Exists(fullpath)) 18 | fullpath = FindFileInPath(path); 19 | 20 | if (!Path.Exists(fullpath)) 21 | throw new FileNotFoundException($"File not found: {path}"); 22 | 23 | if(AppConfig.Instance.Debug) 24 | Console.WriteLine($"ExtendPath: {path} => {fullpath}"); 25 | 26 | return fullpath; 27 | } 28 | 29 | public static string? ExeDir() 30 | { 31 | return Path.GetDirectoryName(Environment.ProcessPath); 32 | } 33 | 34 | public static string WorkDir() 35 | { 36 | return Environment.CurrentDirectory; 37 | } 38 | 39 | public static string? FindFileInPath(string fileName) 40 | { 41 | string? pathEnv = Environment.GetEnvironmentVariable("PATH"); 42 | if (string.IsNullOrEmpty(pathEnv)) 43 | return null; 44 | 45 | char separator = Path.PathSeparator; // Windows上是';',Unix上是':' 46 | string[] pathDirectories = pathEnv.Split(separator, StringSplitOptions.RemoveEmptyEntries); 47 | 48 | foreach (string directory in pathDirectories) 49 | { 50 | string cleanDirectory = directory.Trim(); 51 | if (string.IsNullOrEmpty(cleanDirectory) || !Directory.Exists(cleanDirectory)) 52 | continue; 53 | 54 | string fullPath = Path.Combine(cleanDirectory, fileName); 55 | if (Path.Exists(fullPath)) 56 | { 57 | return fullPath; 58 | } 59 | } 60 | 61 | return null; 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /md2visio/mermaid/@cmn/TypeMap.cs: -------------------------------------------------------------------------------- 1 | using md2visio.mermaid.graph; 2 | using md2visio.mermaid.graph.@internal; 3 | using md2visio.mermaid.journey; 4 | using md2visio.mermaid.packet; 5 | using md2visio.mermaid.pie; 6 | using md2visio.mermaid.xy; 7 | using md2visio.struc.graph; 8 | using md2visio.struc.journey; 9 | using md2visio.struc.packet; 10 | using md2visio.struc.pie; 11 | using md2visio.struc.xy; 12 | 13 | namespace md2visio.mermaid.cmn 14 | { 15 | internal class TypeMap 16 | { 17 | public static readonly Dictionary<string, Type> KeywordMap = new() 18 | { 19 | { "graph", typeof(GSttKeyword) }, { "flowchart", typeof(GSttKeyword) }, 20 | { "journey", typeof(JoSttKeyword) }, 21 | { "pie", typeof(PieSttKeyword) }, 22 | { "packet-beta", typeof(PacSttKeyword) }, { "packet", typeof(PacSttKeyword) }, 23 | { "xychart-beta", typeof(XySttKeyword) }, { "xychart", typeof(XySttKeyword) }, 24 | }; 25 | 26 | public static readonly Dictionary<string, Type> CharMap = new() 27 | { 28 | { "graph", typeof(GSttChar) }, { "flowchart", typeof(GSttChar) }, 29 | { "journey", typeof(JoSttChar) }, 30 | { "pie", typeof(PieSttChar) }, 31 | { "packet-beta", typeof(PaSttChar) }, { "packet", typeof(PaSttChar) }, 32 | { "xychart-beta", typeof(XySttChar) }, { "xychart", typeof(XySttChar) }, 33 | }; 34 | 35 | public static readonly Dictionary<string, Type> BuilderMap = new() 36 | { 37 | { "graph", typeof(GBuilder) }, { "flowchart", typeof(GBuilder) }, 38 | { "journey", typeof(JoBuilder) }, 39 | { "pie", typeof(PieBuilder) }, 40 | { "packet-beta", typeof(PacBuilder) }, { "packet", typeof(PacBuilder) }, 41 | { "xychart-beta", typeof(XyBuilder) }, { "xychart", typeof(XyBuilder) }, 42 | }; 43 | 44 | public static readonly Dictionary<string, string> ConfigMap = new() 45 | { 46 | {typeof(Graph).Name, "flowchart"}, 47 | {typeof(Journey).Name, "journey"}, 48 | {typeof(Packet).Name, "packet"}, 49 | {typeof(Pie).Name, "pie"}, 50 | {typeof(XyChart).Name, "xyChart"}, 51 | }; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /md2visio/vsdx/@base/VBuilder.cs: -------------------------------------------------------------------------------- 1 | using md2visio.main; 2 | using Microsoft.Win32; 3 | using Visio = Microsoft.Office.Interop.Visio; 4 | 5 | namespace md2visio.vsdx.@base 6 | { 7 | internal abstract class VBuilder 8 | { 9 | public static Visio.Application VisioApp = new(); 10 | protected Visio.Document visioDoc; 11 | protected Visio.Page visioPage; 12 | public VBuilder() 13 | { 14 | VisioApp.Visible = AppConfig.Instance.Visible; 15 | visioDoc = VisioApp.Documents.Add(""); // 添加一个新文档 16 | visioPage = visioDoc.Pages[1]; // 获取活动页面 17 | } 18 | 19 | public void SaveAndClose(string outputFile) 20 | { 21 | visioPage.ResizeToFitContents(); 22 | 23 | AppConfig config = AppConfig.Instance; 24 | bool overwrite = true; 25 | if (!config.Quiet && File.Exists(outputFile)) 26 | { 27 | Console.WriteLine($"Output file '{outputFile}' exists, input Y to overwrite: "); 28 | overwrite = Console.ReadLine()?.ToLower() == "y"; 29 | } 30 | 31 | if (overwrite) visioDoc.SaveAsEx(outputFile, 0); 32 | else visioDoc.Saved = true; 33 | 34 | visioDoc.Close(); 35 | } 36 | 37 | 38 | public static string? GetVisioContentDirectory() 39 | { 40 | // 支持从Office 2003 (11.0) 到 Office 2019/2021 (16.0) 41 | int[] officeVersions = Enumerable.Range(11, 16).ToArray(); 42 | 43 | foreach (int version in officeVersions) 44 | { 45 | string subKey = $@"Software\Microsoft\Office\{version}.0\Visio\InstallRoot"; 46 | #pragma warning disable CA1416, CS8604 47 | using RegistryKey? key = Registry.LocalMachine.OpenSubKey(subKey); 48 | object? value = key?.GetValue("Path"); 49 | if (value != null) 50 | { 51 | string contentDir = Path.Combine(value.ToString(), "Visio Content"); 52 | #pragma warning restore CA1416, CS8604 53 | if (Directory.Exists(contentDir)) 54 | { 55 | return contentDir; 56 | } 57 | } 58 | } 59 | 60 | return null; 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /md2visio/mermaid/graph/GSttPaired.cs: -------------------------------------------------------------------------------- 1 | using md2visio.mermaid.cmn; 2 | using md2visio.mermaid.graph.@internal; 3 | using System.Text.RegularExpressions; 4 | 5 | namespace md2visio.mermaid.graph 6 | { 7 | internal class GSttPaired : SynState 8 | { 9 | public override SynState NextState() 10 | { 11 | if (!IsPaired(Ctx)) throw new SynException("expected pair start", Ctx); 12 | 13 | string pairStart = Ctx.TestGroups["start"].Value; 14 | if (!IsShapeStart(pairStart)) throw new SynException("expected shape start", Ctx); 15 | 16 | if (IsPaired(pairStart, Ctx)) 17 | { 18 | string mid = Ctx.TestGroups["mid"].Value; 19 | string close = Ctx.TestGroups["close"].Value; 20 | if (mid.Length == 0) throw new SynException("expected pair label", Ctx); 21 | 22 | string pair = Ctx.TestGroups[0].Value; 23 | AddCompo("start", pairStart); 24 | AddCompo("mid", mid); 25 | AddCompo("close", close); 26 | return Save(pair).Slide(Ctx.TestGroups[0].Length).Forward<GSttChar>(); 27 | } 28 | 29 | throw new SynException("expected pair close", Ctx); 30 | } 31 | 32 | public static bool IsPaired(SynContext ctx) 33 | { 34 | if (!ctx.Test(@"(?<start>[\[\{\(>]+)")) return false; 35 | return IsPaired(ctx.TestGroups["start"].Value, ctx); 36 | } 37 | 38 | public static bool IsPaired(string pairStart, SynContext ctx) 39 | { 40 | if (MmdPaired.IsPaired(pairStart, ctx.Incoming)) 41 | { 42 | ctx.TestGroups = MmdPaired.Groups; 43 | return true; 44 | } 45 | return false; 46 | } 47 | 48 | static Regex regShapeStart = 49 | new(@"^(>|\[{1,2}|\{{1,2}|\({1,3}|\[\(|\[\\|\[/|\(\[)$", RegexOptions.Compiled); 50 | bool IsShapeStart(string fragment) 51 | { 52 | return regShapeStart.IsMatch(fragment); 53 | } 54 | 55 | static Regex regShapeClose = 56 | new(@"^(\]{1,2}|\}{1,2}|\){1,3}|\)\]|\\\]|/\]|\]\))$", RegexOptions.Compiled); 57 | bool IsShapeClose(string fragment) 58 | { 59 | return regShapeClose.IsMatch(fragment); 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /md2visio/struc/pie/PieBuilder.cs: -------------------------------------------------------------------------------- 1 | using md2visio.mermaid.cmn; 2 | using md2visio.mermaid.pie; 3 | using md2visio.struc.figure; 4 | 5 | namespace md2visio.struc.pie 6 | { 7 | internal class PieBuilder(SttIterator iter) : FigureBuilder(iter) 8 | { 9 | readonly Pie pie = new(); 10 | 11 | public override void Build(string outputFile) 12 | { 13 | while (iter.HasNext()) 14 | { 15 | SynState cur = iter.Next(); 16 | if (cur is SttMermaidStart) { } 17 | if (cur is SttMermaidClose) 18 | { 19 | pie.ToVisio(outputFile); 20 | break; 21 | } 22 | if (cur is PieSttKeyword) { BuildKeyword(); } 23 | if (cur is PieSttTuple) { BuildDataItem(); } 24 | if (cur is SttComment) { pie.Config.LoadUserDirectiveFromComment(cur.Fragment); } 25 | if (cur is SttFrontMatter) { pie.Config.LoadUserFrontMatter(cur.Fragment); } 26 | } 27 | } 28 | 29 | void BuildKeyword() 30 | { 31 | string kw = iter.Current.Fragment; 32 | SynState next = iter.PeekNext(); 33 | 34 | if (kw == "pie") { 35 | if(next is PieSttKeywordParam) 36 | { 37 | var dict = ((PieSttKeywordParam) iter.Next()).ParsePieParam(); 38 | pie.ShowData = dict.ContainsKey("showData"); 39 | if(dict.TryGetValue("title", out string? value)) pie.Title = value; 40 | } 41 | } 42 | else if (kw == "title") 43 | { 44 | if (next is not PieSttKeywordParam) throw new SynException("expected title", iter); 45 | pie.Title = iter.Next().Fragment; 46 | } 47 | } 48 | 49 | void BuildDataItem() 50 | { 51 | PieSttTuple tuple = (PieSttTuple) iter.Current; 52 | PieDataItem dataItem = pie.RetrieveNode<PieDataItem>(tuple.CompoList.Get(1)); 53 | 54 | if (!double.TryParse(tuple.CompoList.Get(2), out double data) || 55 | data <= 0) 56 | throw new SynException("data must be a positive number", iter); 57 | dataItem.Data = data; 58 | 59 | pie.AddInnerNode(dataItem); 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /md2visio/struc/journey/JoBuilder.cs: -------------------------------------------------------------------------------- 1 | using md2visio.mermaid.cmn; 2 | using md2visio.mermaid.journey; 3 | using md2visio.struc.figure; 4 | 5 | namespace md2visio.struc.journey 6 | { 7 | internal class JoBuilder : FigureBuilder 8 | { 9 | Journey journey = new Journey(); 10 | JoSection curSection = Empty.Get<JoSection>(); 11 | public JoBuilder(SttIterator iter) : base(iter) { } 12 | 13 | public override void Build(string outputFile) 14 | { 15 | while (iter.HasNext()) 16 | { 17 | SynState cur = iter.Next(); 18 | if (cur is SttMermaidStart) { } 19 | if (cur is SttMermaidClose) 20 | { 21 | journey.ToVisio(outputFile); 22 | break; 23 | } 24 | if (cur is JoSttKeyword) { BuildKeyword(); } 25 | if (cur is JoSttTriple) { BuildTask(); } 26 | if (cur is SttComment) { journey.Config.LoadUserDirectiveFromComment(cur.Fragment); } 27 | if (cur is SttFrontMatter) { journey.Config.LoadUserFrontMatter(cur.Fragment); } 28 | } 29 | } 30 | 31 | void BuildKeyword() 32 | { 33 | string kw = iter.Current.Fragment; 34 | SynState next = iter.PeekNext(); 35 | 36 | if (kw == "journey") { } 37 | else if (kw == "title") 38 | { 39 | if (next is not JoSttKeywordParam) throw new SynException("expected title", iter); 40 | journey.Title = iter.Next().Fragment; 41 | } 42 | else if (kw == "section") 43 | { 44 | if (next is not JoSttKeywordParam) throw new SynException("expected section title", iter); 45 | 46 | curSection = journey.RetrieveNode<JoSection>(iter.Next().Fragment); 47 | journey.AddInnerNode(curSection); 48 | } 49 | 50 | } 51 | 52 | void BuildTask() 53 | { 54 | if (curSection.IsEmpty()) throw new SynException("expected section", iter); 55 | 56 | JoSttTriple triple = (JoSttTriple)iter.Current; 57 | CompoDict compo = triple.CompoList; 58 | JoTask task = new JoTask(compo.Get(1), compo.Get(2), compo.Get(3)); 59 | curSection.AddTask(task); 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /md2visio/main/AppConfig.cs: -------------------------------------------------------------------------------- 1 | using md2visio.vsdx._tool; 2 | 3 | namespace md2visio.main 4 | { 5 | internal class AppConfig 6 | { 7 | public static readonly AppConfig Instance = new AppConfig(); 8 | 9 | public string InputFile { get; set; } = string.Empty; 10 | public string OutputPath { get; set; } = FileTool.WorkDir(); 11 | public bool Visible { get; set; } = false; 12 | public bool Quiet { get; set; } = false; 13 | public bool Debug { get; set; } = false; 14 | public bool Test { get; set; } = false; 15 | 16 | AppConfig() { } 17 | 18 | public bool ParseArgs(string[] args) 19 | { 20 | for (int i = 0; i < args.Length; i++) 21 | { 22 | string arg = args[i].ToUpper(); 23 | if(arg=="/I" && i + 1 < args.Length) 24 | InputFile = args[++i]; 25 | else if(arg=="/O" && i + 1 < args.Length) 26 | OutputPath = args[++i]; 27 | else if(arg=="/Y") 28 | Quiet = true; 29 | else if(arg=="/V") 30 | Visible = true; 31 | else if (arg == "/D") 32 | Debug = true; 33 | else if (arg == "/T") 34 | Test = true; 35 | else if(arg == "/?" 36 | || arg == "/H" || arg == "/HELP" 37 | || arg == "-H" || arg == "-HELP" 38 | || arg == "--H" || arg == "--HELP") 39 | ShowHelp(); 40 | } 41 | 42 | bool success = InputFile != string.Empty && 43 | OutputPath != string.Empty; 44 | if(!success) ShowHelp(); 45 | 46 | return success; 47 | } 48 | 49 | void ShowHelp() 50 | { 51 | Console.WriteLine( 52 | "md2visio /I MD_FILE [/O OUTPUT_PATH] [/V] [/Y]\n\n" + 53 | "/I\tSpecify the path of the input file (.md)\n" + 54 | "/O\tSpecify the output folder or file path (.vsdx) (optional, default is the working directory)\n" + 55 | "/V\tShow the Visio application while drawing (optional, default is invisible)\n" + 56 | "/Y\tQuietly overwrite the existing output file (optional, by default requires user confirmation\n" + 57 | "/?\tPrint this help"); 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /md2visio/struc/figure/FigureBuilderFactory.cs: -------------------------------------------------------------------------------- 1 | using md2visio.mermaid.cmn; 2 | using System.Reflection; 3 | using md2visio.vsdx.@base; 4 | 5 | namespace md2visio.struc.figure 6 | { 7 | internal class FigureBuilderFactory 8 | { 9 | string outputFile; 10 | string? dir = string.Empty, name = string.Empty; 11 | Dictionary<string, Type> builderDict = TypeMap.BuilderMap; 12 | SttIterator iter; 13 | int count = 1; 14 | 15 | public FigureBuilderFactory(SttIterator iter) 16 | { 17 | this.iter = iter; 18 | outputFile = iter.Context.InputFile; 19 | } 20 | 21 | public void Build(string outputFile) 22 | { 23 | this.outputFile = outputFile; 24 | InitOutputPath(); 25 | BuildFigures(); 26 | } 27 | public void BuildFigures() 28 | { 29 | while (iter.HasNext()) 30 | { 31 | List<SynState> list = iter.Context.StateList; 32 | for (int pos = iter.Pos + 1; pos < list.Count; ++pos) 33 | { 34 | string word = list[pos].Fragment; 35 | if (SttFigureType.IsFigure(word)) 36 | BuildFigure(word); 37 | } 38 | } 39 | } 40 | public void Quit() 41 | { 42 | VBuilder.VisioApp.Quit(); 43 | } 44 | 45 | void BuildFigure(string figureType) 46 | { 47 | if (!builderDict.ContainsKey(figureType)) 48 | throw new NotImplementedException($"'{figureType}' builder not implemented"); 49 | 50 | Type type = builderDict[figureType]; 51 | object? obj = Activator.CreateInstance(type, iter); 52 | MethodInfo? method = type.GetMethod("Build", BindingFlags.Public | BindingFlags.Instance, null, 53 | new Type[] { typeof(string) }, null); 54 | 55 | method?.Invoke(obj, new object[] { $"{dir}\\{name}{count++}.vsdx" }); 56 | } 57 | 58 | void InitOutputPath() 59 | { 60 | if (outputFile.ToLower().EndsWith(".vsdx") || File.Exists(outputFile)) // file 61 | { 62 | name = Path.GetFileNameWithoutExtension(outputFile); 63 | dir = Path.GetDirectoryName(outputFile); 64 | } 65 | else // directory 66 | { 67 | if (!Directory.Exists(outputFile)) 68 | throw new FileNotFoundException($"output path doesn't exist: '{outputFile}'"); 69 | name = Path.GetFileNameWithoutExtension(iter.Context.InputFile); 70 | dir = Path.GetFullPath(outputFile).TrimEnd(new char[] { '/', '\\' }); 71 | } 72 | } 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /md2visio/struc/xy/XyBuilder.cs: -------------------------------------------------------------------------------- 1 | using md2visio.mermaid.cmn; 2 | using md2visio.mermaid.xy; 3 | using md2visio.struc.figure; 4 | 5 | namespace md2visio.struc.xy 6 | { 7 | internal class XyBuilder(SttIterator iter) : FigureBuilder(iter) 8 | { 9 | readonly XyChart xy = new(); 10 | 11 | public override void Build(string outputFile) 12 | { 13 | while (iter.HasNext()) 14 | { 15 | SynState cur = iter.Next(); 16 | if (cur is SttMermaidStart) { } 17 | if (cur is SttMermaidClose) { xy.ToVisio(outputFile); break; } 18 | if (cur is XySttKeyword) { BuildKeyword(); } 19 | if (cur is SttComment) { xy.Config.LoadUserDirectiveFromComment(cur.Fragment); } 20 | if (cur is SttFrontMatter) { xy.Config.LoadUserFrontMatter(cur.Fragment); } 21 | } 22 | } 23 | 24 | void BuildKeyword() 25 | { 26 | string kw = iter.Current.Fragment; 27 | SynState next = iter.PeekNext(); 28 | 29 | if (kw == "xychart" || kw == "xychart-beta") 30 | { 31 | if (next is XySttKeywordParam) 32 | xy.FrontMatter.SetValue("init.xyChart.chartOrientation", iter.Next().Fragment); 33 | } 34 | else if (kw == "title") 35 | { 36 | if (next is not XySttKeywordParam) throw new SynException("expected title", iter); 37 | xy.Title = iter.Next().Fragment.Trim('"'); 38 | } 39 | else if(kw == "x-axis") 40 | { 41 | if (next is not XySttKeywordParam) throw new SynException("expected x-axis parameters", iter); 42 | CompoDict compo = iter.Next().CompoList; 43 | xy.XAxis = new XyAxis(compo); 44 | } 45 | else if(kw == "y-axis") 46 | { 47 | if (next is not XySttKeywordParam) throw new SynException("expected y-axis parameters", iter); 48 | CompoDict compo = iter.Next().CompoList; 49 | xy.YAxis = new XyAxis(compo); 50 | } 51 | else if(kw == "line") 52 | { 53 | if (next is not XySttKeywordParam) throw new SynException("expected line parameters", iter); 54 | //xy.Line.Load(iter.Next().Fragment); 55 | xy.Contents.Add((new MmdJsonArray(iter.Next().Fragment), "line")); 56 | } 57 | else if(kw == "bar") 58 | { 59 | if (next is not XySttKeywordParam) throw new SynException("expected bar parameters", iter); 60 | //xy.Bar.Load(iter.Next().Fragment); 61 | xy.Contents.Add((new MmdJsonArray(iter.Next().Fragment), "bar")); 62 | } 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /md2visio/mermaid/graph/GSttKeywordParam.cs: -------------------------------------------------------------------------------- 1 | using md2visio.mermaid.cmn; 2 | using md2visio.mermaid.graph.@internal; 3 | using Microsoft.Office.Interop.Visio; 4 | using System.Text; 5 | 6 | namespace md2visio.mermaid.graph 7 | { 8 | internal class GSttKeywordParam : SynState 9 | { 10 | public override SynState NextState() 11 | { 12 | if (!Ctx.WithinKeyword()) throw new SynException("syntax error", Ctx); 13 | if (!HasParam(Ctx)) return SlideSpaces().Forward<GSttChar>(); 14 | 15 | SlideSpaces(); 16 | SaveParams(); 17 | return SlideSpaces().Forward<GSttChar>(); 18 | } 19 | 20 | public static bool HasParam(SynContext ctx) 21 | { 22 | bool match = ctx.Test(@"^(?<param>[^\n]+?)(?=\n|;)"); 23 | return match && ctx.TestGroups["param"].Value.Trim().Length > 0; 24 | } 25 | 26 | void SaveParams() 27 | { 28 | var text = new StringBuilder(); 29 | while (true) 30 | { 31 | string? next = Peek(); 32 | if (next == null || next == "\n" || next == ";") 33 | { 34 | AddText(text); 35 | break; 36 | } 37 | 38 | if (SttQuoted.TestQuoted(Ctx)) 39 | { 40 | AddText(text).AddCompo("\"", Ctx.TestGroups["quote"].Value); 41 | Slide(Ctx.TestGroups["0"].Length); 42 | } 43 | else if (next == "[") 44 | { 45 | if (!GSttPaired.IsPaired("[", Ctx)) throw new SynException("expected ']'", Ctx); 46 | string mid = Ctx.TestGroups["mid"].Value; 47 | AddText(text).AddCompo("[", mid); 48 | Slide(Ctx.TestGroups["0"].Length); 49 | } 50 | else if (IsKeyValues(Ctx)) 51 | { 52 | AddText(text).AddCompo(":", Ctx.TestGroups["kvs"].Value); 53 | Slide(Ctx.TestGroups["0"].Length); 54 | } 55 | else 56 | { 57 | text.Append(next); 58 | Slide(); 59 | } 60 | } 61 | 62 | Save(compoList.MakeWhole()); 63 | } 64 | 65 | GSttKeywordParam AddText(StringBuilder text) 66 | { 67 | if (text.Length > 0) 68 | { 69 | string t = text.ToString(); 70 | AddCompo("T", t.Trim()); 71 | text.Clear(); 72 | } 73 | return this; 74 | } 75 | 76 | public static bool IsKeyValues(SynContext ctx) 77 | { 78 | // e.g. "classDef className fill : #f9f, stroke:#333, stroke-width : 4px ;" 79 | return ctx.Test(@"^(?<kvs>([^, :\n]+([ \t\v\f]*:[ \t\v\f]*)[^,;\n]+([ \t\v\f]*,[ \t\v\f]*)?)+(?=[;\n]))"); 80 | } 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /md2visio/test/graph.md: -------------------------------------------------------------------------------- 1 | # Subgraph 2 | ```mermaid 3 | --- 4 | title: 带文本的节点 5 | --- 6 | %%{init: {'theme':'forest'}}%% 7 | graph LR 8 | C 9 | <--> 10 | D[[D估算载荷分布]] 11 | 12 | C --> SJ 13 | F[F遍历激光雷达数据点] --> G{G是否位于A/B段?} 14 | 15 | subgraph SJ ["实际扰度 16 | [计算]" 'calc'] 17 | direction 18 | G -- 是 --> H[H计算对应位置的载荷 P] 19 | 20 | subgraph ad [" "] 21 | direction TB 22 | G x-- LINK-=TEXT --> F 23 | end 24 | end 25 | ``` 26 | 27 | ```mermaid 28 | graph LR 29 | subgraph 结果处理 30 | G -->|否| D 31 | G -->|是| H(H:结果分析) 32 | H --> I(I:可视化结果) 33 | end 34 | 35 | subgraph 初始化 36 | A[A:初始化系统] --> B(B:设置仿真与控制参数) 37 | B --> C(C:初始化AUV状态和环境参数) 38 | end 39 | 40 | subgraph 主循环 41 | D{D:主循环} --> E(E:更新状态与时间) 42 | E --> F(F:计算控制输出) 43 | F --> G{G:结束循环?} 44 | end 45 | 46 | C --> D 47 | ``` 48 | 49 | ```mermaid 50 | %%{init: {'theme':'neutral'}}%% 51 | graph TB 52 | subgraph TL [推力控制] 53 | C --> D[D计算速度误差] 54 | D --> E[E计算PID控制输出] 55 | E --> F[F调整发动机转速] 56 | F --> G[G计算推力] 57 | end 58 | subgraph "位置控制" 59 | K 60 | C 61 | I -->|已达到| J[J检查是否到达目标位置] 62 | subgraph Inner 63 | K-->C 64 | end 65 | end 66 | 67 | A[A开始] --> B[B设定期望速度和目标位置] 68 | B --> TL 69 | G --> H[H更新装备速度] 70 | H --> I[I检查是否达到期望速度] 71 | I -->|未达到| C[C读取当前速度和位置] 72 | J -->|未到达| K[K调整方向和速度] 73 | J -->|已到达| L[L结束] 74 | ``` 75 | 76 | 77 | 78 | ## Comment 79 | 80 | `````mermaid 81 | %%{init: {"flowchart": {"htmlLabels": false}, 'theme':'dark'} }%% 82 | graph RL 83 | %% this is a comment 84 | %% 85 | A%% 86 | 87 | %% 88 | -- Text1 --- 89 | A%% 90 | 91 | D"" 92 | `` x==x E --> A%% 93 | 94 | A%% -->|Text2|D"" 95 | ````` 96 | 97 | # Edge and Shape 98 | 99 | ````mermaid 100 | %%{init: {'theme':'base'}}%% 101 | graph RL 102 | - -.-x D 103 | 104 | A ==o xD 105 | A-o--xD 106 | 107 | Ax--xD 108 | Ax--text0 109 | --> 110 | A --"text1" 111 | text2 112 | --> E 113 | 114 | D --> E{"`E{构建理想挠 115 | 曲线**模型**}`"} 116 | 117 | D[ 118 | D:lonely 119 | ] 120 | 121 | : <-- to --> E ~~~~ F 122 | ````` 123 | 124 | 125 | # AMP 126 | 127 | ```````mermaid 128 | graph BT 129 | &A & B --> C 130 | C-->D 131 | ``````` 132 | 133 | # Style 134 | 135 | ```mermaid 136 | graph LR 137 | classDef className fill:#f9f,stroke:#333,stroke-width:4px; 138 | class A className; 139 | style A-B fill:#bbf,stroke:#f66,stroke-width:2px,color:#fff,stroke-dasharray: 5 5 140 | A-B-->B@{shape: rounded, label: 'A: 文件,处理'} 141 | ``` 142 | 143 | # HTML 144 | 145 | ```mermaid 146 | graph LR 147 | A[确定目标距离 D] --> B[计算航行距离 D<sub>nav</sub>] 148 | B --> C{D ≤ D<sub>nav</sub> ?} 149 | C -->|是| D[计算自毁伤害 H] 150 | D --> E[执行撞击动作] 151 | C -->|否| F[继续搜索目标或采取其他行动] 152 | ``` 153 | 154 | -------------------------------------------------------------------------------- /md2visio/obj/md2visio.csproj.nuget.dgspec.json: -------------------------------------------------------------------------------- 1 | { 2 | "format": 1, 3 | "restore": { 4 | "C:\\Users\\TR\\文档\\GitHub\\md2visio\\md2visio\\md2visio.csproj": {} 5 | }, 6 | "projects": { 7 | "C:\\Users\\TR\\文档\\GitHub\\md2visio\\md2visio\\md2visio.csproj": { 8 | "version": "1.0.0", 9 | "restore": { 10 | "projectUniqueName": "C:\\Users\\TR\\文档\\GitHub\\md2visio\\md2visio\\md2visio.csproj", 11 | "projectName": "md2visio", 12 | "projectPath": "C:\\Users\\TR\\文档\\GitHub\\md2visio\\md2visio\\md2visio.csproj", 13 | "packagesPath": "C:\\Users\\TR\\.nuget\\packages\\", 14 | "outputPath": "C:\\Users\\TR\\文档\\GitHub\\md2visio\\md2visio\\obj\\", 15 | "projectStyle": "PackageReference", 16 | "fallbackFolders": [ 17 | "D:\\Program Files (x86)\\Microsoft Visual Studio\\Shared\\NuGetPackages" 18 | ], 19 | "configFilePaths": [ 20 | "C:\\Users\\TR\\AppData\\Roaming\\NuGet\\NuGet.Config", 21 | "C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.FallbackLocation.config", 22 | "C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.Offline.config" 23 | ], 24 | "originalTargetFrameworks": [ 25 | "net8.0" 26 | ], 27 | "sources": { 28 | "C:\\Program Files (x86)\\Microsoft SDKs\\NuGetPackages\\": {}, 29 | "C:\\Program Files\\dotnet\\library-packs": {}, 30 | "https://api.nuget.org/v3/index.json": {} 31 | }, 32 | "frameworks": { 33 | "net8.0": { 34 | "targetAlias": "net8.0", 35 | "projectReferences": {} 36 | } 37 | }, 38 | "warningProperties": { 39 | "warnAsError": [ 40 | "NU1605" 41 | ] 42 | }, 43 | "restoreAuditProperties": { 44 | "enableAudit": "true", 45 | "auditLevel": "low", 46 | "auditMode": "direct" 47 | }, 48 | "SdkAnalysisLevel": "9.0.300" 49 | }, 50 | "frameworks": { 51 | "net8.0": { 52 | "targetAlias": "net8.0", 53 | "dependencies": { 54 | "System.Drawing.Common": { 55 | "target": "Package", 56 | "version": "[9.0.1, )" 57 | }, 58 | "WonderCircuits.Microsoft.Office.Interop.Visio": { 59 | "target": "Package", 60 | "version": "[15.0.0, )" 61 | }, 62 | "YamlDotNet": { 63 | "target": "Package", 64 | "version": "[16.3.0, )" 65 | }, 66 | "stdole": { 67 | "target": "Package", 68 | "version": "[17.13.40008, )" 69 | } 70 | }, 71 | "imports": [ 72 | "net461", 73 | "net462", 74 | "net47", 75 | "net471", 76 | "net472", 77 | "net48", 78 | "net481" 79 | ], 80 | "assetTargetFallback": true, 81 | "warn": true, 82 | "frameworkReferences": { 83 | "Microsoft.NETCore.App": { 84 | "privateAssets": "all" 85 | } 86 | }, 87 | "runtimeIdentifierGraphPath": "C:\\Program Files\\dotnet\\sdk\\9.0.304/PortableRuntimeIdentifierGraph.json" 88 | } 89 | } 90 | } 91 | } 92 | } -------------------------------------------------------------------------------- /md2visio/struc/figure/ConfigDefaults.cs: -------------------------------------------------------------------------------- 1 | using md2visio.mermaid.cmn; 2 | using md2visio.vsdx._tool; 3 | 4 | namespace md2visio.struc.figure 5 | { 6 | internal class ConfigDefaults: IConfig 7 | { 8 | static readonly string defaultDir = FileTool.ExtendPath("default"); 9 | static readonly string themeDir = $"{defaultDir}/theme"; 10 | static readonly Dictionary<string, MmdFrontMatter> defConfig = new(); // ./default/?.yaml 11 | static readonly Dictionary<string, MmdFrontMatter> themeVars = new(); // ./default/theme/?.yaml 12 | static readonly string commonCfg = "default"; // ./default/default.yaml 13 | 14 | public Figure Figure { get; } 15 | public string Theme { get; set; } = "default"; 16 | public bool DarkMode { get; set; } = false; 17 | 18 | public ConfigDefaults(Figure figure) 19 | { 20 | Figure = figure; 21 | LoadFigureConfig(figure); 22 | LoadCommonConfig(); 23 | } 24 | 25 | public bool GetDouble(string keyPath, out double d) 26 | { 27 | return LoadThemeVars(Theme, DarkMode).GetDouble(keyPath, out d) 28 | || LoadFigureConfig(Figure).GetDouble(keyPath, out d) 29 | || LoadCommonConfig().GetDouble(keyPath, out d); 30 | } 31 | public bool GetInt(string keyPath, out int i) 32 | { 33 | return LoadThemeVars(Theme, DarkMode).GetInt(keyPath, out i) 34 | || LoadFigureConfig(Figure).GetInt(keyPath, out i) 35 | || LoadCommonConfig().GetInt(keyPath, out i); 36 | } 37 | public bool GetString(string keyPath, out string s) 38 | { 39 | return LoadThemeVars(Theme, DarkMode).GetString(keyPath, out s) 40 | || LoadFigureConfig(Figure).GetString(keyPath, out s) 41 | || LoadCommonConfig().GetString(keyPath, out s); 42 | } 43 | 44 | MmdFrontMatter LoadFigureConfig(Figure figure) 45 | { 46 | if (!TypeMap.ConfigMap.TryGetValue(figure.GetType().Name, out string? fName)) 47 | return Empty.Get<MmdFrontMatter>(); 48 | 49 | if (defConfig.TryGetValue(fName, out MmdFrontMatter? fm)) 50 | return fm ?? Empty.Get<MmdFrontMatter>(); 51 | 52 | fm = MmdFrontMatter.FromFile($"{defaultDir}/{fName}.yaml"); 53 | defConfig.Add(fName, fm); 54 | return fm; 55 | } 56 | 57 | MmdFrontMatter LoadCommonConfig() 58 | { 59 | if (defConfig.TryGetValue(commonCfg, out MmdFrontMatter? fm)) 60 | return fm; 61 | 62 | fm = MmdFrontMatter.FromFile($"{defaultDir}/{commonCfg}.yaml"); 63 | defConfig.Add(commonCfg, fm); 64 | return fm; 65 | } 66 | MmdFrontMatter LoadThemeVars(string theme2load, bool darkMode = false) 67 | { 68 | DarkMode = darkMode; 69 | Theme = theme2load.ToLower(); 70 | Theme = string.Format("{0}{1}", Theme, Theme == "base" && darkMode ? "-darkMode" : ""); 71 | if (themeVars.TryGetValue(Theme, out MmdFrontMatter? fm)) 72 | return fm ?? Empty.Get<MmdFrontMatter>(); 73 | 74 | fm = MmdFrontMatter.FromFile($"{themeDir}/{Theme}.yaml"); 75 | themeVars.Add(Theme, fm); 76 | 77 | return fm; 78 | } 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /md2visio/mermaid/@cmn/MmdPaired.cs: -------------------------------------------------------------------------------- 1 | using System.Text; 2 | using System.Text.RegularExpressions; 3 | 4 | namespace md2visio.mermaid.cmn 5 | { 6 | internal class MmdPaired 7 | { 8 | static GroupCollection testGroups = Regex.Match("", "").Groups; 9 | static public GroupCollection Groups { get { return testGroups; } } 10 | 11 | public static bool IsPaired(string pairStart, string text) 12 | { 13 | return IsPaired(pairStart, new StringBuilder(text)); 14 | } 15 | 16 | public static bool IsPaired(string pairStart, StringBuilder textBuilder) 17 | { 18 | string pairClose = PairClose(pairStart); 19 | StringBuilder sb = new StringBuilder(); 20 | bool withinQuote = false; 21 | int stackCount = 0; 22 | bool metStart = false; 23 | for (int i = 0; i < textBuilder.Length; ++i) 24 | { 25 | char c = textBuilder[i]; 26 | sb.Append(c); 27 | if (c == '"') withinQuote = !withinQuote; 28 | if (withinQuote) continue; 29 | 30 | // test start tag 31 | int len = Math.Min(pairStart.Length, sb.Length); 32 | if (sb.ToString(sb.Length - len, len) == pairStart) 33 | { 34 | metStart = true; 35 | stackCount++; 36 | } 37 | 38 | // test close tag 39 | len = Math.Min(pairClose.Length, sb.Length); 40 | if (sb.ToString(sb.Length - len, len) == pairClose) stackCount--; 41 | 42 | if (!metStart) continue; 43 | if (stackCount != 0) continue; 44 | 45 | int Lm = sb.Length - 2 * pairClose.Length; 46 | int Lc = pairClose.Length; 47 | testGroups = Regex.Match(textBuilder.ToString(0, sb.Length), 48 | @$"^(?s)(?<start>.{{{Lc}}})(?<mid>.{{{Lm}}})(?<close>.{{{Lc}}})").Groups; 49 | return true; 50 | } 51 | 52 | return false; 53 | } 54 | 55 | public static string PairClose(string pairStart) 56 | { 57 | StringBuilder sb = new StringBuilder(); 58 | foreach (char c in pairStart) 59 | { 60 | sb.Append(PairClose(c)); 61 | } 62 | return sb.ToString(); 63 | } 64 | 65 | public static char PairClose(char pairStart) 66 | { 67 | if (pairStart == '[') return ']'; 68 | else if (pairStart == '{') return '}'; 69 | else if (pairStart == '(') return ')'; 70 | else if (pairStart == '>') return ']'; 71 | else if (pairStart == '\'') return '\''; 72 | else if (pairStart == '"') return '"'; 73 | else if (pairStart == '`') return '`'; 74 | 75 | throw new ArgumentException($"{pairStart}"); 76 | } 77 | 78 | public static string PairPattern(string str) 79 | { 80 | StringBuilder sb = new StringBuilder(); 81 | foreach (char c in str) 82 | { 83 | if (c == '{' || c == '}' 84 | || c == '(' || c == ')' 85 | || c == '[' || c == ']') 86 | sb.Append("\\"); 87 | sb.Append(c); 88 | } 89 | return sb.ToString(); 90 | } 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /md2visio/vsdx/@tool/VRGBColor.cs: -------------------------------------------------------------------------------- 1 | using System.Globalization; 2 | using System.Text.RegularExpressions; 3 | 4 | namespace md2visio.vsdx.@tool 5 | { 6 | internal class VRGBColor: VColor 7 | { 8 | public VRGBColor(float r, float g, float b): this(r, g, b, 1) 9 | { 10 | } 11 | public VRGBColor(float r, float g, float b, float a) 12 | { 13 | (this.r, this.g, this.b, this.a) = (r, g, b, a); 14 | (H, S, L) = RGB2HSL(r, g, b); 15 | Clamp(); 16 | } 17 | public static new VColor Create(string color) 18 | { 19 | (float r, float g, float b, float a) = ParseColor(color); 20 | return new VRGBColor(r, g, b, a); 21 | } 22 | 23 | public static bool IsRGB(string color) 24 | { 25 | color = color.Trim().ToLower(); 26 | return regRGB.IsMatch(color) || 27 | regHexRRGGBB.IsMatch(color) || 28 | regHexRGB.IsMatch(color); 29 | } 30 | 31 | protected static readonly Regex regRGB = new Regex(@"^\s*rgba?\s*\(\s*(?<r>\d*(.\d*)?)\s*,\s*(?<g>\d*(.\d*)?)\s*,\s*(?<b>\d*(.\d*)?)\s*(?<a>\d*(.\d*)?)\s*\)\s*$", RegexOptions.Compiled); 32 | protected static readonly Regex regHexRRGGBB = new Regex(@"^\s*#\s*(?<a>[0-9a-f]{2})?\s*(?<r>[0-9a-f]{2})\s*(?<g>[0-9a-f]{2})\s*(?<b>[0-9a-f]{2})\s*$", RegexOptions.Compiled); 33 | protected static readonly Regex regHexRGB = new Regex(@"^\s*#\s*(?<r>[0-9a-f])\s*(?<g>[0-9a-f])\s*(?<b>[0-9a-f])\s*$", RegexOptions.Compiled); 34 | protected static (float r, float g, float b, float a) ParseColor(string color) 35 | { 36 | color = color.Trim().ToLower(); 37 | (float r, float g, float b, float a) = (0, 0, 0, 1); 38 | 39 | Match match; 40 | // RGB 41 | if ((match = regRGB.Match(color)).Success) 42 | { 43 | float.TryParse(match.Groups["r"].Value, out r); 44 | float.TryParse(match.Groups["g"].Value, out g); 45 | float.TryParse(match.Groups["b"].Value, out b); 46 | if (match.Groups["a"].Success) 47 | float.TryParse(match.Groups["a"].Value, out a); 48 | } 49 | // Hex #RRGGBB 50 | else if ((match = regHexRRGGBB.Match(color)).Success) 51 | { 52 | try { r = int.Parse(match.Groups["r"].Value, NumberStyles.HexNumber); } catch { } 53 | try { g = int.Parse(match.Groups["g"].Value, NumberStyles.HexNumber); } catch { } 54 | try { b = int.Parse(match.Groups["b"].Value, NumberStyles.HexNumber); } catch { } 55 | if (match.Groups["a"].Success) 56 | try { a = int.Parse(match.Groups["a"].Value, NumberStyles.HexNumber); } catch { } 57 | } 58 | // Hex #RGB 59 | else if ((match = regHexRGB.Match(color)).Success) 60 | { 61 | try { r = int.Parse(DoubleHex(match.Groups["r"].Value), NumberStyles.HexNumber); } catch { } 62 | try { g = int.Parse(DoubleHex(match.Groups["g"].Value), NumberStyles.HexNumber); } catch { } 63 | try { b = int.Parse(DoubleHex(match.Groups["b"].Value), NumberStyles.HexNumber); } catch { } 64 | if (match.Groups["a"].Success) 65 | try { a = int.Parse(match.Groups["a"].Value, NumberStyles.HexNumber); } catch { } 66 | } 67 | 68 | return (r, g, b, a); 69 | } 70 | 71 | static string DoubleHex(string value) 72 | { 73 | return $"{value}{value}"; 74 | } 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /md2visio/struc/graph/GSubgraph.cs: -------------------------------------------------------------------------------- 1 | using md2visio.mermaid.cmn; 2 | using md2visio.struc.figure; 3 | using Microsoft.Office.Interop.Visio; 4 | using System.Text; 5 | 6 | namespace md2visio.struc.graph 7 | { 8 | internal class GSubgraph : Graph, INode 9 | { 10 | GLabel label = new GLabel(string.Empty); 11 | List<GNode>? allGroupedNodes = null; 12 | GNode borderNode = Empty.Get<GBorderNode>(); 13 | 14 | public GSubgraph() { } 15 | 16 | public GNode BorderNode { get => borderNode; } 17 | public List<GNode> AllGroupedNodes { get => GetAllGroupedNodes(); } 18 | 19 | public string ID { get => $"_{borderNode.ID}_"; set => SetID(value); } 20 | public string Label 21 | { 22 | get { return label.ToString(); } 23 | set { label.Content = value; } 24 | } 25 | public Container Container { 26 | get => Parent ?? Empty.Get<Container>(); 27 | set { SetContainer(value); } 28 | } 29 | 30 | public GSubgraph(Graph parent) 31 | { 32 | Parent = parent; 33 | } 34 | public Shape? VisioShape { 35 | get => borderNode.VisioShape; 36 | set => borderNode.VisioShape = value; 37 | } 38 | 39 | public List<GEdge> InputEdges { get; set; } = new List<GEdge>(); 40 | 41 | public List<GEdge> OutputEdges { get; set; } = new List<GEdge>(); 42 | 43 | public override void SetParam(CompoDict valueList) 44 | { 45 | StringBuilder t = new StringBuilder(); 46 | foreach (var item in valueList.Values()) 47 | { 48 | if (item.IsPaired()) Label = item.Value; 49 | else if (item.IsText()) t.Append(item.Value); 50 | else if (item.IsQuoted()) t.Append(item.Value); 51 | } 52 | if (t.Length == 0) throw new SynException("expected subgraph ID"); 53 | ID = t.ToString(); 54 | } 55 | public override string ToString() 56 | { 57 | StringBuilder sb = new StringBuilder(); 58 | List<INode> nodes = groupedNodes.Values.ToList(); 59 | foreach(INode node in nodes) 60 | { 61 | if (node == nodes.First()) sb.Append(": "); 62 | if (node.Container == this) sb.Append(node.ID); 63 | if (node != nodes.Last()) sb.Append(", "); 64 | } 65 | sb.Insert(0, ID); 66 | return sb.ToString(); 67 | } 68 | 69 | void SetContainer(Container value) 70 | { 71 | if (Parent != null) 72 | { 73 | Parent.GroupedNodes.Remove(ID); 74 | } 75 | Parent = value; 76 | Parent.AddInnerNode(this); 77 | } 78 | 79 | void SetID(string value) 80 | { 81 | if (nodeDict.ContainsKey(value)) 82 | { 83 | nodeDict[value].Container.GroupedNodes.Remove(value); 84 | nodeDict.Remove(value); 85 | } 86 | 87 | borderNode = RetrieveNode<GBorderNode>(value); 88 | borderNode.Container = this; 89 | 90 | if (label.Content.Length == 0) Label = value; 91 | } 92 | 93 | List<GNode> GetAllGroupedNodes() 94 | { 95 | if(allGroupedNodes != null) return allGroupedNodes; 96 | 97 | allGroupedNodes = new(groupedNodes.Values.OfType<GNode>()) 98 | { 99 | borderNode 100 | }; 101 | foreach(GSubgraph sub in Subgraphs) 102 | { 103 | allGroupedNodes.AddRange(sub.GetAllGroupedNodes()); 104 | } 105 | 106 | return allGroupedNodes; 107 | } 108 | 109 | 110 | } 111 | 112 | } 113 | -------------------------------------------------------------------------------- /md2visio/struc/figure/Container.cs: -------------------------------------------------------------------------------- 1 | using md2visio.struc.graph; 2 | using System.Text.RegularExpressions; 3 | 4 | namespace md2visio.struc.figure 5 | { 6 | internal class Container 7 | { 8 | string direction = "LR"; 9 | GrowthDirection shift; 10 | Container? parent = null; 11 | List<Container>? ancestors = null; 12 | 13 | protected Dictionary<string, INode> nodeDict = new Dictionary<string, INode>(); 14 | protected Dictionary<string, INode> innerNodes = new Dictionary<string, INode>(); 15 | protected Dictionary<string, INode> groupedNodes = new Dictionary<string, INode>(); // nodes grouped by a subgraph 16 | 17 | public string Direction 18 | { 19 | get { return direction; } 20 | set { if (IsDirectionFragment(value)) { direction = value.Trim(); shift.Decide(this); } } 21 | } 22 | public Dictionary<string, INode> InnerNodes { get { return innerNodes; } } 23 | public Dictionary<string, INode> NodeDict { get { return nodeDict; } } 24 | public GrowthDirection GrowthDirect { get { return shift; } } 25 | public Container? Parent 26 | { 27 | get => parent; 28 | set { if (value != null) nodeDict = value.nodeDict; parent = value; } 29 | } 30 | public List<Container> Ancestors { get => GetAncestorList(); } 31 | public Dictionary<string, INode> GroupedNodes { get => groupedNodes; } 32 | public Container() 33 | { 34 | shift = new GrowthDirection(this); 35 | } 36 | 37 | public virtual T RetrieveNode<T>(string id) where T : INode, new() 38 | { 39 | if (nodeDict.ContainsKey(id)) return (T)nodeDict[id]; 40 | 41 | T node = new T(); 42 | node.Container = this; 43 | node.ID = id; 44 | 45 | AddNodeToDict(node); 46 | return node; 47 | } 48 | 49 | public void AddInnerNode(INode node) 50 | { 51 | if (innerNodes.ContainsKey(node.ID)) return; 52 | 53 | innerNodes.Add(node.ID, node); 54 | AddNodeToDict(node); 55 | 56 | // judge container 57 | if (node.Container.IsEmpty()) node.Container = this; 58 | else if (node.Container.GetType() == typeof(Graph)) 59 | { 60 | if (GetType() == typeof(GSubgraph)) 61 | { 62 | node.Container.groupedNodes.Remove(node.ID); 63 | node.Container = this; 64 | } 65 | } 66 | else if (node.Container.GetType() == typeof(GSubgraph)) 67 | { 68 | if (Ancestors.Contains(node.Container)) 69 | { 70 | node.Container.groupedNodes.Remove(node.ID); 71 | node.Container = this; 72 | } 73 | } 74 | 75 | if(node.Container == this && !groupedNodes.ContainsKey(node.ID)) 76 | groupedNodes.Add(node.ID, node); 77 | } 78 | 79 | public T DownCast<T>() where T : Container 80 | { 81 | if (this is T) return (T)this; 82 | 83 | throw new InvalidCastException(); 84 | } 85 | 86 | protected void AddNodeToDict(INode node) 87 | { 88 | if (!nodeDict.ContainsKey(node.ID)) 89 | nodeDict.Add(node.ID, node); 90 | } 91 | 92 | static public bool IsDirectionFragment(string fragment) 93 | { 94 | return Regex.IsMatch(fragment.Trim(), "^(LR|RL|TB|TD|BT)$"); 95 | } 96 | 97 | List<Container> GetAncestorList() 98 | { 99 | if (ancestors != null) return ancestors; 100 | 101 | ancestors = new List<Container>(); 102 | Container? parent = Parent; 103 | while (parent != null) 104 | { 105 | ancestors.Add(parent); 106 | parent = parent.Parent; 107 | } 108 | 109 | return ancestors; 110 | } 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /md2visio/struc/graph/GEdge.cs: -------------------------------------------------------------------------------- 1 | using md2visio.struc.figure; 2 | using System.Text.RegularExpressions; 3 | 4 | namespace md2visio.struc.graph 5 | { 6 | internal class GEdge : Edge 7 | { 8 | GNode from = Empty.Get<GNode>(), to = Empty.Get<GNode>(); 9 | string lineType = "-"; // solid/bold/dashed (-/=/.) 10 | string startTag = "-"; // x/o/-/< 11 | string endTag = "-"; // x/o/-/> 12 | public string Text { get; set; } = string.Empty; 13 | public GNode From { get { return (GNode) from.Container.NodeDict[from.ID]; } } 14 | public GNode To { get { return (GNode) to.Container.NodeDict[to.ID]; ; } } 15 | public string LineType 16 | { 17 | get { return lineType; } 18 | set 19 | { 20 | if (value.Contains("=")) lineType = "="; 21 | else if (value.Contains(".")) lineType = "."; 22 | else if (value.Contains("~")) lineType = "~"; 23 | else lineType = "-"; 24 | } 25 | } 26 | public string StartTag 27 | { 28 | get { return startTag; } 29 | set 30 | { 31 | startTag = value.Substring(0, 1); 32 | LineType = value; 33 | } 34 | } 35 | public string EndTag 36 | { 37 | get { return endTag; } 38 | set 39 | { 40 | endTag = $"{value.Last()}"; 41 | } 42 | } 43 | public GEdge() { } 44 | public GEdge(GNode from) 45 | { 46 | this.from = from; 47 | } 48 | public void ConnectTo(GNode to) 49 | { 50 | if (from.IsEmpty() || to.IsEmpty()) throw new ArgumentException("connection points can't be empty"); 51 | 52 | this.to = to; 53 | from.AddOutEdge(this); 54 | to.AddInEdge(this); 55 | } 56 | 57 | public void Connect(GNode from, GNode to) 58 | { 59 | this.from = from; 60 | ConnectTo(to); 61 | } 62 | 63 | public GEdge Clone() 64 | { 65 | GEdge c = new GEdge(); 66 | c.Text = Text; 67 | c.lineType = lineType; 68 | c.startTag = startTag; 69 | c.endTag = endTag; 70 | c.from = from; 71 | c.to = to; 72 | 73 | return c; 74 | } 75 | 76 | static public bool IsEdgeFragment(string fragment) 77 | { 78 | return Regex.IsMatch(fragment, @"^(--|==)>?$"); 79 | } 80 | 81 | static public bool IsEdgeStartFragment(string fragment) 82 | { 83 | return Regex.IsMatch(fragment, @"^(--|==)$"); 84 | } 85 | 86 | static public string EdgeEndFragmentPattern(string startFragment) 87 | { 88 | if (startFragment == "--") return "-->"; 89 | return "==>"; 90 | } 91 | 92 | static public string GetLineType(string fragment) 93 | { 94 | return fragment.Replace(">", ""); 95 | } 96 | 97 | public override string ToString() 98 | { 99 | return string.Format("{0}{1}{2}", LineType, Text, Text == string.Empty ? ">" : $"{LineType}>"); 100 | } 101 | 102 | public override bool Equals(object? obj) 103 | { 104 | if (ReferenceEquals(this, obj)) return true; 105 | if (obj == null || GetType() != obj.GetType()) return false; 106 | 107 | return from.Equals(((GEdge)obj).from) && 108 | to.Equals(((GEdge)obj).to) && 109 | Text.Equals(((GEdge)obj).Text); 110 | } 111 | 112 | public override int GetHashCode() 113 | { 114 | unchecked 115 | { 116 | string edge = ToString(); 117 | int hash = 17; 118 | hash = hash * 23 + (edge != null ? edge.GetHashCode() : 0); 119 | hash = hash * 23 + (edge != null ? edge.GetHashCode() : 0); 120 | return hash; 121 | } 122 | } 123 | } 124 | } 125 | -------------------------------------------------------------------------------- /md2visio/struc/figure/Config.cs: -------------------------------------------------------------------------------- 1 | namespace md2visio.struc.figure 2 | { 3 | internal class Config: IConfig 4 | { 5 | ConfigDefaults configDefaults; 6 | MmdFrontMatter userFrontMatter = new(); 7 | MmdJsonObj userDirective = new(); 8 | 9 | public MmdFrontMatter UserFrontMatter { get => userFrontMatter; set => userFrontMatter = value; } 10 | public MmdJsonObj UserDirective { get => userDirective; set => userDirective = value; } 11 | 12 | public Config(Figure figure) 13 | { 14 | configDefaults = new(figure); 15 | } 16 | public MmdFrontMatter LoadUserDirective(string directive) 17 | { 18 | try 19 | { 20 | userDirective.Load(directive); 21 | return userFrontMatter.UpdateWith(UserDirective); 22 | } 23 | catch (ArgumentException) 24 | { 25 | return userFrontMatter; 26 | } 27 | } 28 | 29 | public MmdFrontMatter LoadUserDirectiveFromComment(string comment) 30 | { 31 | if (!comment.TrimEnd(' ').EndsWith("%%")) return Empty.Get<MmdFrontMatter>(); 32 | 33 | char[] trims = ['%', '\t', '\n', '\r', '\f', ' ']; 34 | string setting = comment.TrimStart(trims).TrimEnd(trims); 35 | return LoadUserDirective(setting); 36 | } 37 | public MmdFrontMatter LoadUserFrontMatter(string frontMatter) 38 | { 39 | return UserFrontMatter.LoadYaml(frontMatter); 40 | } 41 | 42 | public bool GetDouble(string keyPath, out double d) 43 | { 44 | return GetUserDouble(keyPath, out d) 45 | || UpdateDefaults().GetDouble(keyPath, out d); 46 | } 47 | public bool GetInt(string keyPath, out int i) 48 | { 49 | return GetUserInt(keyPath, out i) 50 | || UpdateDefaults().GetInt(keyPath, out i); 51 | } 52 | public bool GetString(string keyPath, out string s) 53 | { 54 | return GetUserString(keyPath, out s) 55 | || UpdateDefaults().GetString(keyPath, out s); 56 | } 57 | 58 | public List<string> GetStringList(string keyPath, int maxCount = 13) 59 | { 60 | List<string> serial = new(); 61 | if(!GetString(keyPath, out string s)) return serial; 62 | 63 | string[] arr = s.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries); 64 | for (int i = 0; i < Math.Min(arr.Length, maxCount); ++i) 65 | { 66 | serial.Add(arr[i]); 67 | } 68 | return serial; 69 | } 70 | 71 | public List<string> GetStringListFromMultipleKeys(string keyPathPrefix, int maxCount = 13) 72 | { 73 | List<string> serial = new(); 74 | for (int i = 0; i < maxCount; ++i) 75 | { 76 | if(GetString(keyPathPrefix + i, out string s)) 77 | serial.Add(s); 78 | } 79 | return serial; 80 | } 81 | 82 | bool GetUserString(string keyPath, out string s) 83 | { 84 | if (userDirective.GetString(keyPath, out s)) return true; 85 | return userFrontMatter.GetString(keyPath, out s); 86 | } 87 | 88 | bool GetUserInt(string keyPath, out int i) 89 | { 90 | if (userDirective.GetInt(keyPath, out i)) return true; 91 | return userFrontMatter.GetInt(keyPath, out i); 92 | } 93 | 94 | bool GetUserDouble(string keyPath, out double d) 95 | { 96 | if (userDirective.GetDouble(keyPath, out d)) return true; 97 | return userFrontMatter.GetDouble(keyPath, out d); 98 | } 99 | 100 | ConfigDefaults UpdateDefaults() 101 | { 102 | configDefaults.Theme = GetUserString("config.theme", out string theme) ? theme : "default"; 103 | configDefaults.DarkMode = GetUserString("config.themeVariables.darkMode", out string darkMode) 104 | && darkMode == "true"; 105 | 106 | return configDefaults; 107 | } 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # md2visio 4 | 5 | > convert Markdown (`mermaid` / `mmd`) to `Visio` (`vsdx`) 6 | 7 | AI-assisted programming simplifies the creation of algorithm flowcharts. Many large language models (LLMs) are capable of generating Markdown (`Mermaid`) flowcharts. However, Markdown editors lack the functionality to edit these flowcharts as intuitively as specialized drawing tools such as `Visio`, which allow for actions like moving nodes or reorganizing layouts. 8 | 9 | The tool `md2visio` bridges this gap by converting Markdown (`Mermaid`/`MMD`) into `Visio` (`.vsdx`) format. This enables users to leverage the capabilities of LLMs for initial chart creation while also benefiting from the advanced editing features of `Visio` for further customization and refinement of the flowcharts. 10 | 11 | Mermaid example: 12 | 13 | ````bat 14 | ```mermaid 15 | journey 16 | %% journey test 17 | title My working day 18 | section Go to work 19 | Make tea: 5: Me 20 | Go upstairs: 3: Me 21 | Do work: 1: Me, Cat 22 | section Go home 23 | Go downstairs: 5: Me 24 | Sit down: 5: Me 25 | section Go home 26 | Make tea: 3: Me 27 | ``` 28 | ```` 29 | 30 | Generated `Visio` graph: 31 | 32 | <img src="https://github.com/Megre/md2visio/blob/main/example.png" alt="journey.vssx" style="zoom: 50%;" /> 33 | 34 | 35 | 36 | # Usage 37 | 38 | ## Command Line 39 | 40 | ```bat 41 | md2visio /I MD_FILE [/O OUTPUT_PATH] [/V] [/Y] 42 | 43 | /I Specify the path of the input file (.md) 44 | /O Specify the output folder or file path (.vsdx) (optional, default is the working directory) 45 | /V Show the Visio application while drawing (optional, default is invisible) 46 | /Y Quietly overwrite the existing output file (optional, by default requires user confirmation) 47 | /? Print this help 48 | ``` 49 | 50 | Example: 51 | 52 | ```bash 53 | md2visio /I D:\figure.md /O D:\ 54 | ``` 55 | 56 | It converts all `Mermaid` figures in `figure.md` and outputs `.vssx` files to `D:\` 57 | 58 | 59 | 60 | ## Requirements 61 | 62 | - `Microsoft Visio 2010` or later. You need install `Visio` since `md2visio` opens `Visio` and automatically draws figures on it. 63 | - [md2visio.vssx](./md2visio/md2visio.vssx). This stencil file is provided by this project ([./md2visio/md2visio.vssx](./md2visio/md2visio.vssx)). It contains basic figure parts used by `md2visio`. You need to put this file to execution file path (or system path). 64 | 65 | 66 | 67 | # Supported Mermaid Figure 68 | 69 | Development plan: 70 | 71 | - [x] graph / flowchart 72 | - [x] themes 73 | - [x] journey 74 | - [x] themes 75 | - [ ] sequencefigure 76 | - [ ] classfigure 77 | - [ ] statefigure 78 | - [ ] statefigure-v2 79 | - [ ] erfigure 80 | - [ ] gantt 81 | - [x] pie 82 | - [x] themes 83 | - [ ] quadrantChart 84 | - [ ] requirementfigure 85 | - [ ] gitGraph 86 | - [ ] C4Context 87 | - [ ] mindmap 88 | - [ ] timeline 89 | - [ ] zenuml 90 | - [ ] sankey-beta 91 | - [x] xychart-beta 92 | - [ ] block-beta 93 | - [x] packet-beta 94 | - [x] themes 95 | - [ ] kanban 96 | - [ ] architecture-beta 97 | - [x] Configuration 98 | - [x] frontmatter 99 | - [x] directive 100 | 101 | 102 | 103 | # Contributing 104 | 105 | ## Introduction 106 | 107 | The implementation of the project consists of several parts: 108 | 109 | **Syntax Parsing.** When parsing Mermaid syntax, the project treats the Mermaid text as a state machine composed of different fields. By continuously looking ahead and backtracking, it identifies the components that constitute different types of figures. The initial state for every figure is always `SttMermaidStart` (three or more **Backtick**), and the final state is always `SttMermaidClose` (three or more **Backtick**). 110 | 111 | **Building the data structure for figures.** The parsed components are structured into a well-defined format, preparing the data for rendering. 112 | 113 | **Rendering in Visio.** To enable rendering, an `md2visio.vssx` file was created. It contains reusable graphical elements which the rendering program repeatedly uses to construct the figures. 114 | 115 | 116 | 117 | ## Build 118 | 119 | The project is built with Visual Studio 2022. All dependency solution files are uploaded. 120 | 121 | 122 | 123 | ## Depending Packages 124 | 125 | - WonderCircuits.Microsoft.Office.Interop.Visio 126 | - WonderCircuits.Microsoft.Office.Core 127 | - WonderCircuits.Microsoft.Vbe.Interop 128 | - YamlDotNet 129 | -------------------------------------------------------------------------------- /md2visio/obj/Debug/net8.0/md2visio.csproj.FileListAbsolute.txt: -------------------------------------------------------------------------------- 1 | C:\Users\Megre\Documents\GitHub\md2visio\md2visio\bin\Debug\net8.0\md2visio.exe 2 | C:\Users\Megre\Documents\GitHub\md2visio\md2visio\bin\Debug\net8.0\md2visio.deps.json 3 | C:\Users\Megre\Documents\GitHub\md2visio\md2visio\bin\Debug\net8.0\md2visio.runtimeconfig.json 4 | C:\Users\Megre\Documents\GitHub\md2visio\md2visio\bin\Debug\net8.0\md2visio.dll 5 | C:\Users\Megre\Documents\GitHub\md2visio\md2visio\bin\Debug\net8.0\md2visio.pdb 6 | C:\Users\Megre\Documents\GitHub\md2visio\md2visio\obj\Debug\net8.0\md2visio.GeneratedMSBuildEditorConfig.editorconfig 7 | C:\Users\Megre\Documents\GitHub\md2visio\md2visio\obj\Debug\net8.0\md2visio.AssemblyInfoInputs.cache 8 | C:\Users\Megre\Documents\GitHub\md2visio\md2visio\obj\Debug\net8.0\md2visio.AssemblyInfo.cs 9 | C:\Users\Megre\Documents\GitHub\md2visio\md2visio\obj\Debug\net8.0\md2visio.csproj.CoreCompileInputs.cache 10 | C:\Users\Megre\Documents\GitHub\md2visio\md2visio\obj\Debug\net8.0\md2visio.dll 11 | C:\Users\Megre\Documents\GitHub\md2visio\md2visio\obj\Debug\net8.0\refint\md2visio.dll 12 | C:\Users\Megre\Documents\GitHub\md2visio\md2visio\obj\Debug\net8.0\md2visio.pdb 13 | C:\Users\Megre\Documents\GitHub\md2visio\md2visio\obj\Debug\net8.0\md2visio.genruntimeconfig.cache 14 | C:\Users\Megre\Documents\GitHub\md2visio\md2visio\obj\Debug\net8.0\ref\md2visio.dll 15 | C:\Users\Megre\Documents\GitHub\md2visio\md2visio\obj\Debug\net8.0\md2visio.csproj.AssemblyReference.cache 16 | C:\Users\Megre\Documents\GitHub\md2visio\md2visio\obj\Debug\net8.0\md2visio.csproj.Up2Date 17 | C:\Users\Megre\Documents\GitHub\md2visio\md2visio\bin\Debug\net8.0\OFFICE.DLL 18 | C:\Users\Megre\Documents\GitHub\md2visio\md2visio\bin\Debug\net8.0\Interop.Microsoft.Office.Interop.Visio.dll 19 | C:\Users\Megre\Documents\GitHub\md2visio\md2visio\bin\Debug\net8.0\Microsoft.Vbe.Interop.dll 20 | C:\Users\Megre\Documents\GitHub\md2visio\md2visio\bin\Debug\net8.0\Microsoft.Win32.SystemEvents.dll 21 | C:\Users\Megre\Documents\GitHub\md2visio\md2visio\bin\Debug\net8.0\System.Drawing.Common.dll 22 | C:\Users\Megre\Documents\GitHub\md2visio\md2visio\bin\Debug\net8.0\System.Private.Windows.Core.dll 23 | C:\Users\Megre\Documents\GitHub\md2visio\md2visio\bin\Debug\net8.0\runtimes\win\lib\net8.0\Microsoft.Win32.SystemEvents.dll 24 | C:\Users\TR\文档\GitHub\md2visio\md2visio\bin\Debug\net8.0\md2visio.exe 25 | C:\Users\TR\文档\GitHub\md2visio\md2visio\bin\Debug\net8.0\md2visio.deps.json 26 | C:\Users\TR\文档\GitHub\md2visio\md2visio\bin\Debug\net8.0\md2visio.runtimeconfig.json 27 | C:\Users\TR\文档\GitHub\md2visio\md2visio\bin\Debug\net8.0\md2visio.dll 28 | C:\Users\TR\文档\GitHub\md2visio\md2visio\bin\Debug\net8.0\md2visio.pdb 29 | C:\Users\TR\文档\GitHub\md2visio\md2visio\bin\Debug\net8.0\Microsoft.VisualStudio.Imaging.Interop.14.0.DesignTime.dll 30 | C:\Users\TR\文档\GitHub\md2visio\md2visio\bin\Debug\net8.0\Microsoft.VisualStudio.Interop.dll 31 | C:\Users\TR\文档\GitHub\md2visio\md2visio\bin\Debug\net8.0\Microsoft.Win32.SystemEvents.dll 32 | C:\Users\TR\文档\GitHub\md2visio\md2visio\bin\Debug\net8.0\stdole.dll 33 | C:\Users\TR\文档\GitHub\md2visio\md2visio\bin\Debug\net8.0\System.Drawing.Common.dll 34 | C:\Users\TR\文档\GitHub\md2visio\md2visio\bin\Debug\net8.0\System.Private.Windows.Core.dll 35 | C:\Users\TR\文档\GitHub\md2visio\md2visio\bin\Debug\net8.0\OFFICE.DLL 36 | C:\Users\TR\文档\GitHub\md2visio\md2visio\bin\Debug\net8.0\Interop.Microsoft.Office.Interop.Visio.dll 37 | C:\Users\TR\文档\GitHub\md2visio\md2visio\bin\Debug\net8.0\Microsoft.Vbe.Interop.dll 38 | C:\Users\TR\文档\GitHub\md2visio\md2visio\bin\Debug\net8.0\YamlDotNet.dll 39 | C:\Users\TR\文档\GitHub\md2visio\md2visio\bin\Debug\net8.0\runtimes\win\lib\net8.0\Microsoft.Win32.SystemEvents.dll 40 | C:\Users\TR\文档\GitHub\md2visio\md2visio\obj\Debug\net8.0\md2visio.csproj.AssemblyReference.cache 41 | C:\Users\TR\文档\GitHub\md2visio\md2visio\obj\Debug\net8.0\md2visio.GeneratedMSBuildEditorConfig.editorconfig 42 | C:\Users\TR\文档\GitHub\md2visio\md2visio\obj\Debug\net8.0\md2visio.AssemblyInfoInputs.cache 43 | C:\Users\TR\文档\GitHub\md2visio\md2visio\obj\Debug\net8.0\md2visio.AssemblyInfo.cs 44 | C:\Users\TR\文档\GitHub\md2visio\md2visio\obj\Debug\net8.0\md2visio.csproj.CoreCompileInputs.cache 45 | C:\Users\TR\文档\GitHub\md2visio\md2visio\obj\Debug\net8.0\md2visio.sourcelink.json 46 | C:\Users\TR\文档\GitHub\md2visio\md2visio\obj\Debug\net8.0\md2visio.csproj.Up2Date 47 | C:\Users\TR\文档\GitHub\md2visio\md2visio\obj\Debug\net8.0\md2visio.dll 48 | C:\Users\TR\文档\GitHub\md2visio\md2visio\obj\Debug\net8.0\refint\md2visio.dll 49 | C:\Users\TR\文档\GitHub\md2visio\md2visio\obj\Debug\net8.0\md2visio.pdb 50 | C:\Users\TR\文档\GitHub\md2visio\md2visio\obj\Debug\net8.0\md2visio.genruntimeconfig.cache 51 | C:\Users\TR\文档\GitHub\md2visio\md2visio\obj\Debug\net8.0\ref\md2visio.dll 52 | -------------------------------------------------------------------------------- /md2visio/vsdx/@tool/VColor.cs: -------------------------------------------------------------------------------- 1 | namespace md2visio.vsdx.@tool 2 | { 3 | internal abstract class VColor 4 | { 5 | protected float r, g, b; // [0, 255] 6 | protected float a = 1; // [0, 1] 7 | protected float H; // [0, 360] 8 | protected float S, L; // [0, 1] 9 | 10 | public static VColor Create(string color) { 11 | if(VNamedColor.IsNamed(color)) return VNamedColor.Create(color); 12 | if(VRGBColor.IsRGB(color)) return VRGBColor.Create(color); 13 | if(VHSLColor.IsHSL(color)) return VHSLColor.Create(color); 14 | 15 | throw new ArgumentException($"Unsupported color format '{color.Trim()}'"); 16 | } 17 | 18 | public string RGB() 19 | { 20 | return string.Format("rgb({0:F0}, {1:F0}, {2:F0})", 21 | Math.Round(r), Math.Round(g), Math.Round(b)); 22 | } 23 | 24 | public string RGBA() 25 | { 26 | return string.Format("rgba({0:F0}, {1:F0}, {2:F0}, {3:F0})", 27 | Math.Round(r), Math.Round(g), Math.Round(b), Math.Round(a)); 28 | } 29 | 30 | public string HexRGB() 31 | { 32 | return string.Format("#{0:X2}{1:X2}{2:X2}", 33 | Math.Round(r), Math.Round(g), Math.Round(b)); 34 | } 35 | 36 | public string HexARGB() 37 | { 38 | return string.Format("#{0:X2}{1:X2}{2:X2}{3:X2}", 39 | Math.Round(a * 255), Math.Round(r), Math.Round(g), Math.Round(b)); 40 | } 41 | public string HLS() 42 | { 43 | float s = S * 100, l = L * 100; 44 | return $"hsl({H:F0}, {s:F2}%, {l:F2}%)"; 45 | } 46 | public string HLSA() 47 | { 48 | float s = S * 100, l = L * 100; 49 | return $"hsla({H:F0}, {s:F2}%, {l:F2}%, {a:F2})"; 50 | } 51 | 52 | protected static (float H, float S, float L) RGB2HSL(float r, float g, float b) 53 | { 54 | // r, g, b -> [0, 1] 55 | (r, g, b) = (r / 255, g / 255, b / 255); 56 | 57 | // 找到最大值和最小值 58 | float max = Math.Max(r, Math.Max(g, b)); 59 | float min = Math.Min(r, Math.Min(g, b)); 60 | 61 | // 计算 L (亮度) 62 | float l = (max + min) / 2; 63 | 64 | // 计算 S (饱和度) 65 | float s; 66 | if (max == min) 67 | { 68 | s = 0; // 饱和度为 0,表示灰色 69 | } 70 | else 71 | { 72 | s = l > 0.5 ? (max - min) / (2 - max - min) : (max - min) / (max + min); 73 | } 74 | 75 | // 计算 H (色调) 76 | float h = 0; 77 | if (max == min) 78 | { 79 | h = 0; // 无色调 80 | } 81 | else 82 | { 83 | if (max == r) 84 | { 85 | h = (g - b) / (max - min); 86 | } 87 | else if (max == g) 88 | { 89 | h = 2 + (b - r) / (max - min); 90 | } 91 | else if (max == b) 92 | { 93 | h = 4 + (r - g) / (max - min); 94 | } 95 | h *= 60; // 转换为角度 96 | if (h < 0) h += 360; // 确保在 [0, 360] 范围内 97 | } 98 | 99 | return (h, s, l); 100 | } 101 | protected static (float r, float g, float b) HSL2RGB(float H, float S, float L) 102 | { 103 | float r, g, b; 104 | if (S == 0) 105 | { 106 | r = g = b = L; // 如果饱和度为 0,则颜色是灰色 107 | } 108 | else 109 | { 110 | // 根据亮度和区域计算颜色分量 111 | float HueToRgb(float p, float q, float t) 112 | { 113 | if (t < 0) t += 1; 114 | if (t > 1) t -= 1; 115 | if (t < 1 / 6f) return p + (q - p) * 6 * t; 116 | if (t < 1 / 2f) return q; 117 | if (t < 2 / 3f) return p + (q - p) * (2 / 3f - t) * 6; 118 | return p; 119 | } 120 | 121 | float q = L < 0.5f ? L * (1 + S) : L + S - L * S; 122 | float p = 2 * L - q; 123 | 124 | // 计算 RGB 分量 125 | r = HueToRgb(p, q, H / 360f + 1 / 3f); 126 | g = HueToRgb(p, q, H / 360f); 127 | b = HueToRgb(p, q, H / 360f - 1 / 3f); 128 | } 129 | 130 | // 将浮点数转换为 [0, 255] 的整数值 131 | return (r * 255, g * 255, b * 255); 132 | } 133 | protected void Clamp() 134 | { 135 | (r, g, b, a) = (Math.Clamp(r, 0, 255), Math.Clamp(g, 0, 255), Math.Clamp(b, 0, 255), 136 | Math.Clamp(a, 0, 1)); 137 | (H, S, L) = (H % 360, Math.Clamp(S, 0, 1), Math.Clamp(L, 0, 1)); 138 | } 139 | } 140 | } 141 | -------------------------------------------------------------------------------- /md2visio/mermaid/@cmn/SynState.cs: -------------------------------------------------------------------------------- 1 | using md2visio.struc.figure; 2 | using System.Reflection; 3 | using System.Text.RegularExpressions; 4 | 5 | namespace md2visio.mermaid.cmn 6 | { 7 | internal abstract class SynState 8 | { 9 | public static SynState EndOfFile = new EmptyState(); 10 | 11 | SynContext context = Empty.Get<SynContext>(); 12 | protected CompoDict compoList = new CompoDict(); 13 | protected GroupCollection ExpectedGroups { get { return Ctx.ExpectedGroups; } } 14 | public SynContext Ctx { get { return context; } set { context = value; } } 15 | 16 | public string Fragment { get { return compoList.Entire; } set { compoList.Entire = value; } } 17 | public CompoDict CompoList { get { return compoList; } } 18 | public string Buffer { get { return Ctx.Cache.ToString(); } } 19 | 20 | public SynState() { } 21 | 22 | public SynState ClearBuffer() 23 | { 24 | Ctx.ClearCache(); 25 | return this; 26 | } 27 | 28 | public string? Peek(int length = 1) 29 | { 30 | return Ctx.Peek(length); 31 | } 32 | 33 | public SynState SlideSpaces() 34 | { 35 | string? next = Ctx.Peek(); 36 | while (next != null) 37 | { 38 | if (next == "\n") break; 39 | if (!string.IsNullOrWhiteSpace(next)) break; 40 | Ctx.Slide(); 41 | next = Ctx.Peek(); 42 | } 43 | 44 | return this; 45 | } 46 | 47 | public SynState Take(int length = 1) 48 | { 49 | Ctx.Take(length); 50 | return this; 51 | } 52 | 53 | public SynState Slide(int length = 1) 54 | { 55 | Ctx.Slide(length); 56 | return this; 57 | } 58 | 59 | protected bool Expect(string pattern, bool multiline = false) 60 | { 61 | return Ctx.Expect(pattern, multiline); 62 | } 63 | 64 | public bool Until(string pattern, bool multiline = true) 65 | { 66 | return Ctx.Until(pattern, multiline); 67 | } 68 | 69 | 70 | public SynState Restore(int length = 1) 71 | { 72 | Ctx.Restore(length); 73 | return this; 74 | } 75 | 76 | public string ExpectedGroup(string groupName) 77 | { 78 | if (ExpectedGroups.Count > 0) return ExpectedGroups[groupName].Value; 79 | return string.Empty; 80 | } 81 | 82 | public abstract SynState NextState(); 83 | 84 | public SynState Forward<T>() where T : SynState, new() 85 | { 86 | return Create<T>().NextState(); 87 | } 88 | 89 | public SynState Forward(Type sttType) 90 | { 91 | MethodInfo? forwardInfo = GetType().GetMethod("Forward", BindingFlags.Public | BindingFlags.Instance, 92 | null, new Type[] { }, null); 93 | if (forwardInfo == null) throw new MissingMethodException("could not find the method 'Forward'"); 94 | 95 | MethodInfo genericMethod = forwardInfo.MakeGenericMethod(sttType); 96 | object? rst = genericMethod.Invoke(this, null); 97 | 98 | if (rst == null) throw new NullReferenceException("target state can't be null"); 99 | 100 | return (SynState) rst; 101 | } 102 | 103 | public SynState Create<T>() where T : SynState, new() 104 | { 105 | SynState clone = new T(); 106 | clone.Ctx = Ctx; 107 | return clone; 108 | } 109 | 110 | public SynState Save(string frag) 111 | { 112 | compoList.Entire = frag; 113 | Ctx.AddState(this); 114 | return this; 115 | } 116 | 117 | public bool IsEndOfFile() { return this == EndOfFile; } 118 | 119 | public string GetPart(string name) 120 | { 121 | return compoList.Get(name); 122 | } 123 | 124 | public string GetPart(int index) 125 | { 126 | return compoList.Get(index); 127 | } 128 | 129 | public void AddCompo(string name, string value) 130 | { 131 | compoList.Add(name, value); 132 | } 133 | 134 | public void AddCompo(string value) 135 | { 136 | compoList.Add(value); 137 | } 138 | 139 | public override string ToString() 140 | { 141 | if (this is SttFinishFlag) return "■"; 142 | return string.Format("{0} \t@ {1}", compoList.Entire, GetType().Name); 143 | } 144 | 145 | } // SynState 146 | 147 | internal class EmptyState : SynState 148 | { 149 | public static EmptyState Instance { get; } = Empty.Get<EmptyState>(); 150 | 151 | public EmptyState() { } 152 | 153 | public override SynState NextState() 154 | { 155 | throw new NotImplementedException(); 156 | } 157 | } 158 | } 159 | -------------------------------------------------------------------------------- /md2visio/vsdx/@base/VBoundary.cs: -------------------------------------------------------------------------------- 1 | using md2visio.struc.figure; 2 | using Microsoft.Office.Interop.Visio; 3 | 4 | namespace md2visio.vsdx.@base 5 | { 6 | internal class VBoundary 7 | { 8 | protected bool wild = false; // false: pinx/piny/width/height(0/0/0/0) is valid 9 | protected double pinx, piny, width, height; 10 | public double PinX { get { return pinx; } } 11 | public double PinY { get { return piny; } } 12 | public double Width { get { return width; } } 13 | public double Height { get { return height; } } 14 | public double Left 15 | { 16 | get { return pinx - width / 2; } 17 | set 18 | { 19 | double r = Right; 20 | if (value > r) return; 21 | pinx = (value + r) / 2; 22 | width = r - value; 23 | } 24 | } 25 | 26 | public double Right 27 | { 28 | get { return pinx + width / 2; } 29 | set 30 | { 31 | double L = Left; 32 | if (value < L) return; 33 | pinx = (L + value) / 2; 34 | width = value - L; 35 | } 36 | } 37 | 38 | public double Top 39 | { 40 | get { return piny + height / 2; } 41 | set 42 | { 43 | double b = Bottom; 44 | if (value < b) return; 45 | piny = (b + value) / 2; 46 | height = value - b; 47 | } 48 | } 49 | public double Bottom 50 | { 51 | get { return piny - height / 2; } 52 | set 53 | { 54 | double t = Top; 55 | if (value > t) return; 56 | piny = (value + t) / 2; 57 | height = t - value; 58 | } 59 | } 60 | 61 | public VBoundary() { } 62 | 63 | public VBoundary(bool wild = false) { 64 | this.wild = wild; 65 | } 66 | 67 | public VBoundary(double pinx, double piny, double width, double height) 68 | { 69 | this.pinx = pinx; 70 | this.piny = piny; 71 | this.width = width; 72 | this.height = height; 73 | } 74 | 75 | public void AlignLeft(double left) 76 | { 77 | pinx = left + width / 2; 78 | } 79 | 80 | public void AlignTop(double top) 81 | { 82 | piny = top - height / 2; 83 | } 84 | 85 | public void AlignLeftTop(double left, double top) 86 | { 87 | AlignLeft(left); 88 | AlignTop(top); 89 | } 90 | 91 | public void AlignRight(double right) 92 | { 93 | pinx = right - width / 2; 94 | } 95 | 96 | public void AlignBottom(double bottom) 97 | { 98 | piny = bottom + height / 2; 99 | } 100 | 101 | public void AlignRightBottom(double right, double bottom) 102 | { 103 | AlignRight(right); 104 | AlignBottom(bottom); 105 | } 106 | 107 | public VBoundary Clone() 108 | { 109 | VBoundary clone = new VBoundary(); 110 | clone.pinx = pinx; 111 | clone.piny = piny; 112 | clone.width = width; 113 | clone.height = height; 114 | return clone; 115 | } 116 | 117 | public void Expand(VBoundary boundary) 118 | { 119 | if(wild) 120 | { 121 | pinx = boundary.pinx; piny = boundary.piny; 122 | width = boundary.width; height = boundary.height; 123 | wild = false; 124 | return; 125 | } 126 | ExpandBoundary(this, boundary); 127 | } 128 | 129 | public void Expand(Shape shape) 130 | { 131 | Expand(new VShapeBoundary(shape)); 132 | } 133 | 134 | public void Grow(Shape shape, GrowthDirection direct, double space) 135 | { 136 | if (direct.H != 0) 137 | { 138 | if (direct.H > 0) VShapeDrawer.AlignLeft(shape, Right + space); 139 | else VShapeDrawer.AlignRight(shape, Left - space); 140 | } 141 | else if (direct.V != 0) 142 | { 143 | if (direct.V > 0) VShapeDrawer.AlignBottom(shape, Top + space); 144 | else VShapeDrawer.AlignTop(shape, Bottom - space); 145 | } 146 | } 147 | 148 | public override string ToString() 149 | { 150 | return $"L:{Left} T:{Top} R:{Right} B:{Bottom}"; 151 | } 152 | 153 | public static void ExpandBoundary(VBoundary bnd2expand, VBoundary bndCompare) 154 | { 155 | if (bndCompare.IsEmpty()) return; 156 | 157 | if (bndCompare.Left < bnd2expand.Left) bnd2expand.Left = bndCompare.Left; 158 | if (bndCompare.Right > bnd2expand.Right) bnd2expand.Right = bndCompare.Right; 159 | if (bndCompare.Top > bnd2expand.Top) bnd2expand.Top = bndCompare.Top; 160 | if (bndCompare.Bottom < bnd2expand.Bottom) bnd2expand.Bottom = bndCompare.Bottom; 161 | } 162 | 163 | } 164 | } 165 | -------------------------------------------------------------------------------- /md2visio/obj/x64/Debug/net8.0/md2visio.csproj.FileListAbsolute.txt: -------------------------------------------------------------------------------- 1 | C:\Users\Megre\Documents\GitHub\md2visio\md2visio\obj\x64\Debug\net8.0\md2visio.csproj.AssemblyReference.cache 2 | C:\Users\Megre\Documents\GitHub\md2visio\md2visio\obj\x64\Debug\net8.0\md2visio.GeneratedMSBuildEditorConfig.editorconfig 3 | C:\Users\Megre\Documents\GitHub\md2visio\md2visio\obj\x64\Debug\net8.0\md2visio.AssemblyInfoInputs.cache 4 | C:\Users\Megre\Documents\GitHub\md2visio\md2visio\obj\x64\Debug\net8.0\md2visio.AssemblyInfo.cs 5 | C:\Users\Megre\Documents\GitHub\md2visio\md2visio\obj\x64\Debug\net8.0\md2visio.csproj.CoreCompileInputs.cache 6 | C:\Users\Megre\Documents\GitHub\md2visio\md2visio\bin\x64\Debug\net8.0\md2visio.exe 7 | C:\Users\Megre\Documents\GitHub\md2visio\md2visio\bin\x64\Debug\net8.0\md2visio.deps.json 8 | C:\Users\Megre\Documents\GitHub\md2visio\md2visio\bin\x64\Debug\net8.0\md2visio.runtimeconfig.json 9 | C:\Users\Megre\Documents\GitHub\md2visio\md2visio\bin\x64\Debug\net8.0\md2visio.dll 10 | C:\Users\Megre\Documents\GitHub\md2visio\md2visio\bin\x64\Debug\net8.0\md2visio.pdb 11 | C:\Users\Megre\Documents\GitHub\md2visio\md2visio\bin\x64\Debug\net8.0\Microsoft.Win32.SystemEvents.dll 12 | C:\Users\Megre\Documents\GitHub\md2visio\md2visio\bin\x64\Debug\net8.0\System.Drawing.Common.dll 13 | C:\Users\Megre\Documents\GitHub\md2visio\md2visio\bin\x64\Debug\net8.0\System.Private.Windows.Core.dll 14 | C:\Users\Megre\Documents\GitHub\md2visio\md2visio\bin\x64\Debug\net8.0\OFFICE.DLL 15 | C:\Users\Megre\Documents\GitHub\md2visio\md2visio\bin\x64\Debug\net8.0\Interop.Microsoft.Office.Interop.Visio.dll 16 | C:\Users\Megre\Documents\GitHub\md2visio\md2visio\bin\x64\Debug\net8.0\Microsoft.Vbe.Interop.dll 17 | C:\Users\Megre\Documents\GitHub\md2visio\md2visio\bin\x64\Debug\net8.0\runtimes\win\lib\net8.0\Microsoft.Win32.SystemEvents.dll 18 | C:\Users\Megre\Documents\GitHub\md2visio\md2visio\obj\x64\Debug\net8.0\md2visio.csproj.Up2Date 19 | C:\Users\Megre\Documents\GitHub\md2visio\md2visio\obj\x64\Debug\net8.0\md2visio.dll 20 | C:\Users\Megre\Documents\GitHub\md2visio\md2visio\obj\x64\Debug\net8.0\refint\md2visio.dll 21 | C:\Users\Megre\Documents\GitHub\md2visio\md2visio\obj\x64\Debug\net8.0\md2visio.pdb 22 | C:\Users\Megre\Documents\GitHub\md2visio\md2visio\obj\x64\Debug\net8.0\md2visio.genruntimeconfig.cache 23 | C:\Users\Megre\Documents\GitHub\md2visio\md2visio\obj\x64\Debug\net8.0\ref\md2visio.dll 24 | C:\Users\Megre\Documents\GitHub\md2visio\md2visio\obj\x64\Debug\net8.0\md2visio.sourcelink.json 25 | C:\Users\Megre\Documents\GitHub\md2visio\md2visio\bin\x64\Debug\net8.0\YamlDotNet.dll 26 | C:\Users\Megre\Documents\GitHub\md2visio\md2visio\bin\x64\Debug\net8.0\Microsoft.VisualStudio.Imaging.Interop.14.0.DesignTime.dll 27 | C:\Users\Megre\Documents\GitHub\md2visio\md2visio\bin\x64\Debug\net8.0\Microsoft.VisualStudio.Interop.dll 28 | C:\Users\Megre\Documents\GitHub\md2visio\md2visio\bin\x64\Debug\net8.0\stdole.dll 29 | C:\Users\TR\文档\GitHub\md2visio\md2visio\bin\x64\Debug\net8.0\md2visio.exe 30 | C:\Users\TR\文档\GitHub\md2visio\md2visio\bin\x64\Debug\net8.0\md2visio.deps.json 31 | C:\Users\TR\文档\GitHub\md2visio\md2visio\bin\x64\Debug\net8.0\md2visio.runtimeconfig.json 32 | C:\Users\TR\文档\GitHub\md2visio\md2visio\bin\x64\Debug\net8.0\md2visio.dll 33 | C:\Users\TR\文档\GitHub\md2visio\md2visio\bin\x64\Debug\net8.0\md2visio.pdb 34 | C:\Users\TR\文档\GitHub\md2visio\md2visio\bin\x64\Debug\net8.0\Microsoft.VisualStudio.Imaging.Interop.14.0.DesignTime.dll 35 | C:\Users\TR\文档\GitHub\md2visio\md2visio\bin\x64\Debug\net8.0\Microsoft.VisualStudio.Interop.dll 36 | C:\Users\TR\文档\GitHub\md2visio\md2visio\bin\x64\Debug\net8.0\Microsoft.Win32.SystemEvents.dll 37 | C:\Users\TR\文档\GitHub\md2visio\md2visio\bin\x64\Debug\net8.0\stdole.dll 38 | C:\Users\TR\文档\GitHub\md2visio\md2visio\bin\x64\Debug\net8.0\System.Drawing.Common.dll 39 | C:\Users\TR\文档\GitHub\md2visio\md2visio\bin\x64\Debug\net8.0\System.Private.Windows.Core.dll 40 | C:\Users\TR\文档\GitHub\md2visio\md2visio\bin\x64\Debug\net8.0\OFFICE.DLL 41 | C:\Users\TR\文档\GitHub\md2visio\md2visio\bin\x64\Debug\net8.0\Interop.Microsoft.Office.Interop.Visio.dll 42 | C:\Users\TR\文档\GitHub\md2visio\md2visio\bin\x64\Debug\net8.0\Microsoft.Vbe.Interop.dll 43 | C:\Users\TR\文档\GitHub\md2visio\md2visio\bin\x64\Debug\net8.0\YamlDotNet.dll 44 | C:\Users\TR\文档\GitHub\md2visio\md2visio\bin\x64\Debug\net8.0\runtimes\win\lib\net8.0\Microsoft.Win32.SystemEvents.dll 45 | C:\Users\TR\文档\GitHub\md2visio\md2visio\obj\x64\Debug\net8.0\md2visio.csproj.AssemblyReference.cache 46 | C:\Users\TR\文档\GitHub\md2visio\md2visio\obj\x64\Debug\net8.0\md2visio.GeneratedMSBuildEditorConfig.editorconfig 47 | C:\Users\TR\文档\GitHub\md2visio\md2visio\obj\x64\Debug\net8.0\md2visio.AssemblyInfoInputs.cache 48 | C:\Users\TR\文档\GitHub\md2visio\md2visio\obj\x64\Debug\net8.0\md2visio.AssemblyInfo.cs 49 | C:\Users\TR\文档\GitHub\md2visio\md2visio\obj\x64\Debug\net8.0\md2visio.csproj.CoreCompileInputs.cache 50 | C:\Users\TR\文档\GitHub\md2visio\md2visio\obj\x64\Debug\net8.0\md2visio.sourcelink.json 51 | C:\Users\TR\文档\GitHub\md2visio\md2visio\obj\x64\Debug\net8.0\md2visio.csproj.Up2Date 52 | C:\Users\TR\文档\GitHub\md2visio\md2visio\obj\x64\Debug\net8.0\md2visio.dll 53 | C:\Users\TR\文档\GitHub\md2visio\md2visio\obj\x64\Debug\net8.0\refint\md2visio.dll 54 | C:\Users\TR\文档\GitHub\md2visio\md2visio\obj\x64\Debug\net8.0\md2visio.pdb 55 | C:\Users\TR\文档\GitHub\md2visio\md2visio\obj\x64\Debug\net8.0\md2visio.genruntimeconfig.cache 56 | C:\Users\TR\文档\GitHub\md2visio\md2visio\obj\x64\Debug\net8.0\ref\md2visio.dll 57 | --------------------------------------------------------------------------------