Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* 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.internal.rst.ast
import laika.ast.*
import laika.parse.SourceFragment
/** A two-column table-like structure used for bibliographic fields or directive options.
*/
private[rst] case class FieldList(content: Seq[Field], options: Options = Options.empty)
extends Block
with ListContainer
with RewritableContainer {
type Self = FieldList
override def rewriteChildren(rules: RewriteRules): FieldList = {
val zippedContent = content.map(_.rewriteChildren(rules)).zip(content)
if (zippedContent.forall { case (rewritten, old) => rewritten.eq(old) }) this
else copy(content = zippedContent.map(_._1))
}
def withOptions(options: Options): FieldList = copy(options = options)
}
/** A single entry in a field list consisting of name and body.
*/
private[rst] case class Field(
name: Seq[Span],
content: Seq[Block],
options: Options = Options.empty
) extends ListItem
with BlockContainer {
type Self = Field
override def rewriteChildren(rules: RewriteRules): Field =
copy(content = rules.rewriteBlocks(content), name = rules.rewriteSpans(name))
def withContent(newContent: Seq[Block]): Field = copy(content = newContent)
def withOptions(options: Options): Field = copy(options = options)
}
/** A classifier for a term in a definition list.
*/
private[rst] case class Classifier(content: Seq[Span], options: Options = Options.empty)
extends Span
with SpanContainer {
type Self = Classifier
def withContent(newContent: Seq[Span]): Classifier = copy(content = newContent)
def withOptions(options: Options): Classifier = copy(options = options)
}
/** A list of command line options and descriptions.
*/
private[rst] case class OptionList(content: Seq[OptionListItem], options: Options = Options.empty)
extends Block
with ListContainer
with RewritableContainer {
type Self = OptionList
override def rewriteChildren(rules: RewriteRules): OptionList =
copy(content = content.map(_.rewriteChildren(rules)))
def withOptions(options: Options): OptionList = copy(options = options)
}
/** A single item in an option list. The content property serves as the description of the option.
*/
private[rst] case class OptionListItem(
programOptions: Seq[ProgramOption],
content: Seq[Block],
options: Options = Options.empty
) extends ListItem
with BlockContainer {
type Self = OptionListItem
def withContent(newContent: Seq[Block]): OptionListItem = copy(content = newContent)
def withOptions(options: Options): OptionListItem = copy(options = options)
}
/** A single option, including its name and all arguments, but not the description.
*/
private[rst] case class ProgramOption(
name: String,
argument: Option[OptionArgument],
options: Options = Options.empty
) extends Element {
type Self = ProgramOption
def withOptions(options: Options): ProgramOption = copy(options = options)
}
/** A single option argument.
*/
private[rst] case class OptionArgument(
value: String,
delimiter: String,
options: Options = Options.empty
) extends Span {
type Self = OptionArgument
def withOptions(options: Options): OptionArgument = copy(options = options)
}
/** A substitution definition with its span content that will be inserted
* wherever this substitution is referenced in flow content.
*/
private[rst] case class SubstitutionDefinition(
name: String,
content: Span,
options: Options = Options.empty
) extends Definition with Hidden {
type Self = SubstitutionDefinition
def withOptions(options: Options): SubstitutionDefinition = copy(options = options)
}
/** Refers to a substitution definition with the same name.
* This type of element will only temporarily be part of the document tree and replaced
* by the content of the substitution definition in a rewrite step.
*/
private[rst] case class SubstitutionReference(
name: String,
source: SourceFragment,
options: Options = Options.empty
) extends Reference {
type Self = SubstitutionReference
def withOptions(options: Options): SubstitutionReference = copy(options = options)
lazy val unresolvedMessage: String = s"Unresolved substitution reference with name '$name'"
}
/** Represents an interactive Python session.
* Somewhat unlikely to be used in the context of this library,
* but included for the sake of completeness.
*/
private[rst] case class DoctestBlock(content: String, options: Options = Options.empty)
extends Block
with TextContainer {
type Self = DoctestBlock
def withOptions(options: Options): DoctestBlock = copy(options = options)
}
/** Header decoration consisting of both an overline and an underline.
*/
private[rst] case class OverlineAndUnderline(char: Char) extends HeaderDecoration
/** Header decoration consisting of an underline only.
*/
private[rst] case class Underline(char: Char) extends HeaderDecoration
/** Temporary element to represent interpreted text with its associated role name.
* In a post-processing step this text will be replaced by the result of calling
* the corresponding role function.
*/
private[rst] case class InterpretedText(
role: String,
content: String,
source: SourceFragment,
options: Options = Options.empty
) extends Reference with TextContainer {
type Self = InterpretedText
def withOptions(options: Options): InterpretedText = copy(options = options)
lazy val unresolvedMessage: String = s"Unresolved interpreted text with role '$role'"
}
/** Temporary element to represent a customized text role that can be applied
* to spans of interpreted text. The `apply` function can then be applied
* to spans of interpreted text referring to the name of this role and passing
* the text as the argument to the function.
*/
private[rst] case class CustomizedTextRole(
name: String,
apply: String => Span,
options: Options = Options.empty
) extends Definition with Hidden {
type Self = CustomizedTextRole
def withOptions(options: Options): CustomizedTextRole = copy(options = options)
}
/** Temporary element representing a file inclusion.
* The path is interpreted as relative to the path of the processed document if it is not an absolute path.
*/
private[rst] case class Include(
path: String,
source: SourceFragment,
options: Options = Options.empty
) extends Block
with BlockResolver {
type Self = Include
def withOptions(options: Options): Include = copy(options = options)
def resolve(cursor: DocumentCursor): Block =
cursor.parent.target.selectDocument(path) match {
case Some(target) => BlockSequence(target.content.content)
case None => InvalidBlock(s"Unresolvable path reference: $path", source)
}
def runsIn(phase: RewritePhase): Boolean = phase.isInstanceOf[RewritePhase.Render]
lazy val unresolvedMessage: String = s"Unresolved file inclusion with path '$path'"
}
/** Generates a table of contents element inside a topic.
*/
private[rst] case class Contents(
title: String,
source: SourceFragment,
depth: Int = Int.MaxValue,
local: Boolean = false,
options: Options = Options.empty
) extends Block with BlockResolver {
type Self = Contents
def withOptions(options: Options): Contents = copy(options = options)
def resolve(cursor: DocumentCursor): Block = {
val nav = cursor.target.asNavigationItem(
NavigationBuilderContext.defaults
.withRefPath(cursor.target.path)
.withMaxLevels(depth)
.withCurrentLevel(0)
).content
TitledBlock(List(Text(title)), Seq(NavigationList(nav)), options + Style.nav)
}
def runsIn(phase: RewritePhase): Boolean = phase.isInstanceOf[RewritePhase.Render]
lazy val unresolvedMessage: String = s"Unresolved table of contents generator with title '$title'"
}
/** A single item inside a line block.
*/
private[rst] abstract class LineBlockItem extends Block with RewritableContainer {
type Self <: LineBlockItem
}
/** A single line inside a line block.
*/
private[laika] case class Line(content: Seq[Span], options: Options = Options.empty)
extends LineBlockItem
with SpanContainer {
type Self = Line
def withContent(newContent: Seq[Span]): Line = copy(content = newContent)
def withOptions(options: Options): Line = copy(options = options)
}
private[laika] object Line extends SpanContainerCompanion {
type ContainerType = Line
protected def createSpanContainer(spans: Seq[Span]): Line = Line(spans)
}
/** A block containing lines which preserve line breaks and optionally nested line blocks.
*/
private[laika] case class LineBlock(content: Seq[LineBlockItem], options: Options = Options.empty)
extends LineBlockItem
with RewritableContainer with ElementContainer[LineBlockItem] {
type Self = LineBlock
def rewriteChildren(rules: RewriteRules): LineBlock =
copy(content = content.map(_.rewriteChildren(rules)))
def withOptions(options: Options): LineBlock = copy(options = options)
}
private[laika] object LineBlock {
def apply(item: LineBlockItem, items: LineBlockItem*): LineBlock = LineBlock(item +: items.toList)
}
/** Represent a reference name.
* When resolving references whitespace needs to be normalized
* and the name converted to lower case.
*/
private[rst] case class ReferenceName(original: String) {
lazy val normalized: String = original.replaceAll("[\n ]+", " ").toLowerCase
}