public string _loc; // generated lazily.

        public SourceLocation(string file, SectionRef section, MarkdownParagraph paragraph, MarkdownSpan span)
        {
            File      = file;
            Section   = section;
            Paragraph = paragraph;
            Span      = span;
        }
        private MarkdownSpec(IEnumerable <Tuple <string, MarkdownDocument> > sources)
        {
            Sources = sources;

            // (1) Add sections into the dictionary
            string url = "", title = "";

            // (2) Turn all the antlr code blocks into a grammar
            var sbantlr = new StringBuilder();

            foreach (var src in sources)
            {
                var reporter = new Reporter(src.Item1);
                var filename = Path.GetFileName(src.Item1);
                var md       = src.Item2;

                foreach (var mdp in md.Paragraphs)
                {
                    reporter.CurrentParagraph = mdp;
                    reporter.CurrentSection   = null;
                    if (mdp.IsHeading)
                    {
                        try
                        {
                            var sr = new SectionRef(mdp as MarkdownParagraph.Heading, filename);
                            if (Sections.Any(s => s.Url == sr.Url))
                            {
                                reporter.Error("MD02", $"Duplicate section title {sr.Url}");
                            }
                            else
                            {
                                Sections.Add(sr);
                                url   = sr.Url;
                                title = sr.Title;
                                reporter.CurrentSection = sr;
                            }
                        }
                        catch (Exception ex)
                        {
                            reporter.Error("MD03", ex.Message); // constructor of SectionRef might throw
                        }
                    }
                    else if (mdp.IsCodeBlock)
                    {
                        var    mdc = mdp as MarkdownParagraph.CodeBlock;
                        string code = mdc.code, lang = mdc.language;
                        if (lang != "antlr")
                        {
                            continue;
                        }

                        var g = Antlr.ReadString(code, "");
                        Productions.Add(new ProductionRef(code, g.Productions));
                        foreach (var p in g.Productions)
                        {
                            p.Link = url; p.LinkName = title;
                            if (p.Name != null && Grammar.Productions.Any(dupe => dupe.Name == p.Name))
                            {
                                reporter.Warning("MD04", $"Duplicate grammar for {p.Name}");
                            }
                            Grammar.Productions.Add(p);
                        }
                    }
                }
            }
        }