<commit_before>'use strict';

var inquirer       = require('inquirer');
var glob           = require('glob');
var fs             = require('fs-extra-promise');
var path           = require('path');
var chalk          = require('chalk');
var shell          = require('shelljs');
var SuperString    = require('./helpers/super-string');
var config         = require('./config');
var Mustache       = require('./helpers/blogophon-mustache');
var MustacheQuoters= require('./helpers/blogophon-mustache-quoters');
var setup          = require('./setup')();
var Generator      = require('./generator');
var https          = require('https');
var blogophonDate  = require('./models/blogophon-date');

/**
 * Represents the Inquirer dialog with which to edit articles.
 * @constructor
 * @return {Object} [description]
 */
var BlogophonConsole = function() {
  var external     = {};
  var internal     = {};
  var files        = [];
  var choicesStr   = [
    'Create new article',
    'Edit existing article',
    'Rename article',
    'Delete article',
    'Generate & publish articles',
    config.notInitialized ? 'Setup' : 'Change settings',
    'Exit'
  ];

  Mustache.getTemplates();

  /**
   * Get all Markdown files as a simple array.
   * Array values can be simple strings, or objects containing
   * a name (to display in list),
   * a value (to save in the answers hash) and
   * a short (to display after selection) properties.
   * The choices array can also contain a Separator.
   * @return {Array} [description]
   */
  internal.makeChoices = function() {
    var choices = [];
    if (!config.notInitialized) {
      internal.makeFiles();
      choices.push(choicesStr[0]);
      if (files.length > 0) {
        choices.push(choicesStr[1], choicesStr[2], choicesStr[3], choicesStr[4]);
      }
      choices.push(new inquirer.Separator());
    }
    choices.push(choicesStr[5], new inquirer.Separator(), choicesStr[6]);
    return choices;
  };

/**
 * Get listing of all Markdown files which may be edited
 * @return {Array}   [description]
 */
  internal.makeFiles = function() {
    if (config.notInitialized) {
      files = [];
    } else {
      files = glob.sync(config.directories.data + "/**/*.{md,md~}").map(function(v) {
        var filename = v.replace(/^.+\/(.+?)$/, '$1');
        var fileStat = fs.lstatSync(v);
        return {
          name: fileStat.mtime.toLocaleString(config.locale.language || 'en')
            + "\t" + filename + "\t" +Math.ceil(fileStat.size/1000)+' kB',
          value: filename,
          short: filename
        };
      });
      if (files.length > 1) {
        files.push(new inquirer.Separator());
      }
    }
    return files;
  };

  /**
   * Returns the title to be used for generating a filename.
   * @param  {String} title  [description]
   * @param  {Object} config [description]
   * @param  {String} date   [description]
   * @return {String}        [description]
   */
  internal.titleForFilename = function(title, config, date) {
    date = date || new Date();
    if (config.postFileMode) {
      return config.postFileMode
        .replace(/Title/, title)
        .replace(/Date/, blogophonDate(date).format('yyyy-mm-dd'))
      ;
    }
    return title;
  };

  /**
   * Convert title to Markdown filename
   * @param  {String} title [description]
   * @return {String}       [description]
   */
  internal.filenameFromTitle = function(title) {
    return path.join(config.directories.data, internal.shortfilenameFromTitle(title));
  };

  /**
   * Remove stop words from filename and limit it to a sane length.
   * @param  {String} title [description]
   * @return {String}       [description]
   */
  internal.shortfilenameFromTitle = function(title) {
    return SuperString(title.trim().toLowerCase())
      .asciify()
      .replace(/(^|\-)([a-z]|de[rnms]|die(s|se|ser|ses|sen|sem)?|d[aoe]s|[msd]?ein(e|es|er|em|en)?|th(e|is|at|ese|ose)|my|[ea]l|l[ao]s?|[ia][nm]|o[nf]|ist?|[ua]nd)\-/g, '$1')
      .replace(/(^[\-]+|[\-]+$)/g, '')
      .replace(/([\-])[\-]+/g, '$1')
      .replace(/\-(md~?)$/, '.$1')
      .replace(/^(.{64}[^-]*).*?(\.md~?)?$/, '$1$2')
    ;
  };

  /**
   * Convert Markdown filename into corresponding directory name (e.g. for images)
   * @param  {String} filename [description]
   * @return {String}          [description]
   */
  internal.dirnameFromFilename = function(filename) {
    return filename.replace(/\.md~?$/, '');
  };

  /**
   * Get coordinates for address
   * @param  {String}   address  [description]
   * @param  {String}   language [description]
   * @param  {Function} callback [description]
   * @return {Object}            with `latitude, longitude`
   */
  internal.convertAddress = function(address, language, callback) {
    https.get({
      host: 'nominatim.openstreetmap.org',
      path: '/search?q='+encodeURIComponent(address)+'&format=json&accept-language='+encodeURIComponent(language || 'en')
    }, function(response) {
      var body = '';
      response.on('data', function(d) {
        body += d;
      });
      response.on('end', function() {
        var parsed = JSON.parse(body);
        callback(null, {
          latitude:  parsed[0] ? parsed[0].lat : null,
          longitude: parsed[0] ? parsed[0].lon : null
        });
      });
    });
  };


  /**
   * Display the setup dialog.
   * @return {[type]} [description]
   */
  external.setupDialog = function() {
    var themesAvailable= fs.readdirSync(config.directories.theme).filter(function(file) {
      return fs.statSync(path.join(config.directories.theme, file)).isDirectory();
    });
    var questions = [
      {
        type: 'input',
        name: 'name',
        message: 'The name of your site',
        default: config.name,
        validate: function(v) {
          return v ? true : 'Please supply at least a short name for your site.';
        }
      }, {
        type: 'list',
        name: 'theme',
        message: 'Choose theme',
        default: config.theme,
        choices: themesAvailable,
        when: function() {
          return (themesAvailable.length > 1);
        }
      }, {
        type: 'input',
        name: 'baseUrl',
        message: 'Domain of your site, starting with `http`',
        default: config.baseUrl,
        validate: function(v) {
          return v.match(/^http(s)?:\/\/\S+[^/]$/) ? true : 'Please supply a valid url, starting with `http://`, but without trailing `/`.';
        },
        filter: function(v) {
          return v.replace(/\/$/, '');
        }
      }, {
        type: 'input',
        name: 'basePath',
        message: 'Base URL path, usually just `/`',
        default: config.basePath,
        validate: function(v) {
          return v.match(/^[a-zA-Z0-9\.\/_-]*\/$/) ? true : 'Please supply a valid path with a trailing `/`.';
        },
        filter: function(v) {
          return v.replace(/^([^\/])/, '/$1').replace(/([^\/])$/, '$1/');
        }
      }, {
        type: 'input',
        name: 'description',
        message: 'A short description of your blog (optional)',
        default: config.description
      }, {
        type: 'input',
        name: 'locale.language',
        message: 'Standard language of your blog, like `en` for English',
        default: config.locale.language || config.language,
        validate: function(v) {
          return v.match(/^[a-zA-Z]+([\-_][a-zA-Z]+)?$/) ? true : 'Please supply a valid language code like `en`, `es`, `fr`, `de` or `pt-br`.';
        },
        filter: function(v) {
          return v.toLowerCase().replace(/_/, '-');
        }
      }, {
        type: 'list',
        name: 'postPathMode',
        message: 'Choose URL path pattern for your posts:',
        default: config.postPathMode,
        choices: [
          'Static path',
          'Year',
          'Year/Month',
          'Year/Month/Day'
        ]
      }, {
        type: 'list',
        name: 'postFileMode',
        message: 'Choose URL file pattern for your posts:',
        default: config.postFileMode || 'Title',
        choices: [
          'Title',
          'Title-Date',
          'Date-Title',
          'Date'
        ]
      }, {
        type: 'input',
        name: 'itemsPerPage',
        message: 'How many articles per page?',
        default: config.itemsPerPage,
        validate: function(v) {
          return Number(v)> 0 ? true : 'Please supply a positive number.';
        },
        filter: function(v) {
          return Number(v);
        }
      }, {
        type: 'input',
        name: 'defaultAuthor.name',
        message: 'Default name of author',
        default: config.defaultAuthor.name,
        validate: function(v) {
          return v ? true : 'Please supply at least a short name for your site.';
        }
      }, {
        type: 'input',
        name: 'defaultAuthor.email',
        message: 'Default email address of author',
        default: config.defaultAuthor.email,
        validate: function(v) {
          return (v.match(/^\S+@\S+$/)) ? true : 'Please supply a valid email address.';
        }
      }, {
        type: 'input',
        name: 'twitterAccount',
        message: 'Twitter account name (optional)',
        default: config.twitterAccount,
        validate: function(v) {
          return (!v || v.match(/^[a-zA-z0-9_-]+$/)) ? true : 'Please supply a Twitter account name or leave field empty.';
        }
      }, {
        type: 'input',
        name: 'deployCmd',
        message: 'CLI command to copy files to your live server (optional)',
        default: config.deployCmd
      }, {
        type: 'checkbox',
        name: 'useSpecialFeature',
        message: 'Do you want to use the following special features?',
        default: config.useSpecialFeature,
        choices: [
          "Multiple authors",
          "RSS",
          "ATOM",
          "JSON for Slack",
          "JSON-RSS",
          "Apple News",
          "Facebook Instant Articles",
          "Accelerated Mobile Pages",
          "Microsoft tiles",
          "ICS-Calendar",
          "GeoJSON",
          "KML",
          "AJAX"
        ]
      }
    ];

    inquirer.prompt(questions).then(
      function(answers) {
        answers.theme = config.theme ? config.theme : themesAvailable[0];
        answers.locale.direction = answers.locale.direction || config.locale.direction || (answers.language.match(/^(ar|zh|fa|he)/) ? 'rtl' : 'ltr');
        setup
          .buildBasicFiles(config, answers)
          .then(function() {
            console.log("Settings changed, please restart the Blogophon.");
            // TODO: reload config and return to main menu
            // external.init();
          })
        ;
      },
      function(err) {
        console.error(err);
        process.exit(1);
      }
    );
  };

  /**
   * This is the Inquirer dialog for creating a new articles. Will call external.init() on finish.
   * @return {[type]} [description]
   */
  external.createArticleDialog = function() {
    var defaults = {
      classes: 'Normal article',
      link: '',
      location: '',
      images: false,
      keywords: '',
      date: blogophonDate(new Date()).iso,
      author: config.defaultAuthor.name +' <'+config.defaultAuthor.email + '>',
      draft: false,
      edit: true,
      lead: '',
      mainText: 'Lorem ipsum…'
    };

    var questions    = [
      {
        type: 'input',
        name: 'title',
        message: 'Title',
        validate: function(v) {
          if (v.trim().length <= 2) {
            return 'This title is way too short.';
          }
          var filename = internal.filenameFromTitle(v);
          if (fs.existsSync(filename)) {
            return ("File " + filename + ' already exists');
          }
          return true;
        },
        filter: function(v) {
          return v.trim();
        }
      }, {
        type: 'list',
        name: 'classes',
        message: 'Type of article',
        choices: ['Normal article', 'Images', 'Video', 'Link', 'Quote', 'Location'],
        default: defaults.classes,
        filter: function(v) {
          return (v === 'Normal article') ? null : v;
        }
      }, {
        type: 'input',
        name: 'link',
        message: 'URL of page you want to link to',
        default: defaults.link,
        when: function(answers) {
          return answers.classes === 'Link';
        },
        validate: function(v) {
          return v.match(/^http(s)?:\/\/\S+$/) ? true : 'Please supply a valid url, starting with `http://` or `https://`.';
        }
      }, {
        type: 'input',
        name: 'location',
        message: 'Place name or address',
        default: defaults.location,
        when: function(answers) {
          return answers.classes === 'Location';
        }
      }, {
        type: 'confirm',
        name: 'images',
        message: 'Do you want to use images?',
        default: defaults.images,
        when: function(answers) {
          return answers.classes !== 'Images';
        }
      }, {
        type: 'input',
        name: 'keywords',
        message: 'Keywords, comma-separated',
        default: defaults.keywords,
        filter: function(v) {
          return v.trim();
        }
      }, {
        type: 'input',
        name: 'author',
        message: 'Author <E-Mail-Address>',
        default: defaults.author,
        when: function() {
          return config.specialFeatures.multipleauthors;
        }
      }, {
        type: 'input',
        name: 'date',
        message: 'Publishing date',
        default: defaults.date,
        filter: function(v) {
          return blogophonDate(v).iso;
        },
        validate: function(v) {
          return v.match(/^\d[\d:\-\+T]+\d$/) ? true : 'Please supply a valid date like ' + defaults.date + '.';
        }
      }, {
        type: 'confirm',
        name: 'draft',
        message: 'Is this a draft?',
        default: defaults.draft,
        when: function(answers) {
          return answers.date !== defaults.date;
        }
      }, {
        type: 'confirm',
        name: 'edit',
        message: 'Open this in editor right away?',
        default: defaults.edit
      }, {
        type: 'input',
        name: 'lead',
        message: 'Lead / teaser text',
        default: defaults.lead,
        when: function(answers) {
          return !answers.edit && answers.classes !== 'Link';
        }
      }, {
        type: 'input',
        name: 'mainText',
        message: 'Main text',
        default: defaults.mainText,
        when: function(answers) {
          return !answers.edit;
        }
      }
    ];
    inquirer.prompt(questions).then(
      function(answers) {
        var markdownFilename =
          internal.filenameFromTitle(internal.titleForFilename(answers.title, config, answers.date))
          + (answers.draft ? '.md~' : '.md')
        ;
        var filename = internal.dirnameFromFilename(markdownFilename); // TODO: There is a class for that
        var templateData = answers;

        switch (templateData.classes) {
          case 'Images':
            templateData.lead = templateData.lead || "![](image.jpg#default)\n\nLorem ipsum…";
            break;
          case 'Video':
            templateData.lead = templateData.lead || "https://www.youtube.com/watch?v=6A5EpqqDOdk\n\nLorem ipsum…";
            break;
          case 'Link':
            templateData.mainText = templateData.mainText || "[Lorem ipsum…](" + answers.link + ")";
            break;
          case 'Quote':
            templateData.mainText = templateData.mainText || "> Lorem ipsum…\n> <cite>Cicero</cite>";
            break;
          case 'Location':
            templateData.latitude = 0.00001;
            templateData.longitude = 0.00001;
            break;
        }
        if (templateData.location) {
          console.log('Geocoding...');
          internal.convertAddress(templateData.location, config.locale.language, function(err, geo) {
            templateData.latitude = geo.latitude || templateData.latitude;
            templateData.longitude = geo.longitude || templateData.longitude;
            internal.makePost(markdownFilename, filename, templateData);
          });
        } else {
          internal.makePost(markdownFilename, filename, templateData);
        }

      },
      function(err) {
        console.error(err);
      }
    );
  };

  internal.makePost = function(markdownFilename, filename, templateData) {
    templateData.ymlQuote = MustacheQuoters.ymlQuote;
    console.log(templateData);<commit_msg>Removed debug `console.log`<commit_after>'use strict';

var inquirer       = require('inquirer');
var glob           = require('glob');
var fs             = require('fs-extra-promise');
var path           = require('path');
var chalk          = require('chalk');
var shell          = require('shelljs');
var SuperString    = require('./helpers/super-string');
var config         = require('./config');
var Mustache       = require('./helpers/blogophon-mustache');
var MustacheQuoters= require('./helpers/blogophon-mustache-quoters');
var setup          = require('./setup')();
var Generator      = require('./generator');
var https          = require('https');
var blogophonDate  = require('./models/blogophon-date');

/**
 * Represents the Inquirer dialog with which to edit articles.
 * @constructor
 * @return {Object} [description]
 */
var BlogophonConsole = function() {
  var external     = {};
  var internal     = {};
  var files        = [];
  var choicesStr   = [
    'Create new article',
    'Edit existing article',
    'Rename article',
    'Delete article',
    'Generate & publish articles',
    config.notInitialized ? 'Setup' : 'Change settings',
    'Exit'
  ];

  Mustache.getTemplates();

  /**
   * Get all Markdown files as a simple array.
   * Array values can be simple strings, or objects containing
   * a name (to display in list),
   * a value (to save in the answers hash) and
   * a short (to display after selection) properties.
   * The choices array can also contain a Separator.
   * @return {Array} [description]
   */
  internal.makeChoices = function() {
    var choices = [];
    if (!config.notInitialized) {
      internal.makeFiles();
      choices.push(choicesStr[0]);
      if (files.length > 0) {
        choices.push(choicesStr[1], choicesStr[2], choicesStr[3], choicesStr[4]);
      }
      choices.push(new inquirer.Separator());
    }
    choices.push(choicesStr[5], new inquirer.Separator(), choicesStr[6]);
    return choices;
  };

/**
 * Get listing of all Markdown files which may be edited
 * @return {Array}   [description]
 */
  internal.makeFiles = function() {
    if (config.notInitialized) {
      files = [];
    } else {
      files = glob.sync(config.directories.data + "/**/*.{md,md~}").map(function(v) {
        var filename = v.replace(/^.+\/(.+?)$/, '$1');
        var fileStat = fs.lstatSync(v);
        return {
          name: fileStat.mtime.toLocaleString(config.locale.language || 'en')
            + "\t" + filename + "\t" +Math.ceil(fileStat.size/1000)+' kB',
          value: filename,
          short: filename
        };
      });
      if (files.length > 1) {
        files.push(new inquirer.Separator());
      }
    }
    return files;
  };

  /**
   * Returns the title to be used for generating a filename.
   * @param  {String} title  [description]
   * @param  {Object} config [description]
   * @param  {String} date   [description]
   * @return {String}        [description]
   */
  internal.titleForFilename = function(title, config, date) {
    date = date || new Date();
    if (config.postFileMode) {
      return config.postFileMode
        .replace(/Title/, title)
        .replace(/Date/, blogophonDate(date).format('yyyy-mm-dd'))
      ;
    }
    return title;
  };

  /**
   * Convert title to Markdown filename
   * @param  {String} title [description]
   * @return {String}       [description]
   */
  internal.filenameFromTitle = function(title) {
    return path.join(config.directories.data, internal.shortfilenameFromTitle(title));
  };

  /**
   * Remove stop words from filename and limit it to a sane length.
   * @param  {String} title [description]
   * @return {String}       [description]
   */
  internal.shortfilenameFromTitle = function(title) {
    return SuperString(title.trim().toLowerCase())
      .asciify()
      .replace(/(^|\-)([a-z]|de[rnms]|die(s|se|ser|ses|sen|sem)?|d[aoe]s|[msd]?ein(e|es|er|em|en)?|th(e|is|at|ese|ose)|my|[ea]l|l[ao]s?|[ia][nm]|o[nf]|ist?|[ua]nd)\-/g, '$1')
      .replace(/(^[\-]+|[\-]+$)/g, '')
      .replace(/([\-])[\-]+/g, '$1')
      .replace(/\-(md~?)$/, '.$1')
      .replace(/^(.{64}[^-]*).*?(\.md~?)?$/, '$1$2')
    ;
  };

  /**
   * Convert Markdown filename into corresponding directory name (e.g. for images)
   * @param  {String} filename [description]
   * @return {String}          [description]
   */
  internal.dirnameFromFilename = function(filename) {
    return filename.replace(/\.md~?$/, '');
  };

  /**
   * Get coordinates for address
   * @param  {String}   address  [description]
   * @param  {String}   language [description]
   * @param  {Function} callback [description]
   * @return {Object}            with `latitude, longitude`
   */
  internal.convertAddress = function(address, language, callback) {
    https.get({
      host: 'nominatim.openstreetmap.org',
      path: '/search?q='+encodeURIComponent(address)+'&format=json&accept-language='+encodeURIComponent(language || 'en')
    }, function(response) {
      var body = '';
      response.on('data', function(d) {
        body += d;
      });
      response.on('end', function() {
        var parsed = JSON.parse(body);
        callback(null, {
          latitude:  parsed[0] ? parsed[0].lat : null,
          longitude: parsed[0] ? parsed[0].lon : null
        });
      });
    });
  };


  /**
   * Display the setup dialog.
   * @return {[type]} [description]
   */
  external.setupDialog = function() {
    var themesAvailable= fs.readdirSync(config.directories.theme).filter(function(file) {
      return fs.statSync(path.join(config.directories.theme, file)).isDirectory();
    });
    var questions = [
      {
        type: 'input',
        name: 'name',
        message: 'The name of your site',
        default: config.name,
        validate: function(v) {
          return v ? true : 'Please supply at least a short name for your site.';
        }
      }, {
        type: 'list',
        name: 'theme',
        message: 'Choose theme',
        default: config.theme,
        choices: themesAvailable,
        when: function() {
          return (themesAvailable.length > 1);
        }
      }, {
        type: 'input',
        name: 'baseUrl',
        message: 'Domain of your site, starting with `http`',
        default: config.baseUrl,
        validate: function(v) {
          return v.match(/^http(s)?:\/\/\S+[^/]$/) ? true : 'Please supply a valid url, starting with `http://`, but without trailing `/`.';
        },
        filter: function(v) {
          return v.replace(/\/$/, '');
        }
      }, {
        type: 'input',
        name: 'basePath',
        message: 'Base URL path, usually just `/`',
        default: config.basePath,
        validate: function(v) {
          return v.match(/^[a-zA-Z0-9\.\/_-]*\/$/) ? true : 'Please supply a valid path with a trailing `/`.';
        },
        filter: function(v) {
          return v.replace(/^([^\/])/, '/$1').replace(/([^\/])$/, '$1/');
        }
      }, {
        type: 'input',
        name: 'description',
        message: 'A short description of your blog (optional)',
        default: config.description
      }, {
        type: 'input',
        name: 'locale.language',
        message: 'Standard language of your blog, like `en` for English',
        default: config.locale.language || config.language,
        validate: function(v) {
          return v.match(/^[a-zA-Z]+([\-_][a-zA-Z]+)?$/) ? true : 'Please supply a valid language code like `en`, `es`, `fr`, `de` or `pt-br`.';
        },
        filter: function(v) {
          return v.toLowerCase().replace(/_/, '-');
        }
      }, {
        type: 'list',
        name: 'postPathMode',
        message: 'Choose URL path pattern for your posts:',
        default: config.postPathMode,
        choices: [
          'Static path',
          'Year',
          'Year/Month',
          'Year/Month/Day'
        ]
      }, {
        type: 'list',
        name: 'postFileMode',
        message: 'Choose URL file pattern for your posts:',
        default: config.postFileMode || 'Title',
        choices: [
          'Title',
          'Title-Date',
          'Date-Title',
          'Date'
        ]
      }, {
        type: 'input',
        name: 'itemsPerPage',
        message: 'How many articles per page?',
        default: config.itemsPerPage,
        validate: function(v) {
          return Number(v)> 0 ? true : 'Please supply a positive number.';
        },
        filter: function(v) {
          return Number(v);
        }
      }, {
        type: 'input',
        name: 'defaultAuthor.name',
        message: 'Default name of author',
        default: config.defaultAuthor.name,
        validate: function(v) {
          return v ? true : 'Please supply at least a short name for your site.';
        }
      }, {
        type: 'input',
        name: 'defaultAuthor.email',
        message: 'Default email address of author',
        default: config.defaultAuthor.email,
        validate: function(v) {
          return (v.match(/^\S+@\S+$/)) ? true : 'Please supply a valid email address.';
        }
      }, {
        type: 'input',
        name: 'twitterAccount',
        message: 'Twitter account name (optional)',
        default: config.twitterAccount,
        validate: function(v) {
          return (!v || v.match(/^[a-zA-z0-9_-]+$/)) ? true : 'Please supply a Twitter account name or leave field empty.';
        }
      }, {
        type: 'input',
        name: 'deployCmd',
        message: 'CLI command to copy files to your live server (optional)',
        default: config.deployCmd
      }, {
        type: 'checkbox',
        name: 'useSpecialFeature',
        message: 'Do you want to use the following special features?',
        default: config.useSpecialFeature,
        choices: [
          "Multiple authors",
          "RSS",
          "ATOM",
          "JSON for Slack",
          "JSON-RSS",
          "Apple News",
          "Facebook Instant Articles",
          "Accelerated Mobile Pages",
          "Microsoft tiles",
          "ICS-Calendar",
          "GeoJSON",
          "KML",
          "AJAX"
        ]
      }
    ];

    inquirer.prompt(questions).then(
      function(answers) {
        answers.theme = config.theme ? config.theme : themesAvailable[0];
        answers.locale.direction = answers.locale.direction || config.locale.direction || (answers.language.match(/^(ar|zh|fa|he)/) ? 'rtl' : 'ltr');
        setup
          .buildBasicFiles(config, answers)
          .then(function() {
            console.log("Settings changed, please restart the Blogophon.");
            // TODO: reload config and return to main menu
            // external.init();
          })
        ;
      },
      function(err) {
        console.error(err);
        process.exit(1);
      }
    );
  };

  /**
   * This is the Inquirer dialog for creating a new articles. Will call external.init() on finish.
   * @return {[type]} [description]
   */
  external.createArticleDialog = function() {
    var defaults = {
      classes: 'Normal article',
      link: '',
      location: '',
      images: false,
      keywords: '',
      date: blogophonDate(new Date()).iso,
      author: config.defaultAuthor.name +' <'+config.defaultAuthor.email + '>',
      draft: false,
      edit: true,
      lead: '',
      mainText: 'Lorem ipsum…'
    };

    var questions    = [
      {
        type: 'input',
        name: 'title',
        message: 'Title',
        validate: function(v) {
          if (v.trim().length <= 2) {
            return 'This title is way too short.';
          }
          var filename = internal.filenameFromTitle(v);
          if (fs.existsSync(filename)) {
            return ("File " + filename + ' already exists');
          }
          return true;
        },
        filter: function(v) {
          return v.trim();
        }
      }, {
        type: 'list',
        name: 'classes',
        message: 'Type of article',
        choices: ['Normal article', 'Images', 'Video', 'Link', 'Quote', 'Location'],
        default: defaults.classes,
        filter: function(v) {
          return (v === 'Normal article') ? null : v;
        }
      }, {
        type: 'input',
        name: 'link',
        message: 'URL of page you want to link to',
        default: defaults.link,
        when: function(answers) {
          return answers.classes === 'Link';
        },
        validate: function(v) {
          return v.match(/^http(s)?:\/\/\S+$/) ? true : 'Please supply a valid url, starting with `http://` or `https://`.';
        }
      }, {
        type: 'input',
        name: 'location',
        message: 'Place name or address',
        default: defaults.location,
        when: function(answers) {
          return answers.classes === 'Location';
        }
      }, {
        type: 'confirm',
        name: 'images',
        message: 'Do you want to use images?',
        default: defaults.images,
        when: function(answers) {
          return answers.classes !== 'Images';
        }
      }, {
        type: 'input',
        name: 'keywords',
        message: 'Keywords, comma-separated',
        default: defaults.keywords,
        filter: function(v) {
          return v.trim();
        }
      }, {
        type: 'input',
        name: 'author',
        message: 'Author <E-Mail-Address>',
        default: defaults.author,
        when: function() {
          return config.specialFeatures.multipleauthors;
        }
      }, {
        type: 'input',
        name: 'date',
        message: 'Publishing date',
        default: defaults.date,
        filter: function(v) {
          return blogophonDate(v).iso;
        },
        validate: function(v) {
          return v.match(/^\d[\d:\-\+T]+\d$/) ? true : 'Please supply a valid date like ' + defaults.date + '.';
        }
      }, {
        type: 'confirm',
        name: 'draft',
        message: 'Is this a draft?',
        default: defaults.draft,
        when: function(answers) {
          return answers.date !== defaults.date;
        }
      }, {
        type: 'confirm',
        name: 'edit',
        message: 'Open this in editor right away?',
        default: defaults.edit
      }, {
        type: 'input',
        name: 'lead',
        message: 'Lead / teaser text',
        default: defaults.lead,
        when: function(answers) {
          return !answers.edit && answers.classes !== 'Link';
        }
      }, {
        type: 'input',
        name: 'mainText',
        message: 'Main text',
        default: defaults.mainText,
        when: function(answers) {
          return !answers.edit;
        }
      }
    ];
    inquirer.prompt(questions).then(
      function(answers) {
        var markdownFilename =
          internal.filenameFromTitle(internal.titleForFilename(answers.title, config, answers.date))
          + (answers.draft ? '.md~' : '.md')
        ;
        var filename = internal.dirnameFromFilename(markdownFilename); // TODO: There is a class for that
        var templateData = answers;

        switch (templateData.classes) {
          case 'Images':
            templateData.lead = templateData.lead || "![](image.jpg#default)\n\nLorem ipsum…";
            break;
          case 'Video':
            templateData.lead = templateData.lead || "https://www.youtube.com/watch?v=6A5EpqqDOdk\n\nLorem ipsum…";
            break;
          case 'Link':
            templateData.mainText = templateData.mainText || "[Lorem ipsum…](" + answers.link + ")";
            break;
          case 'Quote':
            templateData.mainText = templateData.mainText || "> Lorem ipsum…\n> <cite>Cicero</cite>";
            break;
          case 'Location':
            templateData.latitude = 0.00001;
            templateData.longitude = 0.00001;
            break;
        }
        if (templateData.location) {
          console.log('Geocoding...');
          internal.convertAddress(templateData.location, config.locale.language, function(err, geo) {
            templateData.latitude = geo.latitude || templateData.latitude;
            templateData.longitude = geo.longitude || templateData.longitude;
            internal.makePost(markdownFilename, filename, templateData);
          });
        } else {
          internal.makePost(markdownFilename, filename, templateData);
        }

      },
      function(err) {
        console.error(err);
      }
    );
  };

  internal.makePost = function(markdownFilename, filename, templateData) {
    templateData.ymlQuote = MustacheQuoters.ymlQuote;
{'fraction_non_alphanumeric': 0.15283024570098824, 'fraction_numerical': 0.0030221523769228442, 'mean_word_length': 2.01311236568931, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 23, 'https://': 4, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2850150', 'n_tokens_mistral': 9805, 'n_tokens_neox': 9646, 'n_words': 2322}