View source with formatted comments or as raw
    1% Load using
    2%
    3% swipl -l refactor.pl scasp.pl
    4
    5:- use_module(library(refactor)).    6:- use_module(library(dcg/basics)).    7:- use_module(library(lynx/format)).    8
    9:- op(100,  fx, (?)).                   % pldoc
   10:- op(978, xfx, (::)).   11:- op(500, yfx, (#)).   12:- op(1150, fx,(pred)).   13:- op(1150,xfx,(pred)).   14
   15pred(_).
   16doc(_,_).
   17
   18replace_lpdoc :-
   19    forall(project_file(File),
   20           replace_lpdoc([file(File)])).
   21
   22replace_lpdoc(Options) :-
   23    retractall(doc_data(_,_)),
   24    replace_sentence((:- pred Pred),
   25                      '$NODOT'('$TEXT'(PlDoc)),
   26                     lpdoc2pldoc(Pred, Dict, PlDoc),
   27                     [ variable_names(Dict)
   28                     | Options
   29                     ]),
   30    replace_sentence((:- doc(Type, Text)),
   31                     Replace,
   32                     replace_doc(Type, Text, Replace),
   33                     Options),
   34    replace_sentence((:- use_package(assertions)),
   35                     '$NODOT'('$TEXT'("")),
   36                     true,
   37                     Options),
   38    replace_sentence((:- use_module(library(CiaoLib))),
   39                     Replace,
   40                     ciao_lib(CiaoLib, Replace),
   41                     Options),
   42    replace_sentence((:- expects_dialect(ciao)),
   43                     '$NODOT'('$TEXT'("")),
   44                     true,
   45                     Options),
   46    replace_sentence((:- data(Preds)),
   47                     (:- dynamic(Preds)),
   48                     true,
   49                     Options).
   50
   51replace_goals :-
   52    forall(project_file(File),
   53           replace_goals([file(File)])).
   54
   55replace_goals(Options) :-
   56    replace_goal(if(A,B,C), (A*->B;C), true, Options),
   57    replace_goal(num(X), number(X), true, Options),
   58    replace_goal(struct(X), compound(X), true, Options),
   59    replace_goal(varset(T,Vs), term_variables(T,Vs), true, Options),
   60    replace_goal(insert(S0,E,S), ord_add_element(S0,E,S), true, Options).
   61
   62ciao_lib(CiaoLib, Replace) :-
   63    ciao_swi_lib(CiaoLib, SWILib),
   64    (   SWILib == []
   65    ->  Replace = '$NODOT'('$TEXT'(""))
   66    ;   Replace = (:- use_module(library(SWILib)))
   67    ).
   68
   69ciao_swi_lib(write, []).
   70ciao_swi_lib(terms_vars, []).
   71ciao_swi_lib(formulae, []).
   72ciao_swi_lib(dict, []).
   73ciao_swi_lib(stream_utils, []).
   74ciao_swi_lib(sets, []).
   75ciao_swi_lib(terms_check, []).
   76
   77
   78lpdoc2pldoc(Head : _ # Comment, Dict, PlDoc) =>
   79    lpdoc2pldoc(Head # Comment, Dict, PlDoc).
   80lpdoc2pldoc(Name/Arity # Comment, Dict, PlDoc) =>
   81    functor(Head, Name, Arity),
   82    numbervars(Head, 0, _),
   83    lpdoc2pldoc(Head # Comment, Dict, PlDoc).
   84lpdoc2pldoc(Head # Comment, Dict, PlDoc) =>
   85    maplist(bind_varname, Dict),
   86    lpdoc2markdown_percent(Comment, Dict, MarkDown,
   87                           [ width(68)
   88                           ]),
   89    format(string(PlDoc),
   90           '%!  ~W~n\c
   91            %~n\c
   92            %   ~w~n~n',
   93           [ Head, [numbervars(true), spacing(next_argument)],
   94             MarkDown
   95           ]).
   96
   97bind_varname(Name=Var) :-
   98    Var = ?'$VAR'(Name).
   99
  100lpdoc2markdown_percent(LpDoc, Dict, MarkDown, Options) :-
  101    lpdoc2markdown(LpDoc, Dict, MarkDown0, Options),
  102    split_string(MarkDown0, '\n', "", Lines),
  103    atomics_to_string(Lines, "\n%   ", MarkDown).
  104
  105lpdoc2markdown(LpDoc, Dict, MarkDown, Options) :-
  106    string_codes(LpDoc, Codes),
  107    phrase((blanks,mantex(Parts, Dict)), Codes),
  108    flatten(Parts, Flat),
  109    atomics_to_string(Flat, String),
  110    with_output_to(string(MarkDown),
  111                   format_paragraph(String,
  112                                    [ text_align(justify)
  113                                    | Options
  114                                    ])).
  115
  116mantex([], _) -->
  117    blanks, eos, !.
  118mantex([H|T], Dict) -->
  119    mantex_part(H, Dict),
  120    !,
  121    mantex(T, Dict).
  122
  123mantex_part(Part, Dict) -->
  124    "@", csym(Name), "{", string(CCodes), "}",
  125    !,
  126    { atom_codes(Content, CCodes),
  127      make_part(Name, Content, Dict, Part)
  128    }.
  129mantex_part(Part, _) -->
  130    string_without("@", Codes),
  131    { string_codes(Part, Codes) }.
  132
  133
  134make_part(var, Name, Dict, Part) =>
  135    (   memberchk(Name=_, Dict)
  136    ->  Part = Name
  137    ;   Part = ['`', Name, '`']
  138    ).
  139make_part(pred, Pred, _, Part) =>
  140    Part = Pred.
  141make_part(em, Content, _, Part) =>
  142    Part = ['_', Content, '_'].
  143make_part(bf, Content, _, Part) =>
  144    Part = ['__', Content, '__'].
  145make_part(file, Content, _, Part) =>
  146    Part = ['``', Content, '``'].
  147make_part(Cmd, Content, _, Part) =>
  148    print_message(warning, lpdoc(unknown_command(Cmd))),
  149    Part = [@, Cmd, '{', Content, '}'].
  150
  151csym(Name) -->
  152    csym_code(H),
  153    csym_codes(T),
  154    { atom_codes(Name, [H|T]) }.
  155
  156csym_code(H) -->
  157    [H],
  158    { code_type(H, csym) }.
  159
  160csym_codes([H|T]) --> csym_code(H), !, csym_codes(T).
  161csym_codes([]) --> "".
  162
  163		 /*******************************
  164		 *           SECTION		*
  165		 *******************************/
  166
  167:- thread_local(doc_data/2).  168
  169replace_doc(section, Title, Replace) =>
  170    section_header(Title, SeqHdr),
  171    Replace = '$NODOT'('$TEXT'(SeqHdr)).
  172replace_doc(title, Title, Replace) =>
  173    Replace = '$NODOT'('$NOOP'("")),
  174    asserta(doc_data(title, Title)).
  175replace_doc(author, Author, Replace) =>
  176    Replace = '$NODOT'('$NOOP'("")),
  177    asserta(doc_data(author, Author)).
  178replace_doc(filetype, module, Replace) =>
  179    Replace = '$NODOT'('$NOOP'("")).
  180replace_doc(module, Comment, Replace) =>
  181    lpdoc2markdown(Comment, [], MarkDown, [width(72)]),
  182    doc_data(title, Title),
  183    doc_data(author, Author),
  184    format(string(Header),
  185           '/** <module> ~w~n~n\c
  186           ~w~n~n\c
  187           @author ~w~n\c
  188           */~n~n',
  189           [ Title, MarkDown, Author ]),
  190    Replace = '$NODOT'('$TEXT'(Header)).
  191
  192section_header(Title, SeqHdr) :-
  193    with_output_to(string(SeqHdr), section_header(Title)).
  194
  195section_header(Title) :-
  196    upcase_atom(Title, UTitle),
  197    format('\t\t /~|~`*t~31+~n\c
  198            \t\t *~|~t~w~t~30+*~n\c
  199            \t\t *~|~`*t~30+/~n~n\c', [UTitle]).
  200
  201project_files(Files) :-
  202    findall(File, project_file(File), Files).
  203
  204project_file(File) :-
  205    working_directory(CWD, CWD),
  206    source_file(File),
  207    sub_atom(File, 0, _, _, CWD),
  208    \+ file_base_name(File, 'refactor.pl').
  209
  210/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  211Notes:
  212
  213  - Is there a way to replace on all project files?
  214  - Can e.g., variable renaming be limited to a clause/predicate?
  215- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */