org.clapper.markwrap.MarkWrap.scala Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of markwrap_2.10 Show documentation
Show all versions of markwrap_2.10 Show documentation
A unified API for converting various lightweight markup languages to HTML
The newest version!
/*
---------------------------------------------------------------------------
This software is released under a BSD license, adapted from
http://opensource.org/licenses/bsd-license.php
Copyright (c) 2010-2018, Brian M. Clapper
All rights reserved.
See the accompanying license file for details.
---------------------------------------------------------------------------
*/
/**
* Defines a common API for various simple markup parsers. Currently, this
* API supports Markdown and Textile, using different parsers behind a common
* interface.
*/
package org.clapper.markwrap
import scala.io.Source
import java.io.File
import scala.util.{Failure, Success, Try}
/**
* The common parser interface.
*/
trait MarkWrapParser {
/** The markup type associated with the parser.
*
* @return the markup type.
*/
val markupType: MarkupType
/** Convert the specified markup to an HTML fragment, without
* `html` or `body` tags. The resulting HTML fragment can then be
* included within an existing HTML document.
*
* @param source the source containing the markup
*
* @return the HTML
*/
def parseToHTML(source: Source): String
/** Convert the specified markup to an HTML fragment, without
* `html` or `body` tags. The resulting HTML fragment can then be
* included within an existing HTML document.
*
* @param file the file containing the markup
*
* @return the HTML
*/
def parseToHTML(file: File): String =
parseToHTML(Source.fromFile(file))
/** Convert the specified markup to an HTML fragment, without
* `html` or `body` tags. The resulting HTML fragment can then be
* included within an existing HTML document.
*
* @param markup the string containing the markup
*
* @return the HTML
*/
def parseToHTML(markup: String): String =
parseToHTML(Source.fromString(markup))
/** Simple wrapper function that produces an XHTML-compliant document,
* complete with HTML, HEAD and BODY tags, from a markup document.
*
* @param markupSource The `Source` from which to read the
* lines of markup
* @param title The document title
* @param cssSource Source for any CSS to be included, or None
* @param encoding The encoding to use. Defaults to "UTF-8".
*
* @return the formatted HTML document.
*/
def parseToHTMLDocument(markupSource: Source,
title: String,
cssSource: Option[Source] = None,
encoding: String = "UTF-8"): String = {
// Don't use the XML Scala stuff. It can gag on HTML entities.
// Just build an HTML string.
val htmlBody = "\n" + parseToHTML(markupSource) + "\n\n"
val contentType = "text/html; charset=" + encoding
val style = cssSource.map { s =>
"\n"
}.getOrElse("")
"""
|
|""".stripMargin + title + " " +
style +
"\n" +
"\n" +
htmlBody +
"\n"
}
}
/**
* Supported markup types.
*/
sealed abstract class MarkupType(val name: String, val mimeType: String)
/**
* Defines the various supported lightweight markup types.
*/
object MarkupType {
/**
* Markup type for Markdown. Text is transformed to HTML via Markdown
* parser.
*/
case object Markdown extends MarkupType("markdown", "text/markdown")
/**
* Markup type for Textile. Text is transformed to HTML via Textile
* parser.
*/
case object Textile extends MarkupType("textile", "text/textile")
/**
* Markup type for HTML. Text is emitted as-is.
*/
case object HTML extends MarkupType("html", "text/html")
/**
* Markup type for XHTML. Text is emitted as-is.
*/
case object XHTML extends MarkupType("xhtml", "text/xhtml")
/**
* Markup type for plain text. Text is wrapped in "pre" tags
* and emitted as-is.
*/
case object PlainText extends MarkupType("plaintext", "text/plain")
}
/**
* Factory object to produce parsers for specific markup document types.
*/
object MarkWrap {
import javax.activation.MimetypesFileTypeMap
private lazy val MimeTypeMap = new MimetypesFileTypeMap
MimeTypeMap.addMimeTypes(
"""text/markdown md markdown
|text/textile textile
|text/html htm html
|text/xhtml xhtml xhtm
|text/plain txt TXT text TEXT cfg conf properties
""".stripMargin
)
/** MIME type to MarkupType mapping.
*/
private val MimeTypes = Map(
MarkupType.Markdown.mimeType -> MarkupType.Markdown,
MarkupType.Textile.mimeType -> MarkupType.Textile,
MarkupType.HTML.mimeType -> MarkupType.HTML,
MarkupType.XHTML.mimeType -> MarkupType.XHTML,
MarkupType.PlainText.mimeType -> MarkupType.PlainText
)
/** Get a parser for the specified type.
*
* @param parserType the parser type
*
* @return the parser
*/
@deprecated("Use converterFor", "1.2.0")
def parserFor(parserType: MarkupType): MarkWrapParser = {
converterFor(parserType)
}
/** Get a converter (parser) for the specified type.
*
* @param parserType the parser type
*/
def converterFor(parserType: MarkupType): MarkWrapParser = parserType match {
case MarkupType.Markdown => new MarkdownParser
case MarkupType.Textile => new TextileParser
case MarkupType.HTML => new VerbatimHandler
case MarkupType.XHTML => new VerbatimHandler
case MarkupType.PlainText => new PreWrapHandler
}
/** Get a parser for the specified MIME type.
*
* @param mimeType the MIME type
*
* @return the parser.
*
* @throws IllegalArgumentException unsupported MIME type
*/
@deprecated("Use converterFor", "1.2.0")
def parserFor(mimeType: String): MarkWrapParser = converterFor(mimeType).get
/** Get a converter (parser) for the specified MIME type.
*
* @param mimeType the MIME type
*
* @return a `Success` containing the appropriate object, or a `Failure`
* if the MIME type isn't supported.
*
* @throws IllegalArgumentException unsupported MIME type
*/
def converterFor(mimeType: String): Try[MarkWrapParser] = {
def BadMimeType =
new IllegalArgumentException(s"""Unsupported MIME type $mimeType""")
MimeTypes
.get(mimeType)
.map { p => Success(converterFor(p)) }
.getOrElse(Failure(new IllegalArgumentException(BadMimeType)))
}
/** Get a parser for the specified file.
*
* @param f the file
*
* @return the parser.
*
* @throws IllegalArgumentException unsupported MIME type
*/
@deprecated("Use converterFor", "1.2.0")
def parserFor(f: File): MarkWrapParser = converterFor(f).get
/** Get a converter (parser) for the specified file.
*
* @param f the file
*
* @return a `Success` containing the appropriate object, or a `Failure`
* if the file type isn't supported.
*/
def converterFor(f: File): Try[MarkWrapParser] = {
converterFor(MimeTypeMap.getContentType(f))
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy