rafaqz / FieldDocTables.jl
1
module FieldDocTables
2

3
using DocStringExtensions, PrettyTables
4
import DocStringExtensions: Abbreviation, format
5

6
export FieldDocTable
7

8
struct FieldDocTable{L,T,TR,F} <: Abbreviation
9 18
    labels::L
10
    functions::T
11
    truncation::TR
12
    tableformat::F
13
    fenced::Bool
14
end
15

16
FieldDocTable(labels::L, functions::T; truncation=((100 for f in functions)...,), 
17 18
              tableformat=PrettyTableFormat(markdown), fenced=false) where {L,T} =
18
    FieldDocTable{L,T,typeof(truncation), typeof(tableformat)
19
                 }(labels, functions, truncation, tableformat, fenced)
20

21 18
FieldDocTable(nt::NamedTuple; kwargs...) = FieldDocTable(keys(nt), (nt...,); kwargs...)
22

23

24
function format(doctable::FieldDocTable, buf, doc)
25 18
    local docs = get(doc.data, :fields, Dict())
26 12
    local binding = doc.data[:binding]
27 18
    local object = Docs.resolve(binding)
28
    # On 0.7 fieldnames() on an abstract type throws an error. We then explicitly return
29
    # an empty vector to be consistent with the behaviour on v0.6.
30 18
    local fields = isabstracttype(object) ? Symbol[] : fieldnames(object)
31

32 18
    if !isempty(fields)
33

34
        # Fieldnames and passed in functions
35 18
        colnames = [:Field, doctable.labels...]
36 18
        funcdata = ([safestring.(f(object), doctable.truncation[i])...] for (i, f) in enumerate(doctable.functions))
37 18
        data = hcat([fields...], funcdata...)
38

39
        # Only add a fielddocs column if there are fielddocs
40 12
        fielddocs = []
41 18
        for field in fields
42 18
            if haskey(docs, field) && isa(docs[field], AbstractString)
43 18
                for line in split(docs[field], "\n")
44 18
                    fielddoc = isempty(line) ? "" : rstrip(line)
45
                end
46
            else
47 6
                fielddoc = ""
48
            end
49 18
            push!(fielddocs, fielddoc)
50
        end
51 18
        if any(d -> d != "", fielddocs)
52 18
            data = hcat(data, fielddocs)
53 18
            colnames = [colnames..., :Docs]
54
        end
55

56 18
        println(buf)
57 18
        doctable.fenced && println(buf, "```")
58 18
        pretty_table(buf, data, colnames; tf=doctable.tableformat)
59 18
        doctable.fenced && println(buf, "```")
60 18
        println(buf)
61
    end
62
end
63

64 0
safestring(::Nothing, n) = "nothing"
65 6
safestring(s, n) = truncate_utf8(string(s), n)
66

67
# Is there simpler way to do this?
68 12
truncate_utf8(s, n) = begin
69 12
    eo = lastindex(s)
70 6
    neo = 0
71 18
    for i = 1:n
72 18
      if neo < eo
73 12
          neo = nextind(s, neo)
74
      else
75 18
          break
76
      end
77
    end
78 18
    SubString(s, 1, neo)
79
end
80

81
end # module

Read our documentation on viewing source code .

Loading