function iteratePath (functionNames, inputPath, outputPath, outputRoot) {
  if (!fs.existsSync(outputPath)) {
    mkdirp.sync(outputPath)
  }
  const functions = collectDocs(functionNames, inputPath)
  let issues = []
  for (const fn of Object.values(functions)) {
    issues = issues.concat(fn.issues)
    const markdown = generateMarkdown(fn.doc, functions)
    fs.writeFileSync(outputPath + '/' + fn.name + '.md', markdown)
  }

  /**
   * Helper function to generate a markdown list entry for a function.
   * Used to generate both alphabetical and categorical index pages.
   * @param {string} name Function name
     * @returns {string}    Returns a markdown list entry
     */
  function functionEntry (name) {
    const fn = functions[name]
    let syntax = SYNTAX[name] || (fn.doc && fn.doc.syntax && fn.doc.syntax[0]) || name
    syntax = syntax
      // .replace(/^math\./, '')
      .replace(/\s+\/\/.*$/, '')
      .replace(/;$/, '')
    if (syntax.length < 40) {
      syntax = syntax.replace(/ /g, '&nbsp;')
    }

    let description = ''
    if (fn.doc.description) {
      description = fn.doc.description.replace(/\n/g, ' ').split('.')[0] + '.'
    }

    return '[' + syntax + '](functions/' + name + '.md) | ' + description
  }

  /**
   * Change the first letter of the given string to upper case
   * @param {string} text
   */
  function toCapital (text) {
    return text[0].toUpperCase() + text.slice(1)
  }

  const order = ['core', 'construction', 'expression'] // and then the rest
  function categoryIndex (entry) {
    const index = order.indexOf(entry)
    return index === -1 ? Infinity : index
  }
  function compareAsc (a, b) {
    return a > b ? 1 : (a < b ? -1 : 0)
  }
  function compareCategory (a, b) {
    const indexA = categoryIndex(a)
    const indexB = categoryIndex(b)
    return (indexA > indexB) ? 1 : (indexA < indexB ? -1 : compareAsc(a, b))
  }

  // generate categorical page with all functions
  const categories = {}
  Object.keys(functions).forEach(function (name) {
    const fn = functions[name]
    const category = categories[fn.category]
    if (!category) {
      categories[fn.category] = {}
    }
    categories[fn.category][name] = fn
  })
  let categorical = '# Function reference\n\n'
  categorical += Object.keys(categories).sort(compareCategory).map(function (category) {
    const functions = categories[category]

    return '## ' + toCapital(category) + ' functions\n\n' +
      'Function | Description\n' +
      '---- | -----------\n' +
      Object.keys(functions).sort().map(functionEntry).join('\n') + '\n'
  }).join('\n')
  categorical += '\n\n\n<!-- Note: This file is automatically generated from source code comments. Changes made in this file will be overridden. -->\n'

  fs.writeFileSync(outputRoot + '/' + 'functions.md', categorical)

  // output all issues
  if (issues.length) {
    issues.forEach(function (issue) {
      log('Warning: ' + issue)
    })
    log(issues.length + ' warnings')
  }
}
Iterate over all source files and generate markdown documents for each of them
@param {String[]} functionNames  List with all functions exported from the main instance of mathjs
@param {String} inputPath        Path to /lib/
@param {String} outputPath       Path to /docs/reference/functions
@param {String} outputRoot       Path to /docs/reference