Permalink
Browse files

Added support for .hrl files and tidied up naming conventions etc

  • Loading branch information...
hypernumbers committed Sep 18, 2013
1 parent df94bf6 commit 6bbf392a8cc013c03cbbd8528cb8d1eb73b9881a
View
@@ -5,5 +5,5 @@ deps
*.plt
*~
ebin/
md/.erl/*
md/.erl
src/
include/
View
@@ -19,7 +19,7 @@ The Literate Erlang, like Literate CoffeeScript is blocks of Markdown interpolat
The Literate Erlang compiler is implemented as a ``rebar`` plugin. For more details of ``rebar`` and its role in Erlang development see https://github.com/rebar/rebar.
Literate Erlang files end with ``.erl.md`` and are stored in the ``/md`` directory alonside the ``/src`` directory as part of a normal Erlang/OTP file structure. See the section on directory structure in the Erlang Design principles document http://www.erlang.org/doc/design_principles/applications.html#id73971
Literate Erlang files end with ``.erl.md`` or ``.hrl.md`` and are stored in the ``/src_md`` and ``/include_md`` directories alonside the ``/src`` and ``/include`` directories as part of a normal Erlang/OTP file structure. See the section on directory structure in the Erlang Design principles document http://www.erlang.org/doc/design_principles/applications.html#id73971
The compiler is implemented as a rebar pluging - the source code for it is in the directory ``/priv/rebar_plugins``.
@@ -28,7 +28,7 @@ The compiler works by transforming the Literate Erlang to plain erlang and then
Usage
-----
Write your literate-erlang files in the directory ``/md`` naming them like ``mymodule.erl.md``
Write your literate-erlang files in the directory ``/src_md`` naming them like ``mymodule.erl.md``. Header files are written in ``/include_md`` and named ``myheder.hrl.md``.
Compile them to normal erlang using:
``rebar literate-compile``
@@ -49,20 +49,19 @@ Implementation
The reverse compiler implmented as a ``rebar`` plugin called ``markup``.
This turns all files ending ``.erl`` in the ``src/`` into markdown files which are placed in an `md/` directory.
This turns all files ending ``.erl`` in the ``/src_md/.erl`` directory into markdown files which are placed in an `/src_md` directory and all ``.hrl`` files in ``include_md/.hrl`` directory into ``.hrl.md`` filed in ``/include_md``.
Usage
-----
The canonical version under version control is the markdown files in the ``md/`` directory. So the first step is to compile them to erlang:
The canonical version under version control is the markdown files in the ``src_md/`` directory. So the first step is to compile them to erlang:
``rebar compile_literate``
Then copy the ``.erl`` files to the directory ``md/.erl`` and edit them there.
Then copy the ``.erl`` files to the directory ``src_md/.erl`` and the `..hrl`` files to ``/include_md/.hrl`` and edit them there.
The production of working beam files is then:
``rebar markup``
``rebar literate_compile``
``rebar compile``
Baby Steps
==========
@@ -0,0 +1,5 @@
%%% Another testing record
-record(banjo, {
rupert = dict:new() :: dict(),
bennie
}).
View
@@ -0,0 +1,9 @@
This is the .hrl file for testing
```erlang
-record(test, {
bish = [] :: list(),
bosh = [] :: list()
}).
```
Which is nice
@@ -13,16 +13,19 @@
compile_literate(Config, _AppFile) ->
ErlOpts = rebar_config:get(Config, erl_opts, []),
SrcDirs = get_src_dirs(ErlOpts),
ok = clear_down(SrcDirs),
CompilerOptions = get_compiler_options(ErlOpts),
Files = [filelib:wildcard(X ++ "/../md/*.erl.md") || X <- SrcDirs],
[ok = compile_file(X, CompilerOptions) || X <- lists:merge(Files)],
ErlFiles = [filelib:wildcard(X ++ "/../src_md/*.erl.md") || X <- SrcDirs],
[ok = compile_file(X, CompilerOptions, erl) || X <- lists:merge(ErlFiles)],
HrlFiles = [filelib:wildcard(X ++ "/../include_md/*.hrl.md") || X <- SrcDirs],
[ok = compile_file(X, CompilerOptions, hrl) || X <- lists:merge(HrlFiles)],
ok.
compile_file(File, CompilerOptions) ->
compile_file(File, CompilerOptions, Type) ->
CWD = rebar_utils:get_cwd(),
{ok, Lines} = read_lines(CWD ++ "/" ++ File),
Source = make_erlang_source(Lines),
ok = write_source_and_compile(Source, File, CompilerOptions).
ok = write_source_and_compile(Source, File, CompilerOptions, Type).
make_erlang_source(Lines) ->
make_erl2(Lines, comment, []).
@@ -41,7 +44,7 @@ make_erl3(["\n" | T], erlang, Acc) ->
make_erl3([" " ++ Rest | T], erlang, Acc) ->
make_erl3(T, erlang, [Rest | Acc]);
make_erl3(["```" ++ _Rest | T], erlang, Acc) ->
make_erl2(T, comment, ["\n" | Acc]);
make_erl2(T, comment, ["%%%```\n" | Acc]);
%% Oops, not indented? lets comment out then
make_erl3(List, erlang, Acc) ->
make_erl2(List, comment, Acc).
@@ -68,18 +71,25 @@ get_src_dirs(ErlOpts) ->
get_compiler_options(ErlOpts) ->
proplists:delete(src_dirs, ErlOpts).
write_source_and_compile(Source, File, CompilerOptions) ->
write_source_and_compile(Source, File, CompilerOptions, Type) ->
File2 = filename:basename(filename:rootname(File)),
Dir = filename:dirname(File),
NewCompOpts = adjust_output_dirs(CompilerOptions, Dir),
Dir2 = Dir ++ "/../src/",
Dir2 = case Type of
erl -> Dir ++ "/../src/";
hrl -> Dir ++ "/../include/"
end,
ok = filelib:ensure_dir(Dir2),
ok = file:write_file(Dir2 ++ File2, Source),
case compile:file(Dir2 ++ File2, NewCompOpts) of
{ok, _} -> ok;
error -> io:format("Compile of ~p failed~n", [File])
end,
ok.
%% now compile the .erl files
case Type of
erl -> case compile:file(Dir2 ++ File2, NewCompOpts) of
{ok, _} -> ok;
error -> io:format("Compile of ~p failed~n", [File])
end,
ok;
hrl -> ok
end.
adjust_output_dirs(CompilerOptions, Dir) ->
@@ -92,3 +102,11 @@ adjust_output_dirs(CompilerOptions, Dir) ->
CompilerOptions
end.
clear_down(SrcDirs) ->
WildCards = lists:merge([[
X ++ "/../include/*",
X ++ "/../src/*"
] || X <- SrcDirs]),
Files = lists:merge([filelib:wildcard(X) || X <- WildCards]),
[ok = file:delete(X) || X <- Files],
ok.
@@ -14,20 +14,28 @@
markup(Config, _AppFile) ->
ErlOpts = rebar_config:get(Config, erl_opts, []),
SrcDirs = get_src_dirs(ErlOpts),
Files = lists:merge([filelib:wildcard(X ++ "/../md/.erl/*.erl") || X <- SrcDirs]),
io:format("Files is ~p~n", [Files]),
ErlFiles = get_files(SrcDirs, erl),
HrlFiles = get_files(SrcDirs, hrl),
[ok = markup_to_literate(X, erl) || X <- ErlFiles],
[ok = markup_to_literate(X, hrl) || X <- HrlFiles],
ok.
get_files(SrcDirs, Type) ->
WildCards = case Type of
erl -> "/../src_md/.erl/*.erl";
hrl -> "/../include_md/.hrl/*.hrl"
end,
Files = lists:merge([filelib:wildcard(X ++ WildCards) || X <- SrcDirs]),
FilterFun = fun(X) ->
not filelib:is_dir(X)
end,
Files2 = lists:filter(FilterFun, Files),
[ok = markup_to_literate(X) || X <- Files2],
ok.
lists:filter(FilterFun, Files).
markup_to_literate(File) ->
markup_to_literate(File, Type) ->
CWD = rebar_utils:get_cwd(),
{ok, Lines} = read_lines(CWD ++ "/" ++ File),
Source = make_markdown_source(Lines),
ok = write_source(Source, File).
ok = write_source(Source, File, Type).
make_markdown_source(Lines) ->
make_markdown(Lines, []).
@@ -87,9 +95,12 @@ get_src_dirs(ErlOpts) ->
SrcDirs -> SrcDirs
end.
write_source(Source, File) ->
write_source(Source, File, Type) ->
File2 = filename:basename(File) ++ ".md",
Dir = filename:dirname(File) ++ "/../../md/",
Dir = case Type of
erl -> filename:dirname(File) ++ "/../../src_md/";
hrl -> filename:dirname(File) ++ "/../../include_md/"
end,
ok = filelib:ensure_dir(Dir),
ok = file:write_file(Dir ++ File2, Source).
View

This file was deleted.

Oops, something went wrong.
View
@@ -0,0 +1,49 @@
%%% -----------------------------------------------------------------------------
%%% File util2.erl
%%% @author Gordon Guthrie <gordonguthrie@vixo.com>
%%% @doc
%%% @copyright Hypernumbers Ltd
%%% @private
%%%
%%% Created 22 Nov 2006 by Gordon Guthrie <gordonguthrie@vixo.com>
%%% -----------------------------------------------------------------------------
%%%```erlang
-module(util2).
-export([
timestamp_to_date/1,
get_timestamp/0
]).
-define(MEGA, 1000000000000).
-define(SEC, 1000000).
%%% -----------------------------------------------------------------------------
%%%
%%% Worker functions for the util2
%%% There are two util files cos you can't load one with try/catch into the
%%% debugger (ie that one)
%%%
%%% -----------------------------------------------------------------------------
%%%
%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% %%%
%%% These functions are all utility functions %%%
%%% %%%
%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%
%%%```erlang
-spec get_timestamp() -> pos_integer().
get_timestamp()->
{Mega, Sec, Micro} = now(),
?MEGA * Mega + ?SEC * Sec + Micro.
timestamp_to_date(Stamp) when is_list(Stamp) ->
timestamp_to_date(list_to_integer(Stamp));
timestamp_to_date(Stamp) when is_integer(Stamp) ->
Mega = trunc(Stamp/?MEGA),
Sec = trunc((Stamp - Mega * ?MEGA)/?SEC),
Micro = Stamp - Mega * ?MEGA - Sec * ?SEC,
{Mega, Sec, Micro}.
File renamed without changes.

0 comments on commit 6bbf392

Please sign in to comment.