*! version 4.0.0 MLB 16Feb2022 * work with smclpres 4.0.0 program define pres2html version 14.2 local olddir = c(pwd) capture noisily pres2html_main `0' if _rc { qui cd `"`olddir'"' file close _all exit _rc } end program define pres2html_main version 14.2 syntax using/ , [replace dir(passthru)] Parsedirs using `using' , `dir' local olddir = s(odir) local sourcedir = s(sdir) local stub = s(stub) local ddir = s(ddir) qui cd "`sourcedir'" // initialize the html file tempname tofill appendix tempfile appfile file open `tofill' using `"`ddir'/`stub'.html"', write `replace' Htmlinit, file(`tofill') file open `appendix' using `appfile', write replace // find the slides tempname base file open `base' using `stub'.smcl, read file read `base' line local slideslist = 0 while r(eof) == 0 { gettoken first rest : line gettoken second rest : rest if `"`first'"' == "{*" & `"`second'"' == "slides" { local slideslist = 1 } else if `"`first'"' == "{*" & `"`second'"' == "bottomstyle" { local slideslist = 0 gettoken bottomstyle rest : rest, parse("}") } else if `slideslist' & `"`second'"' != "slides" { gettoken slide bracket : second, parse("}") local slides = `"`slides' `slide'"' } file read `base' line } file close `base' if `"`slides'"' == "" { di as err "{p}`using' does not contain a list of slides{p_end}" exit 198 } local appnumber = 0 foreach slide of local slides { Slide2html using `slide', tofill(`tofill') bottomstyle(`bottomstyle') /// app(`appendix') appnumber(`appnumber') ddir(`ddir') `replace' } file close `appendix' if `appnumber' { Fileappend, file(`appfile') appendto(`tofill') } file write `tofill' "" _n "" _n file close `tofill' qui cd "`olddir'" display as txt `"To see the handout click {browse "`ddir'`c(dirsep)'`stub'.html":here}"' end program define Slide2html version 14.2 syntax using/, tofill(string) bottomstyle(string) app(string) appnumber(integer) ddir(string) [replace] file write `tofill' `"
"' _n file write `tofill' `"
"' tempname base temp tempfile tempsmcl temphtml temphtml2 file open `base' using `using', read file open `temp' using `tempsmcl', write local ignore = 0 local ignorel = 0 file read `base' line while r(eof) == 0 { gettoken first rest : line gettoken second rest : rest if `"`first'"' == "{*" & `"`second'"' == "ex" { file close `temp' qui log html `tempsmcl' `temphtml', replace yebf whbf qui filefilter `temphtml' `temphtml2', from("*digrlink*") to(`"`digrlink'"') replace qui filefilter `temphtml2' `temphtml', from("

") to("
") replace Fileappend, file(`temphtml') appendto(`tofill') file write `tofill' "

" gettoken rest : rest, parse("}") Dohtml using `rest', gen(`temphtml') replace Fileappend, file(`temphtml') appendto(`tofill') local ignore = 1 } if `"`first'"' == "{*" & `"`second'"' == "dofile" { file close `temp' qui log html `tempsmcl' `temphtml', replace yebf whbf qui filefilter `temphtml' `temphtml2', from("*digrlink*") to(`"`digrlink'"') replace qui filefilter `temphtml2' `temphtml', from("

") to("
") replace Fileappend, file(`temphtml') appendto(`tofill') file write `tofill' `"

"' gettoken rest : rest, parse("}") Dohtml using `rest', gen(`temphtml') replace Fileappend, file(`temphtml') appendto(`tofill') file write `tofill' `"
"' file open `temp' using `tempsmcl', write replace local ignorel = 1 } if `"`first'"' == "{*" & `"`second'"' == "apdofile" { file close `temp' qui log html `tempsmcl' `temphtml', replace yebf whbf qui filefilter `temphtml' `temphtml2', from("*digrlink*") to(`"`digrlink'"') replace qui filefilter `temphtml2' `temphtml', from("

") to("
") replace Fileappend, file(`temphtml') appendto(`tofill') gettoken rest : rest, parse("}") gettoken dofilesource rest : rest local rest = ustrtrim(`"`rest'"') file write `tofill' `"

`rest'
"'_n Dohtml using `dofilesource', gen(`temphtml') replace file write `app' `"
"'_n file write `app' `"

`rest'



"'_n Fileappend, file(`temphtml') appendto(`app') local hline : display _dup(79) "-" file write `app' `"
"' file write `app' "

`hline'
"_n file write `app' `"

<<

"'_n file write `app' "
`hline'
"_n file write `app' "
" file write `app' "
" c_local appnumber = `appnumber' + 1 file open `temp' using `tempsmcl', write replace } if `"`first'"' == "{*" & `"`second'"' == "codefile" { file close `temp' qui log html `tempsmcl' `temphtml', replace yebf whbf qui filefilter `temphtml' `temphtml2', from("*digrlink*") to(`"`digrlink'"') replace qui filefilter `temphtml2' `temphtml', from("

") to("
") replace Fileappend, file(`temphtml') appendto(`tofill') file write `tofill' `"

"' gettoken rest : rest, parse("}") file write `tofill' `"
"'_n
			tempname codefile
			file open `codefile' using `rest', read
			file read `codefile' cline
			while r(eof) == 0 {
				local cline : subinstr local cline ">" ">", all
				local cline : subinstr local cline "<" "<", all
				file write `tofill' `"`macval(cline)'"'_n
				file read `codefile' cline
			}
			file close `codefile'
			file write `tofill' "
"_n file write `tofill' `"
"' file open `temp' using `tempsmcl', write replace local ignorel = 1 } if `"`first'"' == "{*" & `"`second'"' == "apcodefile" { file close `temp' qui log html `tempsmcl' `temphtml', replace yebf whbf qui filefilter `temphtml' `temphtml2', from("*digrlink*") to(`"`digrlink'"') replace qui filefilter `temphtml2' `temphtml', from("

") to("
") replace Fileappend, file(`temphtml') appendto(`tofill') gettoken rest : rest, parse("}") gettoken codefilesource rest : rest local rest = ustrtrim(`"`rest'"') file write `tofill' `"

`rest'
"'_n file write `app' `"
"'_n file write `app' `"

`rest'



"'_n file write `app' `"
"'_n
			tempname codefile
			file open `codefile' using `codefilesource', read
			file read `codefile' cline
			while r(eof) == 0 {
				local cline : subinstr local cline ">" ">", all
				local cline : subinstr local cline "<" "<", all
				file write `app' `"`macval(cline)'"'_n
				file read `codefile' cline
			}
			file close `codefile'
			file write `app' "
"_n local hline : display _dup(79) "-" file write `app' `"
"' file write `app' "

`hline'
"_n file write `app' `"

<<

"'_n file write `app' "
`hline'
"_n file write `app' "
" file write `app' "
" c_local appnumber = `appnumber' + 1 file open `temp' using `tempsmcl', write replace } else if `"`first'"' == "{*" & `"`second'"' == "ho_ignore" { // do nothing } else if `"`first'"' == "{*" & `"`second'"' == "endex" { local ignore = 0 file write `tofill' `"
"' file open `temp' using `tempsmcl', write replace } else if `"`first'"' == "{*" & `"`second'"' == "graph" { gettoken graphs : rest, parse("}") foreach graph of local graphs { graph export `"`ddir'/`graph'.png"', name(`graph') width(630) `replace' file write `tofill' `""' _n } } else if `"`first'"' == "{*" & `"`second'"' == "bottombar" { file close `temp' qui log html `tempsmcl' `temphtml', replace yebf whbf qui filefilter `temphtml' `temphtml2', from("*digrlink*") to(`"`digrlink'"') replace qui filefilter `temphtml2' `temphtml', from("

") to("
") replace Fileappend, file(`temphtml') appendto(`tofill') Parsebottom , line(`line') tofill(`tofill') bottomstyle(`bottomstyle') file open `temp' using `tempsmcl', write replace } else if `"`first'"' == "{*" & `"`second'"' == "/p" { file close `temp' qui log html `tempsmcl' `temphtml', replace yebf whbf qui filefilter `temphtml' `temphtml2', from("*digrlink*") to(`"`digrlink'"') replace qui filefilter `temphtml2' `temphtml', from("

") to("
") replace Fileappend, file(`temphtml') appendto(`tofill') local hline : display _dup(79) "-" file write `tofill' "

`hline'
"_n file open `temp' using `tempsmcl', write replace } else if ustrpos(`"`macval(line)'"', "{* digr") { local k = ustrpos(`"`macval(line)'"', "{* digr") Matchingclose, line(`"`macval(line)'"') startnum(`k') local i = r(close) local j = ustrpos(`"`macval(line)'"', "{* /digr") local towrite usubstr(`"`macval(line)'"',1,`=`k'-1') + /// "*digrlink*" + /// usubstr(`"`macval(line)'"',`=`j'+10',.) local towrite = `towrite' file write `temp' `"`macval(towrite)'"' _n local digrlink = usubstr(`"`macval(line)'"', `=`k' + 8', `=`i'-`k'-8') } else if `"`first'"' == "{*" & `"`second'"' == "tocline" { file close `temp' qui log html `tempsmcl' `temphtml', replace yebf whbf qui filefilter `temphtml' `temphtml2', from("*digrlink*") to(`"`digrlink'"') replace qui filefilter `temphtml2' `temphtml', from("

") to("
") replace Fileappend, file(`temphtml') appendto(`tofill') Parsetoc, line(`"`macval(line)'"') tofill("`tofill'") file open `temp' using `tempsmcl', write replace } else if !`ignore' & !`ignorel' { file write `temp' `"`macval(line)'"' _n } else { local ignorel = 0 } file read `base' line } file close `temp' qui log html `tempsmcl' `temphtml', replace yebf whbf qui filefilter `temphtml' `temphtml2', from("*digrlink*") to(`"`digrlink'"') replace qui filefilter `temphtml2' `temphtml', from("

") to("
") replace Fileappend, file(`temphtml') appendto(`tofill') file close `base' file write `tofill' `"

"' _n file write `tofill' `"
"' _n end program define Dohtml version 14.2 syntax using/, [replace] gen(string) // this will also be the name of the .html file that will be created capture confirm new file `gen' if _rc & "`replace'" == "" { di as err "file `gen' already exists" exit 602 } tempfile log html1 html2 tempname logname // do the example and store the output in a log file local ls = c(linesize) set linesize 79 qui log using `log', replace name(`logname') do `using' , nostop qui log close `logname' set linesize `ls' // turn the log file in an .html file qui log html `log' `html1', replace yebf whbf // remove the "end of do-file" message qui filefilter `html1' `html2', /// from(". \nend of do-file\n") /// to(`""') // remove log close message qui filefilter `html2' `html1', /// from("- qui log close") /// to("") replace // remove the "do foo.do" message (where "foo" is the file name stored in `file') qui filefilter `html1' `html2', /// from("

\n. do `using'\n

\n") /// to("") replace // change

to
qui filefilter `html2' `html1', from("

") to("
") replace // change to output class of

	qui filefilter `html1' `gen' ,               ///  
		from("
")                            ///
		to(`"
"') `replace'
end

program define Fileappend
	version 14.2
	syntax, file(string) appendto(string)
	tempname toappend 
	file open `toappend' using `file', read
	file read `toappend' line 
	while r(eof) == 0 {
		file write `appendto' `"`macval(line)'"' _n	
		file read `toappend' line
	}
end

program define Htmlinit
	version 14.2
	syntax, file(string)
	file write `file' "" _n
	file write `file' "" _n
	file write `file' "" _n
	file write `file' "" _n
	file write `file' "" _n
	file write `file' "" _n
end

program define Parsebottom 
	version 14.2
	syntax, line(string) tofill(string) bottomstyle(string)
	
	if "`bottomstyle'" == "arrow" {
		local line = usubinstr(`"`line'"',"{* bottombar }", "", 1)
		local line = usubinstr(`"`line'"',"{center:", `"

"', 1) local line = usubinstr(`"`line'"', "{view ", `""',3) local line = usubinstr(`"`line'"', "<<", "<<", 1) local line = usubinstr(`"`line'"', ">>>", ">>>", 1) local k= 1 local i = 1 local j = 0 while `i' != 0 { local i = ustrpos(`"`line'"', "}", `k') local k = `i' + (`i' != 0) local j = `j' + (`i'!= 0) } local line = usubinstr(`"`line'"', "}", "", `j') local line `"

`line'
"' } else { local line = usubinstr(`"`line'"', "{* bottombar }", `"
"', 1) local line = usubinstr(`"`line'"', "{view ", `"
"',2) local line = usubinstr(`"`line'"', "}}", `"
"',1) local line = usubinstr(`"`line'"', "}", `"
"',1) local line = `"`line'"' + "" } file write `tofill' `"`line'"' _n end program define Parsetoc version 14.2 syntax, line(string) tofill(string) local i = ustrpos(`"`macval(line)'"', "{view ") if `i' == 0 { Smcl2html, line(`"`macval(line)'"') tofill(`"`tofill'"') } else { local t = usubstr(`"`macval(line)'"', `i', .) gettoken view t : t gettoken link : t Matchingclose, line(`"`macval(line)'"') startnum(`i') local t = usubstr(`"`macval(line)'"', 1, `=`i'-1') + " ***a " + /// usubstr(`"`macval(line)'"', `i', `=`r(close)'-`i'') + " ***/a " + /// usubstr(`"`macval(line)'"', `r(close)', .) Smcl2html, line(`"`macval(t)'"') link(`"`link'"') tofill(`"`tofill'"') } end program define Smcl2html, version 14.2 syntax, line(string) [link(string)] tofill(string) tempfile smcl html html2 tempname file file open `file' using `smcl', write file write `file' `"`line'"' _n file close `file' qui log html `smcl' `html', replace yebf whbf qui filefilter `html' `html2', from("

") to("
") replace file open `file' using `html2', read file read `file' line while r(eof) == 0 { if "`link'" != "" { local line : subinstr local line " ***a " `""' local line : subinstr local line " ***/a " "" local line : subinstr local line " ***/a" "" local line : subinstr local line "***/a " "" local line : subinstr local line "***/a" "" } file write `tofill' `"`macval(line)'"' _n file read `file' line } file close `file' end program define Matchingclose, rclass version 14.2 syntax, line(string) startnum(integer) local i = `startnum'+1 // startnum is the position of the open brace, // so you start looking at the next postion local open = 0 local continue = 1 while `continue' { local j = ustrpos(`"`macval(line)'"', "}", `i') local k = ustrpos(`"`macval(line)'"', "{", `i') if `k' < `j' & `k' > 0 & `j' > 0{ local open = `open' + 1 local i = `k'+1 } else if (`j' < `k' | `k' == 0 & `open' == 0) & `j' > 0 { if `open' > 0 { local open = `open' - 1 local i = `j' + 1 } else { local continue = 0 } } else { di as err "no matching brace found" exit 198 } } return scalar close = `j' end program define Parsedirs, sclass version 14.2 syntax using/, [dir(string)] local stub : subinstr local using "\" "/", all while `"`stub'"' != "" { local path `path'`path2' gettoken path2 stub : stub, parse("/\:") } local stub `path2' gettoken stub suffix : stub, parse(".") local odir = c(pwd) quietly { cd `path' local sdir = c(pwd) if `"`dir'"' != "" { cd `"`odir'"' cd `"`dir'"' local ddir = c(pwd) } if ("`odir'" != "`sdir'") & (`"ddir"' == "") { local ddir = `"`odir'"' } cd `"`odir'"' } sreturn local stub `"`stub'"' sreturn local odir `"`odir'"' sreturn local sdir `"`sdir'"' sreturn local ddir `"`ddir'"' end