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

laika.api.format.MarkupFormat.scala Maven / Gradle / Ivy

/*
 * Copyright 2012-2020 the original author or authors.
 *
 * 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.
 */

package laika.api.format

import laika.api.bundle.{ BlockParserBuilder, ExtensionBundle, SpanParserBuilder }
import laika.api.format.MarkupFormat.MarkupParsers
import laika.ast.Block
import laika.parse.Parser
import laika.parse.combinator.Parsers
import laika.parse.text.TextParsers

/** Responsible for creating parser instances for a specific markup format.
  *  A parser is simply a function of type `Input => Document`.
  *
  *  @author Jens Halm
  */
trait MarkupFormat {

  /** Short string describing the markup or output format for tooling and logging.
    */
  def description: String = toString

  /** The file suffixes recognized by this parser.
    *  When transforming entire directories only files with
    *  names ending in one of the specified suffixes will
    *  be considered.
    *
    *  It is recommended not to support `txt`
    *  or similarly common suffixes as this might interfere
    *  with other installed formats.
    */
  def fileSuffixes: Set[String]

  /** All block parsers for the markup language this parser processes.
    */
  def blockParsers: MarkupParsers[BlockParserBuilder]

  /** All span parsers for the markup language this parser processes.
    */
  def spanParsers: MarkupParsers[SpanParserBuilder]

  /** Parses the character after the one that started the escape sequence (usually a backslash).
    *
    * The default implementation parses any character as is, this can be overridden in case
    * the host language has more specific rules for escape sequences.
    */
  def escapedChar: Parser[String] = TextParsers.oneChar

  /** The parser-specific extensions that need to be installed
    *  for each transformation that involves this parser.
    *
    *  One scenario where a parser needs to provide a bundle
    *  is when it produces tree elements that are unknown
    *  to the built-in rewrite rules and renderers.
    */
  def extensions: Seq[ExtensionBundle]

  /** Creates the parser for a sequence of blocks based on the parser
    * for a single block.
    *
    * The parser for a single block is already the result of merging all block parsers
    * defined within this instance with all extension parsers defined
    * by the user.
    *
    * The default implementation simply applies this parser repeatedly while
    * skipping blank lines between the parsed blocks. This method can get overridden
    * for special requirements, for example when the previous result has an influence on
    * which parser to pick for the subsequent block.
    */
  def createBlockListParser(parser: Parser[Block]): Parser[Seq[Block]] =
    (parser <~ Parsers.opt(TextParsers.blankLines)).rep

}

object MarkupFormat {

  /** API for registering parsers for a specific markup format.
    *
    * The only abstract method is `all` that specifies the list of parsers
    * to register with Laika's parser runtime.
    *
    * But parser authors are encouraged to use this type for also creating
    * public properties for each of their individual parsers so that users
    * can compose them for custom formats or parser extensions.
    *
    * The type of these properties should be either `BlockParserBuilder` or
    * `SpanParserBuilder` which allows to keep all parser implementation details
    * private and only offer high level entry points for extension authors.
    */
  trait MarkupParsers[E] {

    /** List of parsers to register with the runtime for a specific markup format.
      *
      * The order of parsers in this sequence is significant and determines
      * the precedence in which parsers are tried on blocks or spans.
      */
    def all: Seq[E]
  }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy