Skip to content

Commit

Permalink
Implemented #2
Browse files Browse the repository at this point in the history
  • Loading branch information
AshurAxelR committed Apr 10, 2019
1 parent b0fdf76 commit 93526dc
Show file tree
Hide file tree
Showing 5 changed files with 221 additions and 78 deletions.
27 changes: 19 additions & 8 deletions mdtool/readme.md
Original file line number Diff line number Diff line change
@@ -1,23 +1,34 @@
# MDTool
# MD Tool

**MDTool** is a JParsedown-based command line tool for converting Markdown files into HTML pages.
**MD** tool is a JParsedown-based command line tool for converting Markdown files into HTML pages.

## Download

**JAR file:** [mdtool.jar](https://github.com/ashurrafiev/JParsedown/releases/download/1.0.1/mdtool.jar) (53.8KB)
**JAR file:** [md.jar](https://github.com/ashurrafiev/JParsedown/releases/download/1.0.2/md.jar) (55.5KB)

**Templates and styles** [templates.zip](https://github.com/ashurrafiev/JParsedown/releases/download/1.0.2/templates.zip) (19.9KB)


## Usage

```
java -jar mdtool.jar inputfile [-o outputfile] [options]
java -jar md.jar sourcefile [-o outputfile] [options]
```

Recursive mode:

```
java -jar md.jar -r sourcedir [-o outputdir] [options]
```

| option | description |
| :--- | :--- |
| **-o** filename | Optional: output file name. By default, the output file name is derived from input file name by replacing the extension with `html`. |
| **-t** filename | Optional: HTML template file name. By default, the output will contain only the body of HTML. |
| **-s** filename | Optional: CSS stylesheet file name. By default, no stylesheet is linked or embedded. |
| **-o** path | Optional: output path or filename. If **-o** is directory or not specified, the output file name is derived from source file name by replacing the extension with `html` or template's extension. |
| **-t** filename | Optional: HTML template file name. If not specified, the output will contain only the body of HTML. |
| **-s** filename | Optional: CSS stylesheet file name. If not specified, no stylesheet is linked or embedded. |
| **-e** | Optional: embed stylesheet within a `<style>` tag. By default, the stylesheet is linked using `<link>` tag. When linking CSS, the **-s** parameter is used in `href` as is without any path conversion. |
| **-r** | Optional: recursive mode. In recursive mode, all MD files in the source directory and its subdirectories are processed automatically. |
| **-m** | Optional: check for modification. The Markdown is processed only if there is no output file or the output file is older than the source, stylesheet, or template. |


## HTML Template Format
Expand Down Expand Up @@ -53,7 +64,7 @@ It is also recommended to use `<meta charset="UTF-8">` as the Markdown processin

## Built-in Templates and Styles

MDTool comes with a set of templates and styles located in `templates` folder.
MD tool comes with a set of templates and styles located in `templates` folder.

### Templates

Expand Down
251 changes: 191 additions & 60 deletions mdtool/src/com/xrbpowered/jparsedown/mdtool/MDTool.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,22 +13,32 @@

public class MDTool {

public static String loadFile(String path) {
public static String style;
public static String template;
public static HashMap<String, String> vars = new HashMap<>();

public static boolean errors;

public static long styleTime;
public static long templateTime;
public static String templateExt;

public static String loadFile(File file) {
try {
FileInputStream f = new FileInputStream(path);
byte[] buf = new byte[f.available()];
f.read(buf);
f.close();
FileInputStream in = new FileInputStream(file);
byte[] buf = new byte[in.available()];
in.read(buf);
in.close();
return new String(buf, StandardCharsets.UTF_8);
}
catch(IOException e) {
return null;
}
}

public static boolean saveFile(String path, String text) {
public static boolean saveFile(File file, String text) {
try {
PrintStream out = new PrintStream(new File(path), "UTF-8");
PrintStream out = new PrintStream(file, "UTF-8");
out.println(text);
out.close();
return true;
Expand Down Expand Up @@ -58,8 +68,110 @@ public static String processTemplate(String template, HashMap<String, String> va
sb.append(template.substring(end));
return sb.toString();
}

public static void processFile(File src, File out, boolean checkTime) {
long outTime = out.exists() ? out.lastModified() : -1L;
if(checkTime && outTime>=0L &&
styleTime>=0L && styleTime<outTime &&
templateTime>=0L && templateTime<outTime &&
src.exists() && src.lastModified()<outTime) {
System.out.println(out.toString()+" is up to date");
return;
}

String source = loadFile(src);
if(source==null) {
System.err.println("*Error* Cannot load "+src.toString());
errors = true;
return;
}

JParsedown parsedown = new JParsedown();
String body = parsedown.text(source);
vars.put("body", body);
vars.put("title", parsedown.title);
String output;
if(template!=null)
output = processTemplate(template, vars);
else
output = body;

if(!saveFile(out, output)) {
System.err.println("*Error* Cannot save "+out.toString());
errors = true;
}
else {
System.out.println("Processed "+out.toString());
}
}

public static void processFile(File src, File outDir, boolean checkTime, boolean checkExtension) {
if(outDir==null) {
outDir = src.getParentFile();
if(outDir==null)
outDir = new File(".");
}
String filename = src.getName();
int dotIndex = filename.lastIndexOf('.');
String name, ext;
if(dotIndex>0 && dotIndex<filename.length()-1) {
name = filename.substring(0, dotIndex);
ext = filename.substring(dotIndex);
}
else {
name = filename;
ext = "";
}

if(!checkExtension || ext.equalsIgnoreCase(".md")) {
processFile(src, new File(outDir, name+templateExt), checkTime);
}
}

public static void scanFolder(File srcDir, File outDir, boolean checkTime) {
if(!outDir.exists()) {
System.out.println("Creating directory "+outDir.toString());
outDir.mkdirs();
}
File[] files = srcDir.listFiles();
for(File f : files) {
if(f.isDirectory()) {
if(!f.getName().startsWith("."))
scanFolder(f, new File(outDir, f.getName()), checkTime);
}
else {
processFile(f, outDir, checkTime, true);
}
}
}

public static void benchmark(String sourcePath, int n) {
String source = loadFile(new File(sourcePath));
if(source==null) {
System.err.println("*Error* Cannot load source file.");
System.exit(1);
}

long tstart = System.currentTimeMillis();
for(int i=0; i<n; i++) {
JParsedown parsedown = new JParsedown();
parsedown.text(source);
}
long time = System.currentTimeMillis() - tstart;
System.out.printf("File %s\n\tParsed %d times in %d ms (%.1fms per iteration)\n",
sourcePath, n, time, (double)time/(double)n);
}

public static void help() {
System.out.println("Usage:\n"
+ "java -jar md.jar sourcefile [-o outputpath] [options]\n\n"
+ "Recursive mode:\n"
+ "java -jar md.jar -r sourcepath [-o outputpath] [options]\n");
}

public static void main(String[] args) {
boolean recursiveMode = false;
boolean checkTime = false;
String sourcePath = null;
String outputPath = null;
String templatePath = null;
Expand All @@ -71,6 +183,12 @@ public static void main(String[] args) {
for(int i=0; i<args.length; i++) {
if(args[i].charAt(0)=='-') {
switch(args[i]) {
case "-r":
recursiveMode = true;
break;
case "-m":
checkTime = true;
break;
case "-o":
outputPath = args[++i];
break;
Expand All @@ -96,77 +214,90 @@ public static void main(String[] args) {
}
}
catch(Exception e) {
System.err.println("Bad command line parameters.");
System.err.println("*Error* Bad command line parameters.");
help();
System.exit(1);
}
if(sourcePath==null) {
System.err.println("No source file");
System.err.println("*Error* No source file or path");
help();
System.exit(1);
}

String source = loadFile(sourcePath);
if(source==null) {
System.err.println("Cannot load source file.");
System.exit(1);
}

if(benchmark>0) {
long tstart = System.currentTimeMillis();
for(int i=0; i<benchmark; i++) {
JParsedown parsedown = new JParsedown();
parsedown.text(source);
}
long time = System.currentTimeMillis() - tstart;
System.out.printf("Parsed %d times in %d ms (%.1fms per iteration)\n",
benchmark, time, (double)time/(double)benchmark);
benchmark(sourcePath, benchmark);
System.exit(0);
}

if(outputPath==null) {
int ext = sourcePath.lastIndexOf('.');
outputPath = ext<0 ? sourcePath : sourcePath.substring(0, ext);
outputPath += ".html";
style = null;
styleTime = -1L;
if(stylePath!=null) {
if(embedStyle) {
File cssFile = new File(stylePath);
String css = loadFile(cssFile);
if(css==null) {
System.err.println("*Error* Cannot load stylesheet.");
System.exit(1);
}
else {
style = "<style><!--\n"+css+"\n--></style>";
styleTime = cssFile.lastModified();
}
}
else
style = "<link rel=\"stylesheet\" href=\""+stylePath+"\" />";
}

JParsedown parsedown = new JParsedown();
String body = parsedown.text(source);
vars.put("style", style);

String output = body;
template = null;
templateTime = -1L;
templateExt = ".html";
if(templatePath!=null) {
HashMap<String, String> vars = new HashMap<>();

vars.put("body", body);
vars.put("title", parsedown.title);

String style = null;
if(stylePath!=null) {
if(embedStyle) {
String css = loadFile(stylePath);
if(css==null)
System.err.println("Cannot load stylesheet.");
else
style = "<style><!--\n"+css+"\n--></style>";
}
else
style = "<link rel=\"stylesheet\" href=\""+stylePath+"\" />";
}
vars.put("style", style);

String template = loadFile(templatePath);
File templateFile = new File(templatePath);
template = loadFile(templateFile);
if(template==null) {
System.err.println("Cannot load template file.");
System.err.println("*Error* Cannot load template file.");
System.exit(1);
}

output = processTemplate(template, vars);
else {
templateTime = templateFile.lastModified();
}
}

if(!saveFile(outputPath, output)) {
System.err.println("Cannot save output file.");

errors = false;
if(recursiveMode) {
File srcDir = new File(sourcePath);
if(!srcDir.isDirectory()) {
System.err.println("*Error* Source path is not a directory");
System.exit(1);
}
File outDir = new File(sourcePath);
if(outputPath!=null) {
outDir = new File(outputPath);
if(!outDir.isDirectory()) {
System.err.println("*Error* Output path is not a directory");
System.exit(1);
}
}
scanFolder(srcDir, outDir, checkTime);
}
else {
if(outputPath!=null) {
File outDir = new File(outputPath);
if(!outDir.isDirectory())
processFile(new File(sourcePath), outDir, checkTime);
else
processFile(new File(sourcePath), outDir, checkTime, false);
}
else
processFile(new File(sourcePath), null, checkTime, false);
}

if(errors) {
System.out.println("Done with errors");
System.exit(1);
}

System.out.println("Done");
else
System.out.println("Done");
}

}
6 changes: 3 additions & 3 deletions mdtool/templates/md_ghlike.css
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,11 @@ div.page {
padding: 48px;
box-sizing: border-box;
}
@media (min-width:900px) {
@media (min-width:1000px) {
div.body {
width: 880px;
width: 980px;
left: 50%;
margin-left: -440px;
margin-left: -490px;
}
div.page {
border: 1px solid #d0d5da;
Expand Down
6 changes: 3 additions & 3 deletions mdtool/templates/preview/cheatsheet_ghlike.html
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,11 @@
padding: 48px;
box-sizing: border-box;
}
@media (min-width:900px) {
@media (min-width:1000px) {
div.body {
width: 880px;
width: 980px;
left: 50%;
margin-left: -440px;
margin-left: -490px;
}
div.page {
border: 1px solid #d0d5da;
Expand Down
Loading

0 comments on commit 93526dc

Please sign in to comment.