     (Option.parse('-' + s) for s in doc.split(/^ *-|\n *-/)[1..])
 
 printable_usage = (doc, name) ->
-    if usage = (/\s*usage:\s*/i).exec(doc)[0]
-        usage = usage.replace(/^\s+/, '')
-        indent = '\n' + /(^)?[^\n]*$/.exec(usage)[0].replace(/./g, (c) ->
-           return (if c is '\t' then '\t' else ' '))
-        uses = doc.substr(usage.length).split(/\n\s*\n/)[0].split('\n')
-        uses = (u.replace /^\s+|\s+$/, '' for u in uses)
-        if name
-            uses = (u.replace /^[^\s]+/, name for u in uses)
-        return usage + uses.join(indent)
-    else
-        throw new UsageMessageError("the first word in the usage should be usage.")
+    [usage, patterns] = doc.split(/(?:^|\n)([\s^\n]*usage:\s*)/i)[1..2]
+    usage = usage.replace(/^\s+/, '')
+    if not /\s$/.test(usage) then usage += ' '
+    indent = '\n' + /(^)?[^\n]*$/.exec(usage)[0].replace(/./g, (c) ->
+       return (if c is '\t' then '\t' else ' '))
+    oldname = /^[^\s]+/.exec(patterns)[0]
+    if name is null then name = oldname
+    uses = patterns.split(/\n\s*\n/)[0]
+    uses = uses.split(new RegExp('(?:^|\\n)\\s*' + oldname))
+    uses = (name + u.replace /\s+$/, '' for u in uses[1..])
+    return usage + uses.join(indent)
 
 formal_usage = (printable_usage) ->
     pu = printable_usage.split()[1..]  # split and drop "usage:"

    move: -> @shift() or null
    current: -> @[0] or null
    toString: -> ([].slice.apply @).toString()
    error: (message) ->
        throw new @error(message)


                         UsageMessageError)
    result = parse_expr(tokens, options)
    if tokens.current() is not null
        raise tokens.error('unexpected ending: ' + tokens.join(' '))
    return new Required(result)


