code: function mkextract (opts) {
    var chunk = null
    var indent = 0
    var number = 0
  
    opts = merge({}, {
      trim: true,
      dotted_names: false,
      parsers: [
        PARSERS.parse_tag,
        PARSERS.parse_type,
        PARSERS.parse_name,
        PARSERS.parse_description
      ]
    }, opts || {})
  
    /**
     * Read lines until they make a block
     * Return parsed block once fullfilled or null otherwise
     */
    return function extract (line) {
      var result = null
      var startPos = line.indexOf(MARKER_START)
      var endPos = line.indexOf(MARKER_END)
  
      // if open marker detected and it's not skip one
      if (startPos !== -1 && line.indexOf(MARKER_START_SKIP) !== startPos) {
        chunk = []
        indent = startPos + MARKER_START.length
      }
  
      // if we are on middle of comment block
      if (chunk) {
        var lineStart = indent
        var startWithStar = false
  
        // figure out if we slice from opening marker pos
        // or line start is shifted to the left
        var nonSpaceChar = line.match(/\S/)
  
        // skip for the first line starting with /** (fresh chunk)
        // it always has the right indentation
        if (chunk.length > 0 && nonSpaceChar) {
          if (nonSpaceChar[0] === '*') {
            lineStart = nonSpaceChar.index + 2
            startWithStar = true
          } else if (nonSpaceChar.index < indent) {
            lineStart = nonSpaceChar.index
          }
        }
  
        // slice the line until end or until closing marker start
        chunk.push({
          number: number,
          startWithStar: startWithStar,
          source: line.slice(lineStart, endPos === -1 ? line.length : endPos)
        })
  
        // finalize block if end marker detected
        if (endPos !== -1) {
          result = parse_block(chunk, opts)
          chunk = null
          indent = 0
        }
      }
  
      number += 1
      return result
    }
  }
docs: Produces `extract` function with internal state initialized