├── .gitattributes ├── .gitignore ├── README.md ├── bin └── jsml ├── doc ├── LANG.md └── TODO.md ├── examples ├── demo.jsml ├── demo_file.jsml ├── demo_js.jsml ├── demo_short.jsml ├── demo_short_single_child.jsml └── lorem.txt ├── index.js ├── jsml.png ├── jsml.svg ├── lib ├── common.js └── optparse.js └── package.json /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | 7 | # Standard to msysgit 8 | *.doc diff=astextplain 9 | *.DOC diff=astextplain 10 | *.docx diff=astextplain 11 | *.DOCX diff=astextplain 12 | *.dot diff=astextplain 13 | *.DOT diff=astextplain 14 | *.pdf diff=astextplain 15 | *.PDF diff=astextplain 16 | *.rtf diff=astextplain 17 | *.RTF diff=astextplain 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Test JSML Folders 2 | 3 | ignore 4 | 5 | # node stuff 6 | 7 | node_modules 8 | 9 | # JSML tarball 10 | 11 | node-jsml-*.tgz 12 | 13 | # Windows image file caches 14 | Thumbs.db 15 | ehthumbs.db 16 | 17 | # Folder config file 18 | Desktop.ini 19 | 20 | # Recycle Bin used on file shares 21 | $RECYCLE.BIN/ 22 | 23 | # Windows Installer files 24 | *.cab 25 | *.msi 26 | *.msm 27 | *.msp 28 | 29 | # Windows shortcuts 30 | *.lnk 31 | 32 | # ========================= 33 | # Operating System Files 34 | # ========================= 35 | 36 | # OSX 37 | # ========================= 38 | 39 | .DS_Store 40 | .AppleDouble 41 | .LSOverride 42 | 43 | # Thumbnails 44 | ._* 45 | 46 | # Files that might appear on external disk 47 | .Spotlight-V100 48 | .Trashes 49 | 50 | # Directories potentially created on remote AFP share 51 | .AppleDB 52 | .AppleDesktop 53 | Network Trash Folder 54 | Temporary Items 55 | .apdisk 56 | 57 | # Compiled html 58 | *.html 59 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ###  2 | 3 | JSML (JSON Markup Language) is an investigation into the effectiveness of creating webpages in JSON. 4 | 5 | [](https://www.npmjs.com/package/node-jsml) 6 | [](https://www.npmjs.com/package/node-jsml) 7 | [](https://www.npmjs.com/package/node-jsml) 8 | 9 | ## Installation 10 | 11 | As JSML is on npm, you can install it easily with the command `npm install -g node-jsml`. 12 | 13 | On some systems, superuser access might be required. 14 | 15 | ## Use 16 | 17 | ### Through the Terminal 18 | 19 | To compile a JSML (a `.jsml` file) into an HTML file, run `jsml [filename]`. 20 | 21 | If you want to output to stdout, use `-c` in front of the file, and `-O` to directly specify the output path. 22 | 23 | ### Through Your Program 24 | 25 | To include JSML, use `jsml = require('node-jsml');` 26 | 27 | To compile a JSML file to HTML, use the following code 28 | 29 | ```JavaScript 30 | 31 | var jsml = require('node-jsml'); 32 | 33 | myJSML = [ 34 | { 35 | t:"p", 36 | T:"this works!" 37 | } 38 | ]; 39 | 40 | output = jsml.parse(myJSML); 41 | ``` 42 | 43 | `parse` has an optional parameter, `eval`. If `true`, then `myJSML` (f.e. in this example) will be run though [eval](http://www.w3schools.com/jsref/jsref_eval.asp). This is helpful when reading `.jsml` files which don't have `"` around every tag. 44 | 45 | ## Syntax and Language 46 | 47 | All the rules and tricks can be found in [`LANG.md`](doc/LANG.md) 48 | 49 | ## Inspiration 50 | 51 | When using APIs, one lets out a groan when if they see the API outputs data in XML format. JSON is expected, nowadays, when using an API. Nobody has this problem when writing HTML, however. Perhaps this is because writing a webpage in XML format is better than writing it in JSON. But, until now, there has been no way to tell. And thus, JSML was born. 52 | 53 | This isn't meant to overtake web design as we know it. It's more of a proof of concept. However, JavaScript code can actually be executed within the JSML file, which is kind of neat. One could make counters, dynamic variables, etc. The possibilities are unexplored and endless! 54 | 55 | ## Easy Coding 56 | 57 | There is a Sublime Text 3 plugin I created which makes writing JSML code a lot faster. You can see it [here](https://github.com/mjkaufer/JSML-Formatter). You can find it in sublime's package control by searching for `JSML Formatter`. 58 | 59 | ## Contributing 60 | 61 | If you have something very major to contribute, submit an issue first. Otherwise, for any small fixes, feel free to send a pull request. 62 | 63 | If you'd like to find issues to work on, check [`TODO.md`](doc/TODO.md). 64 | 65 | **Note:** The logo (svg source file) uses the font [monofur](http://www.dafont.com/monofur.font). 66 | -------------------------------------------------------------------------------- /bin/jsml: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | var fs = require('fs'), 4 | optparse = require('../lib/optparse'), 5 | pac = require('../package.json'), 6 | common = require('../lib/common.js'); 7 | 8 | var parser = new optparse.OptionParser([ 9 | ['-h', '--help', 'Shows help screen'], 10 | ['-O', '--output FILE', 'File output, no argument is stdout'], 11 | ['-c', '--compile FILE', 'compiles .json to .html'] 12 | ]); 13 | 14 | var input, output; 15 | 16 | function showHelp(){ 17 | console.log('Usage: jsml -c FILE [-O FILE]\n'+ 18 | 'JSON Markup Language, or jsml is an investigation into the effectiveness of creating webpages in JSON.\n\n'+ 19 | 'Command Line Arguments:\n'+ 20 | ' -h --help This page\n'+ 21 | ' -O --output HTML file\n'+ 22 | ' -c --compile JSML file\n\n'+ 23 | 'version '+pac.version+', (c) 2015\n'+ 24 | 'Source: '+pac.homepage 25 | ); 26 | } 27 | 28 | if(process.argv.length == 2)//not enough arguments 29 | showHelp(); 30 | 31 | parser.on('help', function() { 32 | showHelp(); 33 | }); 34 | 35 | parser.on('output', function(opt, val) { 36 | output = val; 37 | }); 38 | 39 | parser.on('compile', function(opt, val) { 40 | if (!opt) { // No input file has been specified. 41 | console.error("Specify compile file with option '-C'."); 42 | process.exit(1); 43 | } 44 | 45 | outputJSML(val); 46 | 47 | }); 48 | 49 | parser.on(2, function(val){ //default input 50 | 51 | input = val; 52 | 53 | output = input.replace(/\.jsml$/g, "") + ".html" 54 | if(process.argv.length <= 3) 55 | outputJSML(input); 56 | }); 57 | 58 | parser.on(3, function(val){ 59 | output = val; 60 | outputJSML(input); 61 | }); 62 | 63 | parser.on(function(opt) { 64 | console.log('Error - see `jsml --help`'); 65 | }); 66 | 67 | parser.parse(process.argv); 68 | 69 | function outputJSML(infile){ 70 | fs.readFile(infile || process.stdin, 'utf8', function(err, json) { 71 | if (err) { 72 | console.error(err); 73 | process.exit(1); 74 | } 75 | 76 | var jsml = common.parse(json, true); 77 | 78 | if (!output) console.log(jsml); 79 | else fs.writeFile(output, jsml, function(err) { 80 | if (err) console.error(err); 81 | else 82 | console.log("Done compiling " + input + " - saved as " + output); 83 | }); 84 | }); 85 | } 86 | -------------------------------------------------------------------------------- /doc/LANG.md: -------------------------------------------------------------------------------- 1 | ## Syntax and Language 2 | 3 | Each item is either a JSON object that has a `children` object which defines children, attributes and/or various kinds of content or is simply a string which defines the tag's content. 4 | 5 | ### Simple Example 6 | 7 | A JSML file that would look like this: 8 | 9 | ```JavaScript 10 | [ 11 | { 12 | tag: "p", 13 | text: "JSML is cool" 14 | } 15 | ] 16 | ``` 17 | 18 | would compile to: 19 | 20 | ```HTML 21 |
JSML is cool
22 | ``` 23 | 24 | The objects `tag` attribute was used to set the tag and the value of `text` was inserted into it. 25 | 26 | ### Nested Elements 27 | 28 | Nested elements are either attribute definitions or child(-ren) specifications. Here an example: 29 | 30 | ```JavaScript 31 | [ 32 | { 33 | tag: "p", 34 | attributes:{ 35 | "id": "info" 36 | }, 37 | text: "Hello" 38 | }, 39 | { 40 | tag: "p", 41 | children: [ 42 | { 43 | tag: "b", 44 | text: "World" 45 | } 46 | ] 47 | } 48 | ] 49 | ``` 50 | 51 | which compiles to: 52 | 53 | ```HTML 54 |Hello
55 |56 | World 57 |
58 | ``` 59 | 60 | It's as simple as it seems, the object from `attributes` is written into the tag itself and the `children` array is loaded into it. 61 | 62 | **None:** If `children` and other content is specified, `children` will be added after the content. 63 | 64 | **Example file:** [Children and Attributes](/examples/demo.jsml) 65 | 66 | ### Dynamic JSML and Evaluation 67 | 68 | ```JavaScript 69 | var name = "mjkaufer"; 70 | 71 | [ 72 | { 73 | tag: "h1", 74 | text: name + " - it works!!" 75 | } 76 | ] 77 | ``` 78 | 79 | Basically, any JavaScript can be run above the first `[` tag, or before the JSML array is initialized. Any JavaScript which *does not produce an output* can be run anywhere. For instance, `var name = "mjkaufer"` is ok to use wherever, but something like `console.log("Matthew")` is only ok before the JSML array is initialized. 80 | 81 | **Example file:** [Dynamic JSML](/examples/demo_js.jsml) 82 | 83 | ### Single Child 84 | 85 | If you have a single child, you don't need to bother creating an array for `c` or `children` - you can populate it with a single element instead. 86 | 87 | ```JavaScript 88 | [ 89 | { 90 | tag:"div", 91 | children:{ 92 | tag:"p", 93 | text:"Single child!" 94 | } 95 | } 96 | ] 97 | ``` 98 | 99 | ### Simple Text 100 | 101 | ```HTML 102 | This is nice 103 | ``` 104 | 105 | ```JavaScript 106 | [ 107 | "This is nice" 108 | ] 109 | ``` 110 | 111 | If you use a string instead of an object within an array, it will be directly inserted into the parent. 112 | 113 | ### Short names 114 | 115 | It is much too much work to type `attributes` & co. every time. The next trick may help: 116 | 117 | ```JavaScript 118 | [ 119 | { 120 | t: "ul", 121 | c: [ 122 | { 123 | t: "li", 124 | T: "This is one paragraph." 125 | } 126 | ] 127 | }, 128 | { 129 | t: "a", 130 | a: [ 131 | "href": "google.com" 132 | ], 133 | T: "And this is a link." 134 | } 135 | ] 136 | ``` 137 | 138 | will turn into 139 | 140 | ```HTML 141 |