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); }
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); }
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); }
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)); } }
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; } } }
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; }