Skip to content
philcali edited this page Jul 5, 2012 · 4 revisions

Everything within LMXML is extensible, from parsing to converting.

Extending the Parser

All the parsing is held within the LmxmlParsers trait. Here is an example where one might want to create more in-depth HTML output features.

trait HtmlShortcuts extends LmxmlParsers {
  val js: Parser[TopLevel] = "~" ~ "js" ~> inlineParams ^^ {
    case attrs => 
      LmxmlNode("script", Map("type" -> "text/javascript") ++ attrs, _)
  }

  override def topLevel = super.topLevel | js
}

/*
Now you could do things like:

html
  head
    ~ js @src = "jquery.js"
    ~ js
      ~~~
$(document).ready(function() {
  alert("Page is ready");
});
      ~~~ is unescaped
*/

val indention = 2

val parser = new PlainLmxmlParser(indention) with HtmlShortcuts

val nodes = parser.parseNodes(contents)

Extending Template Logic

Extending template logic can be done by extending from a Processor in the lmxml.transforms package.

Here is an example where a random word is generated 10 times.

object Word extends Processor {
  val rand = new java.util.Random

  val possibilities = List(
    "some", "dude", "tried", "talking", "to", "me",
    "and", "I", "was", "like", "what"
  )

  def word = possibilities(rand.nextInt(possibilities.size))

  def apply(transform: Transform, node: ParsedNode) = TextNode(word)
}

val transform = Transform(
  "10-times" -> Foreach(1 to 10) { _ => Seq(
    "word" -> Word
  ) }
)

LMXML

div #contents
  div #header h1 "These are a few things:"
  div .things
    ul
      10-times li word

Outputs

<div id="contents">
  <div id="header">
    <h1>These are a few things:</h1>
  </div>
  <div class="things">
    <ul>
      <li>some</li>
      <li>was</li>
      <li>dude</li>
      <li>I</li>
      <li>tried</li>
      <li>was</li>
      <li>talking</li>
      <li>what</li>
      <li>dude</li>
      <li>me</li>
    </ul>
  </div>
</div>

Extending Factories

Hooking the custom parser to a factory like the Lmxml object is also very easy.

object CustomLmxml extends LmxmlFactory with FileLoading {
  def createParser(step: Int) = new PlainLmxmlParser(step) with HtmlShortcuts
}

val format = new xml.PrettyPrinter(200, 2).formatNodes(_: xml.NodeSeq)

CustomLmxml.fromFile("test.lmxml")(XmlConvert andThen format andThen println)

Try to keep things as modular as possible.

Clone this wiki locally