module.exports = grammar({
name: 'python_docstring',
rules: {
docstring: $ => seq(
'"""',
$.top_summary,
optional($.summary),
optional($.args_section),
optional($.return_section),
optional($.raises_section),
optional($.examples_section),
optional($.notes_section),
optional($.attributes_section),
'"""\n'
),
top_summary: $ => /[^\n]+\./,
summary: $ => seq($.summary_line, repeat($.summary_line)),
summary_line: $ => /[^\n]+/,
args_section: $ => seq(
'Args:\n',
repeat($.arg)
),
arg: $ => seq(
$.arg_name,
optional($.type_annotation),
':',
$.element_description
),
arg_name: $ => /\s{4}(\*{0,2}[a-zA-Z_][a-zA-Z_0-9]*)/,
type_annotation: $ => seq(
' (',
$.type_name,
')'
),
type_name: $ => seq(/[a-zA-Z_][a-zA-Z_0-9\.]*/, optional(", optional")),
element_description: $ => seq(
seq(/[^\n]+/, '\n'),
optional(repeat(seq(
/\s{8}[^\n]+\n/,
)))
),
element_description_start: $ => seq(/[^\n]+/, '\n'),
element_description_continuation: $ => seq(
/\s{8}/,
/[^\n]+/,
'\n',
),
return_section: $ => seq(
'Returns:\n',
repeat($.return_line)
),
return_line: $ => choice(
/\s{4}[^\n]+\n/,
'\n'),
raises_section: $ => seq(
'Raises:\n',
repeat($.raise_info)
),
raise_info: $ => seq(
seq($.type_name,
':'),
$.raise_description
),
raise_description: $ => seq(
seq(/[^\n]+/, '\n'),
optional(repeat(seq(
/\s{8}/,
/[^\n]+/,
'\n',
)))
),
examples_section: $ => seq(
'Examples:\n',
repeat($.example_line)
),
example_line: $ => seq(/\s{4,}/, /[^\n]+/, '\n'),
notes_section: $ => seq(
'Notes:\n',
repeat($.note_line)
),
note_line: $ => seq(/\s{4,}/, /[^\n]+/, '\n'),
attributes_section: $ => seq(
'Attributes:\n',
repeat($.attribute_line)
),
attribute_line: $ => seq(/\s{4,}/, /[^\n]+/, '\n'),
}
});