2015-09-09 8 views
5

クライアント側でPageDownをエディタとして使用し、サーバー側でそのMarkdownをHTMLに解析しようとしています。PageDown ScriptEngineを間違って解析してマークダウンする

クライアント側でうまく動作しているようですが、サーバー側では、目盛りは、ラップする単語ではなく、後続の文字を「コード化」しているだけです。私はこれを行うのであれば:

test `test` test

を私はこれを期待し、これは、私はクライアント側で得るもの確かです:

test <code>test</code> test

しかし、サーバー側では、私はなって終わります代わりに、この:私はと呼ばれるファイルを作成しました

test <code>t</code>est<code> </code>test

この機能では、単にMarkdown.Converter.jsMarkdown.Sanitizer.js単一のファイルに結合しているは、追加:正しく表示さ

<!DOCTYPE html> 
<html> 
<head> 
<script src="pageDown.js"></script> 
<script> 
function convert(){ 

    var html = getSanitizedHtml("test `test` test"); 

    console.log(html); 

    document.getElementById("content").innerHTML = html; 
} 

</script> 
</head> 

<body onload="convert()"> 
<p id="content"></p> 
</body> 
</html> 

クライアント側で
function getSanitizedHtml(pagedown){ 
    var converter = new Markdown.getSanitizingConverter(); 
    return converter.makeHtml(pagedown); 
} 

が、私はこのようにようにファイルを使用することができます。

0:(Java)のサーバー側で

<p>test <code>test</code> test</p>は、私はJavaのScriptEngineManagerInvocableを通じて、このまったく同じファイルを使用します<p>test <code>t</code>est<code></code>test</p>

私は他の値下げと同様の問題を参照してください:プログラムはこれを印刷し

import java.io.InputStreamReader; 
import javax.script.Invocable; 
import javax.script.ScriptEngine; 
import javax.script.ScriptEngineManager; 

public class PageDownTest{ 

    public static void main(String... args){ 

     try{ 
      ScriptEngineManager manager = new ScriptEngineManager(); 
      ScriptEngine engine = manager.getEngineByName("JavaScript"); 
      engine.eval(new InputStreamReader(PageDownTest.class.getResourceAsStream("pageDown.js"))); 
      Invocable inv = (Invocable) engine; 
      String s = String.valueOf(inv.invokeFunction("getSanitizedHtml", "test `test` test")); 
      System.out.println(s); 
     } 
     catch(Exception e){ 
      e.printStackTrace(); 
     } 
    } 
} 

test **test** testを単に**部分を無視します。ただし、##testは正しく<h2>test</h2>として返します。

私はJavaScriptをHTMLに直接渡すとうまく動作しますが、Javaを経由するとうまく動作しません。何が起きてる?私は、サーバー上でMarkdownを別々に扱うべきですか?

+0

プロジェクトwikiには、サーバー上でNode.JSを使用していることが記載されています。それが最後の手段です。 – approxiblue

+0

なぜこの質問に賞金があるのか​​分かりません。唯一の答えは、問題が使用されているライブラリのバグであることを明確に述べています。バグは、そのライブラリのメンテナにアップストリームで報告する必要があります。私たちが助けるためにここで何かできることはほかにありません。 – Waylan

+0

@Waylan **の前に賞金が追加されました**。回答が掲載された唯一の理由は、賞金を追加したためです。それが賞金の仕組みです。 –

答えて

4

私は、次のコードに問題を軽減するために管理:

function getSanitizedHtml(text) 
{ 
    return text.replace(/(a)(?!b)\1/gm, 'c'); 
} 

getSanitizedHtml('aa'); 

などのブラウザで呼び出された場合、それが返されます。

c 

Nashornから呼び出された場合エンジン:

String s = String.valueOf(inv.invokeFunction("getSanitizedHtml", "aa")); 

それが返されます:私に

cc 

、これはそのキャプチャされたコンテンツ長さがゼロであるため、何も一致し(?!b)、を指す代わりに、(a)を指している必要があり後方参照\1、のように見えます。

Javaで同等のコード:

System.out.println(("aa").replaceAll("(a)(?!b)\\1", "c")); 

がが正しい結果を返します。

c 

結論は

私は、これはNashornエンジンのバグであるかなり確信しています。
私はバグレポートを提出し、そのIDが公開されていれば、そのIDをここに掲載します。あなたの問題については

、私はあなたの唯一のオプションは、少なくとも一時的に、別のJavaScript環境に切り替えることだと思います。

最小、実行可能な実施例

ブラウザで

JS:Nashornエンジンにおける

function x(s){return s.replace(/(a)(?!b)\1/gm, 'c');} 
 
document.write(x('aa'));

JS:

[Ideone]

ピュアJavaの:

[Ideone]

可能性を修正しまし

すでに指摘したように、(この時点で)あなたの唯一のオプションは、他のJavaScript環境に切り替えることです。
利用可能なものは数多くあり、ウィキペディアはa comparison pageです。この例では、io.jsを選択しました(自分でインストールすることができます)。

あなたのページを使用したい場合。JSファイルは、最初にこのように、exportsチェックをコメントアウトして、昔ながらの変数を使用する必要があります:

/*if (typeof exports === "object" && typeof require === "function") // we're in a CommonJS (e.g. Node.js) module 
    Markdown = exports; 
else*/ 
    Markdown = {}; 

/*if (typeof exports === "object" && typeof require === "function") { // we're in a CommonJS (e.g. Node.js) module 
    output = exports; 
    Converter = require("./Markdown.Converter").Converter; 
} else {*/ 
    output = Markdown; 
    Converter = output.Converter; 
//} 

は(私も output = Markdown;output = window.Markdown;を変更したことに注意してください - あなたにあなたの質問に言及するのを忘れてしまったのです。)

また、エクスポートシステムとファイルを別々に使うこともできますが、私は経験がありません私はそれをこのようにします。

さて、io.jsは標準入力からJavaScriptコードを受け入れ、あなたがprocess.stdout.write()経由でstdoutに書き込むことができますので、私たちは(コマンドラインで)、次の操作を行うことができます。

{ cat pageDown.js; echo 'process.stdout.write(getSanitizedHtml("test `test` test"));'; } | iojs; 

そして、我々は戻って、次の取得:

<p>test <code>test</code> test</p> 

あなたは、Javaから、あなたはこのようにそれを行うことができますことを行う必要がある場合:

import java.io.*; 

class Test 
{ 
    public static void main(String[] args) throws Exception 
    { 
     Process p = Runtime.getRuntime().exec("/path/to/iojs"); 
     OutputStream stdin = p.getOutputStream(); 
     InputStream stdout = p.getInputStream(); 
     File file = new File("/path/to/pageDown.js"); 
     byte[] b = new byte[(int)file.length()]; 
     FileInputStream in = new FileInputStream(file); 
     for(int read = 0; read < b.length; read += in.read(b, read, b.length - read)); // <-- note the semicolon 
     stdin.write(b); 
     stdin.write("process.stdout.write(getSanitizedHtml('test `test` test'));".getBytes()); 
     stdin.close(); // <-- important to close 
     p.waitFor(); 
     b = new byte[stdout.available()]; 
     stdout.read(b); 
     System.out.println(new String(b)); 
    } 
} 

forの直後にセミコロンがあることに注意してください(毎回read += in.read(b, read, b.length - read)しかありません)。ストリームの.close()は通常オプションですが、オブジェクトが有効範囲外になると自動的に行われるため、stdin.close()ここで呼び出す必要があります。iojsは入力待ちのままで、p.waitFor()は返されません。

+0

お返事ありがとうございます。他にどのようなJavaScript環境に切り替えることができますか? –

+0

[Here](https://github.com/markdown/markdown.github.com/wiki/Implementations)は、よく知られているMarkdown実装の長い(ただし不完全な)リストです。そこにリストされているJavaScriptライブラリのいずれかの品質については話すことはできませんが、おそらくそのうちの1つが有用なものになります。 – Waylan

関連する問題