Skip to content

Commit eb40e71

Browse files
committed
doc: create man pages for apps with source files split up in sub dirs
1 parent 583e2f9 commit eb40e71

File tree

7 files changed

+120
-57
lines changed

7 files changed

+120
-57
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,9 @@ JAVADOC-GENERATED
116116

117117
*.1
118118
*.3
119+
*.4
120+
*.6
121+
*.7
119122

120123
# Anchored from $ERL_TOP
121124
/bin

lib/stdlib/src/man_docs.erl

Lines changed: 23 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -20,31 +20,35 @@
2020
%% %CopyrightEnd%
2121
%%
2222
-module(man_docs).
23+
-moduledocs false.
24+
2325
-include_lib("kernel/include/eep48.hrl").
2426

25-
-export([module_to_manpage/2, module_to_manpage/3, markdown_to_manpage/2]).
27+
-export([module_to_manpage/3, module_to_manpage/4, markdown_to_manpage/3]).
2628

2729
%% Formats a module documentation as a roff man page.
2830
%% Fetches the documentation for a module with `code:get_doc/1`
29-
-spec module_to_manpage(Module, Path) -> unicode:chardata() when
31+
-spec module_to_manpage(Module, Path, Section) -> unicode:chardata() when
3032
Module :: module(),
31-
Path :: string().
32-
module_to_manpage(Module, Path) when is_atom(Module) ->
33+
Path :: string(),
34+
Section :: string().
35+
module_to_manpage(Module, Path, Section) when is_atom(Module) ->
3336
case code:get_doc(Module) of
3437
{ok, Docs} ->
35-
module_to_manpage(Module, Path, Docs);
38+
module_to_manpage(Module, Path, Docs, Section);
3639
_Error ->
3740
~""
3841
end.
39-
-spec module_to_manpage(Module, Path, Docs) -> unicode:chardata() when
42+
-spec module_to_manpage(Module, Path, Docs, Section) -> unicode:chardata() when
4043
Module :: module(),
4144
Path :: string(),
42-
Docs :: #docs_v1{}.
43-
module_to_manpage(_Module, _Path, #docs_v1{module_doc = None}) when None =:= none; None =:= hidden ->
45+
Docs :: #docs_v1{},
46+
Section :: string().
47+
module_to_manpage(_Module, _Path, #docs_v1{module_doc = None}, _Section) when None =:= none; None =:= hidden ->
4448
~"";
45-
module_to_manpage(Module, Path, #docs_v1{module_doc = #{~"en" := ModuleDoc}, docs = AllDocs})
49+
module_to_manpage(Module, Path, #docs_v1{module_doc = #{~"en" := ModuleDoc}, docs = AllDocs}, Section)
4650
when is_atom(Module) ->
47-
PreludeNDescription = markdown_to_manpage(ModuleDoc, Path),
51+
PreludeNDescription = markdown_to_manpage(ModuleDoc, Path, Section),
4852

4953
Types = [Doc || {{type,_,_},_,_,_,_}=Doc <- AllDocs],
5054
TypesSection = format_section("DATA TYPES", Types, Module, AllDocs),
@@ -56,10 +60,10 @@ module_to_manpage(Module, Path, #docs_v1{module_doc = #{~"en" := ModuleDoc}, doc
5660
iolist_to_binary([PreludeNDescription, TypesSection, FunctionsSection, CallbacksSection]).
5761

5862
%% Formats markdown as a roff man page.
59-
-spec markdown_to_manpage(binary() | shell_docs:chunk_elements(), file:filename()) -> binary().
60-
markdown_to_manpage(Markdown, Path) when is_binary(Markdown) ->
61-
markdown_to_manpage(shell_docs_markdown:parse_md(Markdown), Path);
62-
markdown_to_manpage(MarkdownChunks, Path) ->
63+
-spec markdown_to_manpage(binary() | shell_docs:chunk_elements(), file:filename(), string()) -> binary().
64+
markdown_to_manpage(Markdown, Path, Section) when is_binary(Markdown) ->
65+
markdown_to_manpage(shell_docs_markdown:parse_md(Markdown), Path, Section);
66+
markdown_to_manpage(MarkdownChunks, Path, Section) ->
6367
Path1 = filename:absname(Path),
6468
App = case filename:split(string:prefix(Path1, os:getenv("ERL_TOP"))) of
6569
["/", "lib", AppStr | _] ->
@@ -80,8 +84,8 @@ markdown_to_manpage(MarkdownChunks, Path) ->
8084
Extension = filename:extension(Path),
8185
FileName = list_to_binary(filename:rootname(filename:basename(Path), Extension)),
8286
Name = get_name(MarkdownChunks, FileName),
83-
Prelude = io_lib:format(".TH ~s 3 \"~s ~s\" \"Ericsson AB\" \"Erlang Module Definition\"\n",
84-
[Name, atom_to_binary(App), Version]),
87+
Prelude = io_lib:format(".TH ~s ~s \"~s ~s\" \"Ericsson AB\" \"Erlang Module Definition\"\n",
88+
[Name, Section, atom_to_binary(App), Version]),
8589
I = conv(MarkdownChunks, Name),
8690
iolist_to_binary([Prelude|I]).
8791

@@ -113,10 +117,11 @@ conv([{h1,_,[Head]}|T],_) ->
113117
Name = ~".SH NAME\n",
114118
Desc = ~".SH DESCRIPTION\n",
115119
[Name,Head,$\n,Desc|format(T)];
116-
conv([H|T], Head) ->
120+
conv([{p,_,_}=ShortDesc0|T], Head) ->
117121
Name = ~".SH NAME\n",
118122
Desc = ~".SH DESCRIPTION\n",
119-
[Name,Head,~" - ",format_one(H),$\n,Desc|format(T)].
123+
[~".PP\n"|ShortDesc] = format_one(ShortDesc0),
124+
[Name,Head,~B" \- ",ShortDesc,$\n,Desc|format(T)].
120125

121126
escape(Text) when is_list(Text) ->
122127
escape(iolist_to_binary(Text));

lib/stdlib/src/shell_docs.erl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -618,6 +618,7 @@ render_type(Module, D) ->
618618
render_type(Module, D, #{}).
619619

620620
%% extract AST raw type specifications.
621+
-doc false.
621622
-spec extract_type_specs(module()) -> map().
622623
extract_type_specs(Module) ->
623624
maybe

lib/stdlib/test/shell_docs_SUITE.erl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -326,7 +326,7 @@ render_man(_Config) ->
326326
#{source_path := Path} -> Path;
327327
#{} -> proplists:get_value(source, proplists:get_value(compile, Mod:module_info()))
328328
end,
329-
man_docs:module_to_manpage(Mod, Path1, D)
329+
man_docs:module_to_manpage(Mod, Path1, D, "3")
330330
catch _E:R:ST ->
331331
io:format("Failed to render man page for ~p~n~p:~p~n~p~n",
332332
[Mod,R,ST,D]),

make/doc.mk

Lines changed: 60 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -50,19 +50,38 @@ endif
5050
# ----------------------------------------------------
5151
# Man dependencies
5252
# ----------------------------------------------------
53-
ERL_FILES := $(wildcard $(APP_SRC_DIR)/*.erl)
54-
ERL_FILES_WITH_DOC := $(shell grep -L '-moduledoc false.' $(ERL_FILES))
53+
ERL_FILES := $(wildcard $(APP_SRC_DIR)/*.erl) $(wildcard $(APP_SRC_DIR)/*/*.erl) $(wildcard $(APP_DIR)/preloaded/src/*.erl)
54+
ERL_STRIP := $(strip $(ERL_FILES))
55+
ifneq ($(ERL_STRIP),)
56+
ERL_FILES_WITH_DOC := $(shell grep -L "moduledoc false." $(ERL_FILES))
57+
else
58+
ERL_FILES_WITH_DOC :=
59+
endif
60+
ERL_FILENAMES_ONLY := $(notdir $(ERL_FILES_WITH_DOC))
5561
MAN1_DEPS?=$(wildcard */*_cmd.md)
56-
MAN3_DEPS?=$(wildcard */references/*.md) $(wildcard references/*.md) \
57-
$(wildcard */src/*.md) $(wildcard src/*.md) \
58-
$(ERL_FILES_WITH_DOC)
59-
MAN3_DEPS_FILTERED=$(filter-out $(wildcard */references/*_cmd.md) $(wildcard references/*_cmd.md),$(MAN3_DEPS))
60-
62+
MAN3_DEPS_UNFILTERED?=$(wildcard */src/*.md) $(wildcard src/*.md) \
63+
$(wildcard */references/*.md) $(wildcard references/*.md) \
64+
$(ERL_FILENAMES_ONLY)
65+
MAN4_DEPS=$(wildcard references/app.md references/config.md references/appup.md references/rel.md \
66+
references/relup.md references/script.md references/diameter_dict.md references/erlang.el.md)
67+
MAN3_DEPS=$(filter-out $(wildcard */references/*_cmd.md) $(wildcard references/*_cmd.md) $(MAN4_DEPS),$(MAN3_DEPS_UNFILTERED))
68+
MAN6_DEPS=$(wildcard *_app.md)
69+
MAN7_DEPS=$(wildcard $(APP_DIR)/mibs/*.mib)
6170
MAN1_PAGES=$(MAN1_DEPS:references/%_cmd.md=$(MAN1DIR)/%.1)
62-
MAN3_PAGES=$(MAN3_DEPS_FILTERED:$(APP_SRC_DIR)/%.erl=$(MAN3DIR)/%.3)
63-
MAN3_PAGES+=$(MAN3_DEPS_FILTERED:references/%.md=$(MAN3DIR)/%.3)
64-
MAN3_PAGES+=$(MAN3_DEPS_FILTERED:src/%.md=$(MAN3DIR)/%.3)
65-
71+
MAN3_PAGES=$(MAN3_DEPS:%.erl=$(MAN3DIR)/%.3)
72+
MAN3_PAGES+=$(MAN3_DEPS:src/%.md=$(MAN3DIR)/%.3)
73+
MAN4_PAGES=$(MAN4_DEPS:references/%.md=$(MAN4DIR)/%.4)
74+
MAN6_PAGES=$(MAN6_DEPS:%_app.md=$(MAN6DIR)/%.6)
75+
MAN7_PAGES=$(MAN7_DEPS:$(APP_DIR)/mibs/%.mib=$(MAN7DIR)/%.7)
76+
77+
# 1. Find all possible source directories recursively
78+
ifneq ($(wildcard $(APP_SRC_DIR)),)
79+
ERL_SRC_DIRS := $(shell find $(APP_SRC_DIR) -type d)
80+
else
81+
ERL_SRC_DIRS :=
82+
endif
83+
# 2. Tell make to search for .erl files in all those directories
84+
vpath %.erl $(ERL_SRC_DIRS) $(APP_DIR)/preloaded/src
6685

6786
# ----------------------------------------------------
6887
# Targets
@@ -74,9 +93,19 @@ endif
7493
ifneq ($(MAN1_DEPS),)
7594
DEFAULT_DOC_TARGETS+=man
7695
endif
77-
ifneq ($(MAN3_DEPS_FILTERED),)
96+
ifneq ($(MAN3_DEPS),)
97+
DEFAULT_DOC_TARGETS+=man
98+
endif
99+
ifneq ($(MAN4_DEPS),)
100+
DEFAULT_DOC_TARGETS+=man
101+
endif
102+
ifneq ($(MAN6_DEPS),)
103+
DEFAULT_DOC_TARGETS+=man
104+
endif
105+
ifneq ($(MAN7_DEPS),)
78106
DEFAULT_DOC_TARGETS+=man
79107
endif
108+
80109
DOC_TARGETS?=$(DEFAULT_DOC_TARGETS)
81110

82111
EX_DOC_WARNINGS_AS_ERRORS?=default
@@ -93,21 +122,33 @@ $(HTMLDIR)/index.html: $(HTML_DEPS) docs.exs $(ERL_TOP)/make/ex_doc.exs
93122

94123
html: $(HTMLDIR)/index.html
95124

96-
man: $(MAN1_PAGES) $(MAN3_PAGES)
125+
man: $(MAN1_PAGES) $(MAN3_PAGES) $(MAN4_PAGES) $(MAN6_PAGES) $(MAN7_PAGES)
97126

98127
MARKDOWN_TO_MAN=$(ERL_TOP)/make/markdown_to_man.escript
99128

100129
man1/%.1: references/%_cmd.md $(MARKDOWN_TO_MAN)
101-
escript$(EXEEXT) $(MARKDOWN_TO_MAN) -o $(MAN1DIR) $<
130+
@escript$(EXEEXT) $(MARKDOWN_TO_MAN) -o $(MAN1DIR) $<
102131

103132
man3/%.3: src/%.md $(MARKDOWN_TO_MAN)
104-
escript$(EXEEXT) $(MARKDOWN_TO_MAN) -o $(MAN3DIR) $<
133+
@escript$(EXEEXT) $(MARKDOWN_TO_MAN) -o $(MAN3DIR) $<
134+
135+
man3/%.3: %.erl $(MARKDOWN_TO_MAN)
136+
@escript$(EXEEXT) $(MARKDOWN_TO_MAN) -o $(MAN3DIR) $<
137+
138+
man4/%.4: references/%.md $(MARKDOWN_TO_MAN)
139+
@escript$(EXEEXT) $(MARKDOWN_TO_MAN) -o $(MAN4DIR) -s 4 $<
105140

106-
man3/%.3: references/%.md $(MARKDOWN_TO_MAN)
107-
escript$(EXEEXT) $(MARKDOWN_TO_MAN) -o $(MAN3DIR) $<
141+
man6/%.6: %_app.md $(MARKDOWN_TO_MAN)
142+
@escript$(EXEEXT) $(MARKDOWN_TO_MAN) -o $(MAN6DIR) $<
108143

109-
man3/%.3: ../src/%.erl $(MARKDOWN_TO_MAN)
110-
escript$(EXEEXT) $(MARKDOWN_TO_MAN) -o $(MAN3DIR) $<
144+
man7/%.7: $(APP_DIR)/mibs/%.mib
145+
@mkdir -p man7
146+
$(eval REL_PATH := $(patsubst $(ERL_TOP)/lib/%,%,$(abspath $<)))
147+
$(eval APP_NAME := $(shell echo $(firstword $(subst /, ,$(REL_PATH))) | tr '[:lower:]' '[:upper:]'))
148+
$(eval MIB_NAME := $(basename $(notdir $<)))
149+
@echo .TH $(MIB_NAME) 7 \"$(APP_NAME)\" \"Erlang/OTP\" \"MIB\" > $@
150+
@echo .nf >> $@
151+
@grep -v '^--' $< >> $@
111152

112153
# ----------------------------------------------------
113154

make/markdown_to_man.escript

Lines changed: 29 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -27,44 +27,54 @@
2727

2828
main(Args) ->
2929
try
30-
case parse_args(Args, ".", []) of
30+
case parse_args(Args, "3", ".", []) of
3131
{_,[]} ->
3232
ok;
33-
{OutDir,[_|_]=Files} ->
34-
convert_files(Files, OutDir)
33+
{OutDir,Section,[_|_]=Files} ->
34+
convert_files(Files, OutDir, Section)
3535
end
3636
catch
3737
throw:{error,Error} ->
3838
io:put_chars(standard_error, Error)
3939
end.
4040

41-
parse_args(["-o",OutDir|As], _OutDir, FilesAcc) ->
42-
parse_args(As, OutDir, FilesAcc);
43-
parse_args([F|Fs], OutDir, FilesAcc) ->
44-
parse_args(Fs, OutDir, [F|FilesAcc]);
45-
parse_args([], OutDir, FilesAcc) ->
46-
{OutDir,lists:reverse(FilesAcc)}.
41+
parse_args(["-s", Num|As], _Section, OutDir, FilesAcc) ->
42+
case lists:member(Num, ["1","3","4","6"]) of
43+
true ->
44+
parse_args(As, Num, OutDir, FilesAcc);
45+
false ->
46+
fail(io_lib:format("Invalid section number: ~s", [Num]))
47+
end;
48+
parse_args(["-o",OutDir|As], Section, _OutDir, FilesAcc) ->
49+
parse_args(As, Section, OutDir, FilesAcc);
50+
parse_args([F|Fs], Section, OutDir, FilesAcc) ->
51+
parse_args(Fs, Section, OutDir, [F|FilesAcc]);
52+
parse_args([], Section, OutDir, FilesAcc) ->
53+
{OutDir, Section, lists:reverse(FilesAcc)}.
4754

48-
convert_files([F|Fs], OutDir) ->
49-
convert_file(F, OutDir),
50-
convert_files(Fs, OutDir);
51-
convert_files([], _) ->
55+
convert_files([F|Fs], OutDir, Section) ->
56+
convert_file(F, OutDir, Section),
57+
convert_files(Fs, OutDir, Section);
58+
convert_files([], _, _) ->
5259
ok.
5360

54-
convert_file(Name, OutDir) ->
61+
convert_file(Name, OutDir, Section) ->
5562
case filename:extension(Name) of
5663
".md" ->
5764
Base0 = filename:rootname(filename:basename(Name), ".md"),
5865
case lists:reverse(Base0) of
5966
"dmc_" ++ Base1 ->
6067
Base2 = lists:reverse(Base1),
61-
convert_markdown_to_man(Base2, OutDir, Name, ".1");
68+
convert_markdown_to_man(Base2, OutDir, Name, "1");
69+
"ppa_" ++ Base1 ->
70+
Base2 = lists:reverse(Base1),
71+
convert_markdown_to_man(Base2, OutDir, Name, "6");
6272
_ ->
63-
convert_markdown_to_man(Base0, OutDir, Name, ".3")
73+
convert_markdown_to_man(Base0, OutDir, Name, Section)
6474
end;
6575
".erl" ->
6676
Base0 = filename:rootname(filename:basename(Name), ".erl"),
67-
Output = man_docs:module_to_manpage(list_to_atom(Base0), Name),
77+
Output = man_docs:module_to_manpage(list_to_atom(Base0), Name, "3"),
6878
Outfile = filename:join(OutDir, Base0 ++ ".3"),
6979
_ = filelib:ensure_dir(Outfile),
7080
case Output =/= <<>> andalso file:write_file(Outfile, Output) of
@@ -80,11 +90,11 @@ convert_file(Name, OutDir) ->
8090
end.
8191

8292
convert_markdown_to_man(Base, OutDir, Name, Section) ->
83-
OutFile = filename:join(OutDir, Base ++ Section),
93+
OutFile = filename:join(OutDir, Base ++ "." ++ Section),
8494
_ = filelib:ensure_dir(OutFile),
8595
case file:read_file(Name) of
8696
{ok,Markdown} ->
87-
Man = man_docs:markdown_to_manpage(Markdown, Name),
97+
Man = man_docs:markdown_to_manpage(Markdown, Name, Section),
8898
case file:write_file(OutFile, Man) of
8999
ok ->
90100
ok;

make/otp.mk.in

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,9 @@ DOCDIR=.
218218
HTMLDIR = $(DOCDIR)/html
219219
MAN1DIR = $(DOCDIR)/man1
220220
MAN3DIR = $(DOCDIR)/man3
221+
MAN4DIR = $(DOCDIR)/man4
222+
MAN6DIR = $(DOCDIR)/man6
223+
MAN7DIR = $(DOCDIR)/man7
221224
CHUNKSDIR = $(DOCDIR)/chunks
222225

223226
ifeq ($(HTMLLOGO),)

0 commit comments

Comments
 (0)