
laika.rst.bundle.ExtendedHTMLRenderer.scala Maven / Gradle / Ivy
/*
* Copyright 2013-2016 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.rst.bundle
import laika.ast._
import laika.render.HTMLWriter
import laika.rst.ast._
/** HTML renderer for special reStructuredText tree elements not part of the default document tree model.
*
* The following tree elements are specific to reStructuredText and are not included in the default model:
*
* - `FieldList` and corresponding child elements
* - `OptionList` and corresponding child elements
* - `DoctestBlock`
*
* FieldLists being part of a directive declaration will be processed by the default parser, the `FieldList`
* element only appears in the final document model if field lists are used outside of directives.
*
* The renderer must be applied explicitly when any of these constructs are used in the markup:
*
* {{{
* val transform = Transform from ReStructuredText to HTML rendering ExtendedHTMLRenderer
* }}}
*
* @author Jens Halm
*/
class ExtendedHTMLRenderer extends (HTMLWriter => RenderFunction) {
private case class ProgramOptions (opts: Seq[Element], options: Options = NoOpt) extends Block
/** Converts an `OptionList` to an interim table model for rendering.
*/
def toTable (ol: OptionList): Table = {
def intersperse [T](list: List[T], sep: T): List[T] = list match {
case one :: two :: rest => one :: sep :: intersperse(two :: rest, sep)
case short => short
}
def options (value: Seq[ProgramOption]) = Cell(BodyCell, List(ProgramOptions(intersperse(value.toList,Text(", ")))))
def body (value: Seq[Block]) = Cell(BodyCell, value)
val rows = ol.content map (o => Row(List(options(o.programOptions),body(o.content))))
Table(TableHead(Nil), TableBody(rows), Caption(),
Columns.options(Styles("option"),Styles("description")), Styles("option-list"))
}
/** Converts a `FieldList` to an interim table model for rendering.
*/
def toTable (fl: FieldList): Table = {
def name (value: Seq[Span]) = Cell(HeadCell, List(SpanSequence(value :+ Text(":"))))
def body (value: Seq[Block]) = Cell(BodyCell, value)
val rows = fl.content map (f => Row(List(name(f.name),body(f.content))))
Table(TableHead(Nil), TableBody(rows), Caption(),
Columns.options(Styles("field-name"),Styles("field-body")), Styles("field-list"))
}
def apply (out: HTMLWriter): RenderFunction = {
val pf: RenderFunction = {
case DoctestBlock(content,_) => out << """""" <<<& (">>> "+content) << "
"
case fl: FieldList => out << toTable(fl)
case ol: OptionList => out << toTable(ol)
case ProgramOptions(options,_) => out << "" << options << ""
case ProgramOption(name,arg) => out << """""" << name << arg.getOrElse(Text("")) << ""
case OptionArgument(value,delim)=> out << delim << "" << value << ""
}
pf
}
}
object ExtendedHTMLRenderer extends ExtendedHTMLRenderer
© 2015 - 2025 Weber Informatics LLC | Privacy Policy