diff --git a/Source/README.md b/Source/README.md
index ebff050..bb816e7 100644
--- a/Source/README.md
+++ b/Source/README.md
@@ -1,22 +1,22 @@
# HJSON [![Badge License]][License]
-*A parser / stringifier for **[HJSON]**.*
+A parser / stringifier for **[HJSON]**.
## Import
-```JavaScript
+```js
import HJson from 'https://deno.land/x/hjson/mod.ts'
```
-## Parsing
+## Parse
-```JavaScript
+```js
import { parse } from 'https://deno.land/x/hjson/mod.ts'
const { log } = console;
@@ -48,9 +48,38 @@ log(parse(hjson));
-## Stringification
+## Stringify
-**Work In Progress**
+```js
+import { stringify } from 'https://deno.land/x/hjson/mod.ts'
+
+const { log } = console;
+
+const object = {
+ some : 3 ,
+ variables : [ 'with' , 'a' , 'lot' ] ,
+ inside : { them : 9 }
+}
+
+log(stringify(hjson));
+
+
+/*
+ * {
+ * some : 3
+ *
+ * variables : [
+ * with
+ * a
+ * lot
+ * ]
+ *
+ * inside : {
+ * them : 9
+ * }
+ * }
+ */
+```
diff --git a/Source/Stringify/Encode.js b/Source/Stringify/Encode.js
new file mode 100644
index 0000000..770ad78
--- /dev/null
+++ b/Source/Stringify/Encode.js
@@ -0,0 +1,228 @@
+
+
+export default function stringify(object,options = {}){
+
+ options.style ??= 'modern';
+
+ if(options.style !== 'modern')
+ throw 'Unsupported style';
+
+ const base = modern(object);
+
+ const pretty = base
+ .replace(/\[\s+\{/g,'[{')
+ .replace(/\}\s+\]/g,'}]')
+ .replace(/\}\s*,\s*\{/g,'},{');
+ // .replace(//g,`\n$1:\n\n'''`);
+ // .replace(/\[\{\s*/g,'[{\n\n');
+
+ return [... indent(pretty) ].join('\n');
+}
+
+function * indent(pretty){
+
+ const lines = pretty.split('\n');
+
+ let level = 0;
+ let padding = ' ';
+ let open = false;
+
+
+ for(const line of lines){
+
+ const padded = () =>
+ padding.repeat(Math.max(level,0)) + line;
+
+ const trimmed = line.trim();
+
+ if(trimmed.length < 1){
+ yield padded();
+ continue;
+ }
+
+ if(trimmed.startsWith(`'''`)){
+
+ if(!open)
+ level++
+
+ yield padded();
+
+ if(open)
+ level--;
+
+ open = !open;
+ continue;
+ }
+
+ if(
+ trimmed.startsWith('{') ||
+ trimmed.endsWith('{') ||
+ trimmed.endsWith('[')
+ ){
+ yield padded();
+ level++;
+ continue;
+ }
+
+ if(
+ trimmed.startsWith('}') ||
+ trimmed.endsWith('}') ||
+ trimmed.endsWith(']')
+ ){
+ level--;
+ yield padded();
+ continue;
+ }
+
+ yield padded();
+ }
+}
+
+
+function modern(object){
+
+ let lines = toObject(object);
+
+ return lines.join('\n');
+}
+
+function toItem(item){
+
+ switch(typeof item){
+ case 'number' :
+ return [ `${ item }` ];
+ case 'boolean' :
+ return [ (item) ? 'true' : 'false' ];
+ case 'string' :
+
+ if(item.includes('\n'))
+ return [ `'''` , item , `'''` ];
+
+ if(
+ item.startsWith('#') ||
+ /[,:\[\]\{\}]/g.test(item)
+ ) return [ `'${ item }'`];
+
+ return [ `${ item }` ];
+ case 'array' :
+ return toArray(item);
+ case 'object':
+ return toObject(item);
+ }
+}
+//
+// function indent(string){
+// return ' ' + string;
+// }
+
+function toArray(array){
+
+ const lines = [ '[' ];
+
+ for(const item of array)
+ lines.push(...toItem(item));//.map(indent)
+
+ lines.push(']');
+
+ return (lines.length === 2)
+ ? [ '[]' ]
+ : lines ;
+}
+
+function toObject(object){
+
+ const longestFirst = ([ a ],[ b ]) => b.length - a.length;
+
+ const
+ entries = Object.entries(object) ,
+ simple = entries
+ .filter(([ _ , value ]) => [ 'string' , 'number' , 'boolean' ].includes(typeof value))
+ .sort(longestFirst)
+ .map(formString)
+ .flat();
+ // .map((string) => ' ' + string);
+
+ const complex = entries
+ .filter(([ _ , value ]) => [ 'object' , 'array' ].includes(typeof value))
+ .sort(longestFirst)
+ .map(toComplex)
+ .flat();
+ // .map((string) => ' ' + string);
+
+ complex.shift();
+
+ const lines = [ '{' ];
+
+ if(simple.length && complex.length)
+ lines.push('');
+
+ if(simple.length)
+ lines.push(...simple);
+
+ if(simple.length && complex.length)
+ lines.push('');
+
+ if(complex.length)
+ lines.push(...complex);
+
+ lines.push('}');
+
+ return (lines.length === 2)
+ ? [ '{}' ]
+ : lines ;
+}
+
+function toComplex([ key , value ]){
+
+ if(Array.isArray(value)){
+
+ const [ first , ...rest ] = toArray(value);
+
+ return [
+ '' ,
+ `${ toString(key) } : ${ first }`,
+ ...rest
+ ];
+ } else {
+ const [ first , ...rest ] = toObject(value);
+
+ return [
+ '' ,
+ `${ toString(key) } : ${ first }`,
+ ...rest
+ ];
+ }
+}
+
+
+function formString([ key , value ]){
+ switch(typeof value){
+ case 'number' :
+ return [ `${ toString(key) } : ${ value }` ];
+ case 'boolean' :
+ return [ `${ toString(key) } : ${ (value)
+ ? ['true']
+ : ['false'] }` ]
+ case 'string' :
+
+ if(value.includes('\n'))
+ return [ '' , `${ toString(key) }:` , '' , `'''` , value , `'''` ];
+
+ if(
+ value.startsWith('#') ||
+ /[,:\[\]\{\}]/g.test(value)
+ ) return [ `${ toString(key) } : '${ value }'`];
+
+ return [ `${ toString(key) } : ${ value }` ];
+ }
+}
+
+function toString(value){
+
+ if(
+ value.startsWith('#') ||
+ /[,:\[\]\{\}]/g.test(value)
+ ) return `'${ value }'`;
+
+ return value;
+}
\ No newline at end of file
diff --git a/Source/Stringify/mod.ts b/Source/Stringify/mod.ts
new file mode 100644
index 0000000..f12f1e8
--- /dev/null
+++ b/Source/Stringify/mod.ts
@@ -0,0 +1,7 @@
+
+import encode from './Encode.js'
+
+
+export default function stringify ( value : object , options : object ) : string {
+ return encode(value,options);
+}
\ No newline at end of file
diff --git a/Source/mod.ts b/Source/mod.ts
index 886e73d..d775451 100644
--- a/Source/mod.ts
+++ b/Source/mod.ts
@@ -1,9 +1,16 @@
import decode from './Decode.js'
-
export function parse ( text : string ) : object {
return decode(text);
}
-export default { parse }
\ No newline at end of file
+
+import encode from './Stringify/mod.ts'
+
+export function stringify ( value : object , options : object ) : string {
+ return encode(value,options);
+}
+
+
+export default { parse , stringify }
\ No newline at end of file
diff --git a/Tests/Stringify/Basic.test.js b/Tests/Stringify/Basic.test.js
new file mode 100644
index 0000000..ea38c67
--- /dev/null
+++ b/Tests/Stringify/Basic.test.js
@@ -0,0 +1,34 @@
+
+import { stringify } from '../../Source/mod.ts'
+
+const { log } = console;
+
+
+const object = {
+ difficulty : 3 ,
+ name : 'lab' ,
+ planet : 'pluto' ,
+ sector : 3 ,
+ captureWave : 10 ,
+
+ research : {
+
+ name : '\ntesting \'wow\'\n' ,
+
+ parent : 'nuclearFacility' ,
+
+ objectives: [{
+ preset : 'nuclearFacility' ,
+ type : 'SectorComplete'
+ }]
+ }
+}
+
+
+
+Deno.test('Basic Stringification Test',() => {
+
+ const hjson = stringify(object);
+
+ log(hjson);
+});
\ No newline at end of file