Skip to content

Commit

Permalink
feat: Support multiple doc standard (feature issue #3)
Browse files Browse the repository at this point in the history
  • Loading branch information
kkoomen committed Jun 27, 2019
1 parent a7135bb commit ca67b50
Show file tree
Hide file tree
Showing 23 changed files with 722 additions and 307 deletions.
19 changes: 19 additions & 0 deletions .github/ISSUE_TEMPLATE/doc_standard.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
---
name: Doc standard
about: Suggest a new doc standard for a specific language
title: 'Add <doc-standard> doc standard for <language>'
labels: 'enhancement'
assignees: ''

---

**Documentation standard**
Specify a link to the documentation standard section containing the tags.

**How popular is the doc standard?**
- [ ] Not popular at all
- [ ] Some people use it
- [ ] Quite a lot of people use it
- [ ] It's not the most popular one, but a good alternative
- [ ] Everyone within the <community> community is using it
- [ ] Everyone is using it
41 changes: 20 additions & 21 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ When contributing make sure you:
* [Writing your first pattern](#writing-your-first-pattern)
+ [Additional token formatting](#additional-token-formatting)
- [Default value](#default-value)
- [Prevent rendering when captured group failed to capture](#prevent-rendering-when-captured-group-failed-to-capture)
- [Conditional rendering](#conditional-rendering)
* [Writing proper regex](#writing-proper-regex)

# How does DoGe work?
Expand Down Expand Up @@ -217,35 +217,34 @@ You can also leave the default value empty to just remove the token when it
fails to capture a value. Example: `{type|}`. This will result in:
`* @param $p1 TODO` instead of `* @param {type} $p1 TODO`.

#### Prevent rendering when captured group failed to capture
#### Conditional rendering

When groups fail to capture a value there are scenarios where you do not want
the token to render. You can use the exclamation mark `!` at the beginning of a
sentence in the `template` or `parameters.format` keys to accomplish this.
The syntax for a conditional render is `#(<token>|<value>)` where `<token>` is
the name of the token and `<value>` the value you want to render when `<token>`
is _not empty_.

Example:
Javascript uses JSDoc where a function should use the `@async` tag when a
function is declared using the `async` keyword. We want to render the tag
_only_ when the `async` keyword is used in the function declaration.

This is how it's done:

```vim
" Example taken from ftplugin/python.vim
call add(b:doge_patterns, {
\ 'match': '...\(async\)\?...',
\ 'match_group_names': ['async'],
\ 'parameters': {},
\ " ...
\ 'comment': {
\ 'insert': 'above',
\ 'template': [
\ '/**',
\ ' * @description TODO',
" The '{async}' token renders the word 'async' which ends up in '@async'.
" The whole line is removed when `{async}` fails to be captured.
\ '! * @{async}',
\ ' * {parameters}',
\ ' */',
\ ],
\ 'insert': 'below',
\ 'template': {
\ 'numpy': [
\ '"""',
\ 'TODO',
\ '#(parameters|)', " Render an empty line if '{parameters}' is not empty
\ '#(parameters|Parameters)', " Renders 'Parameters' if '{parameters}' is not empty
\ '#(parameters|----------)', " Renders '----------' if '{parameters}' is not empty
\ '#(parameters|{parameters})', " Renders '{parameters}' if '{parameters}' is not empty
\ '"""',
\ ],
\ }
\ },
\})
```
Expand Down
72 changes: 58 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,20 +61,20 @@ Every language that has a documentation standard should be supported by DoGe.
Is your favorite language not supported?
[Make a feature request](https://github.com/kkoomen/vim-doge/issues/new?labels=enhancement&template=feature_request.md&title=Add+support+for+<language>) :tada:

| | Language | Doc standard |
| --- | --- | --- |
| :white_check_mark: | Python | ([Sphinx reST](http://daouzli.com/blog/docstring.html#restructuredtext)) |
| :white_check_mark: | PHP | ([phpdoc](https://www.phpdoc.org)) |
| :white_check_mark: | JavaScript (Including: ES6, FlowJS and NodeJS) | ([JSDoc](https://jsdoc.app)) |
| :white_check_mark: | TypeScript | ([JSDoc](https://jsdoc.app)) |
| :white_check_mark: | CoffeeScript | ([JSDoc](https://jsdoc.app)) |
| :white_check_mark: | Lua | ([LDoc](https://github.com/stevedonovan/LDoc)) |
| :white_check_mark: | Java | ([JavaDoc](https://www.oracle.com/technetwork/articles/javase/index-137868.html)) |
| :white_check_mark: | Groovy | ([JavaDoc](https://www.oracle.com/technetwork/articles/javase/index-137868.html)) |
| :white_check_mark: | Ruby | ([YARD](https://www.rubydoc.info/gems/yard/file/docs/Tags.md)) |
| :white_check_mark: | Scala | ([ScalaDoc](https://docs.scala-lang.org/style/scaladoc.html)) |
| :white_check_mark: | Kotlin | ([KDoc](https://kotlinlang.org/docs/reference/kotlin-doc.html)) |
| :white_check_mark: | R | ([Roxygen2](https://github.com/klutometis/roxygen)) |
| | Language | Doc standard |
| --- | --- | --- |
| :white_check_mark: | Python | [reST](http://daouzli.com/blog/docstring.html#restructuredtext), [Numpy](http://daouzli.com/blog/docstring.html#numpydoc) |
| :white_check_mark: | PHP | [phpdoc](https://www.phpdoc.org) |
| :white_check_mark: | JavaScript (Including: ES6, FlowJS and NodeJS) | [JSDoc](https://jsdoc.app) |
| :white_check_mark: | TypeScript | [JSDoc](https://jsdoc.app) |
| :white_check_mark: | CoffeeScript | [JSDoc](https://jsdoc.app) |
| :white_check_mark: | Lua | [LDoc](https://github.com/stevedonovan/LDoc) |
| :white_check_mark: | Java | [JavaDoc](https://www.oracle.com/technetwork/articles/javase/index-137868.html) |
| :white_check_mark: | Groovy | [JavaDoc](https://www.oracle.com/technetwork/articles/javase/index-137868.html) |
| :white_check_mark: | Ruby | [YARD](https://www.rubydoc.info/gems/yard/file/docs/Tags.md) |
| :white_check_mark: | Scala | [ScalaDoc](https://docs.scala-lang.org/style/scaladoc.html) |
| :white_check_mark: | Kotlin | [KDoc](https://kotlinlang.org/docs/reference/kotlin-doc.html) |
| :white_check_mark: | R | [Roxygen2](https://github.com/klutometis/roxygen) |

# Getting started

Expand Down Expand Up @@ -128,6 +128,50 @@ Adds the `TODO` suffix after every generated parameter.

Jumps interactively through all `TODO` items in the generated comment.

## Choose different doc standard

DoGe supports multiple doc standard and you can overwrite them per filetype in
your vimrc. Does DoGe not support your preferred dog standard?
[Make a feature request](https://github.com/kkoomen/vim-doge/issues/new?labels=enhancement&template=doc_standard.md)!

Here is the full list of available doc standards per filetype:
- `let g:doge_doc_standard_python`
- Default: `reST`
- Available: `['reST', 'numpy']`
- `let g:doge_doc_standard_php`
- Default: `phpdoc`
- Available: `['phpdoc']`
- `let g:doge_doc_standard_javascript`
- Default: `jsdoc`
- Available: `['jsdoc']`
- `let g:doge_doc_standard_typescript`
- Default: `jsdoc`
- Available: `['jsdoc']`
- `let g:doge_doc_standard_coffeescript`
- Default: `jsdoc`
- Available: `['jsdoc']`
- `let g:doge_doc_standard_lua`
- Default: `ldoc`
- Available: `['ldoc']`
- `let g:doge_doc_standard_java`
- Default: `javadoc`
- Available: `['javadoc']`
- `let g:doge_doc_standard_groovy`
- Default: `javadoc`
- Available: `['javadoc']`
- `let g:doge_doc_standard_ruby`
- Default: `YARD`
- Available: `['YARD']`
- `let g:doge_doc_standard_scala`
- Default: `scaladoc`
- Available: `['scaladoc']`
- `let g:doge_doc_standard_kotlin`
- Default: `kdoc`
- Available: `['kdoc']`
- `let g:doge_doc_standard_r`
- Default: `roxygen2`
- Available: `['roxygen2']`

# Help

To open all the help pages, run `:help doge`.
Expand Down
44 changes: 30 additions & 14 deletions autoload/doge/generate.vim
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ set cpoptions&vim
function! doge#generate#pattern(pattern) abort
" Assuming multiline function expressions won't be longer than 15 lines.
let l:lines_raw = getline('.', line('.') + 15)
let l:lines = map(l:lines_raw, {key, line ->
\ substitute(line, b:doge_pattern_single_line_comment, '' ,'g')})
let l:lines = map(l:lines_raw, { key, line ->
\ substitute(line, b:doge_pattern_single_line_comment, '' ,'g') })

" Skip if the cursor doesn't start with text.
if empty(trim(l:lines[0]))
Expand Down Expand Up @@ -48,7 +48,11 @@ function! doge#generate#pattern(pattern) abort
" Go through each parameter, match the regex, extract the token values and
" replace the 'parameters' key with the formatted version.
let l:formatted_params = []
let l:param_tokens = doge#token#extract(l:params, l:params_dict['match'], l:params_dict['match_group_names'])
let l:param_tokens = doge#token#extract(
\ l:params,
\ l:params_dict['match'],
\ l:params_dict['match_group_names']
\ )

" Preprocess the extracted parameter tokens.
try
Expand All @@ -58,31 +62,43 @@ function! doge#generate#pattern(pattern) abort
endtry

for l:param_token in l:param_tokens
let l:format = doge#token#replace(l:param_token, l:params_dict['format'])
let l:format = join(filter(l:format, "v:val !=# ''"), ' ')
if g:doge_comment_todo_suffix == v:false
let l:format = substitute(l:format, '\m\s*TODO\s*$', '', 'g')
let l:format = doge#token#replace(
\ l:param_token,
\ l:params_dict['format'][b:doge_doc_standard]
\ )
if type(l:format) == v:t_list
if g:doge_comment_todo_suffix == v:false
let l:format = map(l:format, { key, line ->
\ substitute(line, '\m\s*TODO\s*$', '', 'g') })
endif
call add(l:formatted_params, join(l:format, "\n"))
else
if g:doge_comment_todo_suffix == v:false
let l:format = substitute(l:format, '\m\s*TODO\s*$', '', 'g')
endif
call add(l:formatted_params, l:format)
endif
call add(l:formatted_params, l:format)
endfor
let l:tokens['parameters'] = l:formatted_params
endif

" Create the comment by replacing the tokens in the template with their
" corresponding values.
let l:comment = []
for l:line in a:pattern['comment']['template']
for l:line in a:pattern['comment']['template'][b:doge_doc_standard]
" If empty lines are present, just append them to ensure a whiteline is
" inserted rather then completely removed. This allows us to insert some
" whitelines in the comment template.
if empty(l:line)
call add(l:comment, l:line)
let l:line_replaced = doge#token#replace(l:tokens, l:line)
if empty(l:line) || empty(l:line_replaced)
call add(l:comment, '')
continue
elseif l:line_replaced ==# '-'
continue
endif

let l:line_replaced = split(doge#token#replace(l:tokens, l:line), "\n")
for l:replaced in l:line_replaced
call add(l:comment, l:replaced)
for l:replaced in split(l:line_replaced, "\n")
call add(l:comment, doge#indent#convert(l:replaced))
endfor
endfor

Expand Down
13 changes: 12 additions & 1 deletion autoload/doge/indent.vim
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ set cpoptions&vim

""
" @public
" Indent a string based on a given line its indent.
" Indent a string based on a given line its indent, based on the user setting.
function! doge#indent#add(lnum, text) abort
if &expandtab
return repeat(' ', indent(a:lnum)) . a:text
Expand All @@ -12,5 +12,16 @@ function! doge#indent#add(lnum, text) abort
endif
endfunction

""
" @public
" Convert spaces to tabs and tabs to spaces based on the user setting.
function! doge#indent#convert(text) abort
if &expandtab
return substitute(a:text, "\t", repeat(' ', shiftwidth()), 'g')
else
return substitute(a:text, repeat(' ', shiftwidth()), "\t", 'g')
endif
endfunction

let &cpoptions = s:save_cpo
unlet s:save_cpo
Loading

0 comments on commit ca67b50

Please sign in to comment.