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

knockoff.XHTMLWriter.scala Maven / Gradle / Ivy

The newest version!
/*

## Output To XHTML

Knockoff's XHTMLWriter uses match expressions on it's object model to create a
very similar XHTML-style XML document.

Customization involves overriding one of these methods. At times, I've found it
easier to completely re-write or adjust the output method, so this technique may
not be 100% finished.

*/

package knockoff

import scala.util.{ Random }
import scala.xml.{ Group, Node, Text => XMLText, Unparsed }

trait XHTMLWriter {

  /** Backwards compatibility? *cough* */
  def toXML( blocks : collection.Seq[Block] ) : Node = toXHTML( blocks )

  /** Creates a Group representation of the document. */
  def toXHTML( blocks : collection.Seq[Block] ) : Node =
    Group( blocks.map( blockToXHTML(_) ) )

  def blockToXHTML : Block => Node = {
    case Paragraph( spans, _ ) => paragraphToXHTML( spans )
    case Header( level, spans, _ ) => headerToXHTML( level, spans )
    case LinkDefinition( _, _, _, _ ) => Group( Nil )
    case Blockquote( children, _ ) => blockquoteToXHTML( children )
    case CodeBlock( text, _ ) => codeToXHTML( text )
    case HorizontalRule( _ ) => hrXHTML
    case OrderedItem( children, _ ) => liToXHTML( children )
    case UnorderedItem( children, _ ) => liToXHTML( children )
    case OrderedList( items ) => olToXHTML( items )
    case UnorderedList( items ) => ulToXHTML( items )
    case HTMLBlock( content, _ ) => htmlBlockToXHTML( content )
  }

  def htmlBlockToXHTML : String => Node = html => Unparsed( html )

  def paragraphToXHTML : collection.Seq[Span] => Node = spans => {
    def isHTML( s : Span ) = s match {
      case y : HTMLSpan => true
      case Text( content ) => if ( content.trim.isEmpty ) true else false
      case _ => false
    }
    if ( spans.forall( isHTML ) )
      Group( spans.map( spanToXHTML(_) ) )
    else
      

{ spans.map( spanToXHTML(_) ) }

} def headerToXHTML : ( Int, collection.Seq[Span] ) => Node = (level, spans) => { val spanned = spans.map( spanToXHTML(_) ) level match { case 1 =>

{ spanned }

case 2 =>

{ spanned }

case 3 =>

{ spanned }

case 4 =>

{ spanned }

case 5 =>
{ spanned }
case 6 =>
{ spanned }
case _ =>
{ spanned }
} } def blockquoteToXHTML : collection.Seq[Block] => Node = children =>
{ children.map( blockToXHTML(_) ) }
def codeToXHTML : Text => Node = text =>
{ text.content }
def hrXHTML : Node =
def liToXHTML : collection.Seq[Block] => Node = children =>
  • { simpleOrComplex( children ) }
  • private def simpleOrComplex( children : collection.Seq[Block] ) : collection.Seq[Node] = { if ( children.length == 1 ) children.head match { case Paragraph( spans, _ ) => spans.map( spanToXHTML(_) ) case _ => children.map( blockToXHTML(_) ) } else children.map( blockToXHTML(_) ) } def olToXHTML : collection.Seq[Block] => Node = items =>
      { items.map( blockToXHTML(_) ) }
    def ulToXHTML : collection.Seq[Block] => Node = items =>
      { items.map( blockToXHTML(_) ) }
    def spanToXHTML : Span => Node = span => span match { case Text( content ) => textToXHTML( content ) case HTMLSpan( html ) => htmlSpanToXHTML( html ) case CodeSpan( code ) => codeSpanToXHTML( code ) case Strong( children ) => strongToXHTML( children ) case Emphasis( children ) => emphasisToXHTML( children ) case Link( children, url, title ) => linkToXHTML( children, url, title ) case IndirectLink( children, definition ) => linkToXHTML( children, definition.url, definition.title ) case ImageLink( children, url, title ) => imageLinkToXHTML( children, url, title ) case IndirectImageLink( children, definition ) => imageLinkToXHTML( children, definition.url, definition.title ) } def textToXHTML : String => Node = content => XMLText( unescape(content) ) def htmlSpanToXHTML : String => Node = html => Unparsed( html ) def codeSpanToXHTML : String => Node = code => { code } def strongToXHTML : collection.Seq[Span] => Node = spans => { spans.map( spanToXHTML(_) ) } def emphasisToXHTML : collection.Seq[Span] => Node = spans => { spans.map( spanToXHTML(_) ) } def linkToXHTML : ( collection.Seq[Span], String, Option[String] ) => Node = { ( spans, url, title ) => { spans.map( spanToXHTML(_) ) } } def imageLinkToXHTML : ( collection.Seq[Span], String, Option[String] ) => Node = { ( spans, url, title ) => { } def escapeURL( url : String ) : Node = { if ( url.startsWith( "mailto:" ) ) { val rand = new Random val mixed = url.map { ch => rand.nextInt(2) match { case 0 => java.lang.String.format( "&#%d;", int2Integer( ch.toInt ) ) case 1 => java.lang.String.format( "&#x%s;", ch.toInt.toHexString ) } }.mkString("") Unparsed( mixed ) } else { XMLText( url ) } } // TODO put this somewhere else val escapeableChars = List( "\\", "`", "*", "_", "{", "}", "[", "]", "(", ")", "#", "+", "-", ".", "!", ">" ) def unescape(source:String):String = { var buf:String = source for ((escaped, unescaped) <- escapeableChars.map(ch => ("\\" + ch, ch))) buf = buf.replace(escaped, unescaped) buf } }




    © 2015 - 2024 Weber Informatics LLC | Privacy Policy