<commit_before>-module(docsh).

-export([main/1]).

-export_type([external/0,
              internal/0]).

-import(docsh_lib, [print/2, print/3]).

%% External documentation format.
%% Right now the only supported format is docsh_elixir_docs_v1 which
%% (TODO) aims to be compatible with Elixir at some point in the future.
-type external() :: any().

%% Internal documentation format.
%% All `docsh_reader` modules convert to this format from their input.
%% All `docsh_writer` modules convert from this format to desired output.
-type internal() :: [{atom(), any()}].

%%
%% Escript API
%%

-spec main([string()]) -> ok.
main(Args) -> process_args(Args, opts()).

%%
%% Helpers
%%

opts() ->
    [ {"transform BEAMFile to NewBEAMFile", fun transform/1},
      {"diff BEAMFile1 BEAMFile2",          fun diff/1},
      {"help",                              fun usage/1} ].

transform(["transform", BEAMFile, "to", NewBEAMFile]) ->
    'try'(fun () -> {ok, NewBEAM} = docsh_lib:process_beam(BEAMFile),
                    ok = file:write_file(NewBEAMFile, NewBEAM) end).

diff(["diff", BEAM1, BEAM2]) ->
    'try'(fun () -> Diff = docsh_lib:beam_diff(BEAM1, BEAM2),
                    print("~p~n", [Diff]) end).

usage(_) ->
    usage(),
    erlang:halt(1).

process_args(Args, Opts) ->
    lists:foldl(fun process_arg/2, {next, Args}, Opts),
    ok.

process_arg({_Desc, _}, done) -> done;
process_arg({_Desc, F}, {next, Args}) ->
    case catch erlang:apply(F, [Args]) of
        {'EXIT', {function_clause, _}} -> {next, Args};
        _ -> done
    end.

'try'(F) ->
    try F()
    catch
        _:R -> print(standard_error, "~s: ~s~n~s~n",
                     [progname(), docsh_lib:format_error(R),
                      erlang:get_stacktrace()]),
               erlang:halt(2)
    end.

usage() ->
    print(standard_error,
          "usage: ~s", [ [ [padding(I), progname(), " ", Desc, "\n"]
                           || {I, {Desc, _}} <- enum(opts()) ] ]).

padding(1) -> "";
padding(_) -> "       ".

enum(List) -> lists:zip(lists:seq(1, length(List)), List).

progname() ->
    filename:basename(hd(init:get_plain_arguments())).<commit_msg>Rename: opts -> commands<commit_after>-module(docsh).

-export([main/1]).

-export_type([external/0,
              internal/0]).

-import(docsh_lib, [print/2, print/3]).

%% External documentation format.
%% Right now the only supported format is docsh_elixir_docs_v1 which
%% (TODO) aims to be compatible with Elixir at some point in the future.
-type external() :: any().

%% Internal documentation format.
%% All `docsh_reader` modules convert to this format from their input.
%% All `docsh_writer` modules convert from this format to desired output.
-type internal() :: [{atom(), any()}].

%%
%% Escript API
%%

-spec main([string()]) -> ok.
main(Args) -> process_args(Args, commands()).

%%
%% Helpers
%%

commands() ->
    [ {"transform BEAMFile to NewBEAMFile", fun transform/1},
      {"diff BEAMFile1 BEAMFile2",          fun diff/1},
      {"help",                              fun usage/1} ].

transform(["transform", BEAMFile, "to", NewBEAMFile]) ->
    'try'(fun () -> {ok, NewBEAM} = docsh_lib:process_beam(BEAMFile),
                    ok = file:write_file(NewBEAMFile, NewBEAM) end).

diff(["diff", BEAM1, BEAM2]) ->
    'try'(fun () -> Diff = docsh_lib:beam_diff(BEAM1, BEAM2),
                    print("~p~n", [Diff]) end).

usage(_) ->
    usage(),
    erlang:halt(1).

process_args(Args, Opts) ->
    lists:foldl(fun process_arg/2, {next, Args}, Opts),
    ok.

process_arg({_Desc, _}, done) -> done;
process_arg({_Desc, F}, {next, Args}) ->
    case catch erlang:apply(F, [Args]) of
        {'EXIT', {function_clause, _}} -> {next, Args};
        _ -> done
    end.

'try'(F) ->
    try F()
    catch
        _:R -> print(standard_error, "~s: ~s~n~s~n",
                     [progname(), docsh_lib:format_error(R),
                      erlang:get_stacktrace()]),
               erlang:halt(2)
    end.

usage() ->
    print(standard_error,
          "usage: ~s", [ [ [padding(I), progname(), " ", Desc, "\n"]
                           || {I, {Desc, _}} <- enum(commands()) ] ]).

padding(1) -> "";
padding(_) -> "       ".

enum(List) -> lists:zip(lists:seq(1, length(List)), List).

progname() ->
    filename:basename(hd(init:get_plain_arguments())).
{'fraction_non_alphanumeric': 0.18771646271069037, 'fraction_numerical': 0.009235742322789195, 'mean_word_length': 2.6556962025316455, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 44, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '599920', 'n_tokens_mistral': 1498, 'n_tokens_neox': 1481, 'n_words': 339}