Skip to content

Commit

Permalink
Merge pull request #1 from lsms-worldbank/lab_pipe
Browse files Browse the repository at this point in the history
New command: `lab_pipe`
  • Loading branch information
kbjarkefur authored Jan 16, 2024
2 parents f9b91eb + 1a2d271 commit 1c0d45b
Show file tree
Hide file tree
Showing 19 changed files with 1,143 additions and 58 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -52,3 +52,5 @@

# Markdown
!/**/*.md

/src/tests/plus-ado/
21 changes: 0 additions & 21 deletions run-adodown-util.do

This file was deleted.

97 changes: 93 additions & 4 deletions src/ado/labeller.ado
Original file line number Diff line number Diff line change
@@ -1,9 +1,98 @@
cap program drop labeller
program define labeller
program define labeller, rclass

* Update the syntax. This is only a placeholder to make the command run
syntax [anything]
version 13.0

//TODO : implement command here
* UPDATE THESE LOCALS FOR EACH NEW VERSION PUBLISHED
local version "1.0"
local versionDate "05NOV2023"

syntax [anything]

* Command is used used to return version info
if missing("`anything'") {
* Prepare returned locals
return local versiondate "`versionDate'"
return local version = `version'

* Display output
noi di ""
local cmd "labeller"
local vtitle "This version of {inp:`cmd'} installed is version:"
local btitle "This version of {inp:`cmd'} was released on:"
local col2 = max(strlen("`vtitle'"),strlen("`btitle'"))
noi di as text _col(4) "`vtitle'" _col(`col2')"`version'"
noi di as text _col(4) "`btitle'" _col(`col2')"`versionDate'"
}

else {

local allowed_commands "output_verbose output_veryverbose"

gettoken subcommand parameters : anything

if !(`: list subcommand in allowed_commands') {
noi di as error "{pstd}The command labeller does not allow any options or parameters.{p_end}"
error 198
exit
}
* Run the subcommand
`subcommand', `parameters'
}

end

cap program drop output_verbose
program define output_verbose

syntax, title(string) [values(string)]

* Prepare output list
if missing("`values'") local vlist "{it:N/A}"
else {
* Comma seperate the list
local vcount : word count `values'
local vlist = "{bf:`: word 1 of `values''}"
forvalues i = 2/`vcount' {
local vlist "`vlist', {bf:`: word `i' of `values''}"
}
}

* Output the list
noi di as text "{phang}`title'{p_end}"
noi di as text "{phang} - `vlist'{p_end}" _n

end


cap program drop output_veryverbose
program define output_veryverbose

syntax, title(string) ttitle1(string) ttitle2(string) [vars(varlist)]

noi di as text "{pstd}`title'{p_end}"

* Calculate longest string in col 1
local maxvarlen = strlen("`ttitle1'")
foreach varname of local vars {
local maxvarlen = max(`maxvarlen',strlen("`varname'"))
}

* Set column locals
local lind 5
local rind `lind'
local col2 = `maxvarlen' + `lind' + 1
local col2_hang = `col2' + 4
local p2_all "`lind' `col2' `col2_hang' `rind'"

* Write table title
noi di as smcl "{p2colset `p2_all'}"
noi di as text "{p2col `p2_all':{it:{ul:`ttitle1'}}} {it:{ul:`ttitle2'}}" _n

* Write each label
foreach varname of local vars {
local varlab : variable label `varname'
noi di as text "{p2col `p2_all':{bf:`varname'}} {text:`varlab'}" _n
}

end
55 changes: 55 additions & 0 deletions src/ado/lbl_assert_no_pipes.ado
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
*! version XX XXXXXXXXX ADAUTHORNAME ADCONTACTINFO

cap program drop lbl_assert_no_pipes
program define lbl_assert_no_pipes

* Update the syntax. This is only a placeholder to make the command run
syntax, [IGnore_pipes(string) OUTput_level(string)]

* Set defaults
if missing("`output_level'") local output_level "verbose"
if !(inlist("`output_level'","minimal","verbose","veryverbose")) {
noi di as error "{pstd}The value [`output_level'] in option {opt:output_level(`output_level')} is not a valid value. It may only be either minimal, verbose, or veryverbose.{p_end}"
error 198
}

* Get the list of pipes used and the vars they are used for
qui lbl_list_pipes, output_level(minimal)
local pipes_found "`r(pipes)'"

* Add the vars with remaining pipes for each pipe
foreach pipe of local pipes_found {
local `pipe'_v "`r(`pipe'_v)'"
}

* Ignore pipes
local ignore_pipes = subinstr("`ignore_pipes'","%","",.)
local pipes_found : list pipes_found - ignore_pipes

if !missing("`pipes_found'") {
noi di ""
if ("`output_level'" == "minimal") {
noi di as error "{pstd}There are still pipes in the dataset{p_end}"
}
else {
foreach pipe of local pipes_found {
local title "{err:Pipe %`pipe'% still in variable(s):}"
if ("`output_level'" == "verbose") {
//noi di `"output_verbose, title("`title'") values("``pipe'_v'")"'
labeller output_verbose title("`title'") values("``pipe'_v'")
}
else if ("`output_level'" == "veryverbose") {
labeller output_veryverbose title("`title'") vars("``pipe'_v'") ///
ttitle1("Variable") ttitle2("Variable label")
noi di as text "{p2line}" _n
}
}
}
error 9
exit
}
else {
noi di as result _n "{pstd}No more pipes in dataset{p_end}"
}

end
120 changes: 120 additions & 0 deletions src/ado/lbl_list_pipes.ado
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
*! version XX XXXXXXXXX ADAUTHORNAME ADCONTACTINFO

cap program drop lbl_list_pipes
program define lbl_list_pipes, rclass

* Update the syntax. This is only a placeholder to make the command run
syntax , [IGnore_pipes(string) OUTput_level(string)]

* Set defaults
if missing("`output_level'") local output_level "verbose"
if !(inlist("`output_level'","minimal","verbose","veryverbose")) {
noi di as error "{pstd}The value [`output_level'] in option {opt:output_level(`output_level')} is not a valid value. It may only be either minimal, verbose, or veryverbose.{p_end}"
error 198
}

* Initiate locals
local pipes_found ""

**************************************************
* Search for pipes
**************************************************

* Loop over all variables to list all pipes and all vars each are used for
foreach var of varlist _all {

* Reset locals used in serach
local is_pipe 0
local this_pipe ""

* Get this var's var label and its length
local lab : variable label `var'
local lablen = strlen("`lab'")

* Parse the label
forvalues i = 1/`lablen' {
*Get first charachter
local c = substr("`lab'",`i',1)
* Test if beginning or end of pipe
if ("`c'"=="%") {
*Swithc is_pipe bool
local is_pipe = !`is_pipe'
*If no longer pipe, save this pipe and rest
if !(`is_pipe') {
* Test that pipe is a valid pipe - otherwise it is likely not a pipe
* pipes, as variable names, must:
* - start with a letter
* - contain letters, numbers, and underscore
* See more here: https://docs.mysurvey.solutions/questionnaire-designer/components/variable-names/
local valid_pipe = regexm("`this_pipe'","^([A-Za-z])([A-Za-z0-9_]+)$")
if (`valid_pipe') {
local pipes_found : list pipes_found | this_pipe
local `this_pipe'_v "``this_pipe'_v' `var'"
}
* Rest this_pipe
local this_pipe ""
}
}
* Space means its never a pipe as in "what is 20% of 20%?"
else if ("`c'" == " ") {
local is_pipe = 0
local this_pipe ""
}
* Add letter to this pipe
else if (`is_pipe') local this_pipe = "`this_pipe'`c'"
}
}

* Ignore pipes
local ignore_pipes = subinstr("`ignore_pipes'","%","",.)
local pipes_found : list pipes_found - ignore_pipes

**************************************************
* Output results
**************************************************

* Add % % to pipes to always display the pipes as %pipe%
local formatted_pipes = ""
foreach pipe of local pipes_found {
local formatted_pipes "`formatted_pipes' %`pipe'%"
}

* Display pipes
noi di ""
labeller output_verbose ///
title("{ul:{bf:Pipes found in dataset:}}") ///
values("`formatted_pipes'")

if ("`output_level'" != "minimal") & !missing("`pipes_found'") {

noi di as text "{p2line}" _n

foreach pipe of local pipes_found {
local title "{ul:{bf:Pipe %`pipe'% used in variable(s):}}"

if ("`output_level'" == "verbose") {
//noi di `"output_verbose, title("`title'") values("``pipe'_v'")"'
labeller output_verbose title("`title'") values("``pipe'_v'")
}
else if ("`output_level'" == "veryverbose") {
labeller output_veryverbose title("`title'") vars("``pipe'_v'") ///
ttitle1("Variable") ttitle2("Variable label")
noi di as text "{p2line}" _n
}
else error 98
}
}

**************************************************
* Return locals with pip information
**************************************************

* Output the variables used for each pipe
foreach pipe of local pipes_found {
return local `pipe'_v =trim("``pipe'_v'")
}

* Output the pipes found
return local pipes "`pipes_found'"

end
Loading

0 comments on commit 1c0d45b

Please sign in to comment.