All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.sweble.wikitext.lazy.parser.Section.rats Maven / Gradle / Ivy

There is a newer version: 3.1.9
Show newest version
/**
 * Copyright 2011 The Open Source Research Group,
 *                University of Erlangen-Nürnberg
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*!
 *
 * Section Heading
 * ---------------
 *
 *   Grammar:
 *     - '='+ Title '='+ Space* EolOrEof
 *
 *   The title can contain:
 *     - ExternalLink
 *     - InternalLink
 *     - MagicWord
 *     - ParserEntity
 *     - PlainExternalLink
 *     - Signature
 *     - Ticks
 *     - XmlElement
 *     - XmlReference
 *
 *   The title cannot contain:
 *     - Newline
 *       - Tables
 *       - Headings
 *       - Horizontal lines
 *       - Block level elements
 *
 *   The title can not contain (syntactically):
 *     - Newlines
 *
 *   AST node:
 *     Name        : Heading
 *     Extends     : ContentNode
 *     Constructor : "content, level"
 *     NodeType    : org.sweble.wikitext.lazy.AstNodeTypes.NT_HEADING
 *
 *     Properties:
 *       level : int
 *
 * Section
 * -------
 *
 *   AST node:
 *     Name        : Section
 *     Extends     : InnerNode.InnerNode2
 *     Constructor : "level, title, body"
 *     NodeType    : org.sweble.wikitext.lazy.AstNodeTypes.NT_SECTION
 *
 *     Properties:
 *       level   : int
 *
 *     Children:
 *       title : NodeList
 *       body  : NodeList
 *
 */

module org.sweble.wikitext.lazy.parser.Section;

import org.sweble.wikitext.lazy.utils.Warnings;

import org.sweble.wikitext.lazy.parser.Content;
import org.sweble.wikitext.lazy.parser.Whitespace;




// -- Heading ------------------------------------------------------------------

header
{
  import java.util.Stack;
}

body
{
  private Heading createHeading(
      int spanFrom,
      Result spanTo,
      AstNode rt0,
      int oCount,
      NodeList title,
      int cCount,
      AstNode rt1)
  {
    int oOdd = 0;
    int cOdd = 0;

    if (oCount > 6)
    {
      oOdd = oCount - 6;
      oCount = 6;
    }

    if (cCount > 6)
    {
      cOdd = cCount - 6;
      cCount = 6;
    }

    int level;
    if (cCount > oCount)
    {
      level = oCount;
      cOdd += cCount - oCount;
      cCount -= cCount - oCount;
    }
    else
    {
      level = cCount;
      oOdd += oCount - cCount;
      oCount -= oCount - cCount;
    }

    Heading heading = new Heading(title, level);

    Text oOddText = null;
    if (oOdd > 0)
    {
      if (isWarningLevelEnabled(WS_NORMAL))
        fileOddSyntaxWarning(
            heading,
            makeSpan(spanFrom, spanTo),
            WS_NORMAL,
            "Odd number of opening equals");
      oOddText = new Text(StringUtils.strrep('=', oOdd));
    }

    Text cOddText = null;
    if (cOdd > 0)
    {
      if (isWarningLevelEnabled(WS_NORMAL))
        fileOddSyntaxWarning(
            heading,
            makeSpan(spanFrom, spanTo),
            WS_NORMAL,
            "Odd number of closing equals");
      cOddText = new Text(StringUtils.strrep('=', cOdd));
    }

    heading.setContent(new NodeList(oOddText, title, cOddText));

    if (isGatherRtData())
    {
      String equals = StringUtils.strrep('=', level);
      addRtData(heading,
          joinRt(rt0, equals),
          joinRt(equals, rt1));
    }

    return heading;
  }

  private void fixSectionMetadata(Heading heading, Section section)
  {
    RtData rtd = (RtData) heading.getAttribute("RTD");
    if (rtd != null)
    {
      Object[][] newRts = new Object[3][];
      newRts[0] = rtd.getRts()[0];
      newRts[1] = rtd.getRts()[1];
      newRts[2] = null;
      section.setAttribute("RTD", new RtData(newRts));
    }

    Object warnings = heading.getAttribute("warnings");
    if (warnings != null)
      section.setAttribute("warnings", warnings);
  }

  private AstNode makeSections(Section first, Pair
tail) { Stack
stack = new Stack
(); stack.push(first); NodeList result = new NodeList(first); Pair
i = tail; while (!i.isEmpty()) { Section s = i.head(); while (!stack.isEmpty() && s.getLevel() <= stack.peek().getLevel()) stack.pop(); if (stack.isEmpty()) { result.add(s); } else { // TODO: Dangerous! We must clone the section instead! stack.peek().setBody(new NodeList(stack.peek().getBody(), s)); } stack.push(s); i = i.tail(); } return result; } } // -- Sections --[ State Aware Memoization ]------------------------------------ noinline transient AstNode Sections = ^{ StateAwareResult r = (StateAwareResult) pSectionsMemoized(yyBase); final LazyParserContext context = getContext(); Result yyResult = r.getResult(context); if (yyResult == null) yyResult = r.setResult(context, pSectionsTransient(yyBase)); if (returnTrue(r)) return yyResult; } ; noinline memoized AstNode SectionsMemoized = ^{ Result yyResult = new StateAwareResult("Sections", getContext(), pSectionsTransient(yyBase)); if (returnTrue(yyResult)) return yyResult; } ; // -- Sections ----------------------------------------------------------------- noinline transient AstNode SectionsTransient = &{ accept(ParserAtoms.SECTIONS) } first:Section tail:Section* { yyValue = makeSections(first, tail); } ; inline void InlineContentStopperHeading = &{ inScope(ParserScopes.SECTION_HEADING) } EqualsStr pExtSpaceStar slEolOrEof ; inline void BlockStopperNextSection = &{ inScope(ParserScopes.SECTION_BODY) } Heading ; // -- Section ------------------------------------------------------------------ private noinline transient Section Section = h:Heading Eof { yyValue = new Section(h.getLevel(), h.getContent(), new NodeList()); fixSectionMetadata(h, yyValue); } / h:Heading body:SectionContentStar { yyValue = new Section(h.getLevel(), h.getContent(), body); fixSectionMetadata(h, yyValue); } ; // -- Heading --[ State Aware Memoization ]------------------------------------- noinline transient Heading Heading = ^{ StateAwareResult r = (StateAwareResult) pHeadingMemoized(yyBase); final LazyParserContext context = getContext(); Result yyResult = r.getResult(context); if (yyResult == null) yyResult = r.setResult(context, pHeadingTransient(yyBase)); if (returnTrue(r)) return yyResult; } ; noinline memoized Heading HeadingMemoized = ^{ Result yyResult = new StateAwareResult("Heading", getContext(), pHeadingTransient(yyBase)); if (returnTrue(yyResult)) return yyResult; } ; // -- Heading ------------------------------------------------------------------ noinline transient Heading HeadingTransient = rt0:pTpStar open:EqualsStr heading:HeadingContentStar close:EqualsStr rt1:pExtSpaceStar &slEolOrEof { // TODO: add warning productions yyValue = createHeading(yyStart, yyResult, rt0, open.length(), heading, close.length(), rt1); } ; private transient String EqualsStr = "="+ ; // -- Content ------------------------------------------------------------------ private inline stateful NodeList HeadingContentStar = { enter(ParserScopes.SECTION_HEADING); } InlineContentPlus ; private inline stateful NodeList SectionContentStar = { enter(ParserScopes.SECTION_BODY); } BlockContent ; // -- End of file --------------------------------------------------------------




© 2015 - 2024 Weber Informatics LLC | Privacy Policy