2015-09-09 24 views
5

मैं क्लाइंट साइड पर एक संपादक के रूप में PageDown का उपयोग करने की कोशिश कर रहा हूं, और सर्वर पक्ष पर फिर मार्कडाउन को HTML पर पार्स करने का प्रयास कर रहा हूं।स्क्रिप्टइंजिन के माध्यम से पेजडाउन गलत तरीके से पार्सिंग मार्कडाउन

यह क्लाइंट पक्ष पर ठीक काम करता प्रतीत होता है, लेकिन सर्वर की तरफ, टिकटें केवल उस चरित्र को "कोडिंग" कर रही हैं, जो शब्द इसे लपेटती है। तो अगर मैं ऐसा करते हैं:

test `test` test

मैं इस उम्मीद करते हैं, और वास्तव में यही है मैं ग्राहक पक्ष पर क्या मिलेगा:

test <code>test</code> test

लेकिन सर्वर साइड पर, मैं हो रही अंत बजाय इस:

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

मैं एक फ़ाइलबुलाया बना लिया है, जो केवल Markdown.Converter.js और Markdown.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); 
} 

ग्राहक पक्ष पर, मैं इस फ़ाइल इसलिए की तरह उपयोग कर सकते हैं: <p>test <code>test</code> test</p>

(जावा) सर्वर साइड पर, मैं इस एक ही सटीक फ़ाइल का उपयोग, जावा के ScriptEngineManager और Invocable के माध्यम से:

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 बस ** भाग पर ध्यान नहीं देता: <p>test <code>t</code>est<code></code>test</p>

मैं अन्य markdown के साथ इसी तरह की समस्याओं को देखते हैं। हालांकि, ##test सही ढंग से <h2>test</h2> के रूप में लौटता है।

यह सब ठीक काम करता है अगर मैं जावास्क्रिप्ट पर सीधे जावास्क्रिप्ट पर जाता हूं, लेकिन जब मैं जावा से नहीं जाता हूं। यहाँ क्या चल रहा है? क्या मुझे सर्वर पर मार्कडाउन को अलग-अलग संभालना चाहिए?जब Nashorn से कहा जाता

c 

:

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

जब के रूप में

getSanitizedHtml('aa'); 

यह रिटर्न ब्राउज़र में कहा जाता है:

+0

प्रोजेक्ट विकी सर्वर पर नोड.जेएस का उपयोग करने का उल्लेख करता है, यह आपका अंतिम उपाय है। – approxiblue

+0

यह सुनिश्चित नहीं है कि इस प्रश्न का बक्षीस क्यों है। एकमात्र उत्तर स्पष्ट रूप से बताता है कि समस्या पुस्तकालय में एक बग है। उस पुस्तकालय के रखरखाव करने वालों को बग को अपस्ट्रीम की सूचना दी जानी चाहिए। मदद करने के लिए यहां कुछ भी नहीं है जो हम कर सकते हैं। – Waylan

+0

@Waylan ** उत्तर से पहले ** बक्षीस ** जोड़ा गया था। जवाब पोस्ट करने का एकमात्र कारण था क्योंकि मैंने बक्षीस जोड़ा था। इस तरह बाउंटी काम करते हैं। –

उत्तर

4

मैं निम्नलिखित कोड को समस्या को कम करने में कामयाब

के रूप में इंजन
String s = String.valueOf(inv.invokeFunction("getSanitizedHtml", "aa")); 

यह रिटर्न:

cc 
मेरे लिए

, इस backreference \1, जो (a) पर ले जाना चाहिए की तरह दिखता है, बजाय (?!b), जिसका कब्जा कर लिया सामग्री शून्य लंबाई है और इस तरह कुछ भी मेल खाता है के लिए अंक।

जावा में बराबर कोड:

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

सही परिणाम देता है, हालांकि:

c 

निष्कर्ष

मैं बहुत यकीन है कि यह Nashorn इंजन में एक बग है हूँ।
मैंने एक बग रिपोर्ट दायर की और यदि यह सार्वजनिक हो जाए, तो यहां इसकी आईडी पोस्ट कर दी जाएगी।

आपकी समस्या के लिए, मुझे लगता है कि आपका एकमात्र विकल्प कम से कम अस्थायी रूप से एक अलग जावास्क्रिप्ट वातावरण पर स्विच करना है।

मिनिमल, runnable उदाहरण

ब्राउज़र में जे एस:

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

Nashorn इंजन में जे एस:

[Ideone]

शुद्ध जावा:

[Ideone]

संभव फिक्स

के रूप में पहले ही बताया, (इस बिंदु पर) अपने ही एकमात्र विकल्प एक और जावास्क्रिप्ट पर्यावरण के लिए स्विच करने के लिए है।
उनमें से कई उपलब्ध हैं, और विकिपीडिया में 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 stdin से जावा स्क्रिप्ट कोड को स्वीकार करता है, और आप process.stdout.write() के माध्यम से stdout में लिख सकते हैं, तो हम क्या कर सकते हैं (कमांड लाइन पर) के बाद:

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

और हम वापस निम्नलिखित मिल :

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

आपको बस इतना करना है कि जावा से, आप इसे इस तरह से कर सकते हैं:

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

उत्तर के लिए धन्यवाद। मैं अन्य जावास्क्रिप्ट वातावरण कैसे स्विच कर सकता हूं? –

+0

[यहां] (https://github.com/markdown/markdown.github.com/wiki/Implementations) ज्ञात मार्कडाउन कार्यान्वयन की एक लंबी (हालांकि अपूर्ण) सूची है। मैं वहां सूचीबद्ध किसी भी जावास्क्रिप्ट पुस्तकालय की गुणवत्ता से बात नहीं कर सकता, लेकिन शायद उनमें से एक उपयोगी होगा। – Waylan

संबंधित मुद्दे