How can I serialize JavaScript code to a file using Rhino shell? - java

I am using Rhino as part of an Ant build process to bundle and minify JavaScript. In addition to that, I would also like pre-compile client-side templates, i.e. compile them from markup to JavaScript. At a glance, I thought Rhino's serialize() method would do it but that does not seem to be the case.
// Load templating engine
load( "engine.js" );
// Read template file
var template = readFile( "foo.template" ),
// Compile template
compiled = engine.compile( template );
// Write compiled template to file
serialize( compiled, "compiledFoo.js" );
This results in a binary file being written. What I want is a text file which contains the compiled template.
If using serialize() is not the answer, then what is? Since it's Rhino, it would be possible to import Java classes as well. Offhand, I can't figure out a way to do it.
I know this can be done in Node but I'm not in a position to migrate the build process from Ant-Rhino to Grunt-Node right now.

In my search for an answer I came across the fact that SpiderMonkey, Rhino's C/C++ sister, has an uneval() function, which as you can guess does the opposite of JavaScript's eval() function. One more Google search later, I found that Rhino implemented uneval() in 1.5R5. This may be the only documentation that mentions Rhino has this feature (or not).
That being said, here is the solution:
// Load the templating engine
load( "engine.js" );
// Read the template file
var template = readFile( "foo.template" ),
// Compile the template markup to JavaScript
compiled = engine.compile( template ),
// Un-evaluate the compiled template to text
code = uneval( compiled ),
// Create the file for the code
out = new java.io.FileWriter( "foo.js" );
// Write the code to the file
out.write( code, 0, code.length );
out.flush();
out.close();
quit();

Write a function in the javascript that you can call from Java that returns the value that you need as a string.

Related

Read templates from a file StringTemplate

I'm using the template engine StringTemplate for some templates (obviously).
What I want is to be able to store the templates I have in seperate files, ofcourse I can do that with simple .txt files and reading them into a String, looks a bit like this then
ST template = new ST(readTemplateFromFile("template.txt"))
private String readTemplateFromFile(String templateFile){
//read template from file
}
But what I was wondering is if there's functionality in the StringTemplate engine to do that automatically. SO that i don't have to write code that already exists.
I've read something about Group Files but I don't quite understand that,are those like Template files? Or am I completely missing something?
Yes, there is functionality available that can be used directly without providing your own file loading code.
From the ST JavaDoc:
To use templates, you create one (usually via STGroup) and then inject attributes using add(java.lang.String, java.lang.Object). To render its attacks, use render().
To follow that advice the following code can be used.
First, create a file called exampleTemplate.stg and place it on your classpath.
templateExample(param) ::= <<
This is a template with the following param: (<param>)
>>
Then, render the template by using the following code:
// Load the file
final STGroup stGroup = new STGroupFile("exampleTemplate.stg");
// Pick the correct template
final ST templateExample = stGroup.getInstanceOf("templateExample");
// Pass on values to use when rendering
templateExample.add("param", "Hello World");
// Render
final String render = templateExample.render();
// Print
System.out.println(render);
The output is:
This is a template with the following param: (Hello World)
Some additional notes:
STGroupFile is a subclass of STGroup. There are other subclasses as well that you find out more about in the JavaDoc.
In the example above the template file was placed on the classpath. This is not a requirement, files can be placed in a relative folder or a in an absolute folder as well.

can i insert js codes using out.write method in java

How can i insert javascript in java file. If i am inserting html tags it works fine but if i insert following js code it doesn't show any errors but it will not show the chart also.
i'am using chart.js
out.write(""<h1>Graph</h1>\n"");
out.write("<canvas id='canvas' height='450' width='600'></canvas>\n");
out.write("<script>\n");
out.write("var barChartData = \n");
out.write("{labels : ['Pass','Fail'],\n");
out.write("datasets : {\n");
out.write("[fillColor : 'rgba(220,220,220,0.5)',\n");
out.write("strokeColor : 'rgba(220,220,220,1)',\n");
out.write("data : [65,0]},{\n");
out.write("fillColor : 'rgba(151,187,205,0.5)',\n");
out.write("data : [0,47]}]}\n");
out.write("var myLine = new Chart(document.getElementById('canvas').getContext('2d')).Bar(barChartData);\n");
out.write("</script>\n");
Is this is the correct way using out.write ?
According to the HTML 4 specification, a <script> element requires either a type or lang attribute, unless you have specified the default scripting language.
A document that doesn't conform to this is erroneous, and the browser is free to ignore the script.
Another possibility is that your script contains errors. Use your browser's web developer support to check for javascript errors.
If you are writing to a file on Windows, use \r\n instead, because windows filesystem doesn't understands \ns as newlines. Else, you must provide more info. It could also be because you missed declarating the script type.

providing automization with Xtext and Java program

In my current project, I am using xText editor for writing my dsl specifications (i.e., voc.mydsl, arch.mydsl, and network.mydsl). I like the xText editor because of its code-completion and other functionalities.
However, I have a separate Java program. This java program takes text files (i.e., voc.txt, arch.txt, network.txt) as inputs, parse these files using ANTLR parser, and generates code using StringTemplate files.
Now, my problem is that currently, I have to follow these steps manually:
(1) I write dsl specifications in XText editor (voc.mydsl, arch.mydsl, and network.mydsl).
(2) I copy-paste these specification into three text files (i.e., voc.txt, arch.txt, network.txt).
(3) Finally, I run the Java program to parse these .txt files and generate code.
Is there any way that I can automize (performed in a single click) all the above three steps? Let me know if you need any detail.
You could write a "special" generator for your DSL. XText will call this generator whenever you edit and save a *.mydsl file. What you actually do in this "Generator" thing is of no interest to Xtext. So your MydslGenerator.xtend generator could look like this:
// whereever Xtext generates your empty version of this file
package mydsl.xtext.generator
// add imports
#Singleton
class MydslGenerator implements IGenerator {
override void doGenerate(Resource resource, IFileSystemAccess fsa) {
// calculate new filename
val newFilename= resource.URI.lastSegment.replaceAll(".mydsl", ".txt")
// get text representation of parsed model
val textContent = resource.contents.map[NodeModelUtils::getNode(it).text].join
// write text content to new file
fsa.generateFile(newFilename, textContent);
// TODO: call ANTLR parser on new file here
}
}
In the last step you can call your "other" program either by calling its main method directly from Eclipse or by invoking a new JVM. The later is only advisable if the other generator works quickly because it is called whenever you save a *.mydsl file. The first method is only advisable when the other program has no memory leaks and has not to many jar dependencies.

how to create an odt file programmatically with java?

How can I create an odt (LibreOffice/OpenOffice Writer) file with Java programmatically? A "hello world" example will be sufficient. I looked at the OpenOffice website but the documentation wasn't clear.
Take a look at ODFDOM - the OpenDocument API
ODFDOM is a free OpenDocument Format
(ODF) library. Its purpose is to
provide an easy common way to create,
access and manipulate ODF files,
without requiring detailed knowledge
of the ODF specification. It is
designed to provide the ODF developer
community with an easy lightwork
programming API portable to any
object-oriented language.
The current reference implementation
is written in Java.
// Create a text document from a standard template (empty documents within the JAR)
OdfTextDocument odt = OdfTextDocument.newTextDocument();
// Append text to the end of the document.
odt.addText("This is my very first ODF test");
// Save document
odt.save("MyFilename.odt");
later
As of this writing (2016-02), we are told that these classes are deprecated... big time, and the OdfTextDocument API documentation tells you:
As of release 0.8.8, replaced by org.odftoolkit.simple.TextDocument in
Simple API.
This means you still include the same active .jar file in your project, simple-odf-0.8.1-incubating-jar-with-dependencies.jar, but you want to be unpacking the following .jar to get the documentation: simple-odf-0.8.1-incubating-javadoc.jar, rather than odfdom-java-0.8.10-incubating-javadoc.jar.
Incidentally, the documentation link downloads a bunch of jar files inside a .zip which says "0.6.1"... but most of the stuff inside appears to be more like 0.8.1. I have no idea why they say "as of 0.8.8" in the documentation for the "deprecated" classes: just about everything is already marked deprecated.
The equivalent simple code to the above is then:
odt_doc = org.odftoolkit.simple.TextDocument.newTextDocument()
para = odt_doc.getParagraphByIndex( 0, False )
para.appendTextContent( 'stuff and nonsense' )
odt_doc.save( 'mySpankingNewFile.odt' )
PS am using Jython, but the Java should be obvious.
I have not tried it, but using JOpenDocument may be an option. (It seems to be a pure Java library to generate OpenDocument files.)
A complement of previously given solutions would be JODReports, which allows creating office documents and reports in ODT format (from templates, composed using the LibreOffice/OpenOffice.org Writer word processor).
DocumentTemplateFactory templateFactory = new DocumentTemplateFactory();
DocumentTemplate template = templateFactory .getTemplate(new File("template.odt"));
Map data = new HashMap();
data.put("title", "Title of my doc");
data.put("picture", new RenderedImageSource(ImageIO.read(new File("/tmp/lena.png"))));
data.put("answer", "42");
//...
template.createDocument(data, new FileOutputStream("output.odt"));
Optionally the documents can then be converted to PDF, Word, RTF, etc. with JODConverter.
Edit/update
Here you can find a sample project using JODReports (with non-trivial formatting cases).
I have written a jruby DSL for programmatically manipulating ODF documents.
https://github.com/noah/ocelot
It's not strictly java, but it aims to be much simpler to use than the ODFDOM.
Creating a hello world document is as easy as:
% cat examples/hello.rb
include OCELOT
Text::create "hello" do
paragraph "Hello, world!"
end
There are a few more examples (including a spreadsheet example or two) here.
I have been searching for an answer about this question for myself. I am working on a project for generating documents with different formats and I was in a bad need for library to generate ODT files.
I finally can say the that ODFToolkit with the latest version of the simple-odf library is the answer for generating text documents.
You can find the the official page here :
Apache ODF Toolkit(Incubating) - Simple API
Here is a page to download version 0.8.1 (the latest version of Simple API) as I didn't find the latest version at the official page, only version 0.6.1
And here you can find Apache ODF Toolkit (incubating) cookbook
You can try using JasperReports to generate your reports, then export it to ODS. The nice thing about this approach is
you get broad support for all JasperReports output formats, e.g. PDF, XLS, HTML, etc.
Jasper Studio makes it easy to design your reports
The ODF Toolkit project (code hosted at Github) is the new home of the former ODFDOM project, which was until 2018-11-27 a Apache Incubator project.
the solution may be JODF Java API Independentsoft company.
For example, if we want to create an Open Document file using this Java API we could do the following:
import com.independentsoft.office.odf.Paragraph;
import com.independentsoft.office.odf.TextDocument;
public class Example {
public static void main(String[] args)
{
try
{
TextDocument doc = new TextDocument();
Paragraph p1 = new Paragraph();
p1.add("Hello World");
doc.getBody().add(p1);
doc.save("c:\\test\\output.odt", true);
}
catch (Exception e)
{
System.out.println(e.getMessage());
e.printStackTrace();
}
}
}
There are also .NET solutions for this API.

Implementating Showdown.js markdown parser on the server side for ColdFusion

This is a "fact finding" question to see how difficult it would be to create a ColdFusion UDF to parse markdown on the server using the showdown.js parser. There is already a java implementation that utilizes showdown.js (see code at the end of this post) and I want to see how to go about implementing it for ColdFusion. I have no experience in Java and I would not particularly call myself "a programmer," but I don't want this to stop me from trying.
Summary
I would like to run Shadown.js server-side in order to convert markdown to HTML.
Why?
Saving two versions of a user entry, one in markdown format and another in HTML, allows us to display the raw markdown version to the end user in case they wanted to edit their entry.
Why not use a server-side parser?
For two reasons:
As of now there are no ColdFusion markdown parsers for this specific purpose
Using Showdown.js on the client-side, and then a different parser on the server-side will result in inconsistent markup between the preview displayed to the client and the version stored in the database. Given that markdown is loosely defined, most parser implementations will have subtle differences.
There is a very good blog entry that discusses the issue.
Why not do all the parsing on the client-side and post both versions?
This does not strike me as a secure solution. I also think users would potentially be able to post markdown with HTML that does not match.
Are there any existing implementations?
There is one implementation called CFShowdown, but it's not for this specific purpose. Rather, it's for handling output on a page. The comments section of the aforementioned blog features a pure Java implementation written by a user called David:
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine jsEngine = manager.getEngineByName("js");
try
{
jsEngine.eval(new InputStreamReader(getClass().getResourceAsStream("showdown.js")));
showdownConverter = jsEngine.eval("new Showdown.converter()");
}
catch (Exception e)
{
log.error("could not create showdown converter", e);
}
try
{
return ((Invocable) jsEngine).invokeMethod(
showdownConverter,
"makeHtml",
markdownString
) + "";
}
catch (Exception e)
{
log.error("error while converting markdown to html", e);
return "[could not convert input]";
}
Objective
Create a java class that would allow us to use this implementation with a ColdFusion UDF or a custom tag inside a component, something along the lines of <cfset html = getMarkdown(string)>
Since I have no experience with Java, I want to get some advice and input from users on where and how to start going about this task. I created a
Have files showdown.js and a file markdown.txt (example below) in the same directory.
showdown.cfm
<cfscript>
manager = createObject("java", "javax.script.ScriptEngineManager").init();
jsEngine = manager.getEngineByName("js");
showdownJS = fileRead('#getDirectoryFromPath(getCurrentTemplatePath())#/showdown.js');
jsEngine.eval(showdownJS);
showdownConverter = jsEngine.eval("new Showdown.converter()");
markdownString = fileRead("#getDirectoryFromPath(getCurrentTemplatePath())#/markdown.txt");
args = [markdownString];
result = jsEngine.invokeMethod(
showdownConverter,
"makeHtml",
args
) & "";
</cfscript>
markdown.txt
Showdown Demo
-------------
You can try out Showdown on this page:
- Type some [Markdown] text on the left side.
- See the corresponding HTML on the right.
For a Markdown cheat-sheet, switch the right-hand window from *Preview* to *Syntax Guide*.
Showdown is a JavaScript port of the original Perl version of Markdown. You can get the full [source code] by clicking on the version number at the bottom of the page.
Also check out [WMD, the Wysiwym Markdown Editor][wmd]. It'll be open source soon; email me at the address below if you'd like to help me test the standalone version.
**Start with a [blank page] or edit this document in the left window.**
[Markdown]: http://daringfireball.net/projects/markdown/
[source code]: http://attacklab.net/showdown/showdown-v0.9.zip
[wmd]: http://wmd-editor.com/
[blank page]: ?blank=1 "Clear all text"
Update
Here's a version that takes Adam Presley's work in Java and does it all in a CFC. Note I took that little bit of magic he added at the end of showdown.js and put it into a CFC function whose return value is appended (i.e. showdownAdapterJS()).
CFC
<cfcomponent output="false" accessors="true">
<cffunction name="init" output="false" access="public" returntype="Showdown" hint="Constructor">
<cfset variables.manager = createObject("java", "javax.script.ScriptEngineManager").init()>
<cfset variables.engine = manager.getEngineByName("javascript")>
<cfreturn this/>
</cffunction>
<cffunction name="toHTML" output="false" access="public" returntype="any" hint="">
<cfargument name="markdownText" type="string" required="true"/>
<cfset var local = structNew()/>
<cfset var bindings = variables.engine.createBindings()>
<cfset var result = "">
<cftry>
<cfset bindings.put("markdownText", arguments.markdownText)>
<cfset variables.engine.setBindings(bindings, createObject("java", "javax.script.ScriptContext").ENGINE_SCOPE)>
<cfset var showdownJS = fileRead('#getDirectoryFromPath(getCurrentTemplatePath())#/showdown.js')>
<cfset showdownJS &= showdownAdapterJS()>
<cfset result = engine.eval(showdownJS)>
<cfcatch type="javax.script.ScriptException">
<cfset result = "The script had an error: " & cfcatch.Message>
</cfcatch>
</cftry>
<cfreturn result>
</cffunction>
<cffunction name="showdownAdapterJS" output="false" access="private" returntype="string" hint="">
<cfset var local = structNew()/>
<cfsavecontent variable="local.javascript">
<cfoutput>#chr(13)##chr(10)#var __converter = new Showdown.converter();
__converter.makeHtml(markdownText);</cfoutput>
</cfsavecontent>
<cfreturn local.javascript>
</cffunction>
</cfcomponent>
Usage
<cfset showdown = createObject("component", "Showdown").init()>
<cfset markdownString = fileRead("#getDirectoryFromPath(getCurrentTemplatePath())#/markdown.txt")>
<cfoutput>#showdown.toHTML(markdownString)#</cfoutput>
You can run server-side javascript in CF by using CFGroovy - which basically allows you to run any JSR-223 scripting language inline with CFML.
Ben Nadel has an example of running server-side javascript using CFGroovy and Rhino
The example has everything you need - assuming you have the javascript code already put together.
Actually, I've already wrapped up Showdown in a Java library that can be used in ColdFusion. The example I provide, in what I admit is poor documentation, uses a custom tag, but you can use the Java component just as easily like so.
<cfset obj = createObject('java', 'com.adampresley.cfshowdown.Showdown').init() />
<cfset parsedText = obj.toHTML(trim(someMarkdownContent)) />
Perhaps that helps? Either way, long live Markdown! :)
Given that Markdown is not a regular language, and a majority of implementations are a series of regular expressions, there are bound to be differences between them, as you noted. There is almost no avoiding it.
If your objective is just to:
Provide a client-side markdown editor with live-preview (like the Stack Overflow question/answer editor), and
Store an identically-processed copy of the generated html for end-user display
Then I see only two real options:
Do all markdown processing server-side, and accomplish your preview using AJAX to submit the markdown and get the updated preview html (using the same library that you'll ultimately use to generate the stored html), or
Do all markdown processing client-side, and submit both the raw markdown and the generated HTML as parts of your content composition form and store both; so that you can display the original markdown for editing purposes and the generated HTML for display purposes.
Personally I would go with option 2.

Categories