*! version 2.1 *! Doug Hemken *! 4 Feb 2019 program define dyn2do, rclass syntax anything(name=docfile), [SAVing(string) replace] version 15 local docfile = ustrtrim(usubinstr(`"`docfile'"', `"""', "", .)) //confirm file `"`docfile'"' if ("`saving'" == "" ) { di " {text:No output file specified.}" _replaceext using "`docfile'", new("do") local saving "`r(newfile)'" } capture confirm file "`saving'" if (_rc==0 & "`replace'"=="") { display " {error: File `saving' already exists, specify replace} error } mata: dyn2do("`docfile'", "`saving'") display " {text:Output saved as {it:`saving'}}" return local outfile "`saving'" end mata: void function dyn2do (string scalar filename1, string scalar filename2) { X=docread(filename1) di_cnt = (ustrlen(X) :- ustrlen(ustrregexra(X, "<>", 0) ignore_blocks = mark_text_blocks(X, "<>", 0) display_lines = ustrpos(X,"< 0 D = select(X, display_lines) D_rep = select(line_rep, display_lines) for (i=1;i<=rows(D);i++) { if (D_rep[i] > 1) { D[i] = usubinstr(D[i], usubstr(D[i], 1, ustrpos(D[i], "<>"), .), "", 1) X[selectindex(display_lines)] = D unlink(filename2) docwrite(filename2, select(X, (do_blocks :| display_lines) :& !ignore_blocks)) } string colvector docread(string scalar filename) { fh = fopen(filename, "r") string colvector document document= J(0,1,"") while ((line=fget(fh))!=J(0,0,"")) { document = (document\line) } fclose(fh) return(document) } void function docwrite(string scalar filename, /// string colvector document) { fh = fopen(filename, "w") for (i=1; i<=length(document); i++) { fput(fh, document[i]) } fclose(fh) } string matrix function expand_display_rows(string colvector X, /// real colvector count) { string matrix Y Y=J(0,2,"") for(i=1;i<=rows(X);i++) { if (count[i,1] !=0) { for(j=1;j<=count[i];j++) { Y = Y\(X[i,.],strofreal(j)) } } else { Y = Y\(X[i,.],"1") } } return(Y) } real colvector mark_text_blocks(string colvector doc, /// string scalar st_tag, string scalar end_tag, /// real scalar include_tags) { real colvector blocks, starts, stops blocks=.; starts=.; stops=. starts=(ustrpos(doc, st_tag):==1) stops=(ustrpos(doc, end_tag):==1) if (include_tags) { blocks=runningsum(starts-stops)+stops } else { // just what is inside the blocks blocks=runningsum(starts-stops)-starts } return(blocks) } end program define _replaceext, rclass syntax using/, new(string) version 15 _fileext using "`using'" if "`r(extension)'" ~= "" { local newfile: subinstr local using "`r(extension)'" "`new'" } else { local newfile "`using'.`new'" } return local newfile "`newfile'" end program define _fileext, rclass syntax using/ version 15 local check: subinstr local using "." "", all local dots = length("`using'") - length("`check'") if `dots' { local undot: subinstr local using "." " ", all local wc : word count `undot' local extension: word `wc' of `undot' } else { local extension } return local extension "`extension'" end