示例#1
0
        private static bool FetchHeadingAnchor(ParsingContext context, TokenBuffer tokenBuffer, out string anchorId)
        {
            Contract.Requires(context != null);
            Contract.Requires(tokenBuffer != null);

            anchorId = null;

            WikiTextToken token = tokenBuffer.ExpectToken(context, WikiTextToken.TokenType.Text);

            if (token == null)
            {
                return(false);
            }

            string potentialAnchorId = token.Text;

            if (!ValidateAnchor(potentialAnchorId))
            {
                context.ReportError("Invalid heading anchor ID: '{0}'".Fmt(potentialAnchorId));
                return(false);
            }

            anchorId = token.Text;
            tokenBuffer.MoveToNextToken();
            return(true);
        }
示例#2
0
        private static bool ProcessHeadingAnchor(ParsingContext context, TokenBuffer tokenBuffer, out string anchorId)
        {
            Contract.Requires(context != null);
            Contract.Requires(tokenBuffer != null);

            anchorId = null;
            if (!tokenBuffer.EndOfTokens)
            {
                WikiTextToken token = tokenBuffer.Token;
                if (token.Type == WikiTextToken.TokenType.HeadingAnchor)
                {
                    tokenBuffer.MoveToNextToken();
                    if (!FetchHeadingAnchor(context, tokenBuffer, out anchorId))
                    {
                        return(false);
                    }
                }
                else
                {
                    context.ReportError("Unexpected tokens after ending heading token");
                    return(false);
                }
            }

            return(true);
        }
示例#3
0
        private static bool ProcessHeadingText(
            ParsingContext context,
            TokenBuffer tokenBuffer,
            WikiTextToken.TokenType endingTokenNeeded,
            StringBuilder headingText)
        {
            Contract.Requires(context != null);
            Contract.Requires(tokenBuffer != null);
            Contract.Requires(headingText != null);

            WikiTextToken.TokenType?actualEndingToken = tokenBuffer.ProcessUntilToken(
                context,
                t =>
            {
                switch (t.Type)
                {
                case WikiTextToken.TokenType.Text:
                    headingText.Append(t.Text);
                    return(true);

                case WikiTextToken.TokenType.DoubleApostrophe:
                case WikiTextToken.TokenType.TripleApostrophe:
                    throw new NotImplementedException("todo next: add support");

                default:
                    context.ReportError("Unexpected token in heading definition: {0}".Fmt(t.Text));
                    return(false);
                }
            },
                endingTokenNeeded);

            return(actualEndingToken != null && actualEndingToken == endingTokenNeeded);
        }
示例#4
0
        private void ProcessLine(
            DocumentDefBuilder docBuilder,
            ParsingContext context,
            string lineText)
        {
            Contract.Requires(docBuilder != null);
            Contract.Requires(lineText != null);

            WikiTokenizationSettings tokenizationSettings = new WikiTokenizationSettings();

            tokenizationSettings.IsWholeLine = true;
            IList <WikiTextToken> tokens = tokenizer.TokenizeWikiText(lineText, tokenizationSettings);

            if (tokens.Count == 0)
            {
                throw new NotImplementedException("todo next:");
            }

            TokenBuffer tokenBuffer = new TokenBuffer(tokens);

            WikiTextToken firstToken = tokenBuffer.Token;

            switch (firstToken.Type)
            {
            case WikiTextToken.TokenType.Heading1Start:
            case WikiTextToken.TokenType.Heading2Start:
            case WikiTextToken.TokenType.Heading3Start:
            case WikiTextToken.TokenType.Heading4Start:
            case WikiTextToken.TokenType.Heading5Start:
            case WikiTextToken.TokenType.Heading6Start:
                docBuilder.FinalizeCurrentParagraph();
                HandleHeadingLine(docBuilder, context, tokenBuffer);
                break;

            case WikiTextToken.TokenType.Text:
            case WikiTextToken.TokenType.DoubleApostrophe:
            case WikiTextToken.TokenType.TripleApostrophe:
            case WikiTextToken.TokenType.DoubleSquareBracketsOpen:
            case WikiTextToken.TokenType.SingleSquareBracketsOpen:
            case WikiTextToken.TokenType.BulletList:
            case WikiTextToken.TokenType.NumberedList:
            case WikiTextToken.TokenType.Indent:
                HandleText(docBuilder, context, tokenBuffer);
                break;

            default:
                throw new NotImplementedException("todo next: {0}".Fmt(firstToken.Type));
            }
        }
示例#5
0
        private static void HandleText(
            DocumentDefBuilder docBuilder,
            ParsingContext context,
            TokenBuffer tokenBuffer)
        {
            Contract.Requires(docBuilder != null);
            Contract.Requires(context != null);
            Contract.Requires(tokenBuffer != null);

            TextParsingMode       parsingMode         = TextParsingMode.RegularText;
            InternalLinkIdBuilder internalLinkBuilder = new InternalLinkIdBuilder();
            StringBuilder         textBuilder         = null;
            Uri  externalLinkUrl = null;
            bool isFirstTextElementOfContinuedLine = true;

            bool processingSuccessful = tokenBuffer.ProcessUntilEnd(
                t =>
            {
                bool flagCopy = isFirstTextElementOfContinuedLine;

                switch (t.Type)
                {
                case WikiTextToken.TokenType.BulletList:
                    return(HandleBulletListTokenInText(docBuilder, t));

                case WikiTextToken.TokenType.NumberedList:
                    return(HandleNumberedListTokenInText(docBuilder, t));

                case WikiTextToken.TokenType.Indent:
                    return(HandleIndentTokenInText(docBuilder, t));

                case WikiTextToken.TokenType.Text:
                    {
                        isFirstTextElementOfContinuedLine = false;
                        return(HandleTextTokenInText(
                                   docBuilder, parsingMode, t, flagCopy, internalLinkBuilder, ref textBuilder));
                    }

                case WikiTextToken.TokenType.TripleApostrophe:
                    return(HandleTripleApostropheTokenInText(docBuilder));

                case WikiTextToken.TokenType.DoubleApostrophe:
                    return(HandleDoubleApostropheTokenInText(docBuilder));

                case WikiTextToken.TokenType.DoubleSquareBracketsOpen:
                    return(HandleDoubleSquareBracketsOpenTokenInText(context, t, ref parsingMode));

                case WikiTextToken.TokenType.NamespaceSeparator:
                    return(HandleNamespaceSeparatorTokenInText(context, parsingMode, internalLinkBuilder, t));

                case WikiTextToken.TokenType.Pipe:
                    return(HandlePipeTokenInText(context, t, ref parsingMode));

                case WikiTextToken.TokenType.DoubleSquareBracketsClose:
                    return(HandleDoubleSquareBracketsCloseTokenInText(
                               docBuilder,
                               context,
                               ref parsingMode,
                               t,
                               internalLinkBuilder,
                               textBuilder));

                case WikiTextToken.TokenType.SingleSquareBracketsOpen:
                    return(HandleSingleSquareBracketsOpenTokenInText(context, t, ref parsingMode));

                case WikiTextToken.TokenType.ExternalLinkUrlLeadingSpace:
                    return(HandleExternalLinkUrlLeadingSpaceTokenInText(context, t, parsingMode));

                case WikiTextToken.TokenType.ExternalLinkUrl:
                    return(HandleExternalLinkUrlTokenInText(context, t, ref parsingMode, ref externalLinkUrl));

                case WikiTextToken.TokenType.SingleSquareBracketsClose:
                    return(HandleSingleSquareBracketsCloseTokenInText(
                               docBuilder,
                               context,
                               ref parsingMode,
                               t,
                               externalLinkUrl,
                               textBuilder));

                default:
                    throw new NotImplementedException("todo next: {0}".Fmt(t.Type));
                }
            });

            if (processingSuccessful)
            {
                switch (parsingMode)
                {
                case TextParsingMode.InternalLinkPageName:
                case TextParsingMode.InternalLinkDescription:
                    context.ReportError("Missing token ']]'");
                    break;

                case TextParsingMode.ExternalLinkUrl:
                case TextParsingMode.ExternalLinkDescription:
                    context.ReportError("Missing token ']'");
                    break;
                }
            }
        }
示例#6
0
        private static void HandleHeadingLine(DocumentDefBuilder docBuilder, ParsingContext context, TokenBuffer tokenBuffer)
        {
            Contract.Requires(docBuilder != null);
            Contract.Requires(context != null);
            Contract.Requires(tokenBuffer != null);

            WikiTextToken firstToken = tokenBuffer.Token;

            WikiTextToken.TokenType endingTokenNeeded;
            int headingLevel;

            switch (firstToken.Type)
            {
            case WikiTextToken.TokenType.Heading1Start:
                headingLevel      = 1;
                endingTokenNeeded = WikiTextToken.TokenType.Heading1End;
                break;

            case WikiTextToken.TokenType.Heading2Start:
                headingLevel      = 2;
                endingTokenNeeded = WikiTextToken.TokenType.Heading2End;
                break;

            case WikiTextToken.TokenType.Heading3Start:
                headingLevel      = 3;
                endingTokenNeeded = WikiTextToken.TokenType.Heading3End;
                break;

            case WikiTextToken.TokenType.Heading4Start:
                headingLevel      = 4;
                endingTokenNeeded = WikiTextToken.TokenType.Heading4End;
                break;

            case WikiTextToken.TokenType.Heading5Start:
                headingLevel      = 5;
                endingTokenNeeded = WikiTextToken.TokenType.Heading5End;
                break;

            case WikiTextToken.TokenType.Heading6Start:
                headingLevel      = 6;
                endingTokenNeeded = WikiTextToken.TokenType.Heading6End;
                break;

            default:
                throw new InvalidOperationException("BUG");
            }

            tokenBuffer.MoveToNextToken();

            StringBuilder headingText = new StringBuilder();

            if (!ProcessHeadingText(context, tokenBuffer, endingTokenNeeded, headingText))
            {
                return;
            }

            HeadingElement headingEl = new HeadingElement(headingText.ToString().Trim(), headingLevel);

            docBuilder.AddRootChild(headingEl);

            tokenBuffer.MoveToNextToken();
            string anchorId;

            if (!ProcessHeadingAnchor(context, tokenBuffer, out anchorId))
            {
                return;
            }

            tokenBuffer.ProcessUntilEnd(
                t =>
            {
                context.ReportError("Unexpected token at the end of heading");
                return(false);
            });

            headingEl.AnchorId = anchorId;
        }