ignatov/intellij-erlang

generate documentation with code module

ignatov opened this issue · 9 comments

I'm trying to call code:get_doc in order to fetch documentation for standard modules.

Something like that should work, but I failed to run it.

MODULE=$1
FUNCTION=$2
ARITY=$3

erl -noshell -eval "{ok, {Docs, _}} = code:get_doc($MODULE), FunctionDocs = [Doc || #doc_v1{anno = {Function, Arity}, doc = Doc} <- Docs#docs_v1.docs, Function =:= $FUNCTION, Arity =:= $ARITY], io:format('~s~n', [FunctionDocs]), init:stop()." -run init stop > docs.txt

@kvakvs could you please assist?

kpy3 commented

Try this:

getdocs:

#!/usr/bin/env escript
%% -*- erlang -*-
%%! -start_epmd false

-include_lib("kernel/include/eep48.hrl").

main([Mod,Fun,Arity]) ->
  {ok, Docs} = code:get_doc(list_to_existing_atom(Mod)),
  Key ={function,list_to_existing_atom(Fun),list_to_integer(Arity)},
  {Key,_Location,FunSig,FunDocMap,Sig} = lists:keyfind(Key,1,Docs#docs_v1.docs),
  erlang:display({fun_sig, FunSig}),
  erlang:display({fun_doc_raw, maps:get(<<"en">>, FunDocMap)}),
  erlang:display({since, maps:get(since, Sig)}).
$ escript getdocs maps get 2
-module(main).
-author("ignatov").

-export([hello/0]).

hello() ->
  Predicate = fun({{function, quote, 2}, _, _, _, _}) -> true; (_) -> false end,
  {ok, Docs} = code:get_doc(ftp),
  {docs_v1,
    _Anno,
    _BeamLanguage,
    _Format,
    _ModuleDoc,
    _Metadata,
    FunctionDocs} = Docs,

  Res = lists:filter(Predicate, FunctionDocs),
%%  io:format("~p", [Res]),
  [{_Signature, _Location, _Spec, DocMap, _EditUrlMap}] = Res,

  ErlangStructure = maps:get(<<"en">>, DocMap),

  io:format("~p", [ErlangStructure]),

  ShellDoc = shell_docs:get_doc(ftp, quote, 2),

  io:format("~p", [ShellDoc]),
%%  shell_docs:render(ftp, ShellDoc),

  io:format("~p", [ShellDoc]),

  ok.

my half-backed version is the following ;)

even shorter

-module(doc_doc).
-author("ignatov").

%% API
-export([doc/0]).

doc() ->
  io:format("~p", [(shell_docs:get_doc(ftp, quote, 2))]).
  

And now I want to render it to HTML, but I don't know how to use shell_docs/render functions :)

-module(doc_doc).
-author("ignatov").

%% API
-export([doc/0]).

doc() ->

  Module = ftp,
  Function = quote,
  Arity = 2,


  {ok, Doc} = code:get_doc(Module),
  Config = #{encoding => unicode, ansi => false, columns => 100},
  Render = shell_docs:render(Module, Function, Arity, Doc, Config),
  io:format("~p", [Render]),

  ok

.


that prints

[["\n",
  [[160,<<" quote(Pid, Command) -> [FTPLine]">>],"\n"],
  "\n",
  [[32,32,84,121,112,101,115,58,10,32,32,32,32,<<"Pid = pid()">>,10,32,32,32,
    32,<<"Command = string()">>,10,32,32,32,32,<<"FTPLine = string()">>,10,10,
    32,32,78,<<"ote">>,58,10,32,32,32,32,
    <<"The telnet end of line characters, from the FTP protocol definition, CRLF, for\n    example, \"\\\\r\\\\n\" has been removed.">>,
    10,10,32,32,
    <<"Sends an arbitrary FTP command and returns verbatim a list of the lines sent back by\n  the FTP server. This function is intended to give application accesses to FTP commands\n  that are server-specific or that cannot be provided by this FTP client.">>,
    10,10,32,32,78,<<"ote">>,58,10,32,32,32,32|
    <<"FTP commands requiring a data connection cannot be successfully issued with this\n    function.">>],
   "\n"]]]

@kpy3 or @kvakvs need yours help to go further

kvakvs commented

I don't get where this data is going. It will be specific for this current SDK only.
Do you want to preload this when SDK is added? Can this be extracted from the AST, i think that feature with doc on mouse-over already exists and works for standard library?

Not really, just compare.

image
kpy3 commented

@kpy3 or @kvakvs need yours help to go further

It looks like an iolist, so slightly modified script can output readable text:

-module(doc_doc).
-author("ignatov").

%% API
-export([doc/0]).

doc() ->

  Module = ftp,
  Function = quote,
  Arity = 2,


  {ok, Doc} = code:get_doc(Module),
  Config = #{encoding => unicode, ansi => false, columns => 100},
  Render = shell_docs:render(Module, Function, Arity, Doc, Config),
  io:format("~ts", [iolist_to_binary(Render)]),

  ok

.

output:

% erlc doc_doc.erl 
% erl -noshell -noinput -s doc_doc doc -s init stop

  -spec quote(Pid :: pid(), Cmd :: string()) -> [FTPLine :: string()].

  Note:
    The telnet end of line characters, from the FTP protocol definition, CRLF, for
    example, "\\r\\n" has been removed.

  Sends an arbitrary FTP command and returns verbatim a list of the lines sent back by
  the FTP server. This function is intended to give application accesses to FTP commands
  that are server-specific or that cannot be provided by this FTP client.

  Note:
    FTP commands requiring a data connection cannot be successfully issued with this
    function.
kpy3 commented

Hmmm iolist_to_binary seems unneeded and can be removed:

-module(doc_doc).
-author("ignatov").

%% API
-export([doc/0]).

doc() ->

  Module = ftp,
  Function = quote,
  Arity = 2,


  {ok, Doc} = code:get_doc(Module),
  Config = #{encoding => unicode, ansi => false, columns => 100},
  Render = shell_docs:render(Module, Function, Arity, Doc, Config),
  io:format("~ts", [Render]),

  ok

.

Ah, ~ts. Thanks.