var fs = require('fs');
var Hackpad = require('hackpad');
var to_markdown = require('to-markdown');
var east_asian = require('east-asian-width');

// Load configuration files
var settings = {};
try {
    settings = JSON.parse(fs.readFileSync('config.json', 'utf8'));
} catch (e) {
    console.error('Config file (API key and secret) missing.');
    throw e;
}

var hackpad = new Hackpad(settings.client_id, settings.secret, { site: 'ntusa' });

function fetch(pad_id, callback) {
    hackpad.export(pad_id, '', 'html', function(e, data) {
        if (e) {
            console.log('Cannot acquire pad #' + pad_id);
        } else {
            callback(data);
        }
    });
}

function convert(data) {
    // Preprocess Hackpad soup
    var data = data.replace(/(<a href=[^>]+)\/>/gi, '$1>')
                   .replace(/<a href=[^>]+>\s*<\/a>/gi, '')
                   .replace(/<\/?u>/gi, '')
                   .replace(/(&nbsp;)+/g, ' ')

    // Convert to Markdown
    var text = to_markdown(data, {
        converters: [
            {
                filter: function(node) {
                    return node.nodeName == 'UL' && (/none/i.test(node.style.listStyle));
                },
                replacement: function(content, node) {
                    var buf = '';
                    for (var i = 0; i < node.children.length; i++)
                        buf += node.children[i].textContent + '\n'
                    return buf;
                }
            },
            {
                filter: function(node) {
                    return node.nodeName == 'UL' && (/comment/i.test(node.className));
                },
                replacement: function(content, node) {
                    return '// ' + node.textContent;
                }
            },
            {
                filter: function(node) {
                    return node.nodeName == 'A' && node.textContent == node.href;
                },
                replacement: function(content, node) {
                    return node.textContent;
                }
            }
        ]
    });

    // Postprocess
    text = text.replace(/    /g, '  ')
               .replace(/   /g, ' ')

    return text;
}

function wrap(text) {
    // Hard-wrap
    var buffer = '';
    var start_index = 0, length = 0;
    for (var i = 0; i < text.length; i++) {
        var char = text.codePointAt(i);
        var width = east_asian.cjk_char_width(char);
        if (char == 10) { // Line break
            buffer += text.substring(start_index, i+1);
            start_index = i + 1;
            length = 0;
        } else if ((length + width) >= 70) { // Manual wrapping
            buffer += text.substring(start_index, i+1) + '\n';
            start_index = i + 1;
            length = 0;
        } else {
            length += width;
        }
    }

    return buffer;
}

function export_file(pad_id) {
    fetch(pad_id, function(data) {
        if (data) {
            var text = convert(data);
            var wrapped_text = wrap(text);
            fs.writeFile('pads/' + pad_id + '.md', wrapped_text);
        }
    });
}

process.argv.slice(2).forEach(function(val, i, array) {
    if (/[A-Za-z0-9]{10,}/gi.test(val))
        export_file(val);
});

module.exports = {
    fetch: fetch,
    convert: convert,
    wrap: wrap,
    export_file: export_file
};

@@ -2294,24 +2294,64 @@
 length = 0;%0A
+    var indent = 0, has_indent = false;%0A
     for (var
@@ -2378,24 +2378,24 @@
 gth; i++) %7B%0A
-
         var 
@@ -2495,18 +2495,20 @@
 char == 
-1
 0
+x0a
 ) %7B // L
@@ -2517,16 +2517,48 @@
 e break%0A
+            // Start a new line%0A
         
@@ -2653,32 +2653,117 @@
      length = 0;
+%0A%0A            // Reset indent%0A            indent = 0;%0A            has_indent = false;
 %0A        %7D else 
@@ -2811,16 +2811,48 @@
 rapping%0A
+            // Start a new line%0A
         
@@ -2930,32 +2930,139 @@
 t_index = i + 1;
+%0A%0A            // Append indent%0A            if (indent %3E 0)%0A                buffer += ' '.repeat(indent + 2)
 %0A            len
@@ -3063,25 +3063,34 @@
    length = 
-0
+indent + 2
 ;%0A        %7D 
@@ -3088,32 +3088,218 @@
        %7D else %7B%0A
+            // Calculate indent%0A            if (!has_indent)%0A                if (char == 0x20)%0A                    indent++;%0A                else%0A                    has_indent = true;%0A%0A
             leng

Implement indent