示例#1
0
        public bool TryProcessAttributes(IDictionary <string, string> attributes, out HtmlAttributes htmlAttributes, Action <string> logError)
        {
            htmlAttributes = null;
            var target = string.Empty;
            var pivot  = string.Empty;

            foreach (var attribute in attributes)
            {
                var name  = attribute.Key;
                var value = attribute.Value;
                switch (name)
                {
                case "target":
                    if (value != "docs" && value != "chromeless" && value != "pdf")
                    {
                        logError($"Unexpected target \"{value}\". Permitted targets are \"docs\", \"chromeless\" or \"pdf\".");
                        return(false);
                    }
                    target = value;
                    break;

                case "pivot":
                    if (!pivotRegex.IsMatch(value))
                    {
                        logError($"Invalid pivot \"{value}\". Pivot must be a comma-delimited list of pivot names. Pivot names must be lower-case and contain only letters, numbers or dashes.");
                        return(false);
                    }
                    pivot = value;
                    break;

                default:
                    logError($"Unexpected attribute \"{name}\".");
                    return(false);
                }
            }

            if (target == string.Empty && pivot == string.Empty)
            {
                logError($"Either target or privot must be specified.");
                return(false);
            }
            if (target == "pdf" && pivot != string.Empty)
            {
                logError($"Pivot not permitted on pdf target.");
                return(false);
            }

            htmlAttributes = new HtmlAttributes();
            if (target != string.Empty)
            {
                htmlAttributes.AddProperty("data-zone", target);
            }
            if (pivot != string.Empty)
            {
                htmlAttributes.AddProperty("data-pivot", pivot.Trim().ReplaceRegex(pivotReplaceCommasRegex, " "));
            }
            return(true);
        }
示例#2
0
        public bool TryProcessAttributes(IDictionary <string, string> attributes, out HtmlAttributes htmlAttributes, out IDictionary <string, string> renderProperties, Action <string> logError, Action <string> logWarning, MarkdownObject markdownObject)
        {
            htmlAttributes   = null;
            renderProperties = new Dictionary <string, string>();
            var model      = string.Empty;
            var action     = string.Empty;
            var submitText = string.Empty;

            foreach (var attribute in attributes)
            {
                var name  = attribute.Key;
                var value = attribute.Value;
                switch (name)
                {
                case "model":
                    model = value;
                    break;

                case "action":
                    action = value;
                    break;

                case "submittext":
                    submitText = WebUtility.HtmlEncode(value);
                    break;

                default:
                    logError($"Unexpected attribute \"{name}\".");
                    return(false);
                }
            }

            if (action == string.Empty)
            {
                logError("Form action must be specified.");
                return(false);
            }
            if (submitText == string.Empty)
            {
                logError("Submit text must be specified.");
                return(false);
            }


            htmlAttributes = new HtmlAttributes();
            if (model != string.Empty)
            {
                htmlAttributes.AddProperty("data-model", model);
            }
            htmlAttributes.AddProperty("data-action", action);
            htmlAttributes.AddClass("chromeless-form");

            renderProperties.Add(new KeyValuePair <string, string>("submitText", submitText));

            return(true);
        }
        protected override void Write(HtmlRenderer renderer, LinkToParsedModel obj)
        {
            RequestLifetimeService requestLifetimeService = null;

            if (_serviceProvider.GetRequiredService <IHttpContextAccessor>().HttpContext.Items
                .TryGetValue("RequestLifetime", out var lifetimeService))
            {
                requestLifetimeService = (RequestLifetimeService)lifetimeService;
            }

            if (requestLifetimeService == null)
            {
                throw ExceptionFactory.SoftException(ExceptionEnum.SomethingWentWrong, $"If you see this message pls contact admin, {obj.Id}");
            }

            var publicContext = (PublicContext)_serviceProvider.GetService(typeof(PublicContext));

            var isPostOrComment = publicContext.IsPostOrComment(obj.Id);

            var attr = new HtmlAttributes();

            attr.AddClass("link-to");

            attr.AddProperty("target", "_blank");
            attr.AddProperty("rel", "noopener noreferrer");

            attr.AddProperty("href", $"/{requestLifetimeService.Board.Name}/{requestLifetimeService.Post.Id}#{obj.Id}");
            attr.AddProperty("data-thread", requestLifetimeService.Post.Id.ToString());

            var innerText = ">>" + obj.Id;

            var mention = new Mention
            {
                MentionId   = obj.Id,
                MentionerId = requestLifetimeService.MyId,
                IsComment   = requestLifetimeService.IsComment,
            };

            requestLifetimeService.AddMention(mention);

            if (isPostOrComment == 0)
            {
                attr.AddProperty("data-post", obj.Id.ToString());
                innerText += " (OP)";
            }
            else if (isPostOrComment == 1)
            {
                attr.AddProperty("data-comment", obj.Id.ToString());
            }
            else
            {
                attr.AddProperty("data-post", obj.Id.ToString());
                attr.AddProperty("data-comment", obj.Id.ToString());
            }

            renderer.Write("<a").WriteAttributes(attr).Write($">{innerText}</a>");
        }
示例#4
0
        public void TestAddProperty()
        {
            var attributes = new HtmlAttributes();

            attributes.AddProperty("key1", "1");
            Assert.NotNull(attributes.Properties);
            Assert.AreEqual(new List <KeyValuePair <string, string> >()
            {
                new KeyValuePair <string, string>("key1", "1")
            }, attributes.Properties);

            attributes.AddPropertyIfNotExist("key1", "1");
            Assert.NotNull(attributes.Properties);
            Assert.AreEqual(new List <KeyValuePair <string, string> >()
            {
                new KeyValuePair <string, string>("key1", "1")
            }, attributes.Properties);

            attributes.AddPropertyIfNotExist("key2", "2");
            Assert.AreEqual(new List <KeyValuePair <string, string> >()
            {
                new KeyValuePair <string, string>("key1", "1"), new KeyValuePair <string, string>("key2", "2")
            }, attributes.Properties);
        }
示例#5
0
        public bool TryProcessAttributes(IDictionary <string, string> attributes, out HtmlAttributes htmlAttributes, out IDictionary <string, string> renderProperties, Action <string> logError, BlockProcessor processor)
        {
            htmlAttributes   = null;
            renderProperties = new Dictionary <string, string>();
            var src       = string.Empty;
            var alt       = string.Empty;
            var type      = string.Empty;
            var loc_scope = string.Empty;
            var border    = true;

            foreach (var attribute in attributes)
            {
                var name  = attribute.Key;
                var value = attribute.Value;
                switch (name)
                {
                case "alt-text":
                    alt = value;
                    break;

                case "type":
                    type = value;
                    break;

                case "loc-scope":
                    loc_scope = value;
                    break;

                case "source":
                    src = value;
                    break;

                case "border":
                    if (!bool.TryParse(value, out border))
                    {
                        border = true;
                    }
                    break;

                case "lightbox":
                    break;

                default:
                    logError($"Image reference '{src}' is invalid per the schema. Unexpected attribute: '{name}'.");
                    return(false);
                }
            }

            if (string.IsNullOrEmpty(type))
            {
                type = "content";
            }

            if (string.IsNullOrEmpty(src))
            {
                logError("source is a required attribute. Please ensure you have specified a source attribute.");
            }
            if (string.IsNullOrEmpty(alt) && type != "icon")
            {
                logError("alt-text is a required attribute. Please ensure you have specified an alt-text attribute.");
            }
            if ((string.IsNullOrEmpty(alt) && type != "icon") || string.IsNullOrEmpty(src))
            {
                return(false);
            }
            htmlAttributes = new HtmlAttributes();
            htmlAttributes.AddProperty("src", src);

            if (type == "icon")
            {
                htmlAttributes.AddProperty("role", "presentation");
            }
            else
            {
                htmlAttributes.AddProperty("alt", alt);
            }
            var id = GetHtmlId(processor.LineIndex, processor.Column);

            if (type == "complex")
            {
                htmlAttributes.AddProperty("aria-describedby", id);
            }

            RenderDelegate = (renderer, obj) =>
            {
                var currentLightbox  = string.Empty;
                var currentBorderStr = string.Empty;
                var currentBorder    = true;
                obj.Attributes.TryGetValue("lightbox", out currentLightbox); //it's okay if this is null
                obj.Attributes.TryGetValue("border", out currentBorderStr);  //it's okay if this is null
                if (!bool.TryParse(currentBorderStr, out currentBorder))
                {
                    currentBorder = true;
                }

                if (!string.IsNullOrEmpty(currentLightbox))
                {
                    var lighboxHtmlAttributes = new HtmlAttributes();
                    lighboxHtmlAttributes.AddProperty("href", $"{currentLightbox}#lightbox");
                    lighboxHtmlAttributes.AddProperty("data-linktype", $"relative-path");
                    renderer.Write("<a").WriteAttributes(lighboxHtmlAttributes).WriteLine(">");
                }
                if (currentBorder)
                {
                    renderer.WriteLine("<div class=\"mx-imgBorder\"><p>");
                }
                //if obj.Count == 0, this signifies that there is no long description for the image.
                if (obj.Count == 0)
                {
                    renderer.Write("<img").WriteAttributes(obj).WriteLine(">");
                }
                else
                {
                    if (type == "complex" && obj.Count == 0)
                    {
                        logError("If type is \"complex\", then descriptive content is required. Please make sure you have descriptive content.");
                        return(false);
                    }
                    var htmlId = GetHtmlId(obj.Line, obj.Column);
                    renderer.Write("<img").WriteAttributes(obj).WriteLine(">");
                    renderer.WriteLine($"<div id=\"{htmlId}\" class=\"visually-hidden\">");
                    renderer.WriteChildren(obj);
                    renderer.WriteLine("</div>");
                }

                if (currentBorder)
                {
                    renderer.WriteLine("</p></div>");
                }
                if (!string.IsNullOrEmpty(currentLightbox))
                {
                    renderer.WriteLine($"</a>");
                }

                return(true);
            };

            return(true);
        }
示例#6
0
        public bool TryProcessAttributes(IDictionary <string, string> attributes, out HtmlAttributes htmlAttributes, out IDictionary <string, string> renderProperties, Action <string> logError, Action <string> logWarning, TripleColonBlock block)
        {
            htmlAttributes   = null;
            renderProperties = new Dictionary <string, string>();
            var src      = string.Empty;
            var title    = string.Empty;
            var maxWidth = string.Empty;

            foreach (var attribute in attributes)
            {
                var name  = attribute.Key;
                var value = attribute.Value;
                switch (name)
                {
                case "title":
                    title = value;
                    break;

                case "max-width":
                    maxWidth = value;
                    break;

                case "source":
                    src = value;
                    break;

                default:
                    logError($"Video reference '{src}' is invalid per the schema. Unexpected attribute: '{name}'.");
                    return(false);
                }
            }

            if (string.IsNullOrEmpty(src))
            {
                logError("source is a required attribute. Please ensure you have specified a source attribute.");
                return(false);
            }
            if (!src.Contains("channel9.msdn.com") &&
                !src.Contains("youtube.com/embed") &&
                !src.Contains("microsoft.com/en-us/videoplayer/embed"))
            {
                logWarning($"Video source, '{src}', should be from https://channel9.msdn.com, https://www.youtube.com/embed, or https://www.microsoft.com/en-us/videoplayer/embed");
            }
            if (src.Contains("channel9.msdn.com") && !src.Contains("/player"))
            {
                logWarning($"Your source from channel9.msdn.com does not end in '/player'. Please make sure you are correctly linking to the Channel 9 video player. ");
            }

            htmlAttributes = new HtmlAttributes();
            htmlAttributes.AddProperty("src", QuoteSectionNoteRender.FixUpLink(src));
            htmlAttributes.AddProperty("allowFullScreen", "true");
            htmlAttributes.AddProperty("frameBorder", "0");

            if (!string.IsNullOrEmpty(title))
            {
                htmlAttributes.AddProperty("title", title);
            }

            if (!string.IsNullOrEmpty(maxWidth))
            {
                int number;
                if (!int.TryParse(maxWidth, out number))
                {
                    logError($"Video reference '{src}' is invalid. 'max-width' must be a number.");
                    return(false);
                }
                htmlAttributes.AddProperty("style", $"max-width:{maxWidth}px;");
            }

            RenderDelegate = (renderer, obj) =>
            {
                renderer.WriteLine("<div class=\"embeddedvideo\">");
                renderer.Write($"<iframe").WriteAttributes(obj).WriteLine(">");
                renderer.WriteLine("</div>");

                return(true);
            };

            return(true);
        }
示例#7
0
        public bool TryProcessAttributes(IDictionary <string, string> attributes, out HtmlAttributes htmlAttributes, out IDictionary <string, string> renderProperties, Action <string> logError, BlockProcessor processor)
        {
            htmlAttributes   = null;
            renderProperties = new Dictionary <string, string>();
            var source      = string.Empty;
            var range       = string.Empty;
            var id          = string.Empty;
            var highlight   = string.Empty;
            var language    = string.Empty;
            var interactive = string.Empty;

            foreach (var attribute in attributes)
            {
                var name  = attribute.Key;
                var value = attribute.Value;
                switch (name)
                {
                case "source":
                    source = value;
                    break;

                case "range":
                    range = value;
                    break;

                case "id":
                    id = value;
                    break;

                case "highlight":
                    highlight = value;
                    break;

                case "language":
                    language = value;
                    break;

                case "interactive":
                    interactive = value;
                    break;

                default:
                    logError($"Unexpected attribute \"{name}\".");
                    return(false);
                }
            }

            if (string.IsNullOrEmpty(source))
            {
                logError("source is a required attribute. Please ensure you have specified a source attribute");
                return(false);
            }

            if (string.IsNullOrEmpty(language))
            {
                language = InferLanguageFromFile(source, logError);
            }

            htmlAttributes = new HtmlAttributes();
            htmlAttributes.AddProperty("class", $"lang-{language}");
            if (!string.IsNullOrEmpty(interactive))
            {
                htmlAttributes.AddProperty("data-interactive", language);
                htmlAttributes.AddProperty("data-interactive-mode", interactive);
            }
            if (!string.IsNullOrEmpty(highlight))
            {
                htmlAttributes.AddProperty("highlight-lines", highlight);
            }

            RenderDelegate = (renderer, obj) =>
            {
                var currentId     = string.Empty;
                var currentRange  = string.Empty;
                var currentSource = string.Empty;
                obj.Attributes.TryGetValue("id", out currentId);         //it's okay if this is null
                obj.Attributes.TryGetValue("range", out currentRange);   //it's okay if this is null
                obj.Attributes.TryGetValue("source", out currentSource); //source has already been checked above
                var(code, codePath) = _context.ReadFile(currentSource, InclusionContext.File, obj);
                if (string.IsNullOrEmpty(code))
                {
                    logError($"The code snippet \"{currentSource}\" could not be found.");
                    return(false);
                }
                var updatedCode = GetCodeSnippet(currentRange, currentId, code, logError).TrimEnd();

                if (updatedCode == string.Empty)
                {
                    return(false);
                }
                renderer.WriteLine("<pre>");
                renderer.Write("<code").WriteAttributes(obj).Write(">");
                renderer.WriteLine(updatedCode);
                renderer.WriteLine("</code></pre>");

                return(true);
            };

            return(true);
        }
示例#8
0
        public bool TryProcessAttributes(IDictionary <string, string> attributes, out HtmlAttributes htmlAttributes, out IDictionary <string, string> renderProperties, Action <string> logError, BlockProcessor processor)
        {
            htmlAttributes   = null;
            renderProperties = new Dictionary <string, string>();
            var src       = string.Empty;
            var alt       = string.Empty;
            var type      = string.Empty;
            var loc_scope = string.Empty;

            foreach (var attribute in attributes)
            {
                var name  = attribute.Key;
                var value = attribute.Value;
                switch (name)
                {
                case "alt-text":
                    alt = value;
                    break;

                case "type":
                    type = value;
                    break;

                case "loc-scope":
                    loc_scope = value;
                    break;

                case "source":
                    src = value;
                    break;

                default:
                    logError($"Unexpected attribute \"{name}\".");
                    return(false);
                }
            }

            if (string.IsNullOrEmpty(type))
            {
                type = "content";
            }

            if (string.IsNullOrEmpty(src))
            {
                logError($"source is a required attribute. Please ensure you have specified a source attribute.");
            }
            if (string.IsNullOrEmpty(alt) && type != "icon")
            {
                logError($"alt-text is a required attribute. Please ensure you have specified an alt-text attribute.");
            }
            if ((string.IsNullOrEmpty(alt) && type != "icon") || string.IsNullOrEmpty(src))
            {
                return(false);
            }
            htmlAttributes = new HtmlAttributes();
            htmlAttributes.AddProperty("src", src);
            if (type == "icon")
            {
                htmlAttributes.AddProperty("role", "presentation");
            }
            else
            {
                htmlAttributes.AddProperty("alt", alt);
            }
            var id = GetHtmlId(processor.LineIndex, processor.Column);

            if (type == "complex")
            {
                htmlAttributes.AddProperty("aria-describedby", id);
            }

            RenderDelegate = (renderer, obj) =>
            {
                //if obj.Count == 0, this signifies that there is no long description for the image.
                if (obj.Count == 0)
                {
                    renderer.Write("<img").WriteAttributes(obj).WriteLine(">");
                }
                else
                {
                    if (type == "complex" && obj.Count == 0)
                    {
                        logError($"If type is \"complex\", then descriptive content is required. Please make sure you have descriptive content.");
                        return(false);
                    }
                    var htmlId = GetHtmlId(obj.Line, obj.Column);
                    renderer.Write("<img").WriteAttributes(obj).WriteLine(">");
                    renderer.WriteLine($"<div id=\"{htmlId}\" class=\"visually-hidden\">");
                    renderer.WriteChildren(obj);
                    renderer.WriteLine("</div>");
                }

                return(true);
            };

            return(true);
        }
示例#9
0
        public bool TryProcessAttributes(IDictionary <string, string> attributes, out HtmlAttributes htmlAttributes, out IDictionary <string, string> renderProperties, Action <string> logError, BlockProcessor processor)
        {
            htmlAttributes   = null;
            renderProperties = new Dictionary <string, string>();
            var model      = string.Empty;
            var action     = string.Empty;
            var submitText = string.Empty;

            foreach (var attribute in attributes)
            {
                var name  = attribute.Key;
                var value = attribute.Value;
                switch (name)
                {
                case "model":
                    model = value;
                    break;

                case "action":
                    action = value;
                    break;

                case "submittext":
                    submitText = WebUtility.HtmlEncode(value);
                    break;

                default:
                    logError($"Unexpected attribute \"{name}\".");
                    return(false);
                }
            }

            if (action == string.Empty)
            {
                logError("Form action must be specified.");
                return(false);
            }
            if (submitText == string.Empty)
            {
                logError("Submit text must be specified.");
                return(false);
            }


            htmlAttributes = new HtmlAttributes();
            if (model != string.Empty)
            {
                htmlAttributes.AddProperty("data-model", model);
            }
            htmlAttributes.AddProperty("data-action", action);
            htmlAttributes.AddClass("chromeless-form");

            renderProperties.Add(new KeyValuePair <string, string>("submitText", submitText));

            RenderDelegate = (renderer, obj) =>
            {
                var buttonText = "Submit";
                obj.RenderProperties.TryGetValue("submitText", out buttonText);

                renderer.Write("<form").WriteAttributes(obj).WriteLine(">");
                renderer.WriteLine("<div></div>");
                renderer.WriteLine($"<button class=\"button is-primary\" disabled=\"disabled\" type=\"submit\">{buttonText}</button>");
                renderer.WriteLine("</form>");

                return(true);
            };

            return(true);
        }
示例#10
0
        public bool TryProcessAttributes(IDictionary <string, string> attributes, out HtmlAttributes htmlAttributes, out IDictionary <string, string> renderProperties, Action <string> logError, Action <string> logWarning, MarkdownObject markdownObject)
        {
            htmlAttributes   = null;
            renderProperties = new Dictionary <string, string>();
            var src       = string.Empty;
            var alt       = string.Empty;
            var type      = string.Empty;
            var loc_scope = string.Empty;

            foreach (var attribute in attributes)
            {
                var name  = attribute.Key;
                var value = attribute.Value;
                switch (name)
                {
                case "alt-text":
                    alt = value;
                    break;

                case "type":
                    type = value;
                    break;

                case "loc-scope":
                    loc_scope = value;
                    break;

                case "source":
                    src = value;
                    break;

                case "border":
                    break;

                case "lightbox":
                    break;

                case "link":
                    break;

                default:
                    logError($"Image reference '{src}' is invalid per the schema. Unexpected attribute: '{name}'.");
                    return(false);
                }
            }

            if (string.IsNullOrEmpty(type))
            {
                type = "content";
            }

            if (string.IsNullOrEmpty(src))
            {
                logError("source is a required attribute. Please ensure you have specified a source attribute.");
            }
            if (string.IsNullOrEmpty(alt) && type != "icon")
            {
                logError("alt-text is a required attribute. Please ensure you have specified an alt-text attribute.");
            }

            // add loc scope missing/invalid validation here

            if ((string.IsNullOrEmpty(alt) && type != "icon") || string.IsNullOrEmpty(src))
            {
                return(false);
            }
            htmlAttributes = new HtmlAttributes();

            // alt is allowed to be empty for icon type image
            if (string.IsNullOrEmpty(alt) && type == "icon")
            {
                htmlAttributes.AddProperty("src", _context.GetLink(src, markdownObject));
            }
            else
            {
                htmlAttributes.AddProperty("src", _context.GetImageLink(src, markdownObject, alt));
            }

            if (type == "icon")
            {
                htmlAttributes.AddProperty("role", "presentation");
            }
            else
            {
                htmlAttributes.AddProperty("alt", alt);
            }
            var id = GetHtmlId(markdownObject);

            if (type == "complex")
            {
                htmlAttributes.AddProperty("aria-describedby", id);
            }

            return(true);
        }
示例#11
0
        public bool Render(HtmlRenderer renderer, MarkdownObject obj, Action <string> logWarning)
        {
            var tripleColonObj = (ITripleColon)obj;

            if (!tripleColonObj.Attributes.TryGetValue("type", out var currentType))
            {
                currentType = "content";
            }
            tripleColonObj.Attributes.TryGetValue("lightbox", out var currentLightbox); //it's okay if this is null
            tripleColonObj.Attributes.TryGetValue("border", out var currentBorderStr);  //it's okay if this is null
            tripleColonObj.Attributes.TryGetValue("link", out var currentLink);         //it's okay if this is null
            if (!bool.TryParse(currentBorderStr, out var currentBorder))
            {
                if (currentType == "icon")
                {
                    currentBorder = false;
                }
                else
                {
                    currentBorder = true;
                }
            }

            if (currentBorder)
            {
                if (tripleColonObj is Block)
                {
                    renderer.WriteLine("<p class=\"mx-imgBorder\">");
                }
                else
                {
                    renderer.WriteLine("<span class=\"mx-imgBorder\">");
                }
            }
            else
            {
                if (tripleColonObj is Block)
                {
                    renderer.WriteLine("<p>");
                }
            }
            if (!string.IsNullOrEmpty(currentLink))
            {
                var linkHtmlAttributes = new HtmlAttributes();
                currentLink = _context.GetLink(currentLink, obj);
                linkHtmlAttributes.AddProperty("href", $"{currentLink}");
                renderer.Write("<a").WriteAttributes(linkHtmlAttributes).WriteLine(">");
            }
            else if (!string.IsNullOrEmpty(currentLightbox))
            {
                var lightboxHtmlAttributes = new HtmlAttributes();
                var path = _context.GetLink(currentLightbox, obj);
                lightboxHtmlAttributes.AddProperty("href", $"{path}#lightbox");
                lightboxHtmlAttributes.AddProperty("data-linktype", $"relative-path");
                renderer.Write("<a").WriteAttributes(lightboxHtmlAttributes).WriteLine(">");
            }
            if (currentType != "complex")
            {
                renderer.Write("<img").WriteAttributes(obj).WriteLine(">");

                if (tripleColonObj is ContainerBlock &&
                    (tripleColonObj as ContainerBlock).LastChild != null)
                {
                    var inline = ((tripleColonObj as ContainerBlock).LastChild as ParagraphBlock).Inline;
                    renderer.WriteChildren(inline);
                }
            }
            else
            {
                if (currentType == "complex" && tripleColonObj.Count == 0)
                {
                    logWarning("If type is \"complex\", then descriptive content is required. Please make sure you have descriptive content.");
                    return(false);
                }
                var htmlId = GetHtmlId(obj);
                renderer.Write("<img").WriteAttributes(obj).WriteLine(">");
                renderer.WriteLine($"<div id=\"{htmlId}\" class=\"visually-hidden\">");
                renderer.WriteChildren(tripleColonObj as ContainerBlock);
                renderer.WriteLine("</div>");
            }
            if (!string.IsNullOrEmpty(currentLightbox) || !string.IsNullOrEmpty(currentLink))
            {
                renderer.WriteLine($"</a>");
            }
            if (tripleColonObj is Block)
            {
                renderer.WriteLine("</p>");
            }
            else
            {
                if (currentBorder)
                {
                    renderer.WriteLine("</span>");
                }
                renderer.WriteChildren(tripleColonObj as ContainerInline);
            }
            return(true);
        }
示例#12
0
        public void TestCopyTo()
        {
            var from = new HtmlAttributes();

            from.AddClass("test");
            from.AddProperty("key1", "1");

            var to = new HtmlAttributes();

            from.CopyTo(to);

            Assert.True(ReferenceEquals(from.Classes, to.Classes));
            Assert.True(ReferenceEquals(from.Properties, to.Properties));

            //          From: Classes      From: Properties     To: Classes     To: Properties
            // test1:        null                null              null             null
            from = new HtmlAttributes();
            to   = new HtmlAttributes();
            from.CopyTo(to, false, false);
            Assert.Null(to.Classes);
            Assert.Null(to.Properties);

            // test2:      ["test"]            ["key1", "1"]       null             null
            from = new HtmlAttributes();
            to   = new HtmlAttributes();
            from.AddClass("test");
            from.AddProperty("key1", "1");
            from.CopyTo(to, false, false);
            Assert.AreEqual(new List <string>()
            {
                "test"
            }, to.Classes);
            Assert.AreEqual(new List <KeyValuePair <string, string> >()
            {
                new KeyValuePair <string, string>("key1", "1")
            }, to.Properties);

            // test3:        null                null            ["test"]       ["key1", "1"]
            from = new HtmlAttributes();
            to   = new HtmlAttributes();
            to.AddClass("test");
            to.AddProperty("key1", "1");
            from.CopyTo(to, false, false);
            Assert.AreEqual(new List <string>()
            {
                "test"
            }, to.Classes);
            Assert.AreEqual(new List <KeyValuePair <string, string> >()
            {
                new KeyValuePair <string, string>("key1", "1")
            }, to.Properties);

            // test4:      ["test1"]           ["key2", "2"]     ["test"]       ["key1", "1"]
            from = new HtmlAttributes();
            to   = new HtmlAttributes();
            from.AddClass("test1");
            from.AddProperty("key2", "2");
            to.AddClass("test");
            to.AddProperty("key1", "1");
            from.CopyTo(to, false, false);
            Assert.AreEqual(new List <string>()
            {
                "test", "test1"
            }, to.Classes);
            Assert.AreEqual(new List <KeyValuePair <string, string> >()
            {
                new KeyValuePair <string, string>("key1", "1"), new KeyValuePair <string, string>("key2", "2")
            }, to.Properties);
        }
示例#13
0
        public bool TryProcessAttributes(IDictionary <string, string> attributes, out HtmlAttributes htmlAttributes, out IDictionary <string, string> renderProperties, Action <string> logError, Action <string> logWarning, MarkdownObject markdownObject)
        {
            htmlAttributes   = null;
            renderProperties = new Dictionary <string, string>();
            var source      = string.Empty;
            var range       = string.Empty;
            var id          = string.Empty;
            var highlight   = string.Empty;
            var language    = string.Empty;
            var interactive = string.Empty;

            foreach (var attribute in attributes)
            {
                var name  = attribute.Key;
                var value = attribute.Value;
                switch (name)
                {
                case "source":
                    source = value;
                    break;

                case "range":
                    range = value;
                    break;

                case "id":
                    id = value;
                    break;

                case "highlight":
                    highlight = value;
                    break;

                case "language":
                    language = value;
                    break;

                case "interactive":
                    interactive = value;
                    break;

                default:
                    logError($"Unexpected attribute \"{name}\".");
                    return(false);
                }
            }

            if (string.IsNullOrEmpty(source))
            {
                logError("source is a required attribute. Please ensure you have specified a source attribute");
                return(false);
            }

            if (string.IsNullOrEmpty(language))
            {
                language = InferLanguageFromFile(source, logError);
            }

            htmlAttributes = new HtmlAttributes();
            htmlAttributes.AddProperty("class", $"lang-{language}");
            if (!string.IsNullOrEmpty(interactive))
            {
                htmlAttributes.AddProperty("data-interactive", language);
                htmlAttributes.AddProperty("data-interactive-mode", interactive);
            }
            if (!string.IsNullOrEmpty(highlight))
            {
                htmlAttributes.AddProperty("highlight-lines", highlight);
            }

            return(true);
        }