Esempio n. 1
0
        /* Function: AppendToolTip
         *
         * Builds the HTML for the topic's tooltip and appends it to the passed StringBuilder.  If the topic shoudn't have a tooltip it will
         * return false.
         *
         * Parameters:
         *
         *		topic - The topic to build the tooltip for.
         *		context - The context of the page the tooltip is being built for.  The topic will automatically replace the context's topic
         *					  so you can just pass the context of the page, if any.
         *		links - A list of <Links> that must contain any links found in the topic.
         *		imageLinks - A list of <ImageLinks> that must contain any image links found in this topic.
         */
        public bool AppendToolTip(Topics.Topic topic, Context context, IList <Link> links, IList <ImageLink> imageLinks, StringBuilder output)
        {
            if (topic.Prototype == null && topic.Summary == null)
            {
                return(false);
            }

            this.context       = context;
            this.context.Topic = topic;
            this.links         = links;
            this.imageLinks    = imageLinks;

            string simpleCommentTypeName = EngineInstance.CommentTypes.FromID(topic.CommentTypeID).SimpleIdentifier;
            string simpleLanguageName    = EngineInstance.Languages.FromID(topic.LanguageID).SimpleIdentifier;

            // No line breaks and indentation because this will be embedded in JavaScript strings.
            output.Append("<div class=\"NDToolTip T" + simpleCommentTypeName + " L" + simpleLanguageName + "\">");

            if (topic.Prototype != null)
            {
                AppendPrototype(output);
            }

            if (topic.Summary != null)
            {
                AppendSummary(output);
            }

            output.Append("</div>");

            return(true);
        }
Esempio n. 2
0
        /* Function: AppendOpeningLinkTag
         *
         * Constructs an <a> tag from the <Context's> <HTMLTopicPage> to the passed topic and appends it to the passed StringBuilder.
         *
         * Requirements:
         *
         *		- The <Context>'s topic page must be set.
         */
        public void AppendOpeningLinkTag(Topics.Topic targetTopic, StringBuilder output, string extraCSSClass = null)
        {
                        #if DEBUG
            if (Context.TopicPage == null)
            {
                throw new Exception("Tried to call AppendOpeningLinkTag without setting the context's topic page.");
            }
                        #endif

            // The URL can't be only the hash path because it would use the iframe's location.  We need a relative path back to index.html
            // to append it to.

            Path currentOutputFolder = Context.TopicPage.OutputFile.ParentFolder;
            Path indexFile           = Context.Builder.OutputFolder + "/index.html";
            Path pathToIndex         = indexFile.MakeRelativeTo(currentOutputFolder);

            Output.Components.HTMLTopicPage targetTopicPage = Context.TopicPage.GetLinkTarget(targetTopic);

            output.Append("<a ");

            if (extraCSSClass != null)
            {
                output.Append("class=\"" + extraCSSClass + "\" ");
            }

            string topicHashPath = Context.Builder.Source_TopicHashPath(targetTopic, targetTopicPage.IncludeClassInTopicHashPaths);

            output.Append("href=\"" + pathToIndex.ToURL() +
                          '#' + targetTopicPage.OutputFileHashPath.EntityEncode() +
                          (topicHashPath != null ? ':' + topicHashPath.EntityEncode() : "") + "\" " +
                          "target=\"_top\" " +
                          "onmouseover=\"NDContentPage.OnLinkMouseOver(event," + targetTopic.TopicID + ");\" " +
                          "onmouseout=\"NDContentPage.OnLinkMouseOut(event);\" " +
                          ">");
        }
Esempio n. 3
0
        /* Function: BuildToolTip
         *
         * Builds the HTML for the topic's tooltip and returns it as a string.  If the topic shoudn't have a tooltip it will return null.
         *
         * Parameters:
         *
         *		topic - The topic to build the tooltip for.
         *		context - The context of the page the tooltip is being built for.  The topic will automatically replace the context's topic
         *					  so you can just pass the context of the page, if any.
         *		links - A list of <Links> that must contain any links found in the topic.
         *		imageLinks - A list of <ImageLinks> that must contain any image links found in this topic.
         */
        public string BuildToolTip(Topics.Topic topic, Context context, IList <Link> links, IList <ImageLink> imageLinks)
        {
            if (topic.Prototype == null && topic.Summary == null)
            {
                return(null);
            }

            StringBuilder output = new StringBuilder();

            AppendToolTip(topic, context, links, imageLinks, output);
            return(output.ToString());
        }
Esempio n. 4
0
        /* Function: AppendChildClassPrototype
         */
        protected void AppendChildClassPrototype(Topics.Topic childTopic, StringBuilder output)
        {
            CommentType childCommentType = EngineInstance.CommentTypes.FromID(childTopic.CommentTypeID);
            string      memberOperator   = language.MemberOperator;

            AppendOpeningLinkTag(childTopic, output, "CPEntry Child T" + childCommentType.SimpleIdentifier);

            output.Append("<div class=\"CPName\">");

            AppendWrappedTitle(childTopic.Symbol.FormatWithSeparator(memberOperator), WrappedTitleMode.Code, output);

            output.Append("</div>");

            output.Append("</a>");
        }
Esempio n. 5
0
        /* Function: AppendOpeningLinkTag
         *
         * Constructs an <a> tag from the <Context's> <PageLocation> to the passed topic and appends it to the passed StringBuilder.
         *
         * Requirements:
         *
         *		- The <Context>'s page must be set.
         */
        public void AppendOpeningLinkTag(Topics.Topic targetTopic, StringBuilder output, string extraCSSClass = null)
        {
                        #if DEBUG
            if (Context.Page.IsNull)
            {
                throw new Exception("Tried to call AppendOpeningLinkTag without setting the context's page.");
            }
                        #endif

            // Build a context for the link target.  If we're already in a hierarchy page, make the link target go to a hierarchy page as well.
            // However, it may have to fall back to a source file page if the target isn't part of a class.

            Context targetContext;

            if (context.Page.InHierarchy && targetTopic.ClassString != null)
            {
                targetContext = new Context(context.Target, targetTopic.ClassID, targetTopic.ClassString, targetTopic);
            }
            else
            {
                targetContext = new Context(context.Target, targetTopic.FileID, targetTopic);
            }


            // Find the path from the current output file back to index.html.  The target URL needs to include this because relative paths are
            // based on the the iframe's location.

            Path currentOutputFolder = Context.OutputFile.ParentFolder;
            Path indexFile           = Context.Target.OutputFolder + "/index.html";
            Path pathToIndex         = indexFile.MakeRelativeTo(currentOutputFolder);


            // Build the link

            output.Append("<a ");

            if (extraCSSClass != null)
            {
                output.Append("class=\"" + extraCSSClass + "\" ");
            }

            output.Append("href=\"" + pathToIndex.ToURL() +
                          '#' + targetContext.HashPath.EntityEncode() + "\" " +
                          "target=\"_top\" " +
                          "onmouseover=\"NDContentPage.OnLinkMouseOver(event," + targetTopic.TopicID + ");\" " +
                          "onmouseout=\"NDContentPage.OnLinkMouseOut(event);\" " +
                          ">");
        }
Esempio n. 6
0
        /* Function: AppendSyntaxHighlightedTextWithTypeLinks
         *
         * Formats the text between the iterators with syntax highlighting and links for any tokens marked with
         * <PrototypeParsingType.Type> and <PrototypeParsingType.TypeQualifier>.  Appends the result to the passed StringBuilder.
         *
         * Parameters:
         *
         *		start - The first token of the text to convert.
         *		end - The end of the text to convert, which is one token past the last one included.
         *		output - The StringBuilder to append the output to.
         *
         *		links - A list of <Links> that should  contain any appearing in the code.
         *		linkTargets - A list of topics that should contain any used as targets in the list of links.
         *
         *		extendTypeSearch - If true, it will search beyond the bounds of the iterators to get the complete type.  This allows you to
         *									 format only a portion of the link with this function yet still have the link go to the complete destination.
         *
         * Requirements:
         *
         *		- The <Context>'s topic and page must be set.
         */
        public void AppendSyntaxHighlightedTextWithTypeLinks(TokenIterator start, TokenIterator end, StringBuilder output,
                                                             IList <Link> links, IList <Topics.Topic> linkTargets,
                                                             bool extendTypeSearch = false)
        {
                        #if DEBUG
            if (Context.Topic == null)
            {
                throw new Exception("Tried to call AppendSyntaxtHighlightedTextWithTypeLinks without setting the context's topic.");
            }
            if (Context.Page.IsNull)
            {
                throw new Exception("Tried to call AppendSyntaxtHighlightedTextWithTypeLinks without setting the context's page.");
            }
            if (links == null)
            {
                throw new Exception("Tried to call AppendSyntaxtHighlightedTextWithTypeLinks without setting the links variable.");
            }
            if (linkTargets == null)
            {
                throw new Exception("Tried to call AppendSyntaxtHighlightedTextWithTypeLinks without setting the linkTargets variable.");
            }
                        #endif

            Language language = EngineInstance.Languages.FromID(Context.Topic.LanguageID);


            // Find each Type/TypeQualifier stretch in the text

            TokenIterator iterator = start;

            while (iterator < end)
            {
                if (iterator.PrototypeParsingType == PrototypeParsingType.Type ||
                    iterator.PrototypeParsingType == PrototypeParsingType.TypeQualifier)
                {
                    TokenIterator textStart = iterator;
                    TokenIterator textEnd   = iterator;

                    do
                    {
                        textEnd.Next();
                    }while (textEnd < end &&
                            (textEnd.PrototypeParsingType == PrototypeParsingType.Type ||
                             textEnd.PrototypeParsingType == PrototypeParsingType.TypeQualifier));

                    TokenIterator symbolStart = textStart;
                    TokenIterator symbolEnd   = textEnd;


                    // Extend past start and end if the flag is set

                    if (extendTypeSearch && symbolStart == start)
                    {
                        TokenIterator temp = symbolStart;
                        temp.Previous();

                        while (temp.IsInBounds &&
                               (temp.PrototypeParsingType == PrototypeParsingType.Type ||
                                temp.PrototypeParsingType == PrototypeParsingType.TypeQualifier))
                        {
                            symbolStart = temp;
                            temp.Previous();
                        }
                    }

                    if (extendTypeSearch && symbolEnd == end)
                    {
                        while (symbolEnd.IsInBounds &&
                               (symbolEnd.PrototypeParsingType == PrototypeParsingType.Type ||
                                symbolEnd.PrototypeParsingType == PrototypeParsingType.TypeQualifier))
                        {
                            symbolEnd.Next();
                        }
                    }


                    // Built in types don't get links

                    if (language.IsBuiltInType(symbolStart, symbolEnd))
                    {
                        AppendSyntaxHighlightedText(textStart, textEnd, output);
                    }

                    else
                    {
                        // Create a link object with the identifying properties needed to look it up in the list of links.

                        Link linkStub = new Link();
                        linkStub.Type        = LinkType.Type;
                        linkStub.Symbol      = SymbolString.FromPlainText_NoParameters(symbolStart.TextBetween(symbolEnd));
                        linkStub.Context     = Context.Topic.PrototypeContext;
                        linkStub.ContextID   = Context.Topic.PrototypeContextID;
                        linkStub.FileID      = Context.Topic.FileID;
                        linkStub.ClassString = Context.Topic.ClassString;
                        linkStub.ClassID     = Context.Topic.ClassID;
                        linkStub.LanguageID  = Context.Topic.LanguageID;


                        // Find the actual link so we know if it resolved to anything.

                        Link fullLink = null;

                        foreach (Link link in links)
                        {
                            if (link.SameIdentifyingPropertiesAs(linkStub))
                            {
                                fullLink = link;
                                break;
                            }
                        }

                                                #if DEBUG
                        if (fullLink == null)
                        {
                            throw new Exception("All links in a topic must be in the list passed to AppendSyntaxtHighlightedTextWithTypeLinks.");
                        }
                                                #endif


                        // If it didn't resolve, we just output the original text.

                        if (!fullLink.IsResolved)
                        {
                            AppendSyntaxHighlightedText(textStart, textEnd, output);
                        }

                        else
                        {
                            // If it did resolve, find Topic it resolved to.

                            Topics.Topic targetTopic = null;

                            foreach (var linkTarget in linkTargets)
                            {
                                if (linkTarget.TopicID == fullLink.TargetTopicID)
                                {
                                    targetTopic = linkTarget;
                                    break;
                                }
                            }

                                                        #if DEBUG
                            if (targetTopic == null)
                            {
                                throw new Exception("All links targets for a topic must be in the list passed to AppendSyntaxtHighlightedTextWithTypeLinks.");
                            }
                                                        #endif

                            AppendOpeningLinkTag(targetTopic, output);
                            AppendSyntaxHighlightedText(textStart, textEnd, output);
                            output.Append("</a>");
                        }
                    }

                    iterator = textEnd;
                }

                else                 // not on a type
                {
                    TokenIterator startText = iterator;

                    do
                    {
                        iterator.Next();
                    }while (iterator < end &&
                            iterator.PrototypeParsingType != PrototypeParsingType.Type &&
                            iterator.PrototypeParsingType != PrototypeParsingType.TypeQualifier);

                    AppendSyntaxHighlightedText(startText, iterator, output);
                }
            }
        }
Esempio n. 7
0
        /* Function: AppendNaturalDocsLink
         */
        protected void AppendNaturalDocsLink(NDMarkup.Iterator iterator, StringBuilder output)
        {
            // Create a link object with the identifying properties needed to look it up in the list of links.

            Link linkStub = new Link();

            linkStub.Type        = LinkType.NaturalDocs;
            linkStub.Text        = iterator.Property("originaltext");
            linkStub.Context     = context.Topic.BodyContext;
            linkStub.ContextID   = context.Topic.BodyContextID;
            linkStub.FileID      = context.Topic.FileID;
            linkStub.ClassString = context.Topic.ClassString;
            linkStub.ClassID     = context.Topic.ClassID;
            linkStub.LanguageID  = context.Topic.LanguageID;


            // Find the actual link so we know if it resolved to anything.

            Link fullLink = null;

            foreach (Link link in links)
            {
                if (link.SameIdentifyingPropertiesAs(linkStub))
                {
                    fullLink = link;
                    break;
                }
            }

                        #if DEBUG
            if (fullLink == null)
            {
                throw new Exception("All links in a topic must be in the list passed to HTMLTopic.");
            }
                        #endif


            // If it didn't resolve, we just output the original text and we're done.

            if (!fullLink.IsResolved)
            {
                output.EntityEncodeAndAppend(iterator.Property("originaltext"));
                return;
            }


            // If it did resolve, find the interpretation that was used.  If it was a named link it would affect the link text.

            LinkInterpretation linkInterpretation = null;

            string ignore;
            List <LinkInterpretation> linkInterpretations = EngineInstance.Comments.NaturalDocsParser.LinkInterpretations(fullLink.Text,
                                                                                                                          Comments.Parsers.NaturalDocs.LinkInterpretationFlags.AllowNamedLinks |
                                                                                                                          Comments.Parsers.NaturalDocs.LinkInterpretationFlags.AllowPluralsAndPossessives |
                                                                                                                          Comments.Parsers.NaturalDocs.LinkInterpretationFlags.FromOriginalText,
                                                                                                                          out ignore);

            linkInterpretation = linkInterpretations[fullLink.TargetInterpretationIndex];


            // Find the Topic it resolved to.

            Topics.Topic targetTopic = null;

            foreach (var linkTarget in linkTargets)
            {
                if (linkTarget.TopicID == fullLink.TargetTopicID)
                {
                    targetTopic = linkTarget;
                    break;
                }
            }

                        #if DEBUG
            if (targetTopic == null)
            {
                throw new Exception("All links targets for a topic must be in the list passed to HTMLTopic.");
            }
                        #endif

            AppendOpeningLinkTag(targetTopic, output);
            output.EntityEncodeAndAppend(linkInterpretation.Text);
            output.Append("</a>");
        }
Esempio n. 8
0
        /* Function: AppendTopic
         *
         * Builds the HTML for the topic and appends it to the passed StringBuilder.
         *
         * Parameters:
         *
         *		topic - The topic to build.
         *		context - The <Context> the topic appears in.  The topic will automatically replace the context's topic, so you can just
         *					  pass the context of the page.
         *		links - A list of <Links> that must contain any links found in the topic.
         *		linkTargets - A list of topics that must contain any topics used as targets in the links.
         *		imageLinks - A list of <ImageLinks> that must contain any image links found in this topic.
         *		output - The StringBuilder that the output will be appended to.
         *		embeddedTopics - A list of topics that contains any embedded topics contained in this one.
         *		embeddedTopicIndex - The index into embeddedTopics to start at.
         *		extraClass - If specified, this string will be added to the CTopic div as an extra CSS class.
         */
        public void AppendTopic(Topics.Topic topic, Context context, IList <Link> links, IList <Topics.Topic> linkTargets,
                                IList <ImageLink> imageLinks, StringBuilder output, IList <Topics.Topic> embeddedTopics = null,
                                int embeddedTopicIndex = 0, string extraClass = null)
        {
            try
            {
                // Setup

                context.Topic = topic;

                this.context            = context;
                this.links              = links;
                this.linkTargets        = linkTargets;
                this.imageLinks         = imageLinks;
                this.embeddedTopics     = embeddedTopics;
                this.embeddedTopicIndex = embeddedTopicIndex;


                // Core

                string simpleCommentTypeName = EngineInstance.CommentTypes.FromID(topic.CommentTypeID).SimpleIdentifier;
                string simpleLanguageName    = EngineInstance.Languages.FromID(topic.LanguageID).SimpleIdentifier;
                string topicHashPath         = context.TopicOnlyHashPath;

                if (topicHashPath != null)
                {
                    output.Append("<a name=\"" + topicHashPath.EntityEncode() + "\"></a>");
                }

                output.Append(
                    "<a name=\"Topic" + topic.TopicID + "\"></a>" +
                    "<div class=\"CTopic T" + simpleCommentTypeName + " L" + simpleLanguageName +
                    (extraClass == null ? "" : ' ' + extraClass) + "\">" +

                    "\r\n ");
                AppendTitle(output);

                                                #if SHOW_NDMARKUP
                if (topic.Body != null)
                {
                    htmlOutput.Append(
                        "\r\n " +
                        "<div class=\"CBodyNDMarkup\">" +
                        topic.Body.ToHTML() +
                        "</div>");
                }
                                                #endif

                if (topic.Prototype != null)
                {
                    output.Append("\r\n ");
                    AppendPrototype(output);
                }

                if (topic.Body != null)
                {
                    output.Append("\r\n ");
                    AppendBody(output);
                }

                output.Append(
                    "\r\n" +
                    "</div>"
                    );
            }

            catch (Exception e)
            {
                // Build a message to show the topic we crashed on
                if (topic != null)
                {
                    StringBuilder task = new StringBuilder("Building HTML for topic");

                    // Topic name
                    if (topic.Title == null)
                    {
                        task.Append(" ID " + topic.TopicID + " (null title)");
                    }
                    else if (topic.Title == "")
                    {
                        task.Append(" ID " + topic.TopicID + " (empty string title)");
                    }
                    else
                    {
                        task.Append(" \"" + topic.Title + "\"");
                    }

                    // File name
                    var file = (topic.FileID > 0 ? EngineInstance.Files.FromID(topic.FileID) : null);

                    if (file != null)
                    {
                        task.Append(" from file " + file.FileName);
                    }
                    else
                    {
                        task.Append(" from file ID " + topic.FileID);
                    }

                    // Line number
                    if (topic.CommentLineNumber > 0)
                    {
                        if (topic.CodeLineNumber > 0 && topic.CodeLineNumber != topic.CommentLineNumber)
                        {
                            task.Append(" lines " + topic.CommentLineNumber + " and " + topic.CodeLineNumber);
                        }
                        else
                        {
                            task.Append(" line " + topic.CommentLineNumber);
                        }
                    }
                    else
                    {
                        task.Append(" line " + topic.CodeLineNumber);
                    }

                    e.AddNaturalDocsTask(task.ToString());
                }

                throw;
            }
        }