diff --git a/vlib/flag/flag_to.v b/vlib/flag/flag_to.v index 7cdb9a2362..2a1aee5ca0 100644 --- a/vlib/flag/flag_to.v +++ b/vlib/flag/flag_to.v @@ -732,21 +732,22 @@ pub fn (fm FlagMapper) fields_docs(dc DocConfig) ![]string { } flag_line_diff := flag_line.len - pad_desc if flag_line_diff < 0 { + // This makes sure the description is put on a new line if the flag line is + // longer than the padding. diff := -flag_line_diff - mut line := flag_line + ' '.repeat(diff) + + line := flag_line + ' '.repeat(diff) + keep_at_max(doc, desc_max).replace('\n', '\n${empty_padding}') - if !dc.options.compact { - line += '\n' - } - docs << line + docs << line.trim_right(' \n\t\v\f\r') } else { - docs << flag_line - mut line := empty_padding + - keep_at_max(doc, desc_max).replace('\n', '\n${empty_padding}') - if !dc.options.compact { - line += '\n' + docs << flag_line.trim_right(' \n\t\v\f\r') + if doc != '' { + line := empty_padding + + keep_at_max(doc, desc_max).replace('\n', '\n${empty_padding}') + docs << line.trim_right(' \n\t\v\f\r') } - docs << line + } + if !dc.options.compact { + docs << '' } } // Look for custom flag entries starting with delimiter @@ -754,26 +755,28 @@ pub fn (fm FlagMapper) fields_docs(dc DocConfig) ![]string { if entry.starts_with(dc.delimiter) { flag_line_diff := entry.len - pad_desc + indent_flags if flag_line_diff < 0 { + // This makes sure the description is put on a new line if the flag line is + // longer than the padding. diff := -flag_line_diff - mut line := indent_flags_padding + entry.trim(' ') + ' '.repeat(diff) + + line := indent_flags_padding + entry.trim(' ') + ' '.repeat(diff) + keep_at_max(doc, desc_max).replace('\n', '\n${empty_padding}') - if !dc.options.compact { - line += '\n' - } - docs << line + docs << line.trim_right(' \n\t\v\f\r') } else { docs << indent_flags_padding + entry.trim(' ') - mut line := empty_padding + + line := empty_padding + keep_at_max(doc, desc_max).replace('\n', '\n${empty_padding}') - if !dc.options.compact { - line += '\n' - } - docs << line + docs << line.trim_right(' \n\t\v\f\r') + } + if !dc.options.compact { + docs << '' } } } if docs.len > 0 { - docs[docs.len - 1] = docs[docs.len - 1].trim_right(' \n') + if !dc.options.compact { + // In non-compact mode the last item will be an empty line, delete it + docs.delete_last() + } } return docs } diff --git a/vlib/flag/flag_to_doc_test.v b/vlib/flag/flag_to_doc_test.v index 304187717b..b26cb0f3ca 100644 --- a/vlib/flag/flag_to_doc_test.v +++ b/vlib/flag/flag_to_doc_test.v @@ -70,3 +70,126 @@ fn test_attrs_override() { description: 'My application' )! == doc3 } + +const doc4 = 'flag_to_doc_test 1.0 +-------------------------------------------------------------------------------- +Flag to doc test. +Content here + +Options: + -v, --show-version Show version and exit + + -d, --debug Debug level + + -l Level of lorem ipsum + and more + many many many more. + Notice how user newlines/format is kept since + input lines are all less or within + the default layout.description_padding + and max width + + --example Looong example text without newlines or anything + else and lorem ipsum and more and many many many + more. Should be auto fitted + + --square + + -m, -mmm... (can repeat) This flag can be repeated + + -w, --wroom (allowed multiple times) + + --the-limit Looongbobbytextwithoutnewlinesoranythingelseandlorem + ipsumandmoreandmanymanymanymore + ffffffffffffffffffffffffffffffff f + + -e, --extra Secret flag that does not exist on the struct, + but we want documented (in same format as the + others) + + -q, --quiet-and-quite-long-flag + Mega long description and secret flag that does + not exist on the struct, but we want documented. + Also the flag has custom newlines and the flag + line itself is super long + +Footer content' + +const doc5 = 'flag_to_doc_test 1.0 +-------------------------------------------------------------------------------- +Flag to doc test. +Content here + +Options: + -v, --show-version Show version and exit + -d, --debug Debug level + -l Level of lorem ipsum + and more + many many many more. + Notice how user newlines/format is kept since + input lines are all less or within + the default layout.description_padding + and max width + --example Looong example text without newlines or anything + else and lorem ipsum and more and many many many + more. Should be auto fitted + --square + -m, -mmm... (can repeat) This flag can be repeated + -w, --wroom (allowed multiple times) + --the-limit Looongbobbytextwithoutnewlinesoranythingelseandlorem + ipsumandmoreandmanymanymanymore + ffffffffffffffffffffffffffffffff f + -e, --extra Secret flag that does not exist on the struct, + but we want documented (in same format as the + others) + -q, --quiet-and-quite-long-flag + Mega long description and secret flag that does + not exist on the struct, but we want documented. + Also the flag has custom newlines and the flag + line itself is super long + +Footer content' + +@[name: 'flag_to_doc_test'] +@[version: '1.0'] +struct DocTest { + show_version bool @[short: v; xdoc: 'Show version and exit'] + debug_level int @[long: debug; short: d; xdoc: 'Debug level'] + level f32 @[only: l; xdoc: 'Override this doc string'] + example string + square bool + multi int @[only: m; repeats] + wroom []int @[short: w] + the_limit string +} + +const field_docs = { + 'level': 'Level of lorem ipsum\nand more\nmany many many more.\nNotice how user newlines/format is kept since\ninput lines are all less or within\nthe default layout.description_padding\nand max width' + 'example': 'Looong example text without newlines or anything else and lorem ipsum and more and many many many more. Should be auto fitted' + 'the_limit': 'Looongbobbytextwithoutnewlinesoranythingelseandlorem ipsumandmoreandmanymanymanymore ffffffffffffffffffffffffffffffff f' + 'multi': 'This flag can be repeated' + '-e, --extra': 'Secret flag that does not exist on the struct, but we want documented (in same format as the others)' + '-q, --quiet-and-quite-long-flag ': 'Mega long description and secret flag that does not exist on the struct, but we want documented. Also the flag has custom newlines\nand the flag line itself is super long' +} + +fn test_flag_to_doc_spacing_and_new_lines() { + assert flag.to_doc[DocTest]( + description: 'Flag to doc test. +Content here' + footer: ' +Footer content' + fields: unsafe { field_docs } + )! == doc4 + + // Test in compact mode also + assert flag.to_doc[DocTest]( + options: flag.DocOptions{ + compact: true + } + description: 'Flag to doc test. +Content here' + footer: ' +Footer content' + fields: unsafe { field_docs } + )! == doc5 +}