Skip to content

Commit

Permalink
doc: parse and document notifications (#1471)
Browse files Browse the repository at this point in the history
* Parse records and doc comment in zotonic_notifications.hrl to produce
  a list of notifications.
* Commit the meta doc files because we cannot run Erlang on Read the Docs.
  • Loading branch information
ddeboer committed Oct 7, 2016
1 parent d76d54a commit 0bef4ac
Show file tree
Hide file tree
Showing 260 changed files with 3,451 additions and 492 deletions.
2 changes: 1 addition & 1 deletion doc/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@

# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
exclude_patterns = ['_build', '**/doc-*', '**/meta-*']
exclude_patterns = ['_build', '**/doc-*', '**/meta-*', '**/includes']

# The reST default role (used for this markup: `text`) to use for all documents.
#default_role = None
Expand Down
21 changes: 17 additions & 4 deletions doc/developer-guide/notifications.rst
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ back. They can do this in various ways described in the methods below.
Notification types
------------------

.. _notification-notify:

notify
^^^^^^

Expand All @@ -69,16 +71,27 @@ This is used to get information from one of the observers. By
using the notification system it makes sure that modules are
decoupled.

.. _notification-map:

map
Call all observers and get a list of all answers.
^^^

Call all observers and get a list of all answers.

.. _notification-foldl:

foldl
Do a fold over all observers, high prio observers first.
^^^^^

Do a fold over all observers, high prio observers first.

.. _notification-foldr:

foldr
Do a fold over all observers, low prio observers first.
^^^^^

Do a fold over all observers, low prio observers first.

You can also send notifications from JavaScript.

.. _guide-notifications-observe:

Expand Down
8 changes: 0 additions & 8 deletions doc/index.rst
Original file line number Diff line number Diff line change
@@ -1,8 +1,3 @@
.. Zotonic documentation master file, created by
sphinx-quickstart on Tue Sep 11 07:05:17 2012.
You can adapt this file completely to your liking, but it should at least
contain the root `toctree` directive.
Zotonic |version| documentation
===============================

Expand Down Expand Up @@ -33,9 +28,6 @@ editors.

.. toctree::
:maxdepth: 2
:titlesonly:
:name: hello
:caption: dinges

user-guide/index

Expand Down
1 change: 1 addition & 0 deletions doc/ref/.gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
*~
meta-*
!notifications/includes/*
2 changes: 1 addition & 1 deletion doc/ref/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ All the nitty gritty details when the big picture has settled.
validators/index
directory-structure
icons
notifications
notifications/index
installation/requirements
configuration/zotonic-configuration
configuration/site-configuration
Expand Down
160 changes: 0 additions & 160 deletions doc/ref/notifications.rst

This file was deleted.

117 changes: 117 additions & 0 deletions doc/ref/notifications/.parse-notifications
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
#!/usr/bin/env escript

main([]) ->
File = "../../../include/zotonic_notifications.hrl",
{ok, Epp} = epp:open(File, []),
{ok, _} = epp:parse_erl_form(Epp),
Comments = erl_comment_scan:file(File),
Records = parse(Epp, Comments, []),

lists:foreach(
fun({Name, Doc, Fields}) ->

%% Always overwrite the generated meta file
MetaFilename = filename:join(["includes", "meta-" ++ Name ++ ".rst"]),
{ok, MetaFile} = file:open(MetaFilename, [write]),
write_record_to_rst(MetaFile, {Name, Doc, Fields}),
ok = file:close(MetaFile),

%% Only write the include file if it doesn't yet exist
NotificationFilename = filename:join(["includes", Name ++ ".rst"]),
case filelib:is_file(NotificationFilename) of
true ->
noop;
false ->
ok = file:write_file(NotificationFilename, [
".. include:: includes/meta-", Name, ".rst", "\n\n"
])
end
end,
Records
).

parse({ok, {attribute, Line, record, {RecordName, Fields}}}, Epp, Comments, Acc) ->
ParsedFields = lists:map(
fun (Field) ->
parse_record_field(Field)
end,
Fields
),
Record = {atom_to_list(RecordName), find_comment(Line, Comments), ParsedFields},
parse(Epp, Comments, [Record|Acc]);
parse({eof,_}, _Epp, _Comments, Acc) ->
lists:sort(Acc).


parse(Epp, Comments, Acc) ->
parse(epp:parse_erl_form(Epp), Epp, Comments, Acc).

parse_record_field({typed_record_field, {record_field, _Line, {atom, _Line, Name}}, {type, _Line, union, Props}}) ->
{Name, [parse_type(Prop) || Prop <- Props]};
parse_record_field({typed_record_field, {record_field, _Line, {atom, _Line, Name}}, {remote_type, _Line, Parts}}) ->
{Name, list_to_binary(lists:join(":", [atom_to_list(V) || {atom, _L, V} <- Parts]) ++ "()")};
parse_record_field({typed_record_field, {record_field, _Line, {atom, _Line, Name}}, {type, _Line, Type, _L}}) ->
{Name, Type};
parse_record_field({typed_record_field, {record_field, _Line, {atom, _Line, Name}, {_, _, _Default}}, {type, _Line, Type, _L}}) ->
{Name, Type};
parse_record_field({typed_record_field, {record_field, _Line, {atom, _Line, Name}, {nil, _}}, {type, _Line, Type, _L}}) ->
{Name, Type};
parse_record_field({record_field, _Line, {atom, _Line, Name}}) ->
{Name, unknown};
parse_record_field(Dunno) ->
io:format("dunno ~p\n", [Dunno]),
{unknown, unknown}.

parse_type({atom, _Line, Type}) ->
atom_to_list(Type);
parse_type({type, _Line, Type, _Props}) ->
atom_to_list(Type).

find_comment(MatchLine, [{_PreviousLine, 1, 0, Previous}, {Line, 1, 0, _Comment}|_Comments]) when Line >= MatchLine ->
Previous;
find_comment(MatchLine, [_Comment|Comments]) ->
find_comment(MatchLine, Comments);
find_comment(MatchLine, []) ->
MatchLine.

field_output({Name, Type}) when is_binary(Name) and is_binary(Type) ->
<<" - ", Name/binary, ": ``", Type/binary, "``\n">>;
field_output({Name, Types}) when is_list(Types) ->
field_output({atom_to_binary(Name, utf8), list_to_binary(lists:join("|", Types))});
field_output({Name, Type}) when is_binary(Type) ->
field_output({atom_to_binary(Name, utf8), Type});
field_output({Name, Type}) ->
field_output({atom_to_binary(Name, utf8), atom_to_binary(Type, utf8)}).

write_record_to_rst(File, {Name, Doc, Fields}) ->
{ParsedDoc, Type, Return} = parse_doc(Doc, [], "first", ""), "\n",

FieldsOutput = case lists:map(fun(Field) -> field_output(Field) end, Fields) of
[] -> <<"none">>;
List -> List
end,

file:write(
File,
[
".. _", Name, ":\n\n",
Name, "\n",
lists:duplicate(length(Name), $^), "\n\n",
ParsedDoc, "\n\n",
"Type: \n", " :ref:`notification-", Type, "`\n\n",
"Return: \n ", Return, "\n\n",
"``#", Name, "{}`` properties:\n" ++ FieldsOutput

]
).

parse_doc(["% @doc " ++ Doc|Docs], Acc, Type, Return) ->
parse_doc(Docs, [Doc ++ " \n"|Acc], Type, Return);
parse_doc(["% Type: " ++ Type|Docs], Acc, _Type, Return) ->
parse_doc(Docs, Acc, Type, Return);
parse_doc(["% Return: " ++ Return|Docs], Acc, Type, _Return) ->
parse_doc(Docs, Acc, Type, Return);
parse_doc(["% " ++ Doc|Docs], Acc, Type, Return) ->
parse_doc(Docs, [Doc ++ " \n"|Acc], Type, Return);
parse_doc([], Acc, Type, Return) ->
{lists:reverse(Acc), Type, Return}.
11 changes: 11 additions & 0 deletions doc/ref/notifications/acl.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
ACL notifications
-----------------

.. include:: includes/acl_context_authenticated.rst
.. include:: includes/acl_is_allowed.rst
.. include:: includes/acl_is_allowed_prop.rst
.. include:: includes/acl_is_owner.rst
.. include:: includes/acl_logoff.rst
.. include:: includes/acl_logon.rst
.. include:: includes/acl_mqtt.rst
.. include:: includes/acl_rsc_update_check.rst
15 changes: 15 additions & 0 deletions doc/ref/notifications/dispatch-url.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
Dispatch notifications
----------------------

.. include:: includes/content_types_dispatch.rst

.. include:: includes/dispatch_host.rst
.. include:: includes/dispatch_match.rst
.. include:: includes/dispatch_redirect.rst
.. include:: includes/dispatch_rewrite.rst

.. include:: includes/page_url.rst

.. include:: includes/url_abs.rst
.. include:: includes/url_rewrite.rst

0 comments on commit 0bef4ac

Please sign in to comment.