diff --git a/vlib/builtin/string.v b/vlib/builtin/string.v index 293b48bcca..70bbd013dc 100644 --- a/vlib/builtin/string.v +++ b/vlib/builtin/string.v @@ -555,7 +555,6 @@ pub fn (s string) u64() u64 { // This method directly exposes the `parse_uint` function from `strconv` // as a method on `string`. For more advanced features, // consider calling `strconv.common_parse_uint` directly. -// Example: pub fn (s string) parse_uint(_base int, _bit_size int) ?u64 { return strconv.parse_uint(s, _base, _bit_size) } @@ -1823,13 +1822,15 @@ pub fn (s string) fields() []string { // the value in ``. // // Example: +// ```v // st := 'Hello there, // |this is a string, // | Everything before the first | is removed'.strip_margin() -// Returns: -// Hello there, +// +// assert st == 'Hello there, // this is a string, -// Everything before the first | is removed +// Everything before the first | is removed' +// ``` pub fn (s string) strip_margin() string { return s.strip_margin_custom(`|`) } diff --git a/vlib/v/doc/comment.v b/vlib/v/doc/comment.v index 5a870b258a..97e3f8df9e 100644 --- a/vlib/v/doc/comment.v +++ b/vlib/v/doc/comment.v @@ -13,13 +13,22 @@ pub mut: pos token.Pos } -// is_example returns true if the contents of this comment is a doc example. +// is_example returns true if the contents of this comment is an inline doc example. // The current convention is '// Example: ' pub fn (dc DocComment) is_example() bool { return dc.text.starts_with(doc.example_pattern) } -// example returns the content of the example body +// example returns the content of the inline example body pub fn (dc DocComment) example() string { return dc.text.all_after(doc.example_pattern) } + +pub fn (dc DocComment) is_multi_line_example() bool { + return dc.text == '\x01 Example:' +} + +pub fn (dc DocComment) has_triple_backtick() bool { + return dc.text.starts_with('\x01 ```') +} + diff --git a/vlib/v/doc/node.v b/vlib/v/doc/node.v index c43be887ac..4abe2d6fed 100644 --- a/vlib/v/doc/node.v +++ b/vlib/v/doc/node.v @@ -54,7 +54,28 @@ pub fn (dc DocNode) merge_comments() string { // merge_comments_without_examples returns a `string` with the // combined contents of `DocNode.comments` - excluding any examples. pub fn (dc DocNode) merge_comments_without_examples() string { - sans_examples := dc.comments.filter(!it.is_example()) + mut sans_examples := []DocComment{cap:dc.comments.len} + for i := 0; i < dc.comments.len; i++ { + if dc.comments[i].is_example() { continue } + if dc.comments[i].is_multi_line_example() { + i++ + if i == dc.comments.len || !dc.comments[i].has_triple_backtick() { + eprintln('${dc.file_path}: Expected code block after empty example line:') + eprintln('// ```') + if i < dc.comments.len { + eprintln('Found:') + eprintln('//' + dc.comments[i].text[1..]) + } + exit(1) + } + i++ + for i < dc.comments.len && !dc.comments[i].has_triple_backtick() { + i++ + } + } else { + sans_examples << dc.comments[i] + } + } return merge_doc_comments(sans_examples) } @@ -64,15 +85,14 @@ pub fn (dn DocNode) examples() []string { for i, comment in dn.comments { if comment.is_example() { output << comment.example() - } else if comment.text == '\x01 Example:' { + } else if comment.is_multi_line_example() { mut j := i + 1 //~ comments = dn.comments mut ml_ex := '' - mdcode := '\x01 ```' - if j + 2 < dn.comments.len && dn.comments[j].text == mdcode + 'v' + if j + 2 < dn.comments.len && dn.comments[j].has_triple_backtick() { j++ - for j < dn.comments.len && dn.comments[j].text != mdcode { + for j < dn.comments.len && !dn.comments[j].has_triple_backtick() { //~ println(dn.comments[j].text) if ml_ex.len > 0 { ml_ex += '\n'