Exemplo n.º 1
0
 private void commit(ref MdElement ele)
 {
     if (ele.Text != null)
     {
         _elements.Add(ele);
     }
     ele      = new MdElement();
     ele.Line = _line + 1;
 }
Exemplo n.º 2
0
        /// <summary>
        /// 对命令进行扩展,返回 true 如果这次过程中有命令被展开或定义。
        /// </summary>
        /// <returns></returns>
        private MdElement expandCommand(MdElement ele)
        {
            int col = 0;

            _line = ele.Line;
            string text = null;

            var commands = findCommandElements(ele.Text).ToArray();

            foreach (var cmd in commands)
            {
                if (!_commands.ContainsKey(cmd.Text))
                {
                    continue;
                }
                if (cmd.ColStart > col + 1)
                {
                    text += ele.Text.Substring(col, cmd.ColStart - 1 - col);
                }
                col = cmd.ColEnd + 1;
                try {
                    for (int argi = 0; argi < cmd.Args.Length; ++argi)
                    {
                        MdElement tmp = new MdElement();
                        tmp.ElementType = MdElementType.Text; tmp.Line = -1; tmp.Text = cmd.Args[argi];
                        tmp             = expandCommand(tmp);
                        cmd.Args[argi]  = tmp.Text;
                    }
                    string fmt = string.Format(_commands [cmd.Text], cmd.Args);
                    text += fmt;
                } catch {
                    warn("Arguments failure while expanding command `" + cmd.Text + "`.");
                }
            }

            if (col < ele.Text.Length)
            {
                text += ele.Text.Substring(col);
            }

            ele.Text = text;

            return(ele);
        }
Exemplo n.º 3
0
        private void parseLines()
        {
            MdElement ele = new MdElement();

            ele.Line  = 1;
            _elements = new List <MdElement> ();

            string line = null;

            for (_line = 1; _line <= _lines.Length; ++_line)
            {
                line = _lines [_line - 1].Trim();
                if (string.IsNullOrWhiteSpace(line))
                {
                    commit(ref ele);
                    continue;
                }

                if (line.Length == 1)
                {
                    ele.Text = (ele.Text ?? "") + line;
                    continue;
                }

                switch (line [0])
                {
                case '#':                 // 带编号标题
                    int headlineLevel = 1;
                    for (; headlineLevel < line.Length && line [headlineLevel] == '#'; ++headlineLevel)
                    {
                        ;
                    }

                    ele.Args        = new string[] { "" + headlineLevel };
                    ele.ElementType = MdElementType.Headline;
                    ele.Text        = line.Substring(headlineLevel).Trim();
                    if (ele.Text.EndsWith("#"))
                    {
                        ele.Text = ele.Text.Substring(0, ele.Text.IndexOf('#')).Trim();
                    }
                    commit(ref ele);
                    break;

                case '-':
                    if (line.All(c => c == '-'))                        // 副标题
                    {
                        ele.ElementType = MdElementType.Headline;
                        ele.Args        = new string[] { "-1" };
                        commit(ref ele);
                    }
                    else                         // 无编号列举项目
                    {
                        ele.ElementType = MdElementType.Ul;
                        ele.Text        = (ele.Text ?? "") + line.Substring(1).Trim() + "\n";
                    }

                    break;

                case '=':
                    if (line.All(c => c == '='))                        // 主标题
                    {
                        ele.ElementType = MdElementType.Headline;
                        ele.Args        = new string[] { "0" };
                    }
                    break;

                case '>':                 // 引用
                    ele.ElementType = MdElementType.BlockQuote;
                    ele.Text        = (ele.Text ?? "") + line.Substring(1).Trim();
                    break;

                case '!':                 // 图像或表格
                    ele.ElementType = MdElementType.Image;
                    var mBang = Regex.Match(line, @"\!\[(\w+)\]\((.*?)\)");
                    if (mBang == null || string.IsNullOrEmpty(mBang.Groups [2].Value))
                    {
                        warn("Wrong arguments for `!` direction.");
                        continue;
                    }
                    ele.Text = mBang.Groups [1].Value;
                    ele.Args = mBang.Groups [2].Value.Split(' ');
                    if (ele.Args [0] == "")                       // 表格
                    {
                        ele.ElementType = MdElementType.Table;
                    }
                    else                         // 图像的话就直接提交了
                    {
                        commit(ref ele);
                        continue;
                    }
                    break;

                default:                                                // 普通的文本
                    if (line.StartsWith("%=") || line.StartsWith("%%")) // 定义命令
                    {
                        if (line.Length <= 2 || !line.Contains(":"))
                        {
                            warn("Insufficient arguments for command definition.");
                            continue;
                        }
                        string commandName = line.Substring(2);
                        commandName = commandName.Substring(0, commandName.IndexOf(':'));
                        string commandReplacement = line.Substring(line.IndexOf(':') + 1);
                        if (_commands.ContainsKey(commandName))
                        {
                            if (line.StartsWith("%%"))
                            {
                                _commands [commandName] = commandReplacement;
                            }
                            else
                            {
                                warn("Command `" + commandName + "` already defined.");
                            }
                            continue;
                        }
                        _commands.Add(commandName, commandReplacement);
                        continue;
                    }
                    if (line.StartsWith("1."))                        // Ol
                    {
                        ele.ElementType = MdElementType.Ol;
                        ele.Text        = (ele.Text ?? "") + line.Substring(2) + "\n";
                        break;
                    }
                    if (ele.Text == null)
                    {
                        ele.Text = "";
                    }
                    else if (!string.IsNullOrEmpty(ele.Text) && !ele.Text.EndsWith("\n"))
                    {
                        ele.Text += "\n";
                    }
                    ele.Text += line;
                    break;
                }
            }
        }
Exemplo n.º 4
0
        private void renderElement(MdElement ele)
        {
            applyStyle("");
            _line = ele.Line;
            try {
                switch (ele.ElementType)
                {
                case MdElementType.BlockQuote:
                    _builder.ParagraphFormat.LeftIndent  = 10;
                    _builder.ParagraphFormat.SpaceBefore = 10;
                    _builder.ParagraphFormat.SpaceAfter  = 10;
                    applyStyle("blockquote");
                    renderText(ele.Text);
                    break;

                case MdElementType.Headline:
                    applyStyle("headline");
                    _builder.ParagraphFormat.SpaceBefore = 10;
                    if (int.Parse(ele.Args [0]) <= 0)
                    {
                        _builder.Font.Size = ele.Args[0] == "0" ? 24 : 18;
                        _builder.ParagraphFormat.Alignment = ParagraphAlignment.Center;
                    }
                    else
                    {
                        try {
                            _builder.ParagraphFormat.OutlineLevel = (OutlineLevel)Enum.Parse(typeof(OutlineLevel), "Level" + ele.Args[0]);
                        }catch {}
                        _builder.Font.Bold = true;
                    }
                    applyStyle("headline" + ele.Args[0]);
                    renderText(ele.Text);
                    break;

                case MdElementType.Image:
                    if (ele.Args.Length == 0)
                    {
                        warn("Image instructive needs more than 0 arguments.");
                    }
                    else
                    {
                        var img = System.Drawing.Image.FromFile(ele.Args[0]);
                        applyStyle("image");
                        _builder.InsertImage(img, img.Width, img.Height);
                        _builder.InsertParagraph();
                        if (ele.Args.Length > 1)
                        {
                            _counters[ele.Args[1]]++;
                            _counters[ele.Text] = _counters[ele.Args[1]];
                            applyStyle("caption");
                            _builder.Write(ele.Args[1] + _counters[ele.Args[1]]);
                            _builder.Write(ele.Args.Length > 2 ? " " + ele.Args[2] : "");
                        }
                    }
                    break;

                case MdElementType.Text:
                    renderText(ele.Text);
                    break;

                case MdElementType.Command:
                    warn("Skipped command `" + ele.Text + "`; invalid position.");
                    break;

                case MdElementType.Ol:
                    _builder.CurrentParagraph.ListFormat.List = _docx.Lists.Add(Aspose.Words.Lists.ListTemplate.NumberDefault);
                    var olitems = ele.Text.Split('\n');
                    for (int i = 0; i < olitems.Length - 1; ++i)
                    {
                        _builder.Write(olitems[i]);
                        _builder.InsertParagraph();
                    }
                    _builder.CurrentParagraph.ListFormat.List = null;
                    break;

                case MdElementType.Ul:
                    _builder.CurrentParagraph.ListFormat.List = _docx.Lists.Add(Aspose.Words.Lists.ListTemplate.BulletDefault);
                    var ulitems = ele.Text.Split('\n');
                    for (int i = 0; i < ulitems.Length - 1; ++i)
                    {
                        _builder.Write(ulitems[i]);
                        _builder.InsertParagraph();
                    }
                    _builder.CurrentParagraph.ListFormat.List = null;
                    break;

                case MdElementType.Table:
                    _builder.CellFormat.Borders.LineStyle = LineStyle.Single;

                    if (ele.Args.Length > 2)
                    {
                        _counters[ele.Text] = ++_counters[ele.Args[1]];
                        applyStyle("caption");
                        _builder.Write(ele.Args[1] + _counters[ele.Args[1]]);
                        _builder.Write(ele.Args.Length > 3 ? " " + ele.Args[2] : "");
                        _builder.InsertParagraph();
                    }

                    applyStyle(""); applyStyle("table");

                    _builder.StartTable();

                    string[] tableRows = ele.Text.Split('\n');

                    //Insert some table
                    for (int i = 1; i < tableRows.Length - 1; i++)
                    {
                        string row = tableRows[i];
                        foreach (var vp in Regex.Split(row, @"\t+"))
                        {
                            _builder.InsertCell();
                            _builder.Write(vp);
                        }
                        _builder.EndRow();
                    }
                    _builder.EndTable();
                    break;
                }
            } catch (Exception e) {
                warn(e.Message);
            }

            _builder.InsertParagraph();
        }
Exemplo n.º 5
0
        private IEnumerable <MdElement> findCommandElements(string text)
        {
            MdElement     ele      = null;
            string        argstr   = "";
            int           balanced = 0;
            List <string> argList  = new List <string>();

            for (int col = 0; col < text.Length; ++col)
            {
                switch (text [col])
                {
                case '\\':
                    ++col;
                    break;

                case '%':                 // 命令
                    if (balanced == 0)
                    {
                        ele             = new MdElement();
                        ele.ElementType = MdElementType.Command;
                        ele.ColStart    = col;
                        var mName = Regex.Match(text.Substring(col), @"\%(\w+)");
                        if (mName != null)
                        {
                            ele.Text = mName.Groups [1].Value;
                            col     += ele.Text.Length;
                        }
                        else
                        {
                            argstr += "%";
                        }
                    }
                    else
                    {
                        argstr += '%';
                    }
                    break;

                case '@':
                    ele = new MdElement {
                        ElementType = MdElementType.Command,
                        Text        = "footnote"
                    };
                    break;

                case '^':
                    ele = new MdElement {
                        ElementType = MdElementType.Command,
                        Text        = "endnote"
                    };
                    break;

                case '{':
                    if (ele != null)
                    {
                        ++balanced;
                    }
                    if (balanced > 1)
                    {
                        argstr += '{';
                    }
                    break;

                default:
                    if (ele != null)
                    {
                        if (char.IsWhiteSpace(text [col]) && balanced == 1)
                        {
                            argList.Add(argstr);
                            argstr = "";
                            continue;
                        }
                        if (text [col] == '}' && balanced > 0)
                        {
                            balanced--;
                        }
                        if (balanced == 0)
                        {
                            argList.Add(argstr);
                            ele.Args   = argList.ToArray();
                            ele.ColEnd = col;
                            yield return(ele);

                            ele = null; argstr = ""; argList.Clear();
                        }
                        else
                        {
                            argstr += text [col];
                        }
                    }
                    break;
                }
            }
            if (ele != null)
            {
                ele.ColEnd = text.Length - 1;
                yield return(ele);
            }
        }