Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RFC: Towards consistent style, part 2: a documentation guide #790

Open
johnnychen94 opened this issue Mar 30, 2019 · 1 comment
Open

RFC: Towards consistent style, part 2: a documentation guide #790

johnnychen94 opened this issue Mar 30, 2019 · 1 comment
Labels
documentation Modifies the documentation.

Comments

@johnnychen94
Copy link
Member

johnnychen94 commented Mar 30, 2019

This is the continuation of https://github.com/JuliaImages/Images.jl/issues/767 on documentation style

!!! Warning ⚠️

This is not a guideline yet, at present it's just some material to inspire thoughts.

Why we need an extra documentation guide for Images.jl?

Many image processing algorithms are too complicated that well-explained documentations is absolutely necessary. The old way of documentation in other languages is to write step-by-step tutorials. For julia, Documenter.jl provides an alternative -- we can make everything documented in docstring, then the (step-by-step) tutorial of the function can be generated.

However, julia guide on documentation isn't prepared for this kind of docstring work -- most docstring in julia are quite small.

What part would this guide contain?

  1. what are contained in a complete docstring?
  2. best practice to write each part of docstring.

Based on julia documentation, a complete docstring contains:

  1. [Required] signature of a function
  2. [Required] a single one-line sentence
  3. [Recomended] detailed description
  4. [Optional] argument list when really necessary
  5. [Recomended] code examples
  6. [Recomended] reference list
  7. [Recomended] hints to related functions

detailed explaination

docstring with math

if you need to write math in your docstring, it's very likely that you need to write a huge mount of math, it's recommended to use

@doc raw"""
``\LaTeX``
"""
imhist # single backslash `\`

instead of

"""
``\\LaTeX``
"""
imhist # double backslash `\\`

The former helps you debug your latex codes with your local latex compiler

One exception: if you just need some symbols, using Unicode (e.g., α) is sufficient. -- REPL support unicode, but doesn't support latex.

argument list

do I need an argument list?

You only need an detailed argument list when there is arguments that control the behavior and result of the function, otherwise, good design on names and method signature is enough.

argument list style

julia documentation uses the following style

# Arguments
- `n::Integer`: the number of elements to compute.
- `dim::Integer=1`: the dimensions along which to perform the computation.

we take another way,

# Arguments
Various options for the parameters of this function are described in more detail
below.

## Choices for `n::Interger`
the number of elements to compute.

## Choices for `dim::Integer=1`
the dimensions along which to perform the computation.

This is because most arguments are too complicated to be explained using one-line sentence.

img arugment(s)

Most image processing functions have img argument(s):

  • if there's only one single img (e.g., binarize(alg::Otsu, img::AbstractArray{T,2}) where T<: Colorant), you don't need to explain it unless it's necessary
  • if there're more than one img arguments, (e.g., ssd(img1, img2)), you need to explain what each img represents.

code examples

the challenge with good-quality code example is:

  • we need incorporate jldoctest with CI to make sure code example works as expected -- otherwise it might be a misleading.
  • images are usually large arrays.
  • some function works with random.

(TODO: Literate provides a way to write such kind of demos/tutorials, but I'm not sure if this works well with docstring examples.)

reference list

The following serves as a recommendation

# References
1. apa style reference
    > description of reference1
2. apa style reference
    > description of reference2

APA style is not compulsory, the point is: you can't just simply provide an url link.

For example,

"""
...
# References
1. Rudin, L. I., Osher, S., and Fatemi, E. (1992). Nonlinear total variation based noise removal algorithms. Physica D: nonlinear phenomena, 60(1-4), 259-268.
    > The classic paper that uses variational model to do image denoising.
    >
    > detailed description
2. Goldstein, T., & Osher, S. (2009). The split Bregman method for L1-regularized problems. SIAM journal on imaging sciences, 2(2), 323-343.
    > use Split Bregman method to solve ROF model
    > 
    > https://epubs.siam.org/doi/abs/10.1137/080725891
"""
denoise(algo::ROF, img)

hints to related functions

syntax of @ref

The following ways are recommended:

  • generic
See also: [`binarize`](@ref)
  • with signature specified
see also: [`binarize(::BinarizationAlgorithm, img)`](@ref)
  • with description
See also:
* [`binarize`](@ref) returns a binarized image using [`BinarizationAlgorithm`](@ref)
* [`Otsu`](@ref) construct an instance of `Otsu` binarization algorithm.
@johnnychen94
Copy link
Member Author

johnnychen94 commented Mar 30, 2019

RFC: Detailed description

In #772 and JuliaImages/ImageBinarization.jl#23, we reach a consensus that a julia way of implementing image processing algorithm is to take advantage of multiple dispatch

abstract type BinarizationAlgorithm end
struct Otsu <: BinarizationAlgorithm end
struct Yen <: BinarizationAlgorithm end

function binarize(algo::Otsu, img)
# implementation
end

function binarize(algo::Yen, img)
# implementation
end

However, we will meet problem when writing docstring to each binarize methods. Users will get pages of docstring with a single ?binarize

Why this is terrible?

  • users type ?binarize much more often than ?binarize(Otsu(),img)
  • users don't want to see implementation details of Yen when they're looking for docstring of Otsu
  • too much documentation equals to no documentation.
  • users can't find out how many methods are implemented from ?binarize

The reason for this behavior is

When retrieving documentation for a generic function, the metadata for each method is concatenated with the catdoc function, which can of course be overridden for custom types.

One way to solve this problem is to

  • move docstring to Otsu, Yen and etc. -- They're inherited type.
  • use one-line documentation for specific methods unless it's necessary -- no examples provided in specific methods

In general, only the most generic method should be documented, or even the function itself (i.e. the object created without any methods by function bar end). Specific methods should only be documented if their behaviour differs from the more generic ones. In any case, they should not repeat the information provided elsewhere.

For example:

"""
    Otsu()

one-line description

# Algorithm details
...

# Argument list
...

# Examples
...

# References
...

See also: [`binarize`](@ref ), [`BinarizationAlgorithm`](@ref)
"""
struct Otsu <: BinarizationAlgorithm end

"""
    binarize(algo::Otsu, img)

one-line description

Check [`ImageBinarization.Otsu`](@ref ImageBinarization.Otsu) for more details
"""
function binarize(algo::Otsu, img)
# implementation
end

# In ImageBinarization.jl
"""
    binarize(algo::BinarizationAlgorithm, img)

one-line description

detailed explaination

# Example
...

See also: [`BinarizationAlgorithm`](@ref)
"""
binarize

By doing this, we can get a more concise result with ?binarize

result of `?binarize(Otsu(), img)`
  binarize(algorithm::Otsu,  img::AbstractArray{T,2}) where T <: Colorant

  Binarizes the image using Otsu histogram thresholding method.

  Under the assumption that the image histogram is bimodal the binarization threshold is set so
  that the resultant between-class variance is maximal.

  Check Otsu for more details
result of `?binarize`
 binarize(algorithm::Otsu,  img::AbstractArray{T,2}) where T <: Colorant

  Binarizes the image using Otsu histogram thresholding method.

  Under the assumption that the image histogram is bimodal the binarization threshold is set so
  that the resultant between-class variance is maximal.

  Check Otsu for more details
────────────────────────────────────────────────────────────────────────────────────────────────
  binarize(algorithm::BinarizationAlgorithm,  img::AbstractArray{T,2}) where T <: Colorant

  Returns the binarized image as an Array{Gray{Bool},2}

  Example
  ≡≡≡≡≡≡≡≡≡

  Binarizes the "cameraman" image in the TestImages package using Otsu method. All other
  algorithms are used in a similar way.

  using TestImages, ImageBinarization
  
  img = testimage("cameraman")
  binarize_method = Otsu()
  img_binary = binarize(binarize_method, img)

  See also: BinarizationAlgorithm

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation Modifies the documentation.
Projects
None yet
Development

No branches or pull requests

1 participant