java – 使用Rhino调用showdown

我想使用Rhino的showdownjs
javascript markdown库.

它是这样使用的:

var Showdown = require('showdown');
var converter = new Showdown.converter();

converter.makeHtml('#hello markdown!');

// <h1 id="hellomarkdown">hello, markdown</h1>

所以我有showdown.js文件(https://raw.githubusercontent.com/showdownjs/showdown/master/compressed/Showdown.js),我怎么去调用这个makeHTML方法,同时传递一个我在jvm方面的参数?

我在网上找到了这段代码:

import org.mozilla.javascript.Scriptable
import org.mozilla.javascript.ScriptableObject
import org.mozilla.javascript.{Context, Function}
import java.io.InputStreamReader

class Showdown {

  def markdown(text: String): String = {
    // Initialize the Javascript environment
    val ctx = Context.enter
    try {
      val scope = ctx.initStandardObjects
      // Open the Showdown script and evaluate it in the Javascript
      // context.
      val showdownURL = getClass.getClassLoader.getResource("showdown.js")
      val stream = new InputStreamReader(showdownURL.openStream)
      ctx.evaluateReader(scope, stream, "showdown", 1, null)
      // Instantiate a new Showdown converter.
      val converterCtor = ctx.evaluateString(scope, "Showdown converter", "converter", 1, null).asInstanceOf[Function]
      val converter = converterCtor.construct(ctx, scope, null)
      // Get the function to call.
      val makeHTML = converter.get("makeHtml", converter).asInstanceOf[Function]

      val htmlBody = makeHTML.call(ctx, scope, converter, Array[AnyRef](text))

      htmlBody.toString
    }

    finally {
      Context.exit
    }
  }

}

当我像这样使用它时:

val s = new Showdown()
s.markdown("hello")

我收到一个错误:

org.mozilla.javascript.EvaluatorException: missing ; before statement (converter#1)
    at org.mozilla.javascript.DefaultErrorReporter.runtimeError(DefaultErrorReporter.java:109)
    at org.mozilla.javascript.DefaultErrorReporter.error(DefaultErrorReporter.java:96)
    at org.mozilla.javascript.Parser.addError(Parser.java:146)
    at org.mozilla.javascript.Parser.reportError(Parser.java:160)
    at org.mozilla.javascript.Parser.statementHelper(Parser.java:1266)
    at org.mozilla.javascript.Parser.statement(Parser.java:707)
    at org.mozilla.javascript.Parser.parse(Parser.java:401)
    at org.mozilla.javascript.Parser.parse(Parser.java:338)
    at org.mozilla.javascript.Context.compileImpl(Context.java:2368)
    at org.mozilla.javascript.Context.compileString(Context.java:1359)
    at org.mozilla.javascript.Context.compileString(Context.java:1348)
    at org.mozilla.javascript.Context.evaluateString(Context.java:1101)

我之前从未使用过Rhino,所以我不确定问题是什么.

我的方法中的这一行看起来是否正确?

val converterCtor = ctx.evaluateString(scope, "Showdown converter", "converter", 1, null).asInstanceOf[Function]

最佳答案 使用Rhino的内置load()函数,用于将外部JS文件加载到Rhino JavaScript环境中.

load([filename, …])

Load JavaScript source files named by string arguments. If multiple arguments are given, each file is read in and executed in turn.

Official Mozilla Rhino Docs.

例如,如果我想使用存储在另一个类中的JavaScript函数,我会这样做:

>外部文件(为了示例,称为testFile.js):

//Example Class testFile.js
function sayHi(){
    Packages.java.lang.System.out.println('hi');
}

>运行sayHi()函数的实际代码(标准java,而不是scala):

Context ctx = Context.enter();
Scriptable scope = ctx.initStandardObjects();
Object o = ctx.evaluateString(scope,
                         "load('testFile.js');
                          sayHi();",
                         1,
                         null);

这将导入testFile.js文件,并运行sayHi()函数,该函数访问java.lang.System类,并使用args hi执行out.println(args)方法.

点赞