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

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