help elabel programming

Title

elabel -- elabel programming

Description

The commands and functions described here are primarily used for developing
the elabel package. Some of these commands and functions might be of
interest to programmers.

Below the list of commands and functions is a short description of
how to add new commands to elabel.

Programming commands

elabel confirm
Argument verification

elabel numlist
Parse numeric list

elabel parse
Parse elabel syntax

elabel unab
Unabbreviate value label names

elabel _u*
Utility commands

Mata functions (elabel)

elabel_dir()
Obtain lists of value label names

elabel_ldir()
Obtain list of label languages

elabel_rename()
Rename value label

elabel_unab()
Unabbreviate value label names

elabel_numlist()
Parse numeric list

elabel_vl*()
Manipulate value label

Mata functions (generic)

aandb()
Manipulate row vectors

distinctrowsof()
Distinct rows of matrix

range_mv()
Real vector over range

tokenpreview()
Peek ahead at tokens

tokendiscard()
Discard successive tokens

Mata utilities (elabel)

elabel_u_*()
elabel utility functions

Development

elabel development

Adding commands to elabel

New commands for elabel are typically written in
ado; technically, it suffices to define a program in
memory. A new command must be named elabel_cmd_newcmd
and possibly stored in elabel_cmd_newcmd.ado, where
Stata can find it. The new command is then called as
elabel newcmd ...

Although a new command must be written in (a)do, much of the work might
be done in Mata. Many of the programming tools described above are
written in Mata; these functions, however, often call Stata and often
exit with Stata error messages.

A new command might look like this:

program elabel_cmd_newcmd

version

elabel parse elblnamelist [ mappings ] [ iff ] [ , OPname ] : `0'

code referring to `lblnamelist'

code referring to `mappings'

code referring to `iff'

code referring to `opname'

...

mata : elabel_cmd_newcmd()

end

version

mata :

void elabel_cmd_newcmd()

{

...

}

end

exit

Some of elabel's subcommands, e.g.,
elabel recode, are implemented as ado-files.

Adding (pseudo-)functions to elabel

Some elabel commands allow (pseudo-)functions
of the form fcn(arguments) in mappings. These
(pseudo-)functions are just programs; this section explains how to write
these programs.

New (pseudo-)functions for elabel are typically written in
ado; technically, it suffices to define a program in memory. A new
elabel (pseudo-)function is named elabel_fcn_newfcn
and possibly stored in elabel_fcn_newfcn.ado, where Stata
can find it. Optionally, elabel_fcn_newfcn may have
program properties associated with it;
see below.

The syntax for elabel (pseudo-) functions is

elabel variable
varlist
= newfcn(arguments)
[ iff ]
[ , options ]

or

elabel define
elblnamelist
= newfcn(arguments)
[ iff ]
[ , {add|modify|replace} nofix options ]

and passed to elabel_fcn_newfcn.ado is

variable
varlist
= arguments
[ iff ]
[ , options ]

or

define
lblnamelist
= arguments
[ iff ]
[ , {add|modify|replace} nofix options ]

In the above, varlist is the expanded variable list lblnamelist is the expanded elblnamelist, and arguments are arguments as
typed; note that iff and options are also passed through as
typed. Typically, elabel_fcn_newfcn.ado reads

program elabel_fcn_newfcn

version

elabel fcncall
{variable|define} names 0 : `0'

{syntax ...|elabel parse ... : `0'}

...

elabel {variable|define} `names' ...

end

See elabel fcncall for the recommended way to
parse elabel (pseudo-)function calls. All existing
(pseudo-)functions are implemented as ado-files.

elabel variable and elabel define do not parse arguments,
iff, and options, and they do not define new or modify existing
variable or value labels; elabel_fcn_newfcn may, and usually
does, call elabel variable or elabel define.

Writing (pseudo-)functions for elabel variable

When elabel variable calls
elabel_fcn_newfcn.ado, you can be sure that

1. variable names in varlist are unique

2. if elabel_fcn_newfcn exits with error, the data in memory
is not altered but preserved

Writing (pseudo-)functions for elabel define

If you write a (pseudo-)function for elabel define, you may
specify program properties elabel_vvl as in

program elabel_fcn_newfcn , properties(elabel_vvl)

and if you do, elabel_fcn_newfcn allows
varname:elblname in
elblnamelist. If you specify
elabel_vvl, elblnamelist is not expanded but passed
through as typed. Value labels are not attached to variables,
either; for that see elabel varvaluelabel.

Before elabel define calls elabel_fcn_newfcn.ado, it
parses elblnamelist and its own options; elabel_fcn_newfcn
is only called if there is no syntax error.

When elabel define calls
elabel_fcn_newfcn.ado, you can be sure that

1. only one of the options add, modify, or replace is
specified

2. if none of the above options was specified, lblnamelist only
contains new, not yet defined, value label names

3. if lblnamelist contains new value label names, new value label
names are unique

4. if elabel_fcn_newfcn exits with error, the data in memory
is not altered but preserved

Advanced: Setting locals in the caller's namespace

In general, there is nothing special that you need to do to set local
macros in the namespace of elabel_cmd_newcmd's (or
elabel_fcn_newfcn's) caller. Technically, elabel.ado
calls elabel_cmd_newcmd (or elabel_fcn_newfcn). Thus,
when you set local macros in the namespace of elabel_cmd_newcmd's
(or elabel_fcn_newfcn's) caller, you are setting these local
macros in the namespace of elabel.ado; the latter, however, is set up
to pass any local macros through to its caller, respectively.

The only thing that you cannot do in the usual way is (re)set a local
macro in the caller's namespace to missing, i.e. ""; to do this,
you must additionally tell elabel about the local macros that you
wish to set in its caller's namespace. You tell elabel about the
local macros that you wish to set in its caller's namespace by prefixing
the respective (not documented) command with elabel and then
listing all local macro names but not their contents.

Utility commands

Syntax

elabel _u_gmappings
lmacname1 lmacname2
: (spec1) (spec2)

elabel _u_parse_rules
[[ , norules ] : ]
(rules) [ (rules) ... ]

elabel _u_usedby
lmacname
: lblnamelist

where lmacname1, lmacname2, and lmacname are
local macro names

spec1 and spec2 are simply strings

rules are the rules described in
elabel recode

Description

elabel _u_gmappings parses grouped mappings of the form
(spec1) (spec2) and puts spec1
into local macro lmacname1 and spec2 into local macro
lmacname2. If mapppings do not have the required form, the
command exists with return code 498. If there is a syntax error in the
command itself, the command exits with return code 197.

elabel _u_parse_rules parses rules of the form
(from_numlist = to_numlist ["label"
[...]]) ...,
and returns the respective elements in s(from#),
s(to#), and s(text#). The number of rules
is returned in s(n_rules). Additionally, s(null#)
contains 1 if s(text#) is specified as "", and contains
0 otherwise. s(rules) containes all rules in the form
(from#=to#) ... unless option norules
is specified. If rules are invalid, the command exists with the respective
error message. If there is a syntax error in the command itself, the command
exits with return code 197.

elabel _u_usedby puts in lmacname the variable names that have
one of lblnamelist attached (in any label language). If any of
the names in lblnamelist is invalid, the command exists with syntax
error 198. Note that wildcards are not allowed and _all is treated
as a simple name; elabel _u_usedby does not unabbreviate value label
names. If there is a syntax error in the command itself, the command exits
with return code 197.

Author

Daniel Klein

University of Kassel

klein.daniel.81@gmail.com

Also see

Online: Mata

if installed: elabel