コード例 #1
0
        static int Main(string[] args)
        {
            // mdspec2docx *.md csharp.g4 template.docx -o spec.docx
            var    ifiles    = new List <string>();
            var    ofiles    = new List <string>();
            string argserror = "";

            for (int i = 0; i < args.Length; i++)
            {
                var arg = args[i];
                if (arg.StartsWith("-"))
                {
                    if (arg == "-o" && i < args.Length - 1)
                    {
                        i++; ofiles.Add(args[i]);
                    }
                    else
                    {
                        argserror += $"Unrecognized '{arg}'\n";
                    }
                }
                else if (!arg.Contains("*") && !arg.Contains("?"))
                {
                    if (!File.Exists(arg))
                    {
                        Console.Error.WriteLine($"Not found - {arg}"); return(1);
                    }
                    ifiles.Add(arg);
                }
                else
                {
                    // Windows command-shell doesn't do globbing, so we have to do it ourselves
                    string dir = Path.GetDirectoryName(arg), filename = Path.GetFileName(arg);
                    if (dir.Contains("*") || dir.Contains("?"))
                    {
                        Console.Error.WriteLine("Can't match wildcard directory names");
                        return(1);
                    }
                    if (dir == "")
                    {
                        dir = Directory.GetCurrentDirectory();
                    }

                    if (!Directory.Exists(dir))
                    {
                        Console.Error.WriteLine($"Not found - \"{dir}\""); return(1);
                    }
                    var fns2 = Directory.GetFiles(dir, filename);
                    if (fns2.Length == 0)
                    {
                        Console.Error.WriteLine($"Not found - \"{arg}\""); return(1);
                    }
                    ifiles.AddRange(fns2);
                }
            }

            var    imdfiles = new List <string>();
            string ireadmefile = null, iantlrfile = null, idocxfile = null, odocfile = null;

            foreach (var ifile in ifiles)
            {
                var name = Path.GetFileName(ifile);
                var ext  = Path.GetExtension(ifile).ToLower();
                if (ext == ".g4")
                {
                    if (iantlrfile != null)
                    {
                        argserror += "Multiple input .g4 files\n";
                    }
                    iantlrfile = ifile;
                }
                else if (ext == ".docx")
                {
                    if (idocxfile != null)
                    {
                        argserror += "Multiple input .docx files\n";
                    }
                    idocxfile = ifile;
                }
                else if (ext != ".md")
                {
                    argserror += $"Not .g4 or .docx or .md '{ifile}'\n"; continue;
                }
                else if (String.Equals(name, "readme.md", StringComparison.InvariantCultureIgnoreCase))
                {
                    if (ireadmefile != null)
                    {
                        argserror += "Multiple readme.md files\n";
                    }
                    ireadmefile = ifile;
                }
                else
                {
                    imdfiles.Add(ifile);
                }
            }
            foreach (var ofile in ofiles)
            {
                var ext = Path.GetExtension(ofile).ToLower();
                if (ext == ".docx")
                {
                    if (odocfile != null)
                    {
                        argserror += "Multiple output docx files\n";
                    }
                    odocfile = ofile;
                }
                else
                {
                    argserror += $"Unknown output file extension: {ext}\n";
                }
            }

            if (odocfile == null)
            {
                argserror += "No output .docx file specified\n";
            }

            if (ireadmefile == null && ifiles.Count == 0)
            {
                argserror += "No .md files supplied\n";
            }

            if (idocxfile == null)
            {
                argserror += "No template.docx supplied\n";
            }

            if (argserror != "")
            {
                Console.Error.WriteLine(argserror);
                Console.Error.WriteLine("mdspec2docx *.md grammar.g4 template.docx -o spec.docx");
                Console.Error.WriteLine();
                Console.Error.WriteLine("Turns the markdown files into a word document based on the template.");
                Console.Error.WriteLine("If readme.md and other files are given, then readme is used solely to");
                Console.Error.WriteLine("   sort the docx based on its list of `* [Link](subfile.md)`.");
                Console.Error.WriteLine("If a .g4 is given, it verifies 1:1 correspondence with ```antlr blocks.");
                Console.Error.WriteLine("The -td temp directory will enable incremental (faster) runs in future.");
                return(1);
            }

            Console.WriteLine("mdspec2docx");
            Console.WriteLine("Reading markdown files");

            // Read input file. If it contains a load of linked filenames, then read them instead.
            List <string> ifiles_in_order = new List <string>();
            List <Tuple <int, string, string, SourceLocation> > urls = null;

            if (ireadmefile == null)
            {
                ifiles_in_order.AddRange(ifiles);
            }
            else if (ireadmefile != null && ifiles.Count == 0)
            {
                ifiles_in_order.Add(ireadmefile);
            }
            else
            {
                var readme = FSharp.Markdown.Markdown.Parse(File.ReadAllText(ireadmefile));
                urls = new List <Tuple <int, string, string, SourceLocation> >();
                // is there a nicer way to get the URLs of all depth-1 and depth-2 URLs in this list? ...
                foreach (var list in readme.Paragraphs.OfType <FSharp.Markdown.MarkdownParagraph.ListBlock>())
                {
                    var pp = new List <Tuple <int, FSharp.Markdown.MarkdownParagraph> >();
                    foreach (var pars in list.items)
                    {
                        foreach (var par in pars)
                        {
                            pp.Add(Tuple.Create(1, par));
                            var sublist = par as FSharp.Markdown.MarkdownParagraph.ListBlock;
                            if (sublist != null)
                            {
                                pp.AddRange(from subpars in sublist.items
                                            from subpar in subpars
                                            select Tuple.Create(2, subpar));
                            }
                        }
                    }
                    foreach (var tpp in pp)
                    {
                        var level   = tpp.Item1;
                        var spanpar = tpp.Item2 as FSharp.Markdown.MarkdownParagraph.Span;
                        if (spanpar == null)
                        {
                            continue;
                        }

                        var links = spanpar.body.OfType <FSharp.Markdown.MarkdownSpan.DirectLink>();
                        urls.AddRange(from link in links
                                      let title                     = string.Join("", link.body.OfType <FSharp.Markdown.MarkdownSpan.Literal>().Select(l => l.text))
                                                            let url = link.link
                                                                      where url.ToLower().EndsWith(".md") || url.ToLower().Contains(".md#")
                                                                      let loc = new SourceLocation(ireadmefile, null, list, link)
                                                                                select Tuple.Create(level, title, url, loc));
                    }
                }
                var filelinks = (from turl in urls
                                 let url = turl.Item3
                                           let i = url.IndexOf('#')
                                                   let url2 = (i == -1 ? url : url.Substring(0, i))
                                                              select url2).ToList().Distinct();
                foreach (var link in filelinks)
                {
                    var ifile = ifiles.FirstOrDefault(f => Path.GetFileName(f) == link);
                    if (ifile == null)
                    {
                        Console.Error.WriteLine($"readme.md link '{link}' wasn't one of the files passed on the command line"); return(1);
                    }
                    ifiles_in_order.Add(ifile);
                }
            }
            var md = MarkdownSpec.ReadFiles(ifiles_in_order, urls);


            // Now md.Gramar contains the grammar as extracted out of the *.md files, and moreover has
            // correct references to within the spec. We'll check that it has the same productions as
            // in the corresponding ANTLR file
            if (iantlrfile != null)
            {
                Console.WriteLine($"Reading {Path.GetFileName(iantlrfile)}");
                var grammar = Antlr.ReadFile(iantlrfile);
                foreach (var diff in CompareGrammars(grammar, md.Grammar))
                {
                    if (diff.authority == null)
                    {
                        Report("MD21", "error", $"markdown has superfluous production '{diff.productionName}'", "mdspec2docx");
                    }
                    else if (diff.copy == null)
                    {
                        Report("MD22", "error", $"markdown lacks production '{diff.productionName}'", "mdspec2docx");
                    }
                    else
                    {
                        Report("MD23", "error", $"production '{diff.productionName}' differs between markdown and antlr.g4", "mdspec2docx");
                        Report("MD23b", "error", "antlr.g4 says " + diff.authority.Replace("\r", "\\r").Replace("\n", "\\n"), "mdspec2docx");
                        Report("MD23c", "error", "markdown says " + diff.copy.Replace("\r", "\\r").Replace("\n", "\\n"), "mdspec2docx");
                    }
                }
                foreach (var p in grammar.Productions)
                {
                    p.Link     = md.Grammar.Productions.FirstOrDefault(mdp => mdp?.Name == p.Name)?.Link;
                    p.LinkName = md.Grammar.Productions.FirstOrDefault(mdp => mdp?.Name == p.Name)?.LinkName;
                }
            }

            // Generate the Specification.docx file
            if (odocfile != null)
            {
                var odocfile2 = odocfile;
                if (odocfile2 != odocfile)
                {
                    Report("MD26", "error", $"File '{odocfile}' was in use", "mdspec2docx");
                }

                Console.WriteLine($"Writing '{Path.GetFileName(odocfile2)}'");
                try
                {
                    MarkdownSpecConverter.ConvertToWord(md, idocxfile, odocfile2);
                }
                catch (Exception ex)
                {
                    Report("MD27", "error", ex.Message, "mdspec2docx");
                    return(1);
                }
                if (odocfile2 != odocfile)
                {
                    return(1);
                }
            }
            return(0);
        }
コード例 #2
0
ファイル: Program.cs プロジェクト: AdamSpeight2008/csharpspec
    static int Main(string[] args)
    {
        var ifn = (args.Length >= 2 ? args[1] : "readme.md");

        if (!File.Exists(ifn) || !File.Exists("template.docx") || Directory.GetFiles(".", "*.g4").Length > 1)
        {
            Console.Error.WriteLine("md2docx <filename>.md -- converts it to '<filename>.docx', based on 'template.docx'");
            Console.Error.WriteLine();
            Console.Error.WriteLine("If no file is specified:");
            Console.Error.WriteLine("    it looks for readme.md instead");
            Console.Error.WriteLine("If input file has a list with links of the form `* [Link](subfile.md)`:");
            Console.Error.WriteLine("   it converts the listed subfiles instead of <filename>.md");
            Console.Error.WriteLine("If the current directory contains one <grammar>.g4 file:");
            Console.Error.WriteLine("   it verifies all ```antlr blocks correspond, and also generates <grammar>.html");
            Console.Error.WriteLine("If 'template.docx' contains a Table of Contents:");
            Console.Error.WriteLine("   it replaces it with one based on the markdown (but page numbers aren't supported)");
            return(1);
        }

        // Read input file. If it contains a load of linked filenames, then read them instead.
        var readme = FSharp.Markdown.Markdown.Parse(File.ReadAllText(ifn));
        var files  = (from list in readme.Paragraphs.OfType <FSharp.Markdown.MarkdownParagraph.ListBlock>()
                      let items = list.Item2
                                  from par in items
                                  from spanpar in par.OfType <FSharp.Markdown.MarkdownParagraph.Span>()
                                  let spans = spanpar.Item
                                              from link in spans.OfType <FSharp.Markdown.MarkdownSpan.DirectLink>()
                                              let url = link.Item2.Item1
                                                        where url.EndsWith(".md", StringComparison.InvariantCultureIgnoreCase)
                                                        select url).ToList().Distinct();

        if (files.Count() == 0)
        {
            files = new[] { ifn }
        }
        ;
        var md = MarkdownSpec.ReadFiles(files);


        // Now md.Gramar contains the grammar as extracted out of the *.md files, and moreover has
        // correct references to within the spec. We'll check that it has the same productions as
        // in the corresponding ANTLR file
        var antlrfn = Directory.GetFiles(".", "*.g4").FirstOrDefault();

        if (antlrfn != null)
        {
            var htmlfn  = Path.ChangeExtension(antlrfn, ".html");
            var grammar = Antlr.ReadFile(antlrfn);
            if (!AreProductionsSame(grammar, md.Grammar))
            {
                throw new Exception("Grammar mismatch");
            }
            foreach (var p in grammar.Productions)
            {
                p.Link     = md.Grammar.Productions.FirstOrDefault(mdp => mdp?.ProductionName == p.ProductionName)?.Link;
                p.LinkName = md.Grammar.Productions.FirstOrDefault(mdp => mdp?.ProductionName == p.ProductionName)?.LinkName;
            }

            File.WriteAllText(htmlfn, grammar.ToHtml(), Encoding.UTF8);
            Process.Start(htmlfn);
        }

        // Generate the Specification.docx file
        var fn = PickUniqueFilename(Path.ChangeExtension(ifn, ".docx"));

        md.WriteFile("template.docx", fn);
        Process.Start(fn);
        return(0);
    }
コード例 #3
0
        static int Main(string[] args)
        {
            // mdspec2docx *.md csharp.g4 template.docx -o spec.docx
            var    ifiles    = new List <string>();
            var    ofiles    = new List <string>();
            string argserror = "";

            for (int i = 0; i < args.Length; i++)
            {
                var arg = args[i];
                if (arg.StartsWith("-"))
                {
                    if (arg == "-o" && i < args.Length - 1)
                    {
                        i++; ofiles.Add(args[i]);
                    }
                    else
                    {
                        argserror += $"Unrecognized '{arg}'\n";
                    }
                }
                else if (!arg.Contains("*") && !arg.Contains("?"))
                {
                    if (!File.Exists(arg))
                    {
                        Console.Error.WriteLine($"Not found - {arg}"); return(1);
                    }
                    ifiles.Add(arg);
                }
                else
                {
                    // Windows command-shell doesn't do globbing, so we have to do it ourselves
                    string dir = Path.GetDirectoryName(arg), filename = Path.GetFileName(arg);
                    if (dir.Contains("*") || dir.Contains("?"))
                    {
                        Console.Error.WriteLine("Can't match wildcard directory names");
                        return(1);
                    }
                    if (dir == "")
                    {
                        dir = Directory.GetCurrentDirectory();
                    }

                    if (!Directory.Exists(dir))
                    {
                        Console.Error.WriteLine($"Not found - \"{dir}\""); return(1);
                    }
                    var fns2 = Directory.GetFiles(dir, filename);
                    if (fns2.Length == 0)
                    {
                        Console.Error.WriteLine($"Not found - \"{arg}\""); return(1);
                    }
                    ifiles.AddRange(fns2);
                }
            }

            var    imdfiles = new List <string>();
            string idocxfile = null, odocfile = null;

            foreach (var ifile in ifiles)
            {
                var name = Path.GetFileName(ifile);
                // Ignore the README, which is maintained separately and not part of the Standard.
                if (name.Equals("README.md", StringComparison.OrdinalIgnoreCase))
                {
                    continue;
                }
                var ext = Path.GetExtension(ifile).ToLower();
                if (ext == ".docx")
                {
                    if (idocxfile != null)
                    {
                        argserror += "Multiple input .docx files\n";
                    }
                    idocxfile = ifile;
                }
                else if (ext != ".md")
                {
                    argserror += $"Not .g4 or .docx or .md '{ifile}'\n"; continue;
                }
                else
                {
                    imdfiles.Add(ifile);
                }
            }
            foreach (var ofile in ofiles)
            {
                var ext = Path.GetExtension(ofile).ToLower();
                if (ext == ".docx")
                {
                    if (odocfile != null)
                    {
                        argserror += "Multiple output docx files\n";
                    }
                    odocfile = ofile;
                }
                else
                {
                    argserror += $"Unknown output file extension: {ext}\n";
                }
            }

            if (odocfile == null)
            {
                argserror += "No output .docx file specified\n";
            }

            if (idocxfile == null)
            {
                argserror += "No template.docx supplied\n";
            }

            if (argserror != "")
            {
                Console.Error.WriteLine(argserror);
                Console.Error.WriteLine("mdspec2docx *.md grammar.g4 template.docx -o spec.docx");
                Console.Error.WriteLine();
                Console.Error.WriteLine("Turns the markdown files into a word document based on the template.");
                Console.Error.WriteLine("If readme.md and other files are given, then readme is used solely to");
                Console.Error.WriteLine("   sort the docx based on its list of `* [Link](subfile.md)`.");
                return(1);
            }

            Console.WriteLine("Reading markdown files");

            // Read input file. If it contains a load of linked filenames, then read them instead.
            var md = MarkdownSpec.ReadFiles(imdfiles);

            // Generate the Specification.docx file
            if (odocfile != null)
            {
                var odocfile2 = odocfile;
                if (odocfile2 != odocfile)
                {
                    Report("MD26", error: true, $"File '{odocfile}' was in use", "mdspec2docx");
                }

                Console.WriteLine($"Writing '{Path.GetFileName(odocfile2)}'");
                try
                {
                    MarkdownSpecConverter.ConvertToWord(md, idocxfile, odocfile2);
                }
                catch (Exception ex)
                {
                    Report("MD27", error: true, ex.Message, ex.StackTrace);
                    return(1);
                }
                if (odocfile2 != odocfile)
                {
                    return(1);
                }
            }
            Console.WriteLine($"Errors: {errors}");
            Console.WriteLine($"Warnings: {warnings}");
            return(errors == 0 ? 0 : 1);
        }
コード例 #4
0
        static int Main(string[] args)
        {
            // mdspec2docx *.md csharp.g4 template.docx -o spec.docx
            var    ifiles    = new List <string>();
            var    ofiles    = new List <string>();
            string argserror = "";

            for (int i = 0; i < args.Length; i++)
            {
                var arg = args[i];
                if (arg.StartsWith("-"))
                {
                    if (arg == "-o" && i < args.Length - 1)
                    {
                        i++; ofiles.Add(args[i]);
                    }
                    else
                    {
                        argserror += $"Unrecognized '{arg}'\n";
                    }
                }
                else if (!arg.Contains("*") && !arg.Contains("?"))
                {
                    if (!File.Exists(arg))
                    {
                        Console.Error.WriteLine($"Not found - {arg}"); return(1);
                    }
                    ifiles.Add(arg);
                }
                else
                {
                    // Windows command-shell doesn't do globbing, so we have to do it ourselves
                    string dir = Path.GetDirectoryName(arg), filename = Path.GetFileName(arg);
                    if (dir.Contains("*") || dir.Contains("?"))
                    {
                        Console.Error.WriteLine("Can't match wildcard directory names");
                        return(1);
                    }
                    if (dir == "")
                    {
                        dir = Directory.GetCurrentDirectory();
                    }

                    if (!Directory.Exists(dir))
                    {
                        Console.Error.WriteLine($"Not found - \"{dir}\""); return(1);
                    }
                    var fns2 = Directory.GetFiles(dir, filename);
                    if (fns2.Length == 0)
                    {
                        Console.Error.WriteLine($"Not found - \"{arg}\""); return(1);
                    }
                    ifiles.AddRange(fns2);
                }
            }

            var    imdfiles = new List <string>();
            string ireadmefile = null, idocxfile = null, odocfile = null;

            foreach (var ifile in ifiles)
            {
                var name = Path.GetFileName(ifile);
                var ext  = Path.GetExtension(ifile).ToLower();
                if (ext == ".docx")
                {
                    if (idocxfile != null)
                    {
                        argserror += "Multiple input .docx files\n";
                    }
                    idocxfile = ifile;
                }
                else if (ext != ".md")
                {
                    argserror += $"Not .g4 or .docx or .md '{ifile}'\n"; continue;
                }
                else if (String.Equals(name, "readme.md", StringComparison.InvariantCultureIgnoreCase))
                {
                    if (ireadmefile != null)
                    {
                        argserror += "Multiple readme.md files\n";
                    }
                    ireadmefile = ifile;
                }
                else
                {
                    imdfiles.Add(ifile);
                }
            }
            foreach (var ofile in ofiles)
            {
                var ext = Path.GetExtension(ofile).ToLower();
                if (ext == ".docx")
                {
                    if (odocfile != null)
                    {
                        argserror += "Multiple output docx files\n";
                    }
                    odocfile = ofile;
                }
                else
                {
                    argserror += $"Unknown output file extension: {ext}\n";
                }
            }

            if (odocfile == null)
            {
                argserror += "No output .docx file specified\n";
            }

            if (ireadmefile == null && ifiles.Count == 0)
            {
                argserror += "No .md files supplied\n";
            }

            if (idocxfile == null)
            {
                argserror += "No template.docx supplied\n";
            }

            if (argserror != "")
            {
                Console.Error.WriteLine(argserror);
                Console.Error.WriteLine("mdspec2docx *.md grammar.g4 template.docx -o spec.docx");
                Console.Error.WriteLine();
                Console.Error.WriteLine("Turns the markdown files into a word document based on the template.");
                Console.Error.WriteLine("If readme.md and other files are given, then readme is used solely to");
                Console.Error.WriteLine("   sort the docx based on its list of `* [Link](subfile.md)`.");
                return(1);
            }

            Console.WriteLine("Reading markdown files");

            // Read input file. If it contains a load of linked filenames, then read them instead.
            List <string> ifiles_in_order = new List <string>();
            List <Tuple <int, string, string, SourceLocation> > urls = null;

            if (ireadmefile == null)
            {
                ifiles_in_order.AddRange(imdfiles);
            }
            else if (ireadmefile != null && ifiles.Count == 0)
            {
                ifiles_in_order.Add(ireadmefile);
            }
            else
            {
                var readme = FSharp.Markdown.Markdown.Parse(File.ReadAllText(ireadmefile));
                urls = new List <Tuple <int, string, string, SourceLocation> >();
                // is there a nicer way to get the URLs of all depth-1 and depth-2 URLs in this list? ...
                foreach (var list in readme.Paragraphs.OfType <FSharp.Markdown.MarkdownParagraph.ListBlock>())
                {
                    var pp = new List <Tuple <int, FSharp.Markdown.MarkdownParagraph> >();
                    foreach (var pars in list.items)
                    {
                        foreach (var par in pars)
                        {
                            pp.Add(Tuple.Create(1, par));
                            var sublist = par as FSharp.Markdown.MarkdownParagraph.ListBlock;
                            if (sublist != null)
                            {
                                pp.AddRange(from subpars in sublist.items
                                            from subpar in subpars
                                            select Tuple.Create(2, subpar));
                            }
                        }
                    }
                    foreach (var tpp in pp)
                    {
                        var level   = tpp.Item1;
                        var spanpar = tpp.Item2 as FSharp.Markdown.MarkdownParagraph.Span;
                        if (spanpar == null)
                        {
                            continue;
                        }

                        var links = spanpar.body.OfType <FSharp.Markdown.MarkdownSpan.DirectLink>();
                        urls.AddRange(from link in links
                                      let title                     = string.Join("", link.body.OfType <FSharp.Markdown.MarkdownSpan.Literal>().Select(l => l.text))
                                                            let url = link.link
                                                                      where url.ToLower().EndsWith(".md") || url.ToLower().Contains(".md#")
                                                                      let loc = new SourceLocation(ireadmefile, null, list, link)
                                                                                select Tuple.Create(level, title, url, loc));
                    }
                }
                var filelinks = (from turl in urls
                                 let url = turl.Item3
                                           let i = url.IndexOf('#')
                                                   let url2 = (i == -1 ? url : url.Substring(0, i))
                                                              select url2).ToList().Distinct();
                foreach (var link in filelinks)
                {
                    var ifile = ifiles.FirstOrDefault(f => Path.GetFileName(f) == link);
                    if (ifile == null)
                    {
                        Console.Error.WriteLine($"readme.md link '{link}' wasn't one of the files passed on the command line"); return(1);
                    }
                    ifiles_in_order.Add(ifile);
                }
            }
            var md = MarkdownSpec.ReadFiles(ifiles_in_order, urls);

            // Generate the Specification.docx file
            if (odocfile != null)
            {
                var odocfile2 = odocfile;
                if (odocfile2 != odocfile)
                {
                    Report("MD26", error: true, $"File '{odocfile}' was in use", "mdspec2docx");
                }

                Console.WriteLine($"Writing '{Path.GetFileName(odocfile2)}'");
                try
                {
                    MarkdownSpecConverter.ConvertToWord(md, idocxfile, odocfile2);
                }
                catch (Exception ex)
                {
                    Report("MD27", error: true, ex.Message, ex.StackTrace);
                    return(1);
                }
                if (odocfile2 != odocfile)
                {
                    return(1);
                }
            }
            Console.WriteLine($"Errors: {errors}");
            Console.WriteLine($"Warnings: {warnings}");
            return(errors == 0 ? 0 : 1);
        }