Skip to content

Commit

Permalink
implement default arguments for command definition
Browse files Browse the repository at this point in the history
  • Loading branch information
make-github-pseudonymous-again committed Oct 16, 2018
1 parent 7db7c3d commit b1875de
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 133 deletions.
26 changes: 11 additions & 15 deletions src/grammar.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,8 @@ const productions = {
"truecmd" : [ '=truecmd' ] , // 1.4
"comment" : [ '=comment' ] , // 1.5
"def" : [ '=def' , '=othercmd' , '={' , "&anything" , '=}' ] , // 1.7
"newcommand" : [ '=newcommand' , "&cmddef" ] , // 1.8
"renewcommand" : [ '=renewcommand' , "&cmddef" ] ,
"newcommand" : [ '=newcommand' , "&command-definition" ] , // 1.8
"renewcommand" : [ '=renewcommand' , "&command-definition" ] ,
"newenvironment" : [ '=newenvironment' , "&environment-definition" ] ,
"renewenvironment" : [ '=renewenvironment' , "&environment-definition" ] ,
"\n" : [ '=\n' ] ,
Expand All @@ -75,24 +75,20 @@ const productions = {
"elsefi" : [ '=else' , "&anything" , '=fi' ] , // 2.0
"fi" : [ '=fi' ] , // 2.1
} ,
"cmddef" : { // command definition 3
"{cmd}[x]{anything}" : [ '={' , '=othercmd' , '=}' , "&cmddefargs" , '={' , "&anything" , '=}' ] ,
"cmd[x]{anything}" : [ '=othercmd' , "&cmddefargs" , '={' , "&anything" , '=}' ] ,
"*cmd[x]{anything}" : [ '=*' , '=othercmd' , "&cmddefargs" , '={' , "&anything" , '=}' ] ,
} ,
"cmddefargs" : { // command definition arguments 4
"yes" : [ '=[' , '=text' , '=]' ] , // 4.0
"no" : [ ] , // 4.1
"command-definition" : { // command definition 3
"{cmd}[nargs][default]{anything}" : [ '={' , '=othercmd' , '=}' , "&definition-parameters" , '={' , "&anything" , '=}' ] ,
"cmd[nargs][default]{anything}" : [ '=othercmd' , "&definition-parameters" , '={' , "&anything" , '=}' ] ,
"*cmd[nargs][default]{anything}" : [ '=*' , '=othercmd' , "&definition-parameters" , '={' , "&anything" , '=}' ] ,
} ,
"environment-definition" : {
"{envname}[nargs][default]{begin}{end}" : [ '={' , '=text' , '=}' , "&ignore" , "&arguments-for-environment-definition" , '={' , "&anything" , '=}' , "&ignore" , '={' , "&anything" , '=}' ] ,
"*{envname}[nargs][default]{begin}{end}" : [ '=*' , '={' , '=text' , '=}' , "&arguments-for-environment-definition" , '={' , "&anything" , '=}' , '={' , "&anything" , '=}' ] ,
"{envname}[nargs][default]{begin}{end}" : [ '={' , '=text' , '=}' , "&ignore" , "&definition-parameters" , '={' , "&anything" , '=}' , "&ignore" , '={' , "&anything" , '=}' ] ,
"*{envname}[nargs][default]{begin}{end}" : [ '=*' , '={' , '=text' , '=}' , "&definition-parameters" , '={' , "&anything" , '=}' , '={' , "&anything" , '=}' ] ,
} ,
"arguments-for-environment-definition" : {
"yes" : [ '=[' , '=text' , '=]' , '&default-argument-for-environment-definition' , "&ignore" ] ,
"definition-parameters" : {
"yes" : [ '=[' , '=text' , '=]' , '&default-argument-for-definition' , "&ignore" ] ,
"no" : [ ] ,
} ,
"default-argument-for-environment-definition" : {
"default-argument-for-definition" : {
"yes" : [ '=[' , '&anything-but-]' , '=]' ] ,
"no" : [ ] ,
} ,
Expand Down
165 changes: 47 additions & 118 deletions src/shaker.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,29 @@ async function* chain ( iterables ) {

}

async function parseDefinitionParameters ( parameters ) {
let nargs = 0;
let dfltarg = null;
if (parameters.production === 'yes') {
const it2 = iter(parameters.children);
await next(it2) ; // [
const text = await next(it2) ;
nargs = parseInt(text.buffer, 10);
await next(it2) ; // ]

const dfltparam = await next(it2) ;
if ( dfltparam.production === 'yes' ) {
const it3 = iter(dfltparam.children);
await next(it3) ; // [
const anything3 = await next(it3);
dfltarg = await ast.materialize(anything3) ;
await next(it3) ; // ]
}

}
return [ nargs , dfltarg ] ;
}


const empty = {
'type' : 'node' ,
Expand All @@ -57,7 +80,6 @@ const recurse = ( nonterminal , production ) => ( tree , match , ctx ) => ({
"children" : ast.cmap( async x => x.type === 'leaf' ? x : await t( x , match , ctx ) , tree.children ) ,
}) ;


export default {

"document" : {
Expand Down Expand Up @@ -381,83 +403,57 @@ export default {
"fi" : tree => tree ,
} ,

"cmddef" : {
"command-definition" : {

"{cmd}[x]{anything}": async ( tree , _ , { variables } ) => {
"{cmd}[nargs][default]{anything}": async ( tree , _ , { variables } ) => {
const it = iter(tree.children) ;
await next(it); // {
const othercmd = await next(it);
const othercmd = await next(it); // cmd
const cmd = othercmd.buffer;
await next(it); // }
const cmddefargs = await next(it);
let nargs = 0;
if (cmddefargs.production === 'yes') {
const it2 = iter(cmddefargs.children);
await next(it2) ; // [
const text = await next(it2) ;
nargs = parseInt(text.buffer, 10);
await next(it2) ; // ]
}
const parameters = await next(it); // [nargs][default]
const [ nargs , dflt ] = await parseDefinitionParameters( parameters ) ;
await next(it); // {
const anything = await next(it);
const blob = await ast.materialize(anything) ;
variables.get('cmd').set(cmd, [ nargs , null , blob ]);
const blob = await ast.materialize(anything) ; // anything
variables.get('cmd').set(cmd, [ nargs , dflt , blob ]);
await next(it); // }
return empty;
} ,

"cmd[x]{anything}": async ( tree , _ , { variables } ) => {
"cmd[nargs][default]{anything}": async ( tree , _ , { variables } ) => {
const it = iter(tree.children) ;
const othercmd = await next(it);
const cmd = othercmd.buffer;
const cmddefargs = await next(it);
let nargs = 0;
if (cmddefargs.production === 'yes') {
const it2 = iter(cmddefargs.children);
await next(it2) ; // [
const text = await next(it2) ;
nargs = parseInt(text.buffer, 10);
await next(it2) ; // ]
}
const parameters = await next(it); // [nargs][default]
const [ nargs , dflt ] = await parseDefinitionParameters( parameters ) ;
await next(it); // {
const anything = await next(it);
const blob = await ast.materialize(anything) ;
variables.get('cmd').set(cmd, [ nargs , null ,blob ]);
variables.get('cmd').set(cmd, [ nargs , dflt ,blob ]);
await next(it); // }
return empty;
} ,

"*cmd[x]{anything}": async ( tree , _ , { variables } ) => {
"*cmd[nargs][default]{anything}": async ( tree , _ , { variables } ) => {
// do not know what to do with '*' at the moment
// see https://tex.stackexchange.com/questions/1050/whats-the-difference-between-newcommand-and-newcommand
const it = iter(tree.children) ;
await next(it); // *
const othercmd = await next(it);
const cmd = othercmd.buffer;
const cmddefargs = await next(it);
let nargs = 0;
if (cmddefargs.production === 'yes') {
const it2 = iter(cmddefargs.children);
await next(it2) ; // [
const text = await next(it2) ;
nargs = parseInt(text.buffer, 10);
await next(it2) ; // ]
}
const parameters = await next(it); // [nargs][default]
const [ nargs , dflt ] = await parseDefinitionParameters( parameters ) ;
await next(it); // {
const anything = await next(it);
const blob = await ast.materialize(anything) ;
variables.get('cmd').set(cmd, [ nargs , null ,blob ]);
variables.get('cmd').set(cmd, [ nargs , dflt ,blob ]);
await next(it); // }
return empty;
} ,

} ,

"cmddefargs": {
"yes" : err( "cmddefargs" , "yes" ) ,
"no" : err( "cmddefargs" , "no" ) ,
} ,

"environment-definition" : {
"{envname}[nargs][default]{begin}{end}" : async ( tree , _ , { variables } ) => {
// do not know what to do with '*' at the moment
Expand All @@ -469,26 +465,8 @@ export default {
const env = envtext.buffer;
await next(it); // }
await next(it); // ignore
const args = await next(it); // [nargs][default]
let nargs = 0;
let dfltarg = null;
if (args.production === 'yes') {
const it2 = iter(args.children);
await next(it2) ; // [
const text = await next(it2) ;
nargs = parseInt(text.buffer, 10);
await next(it2) ; // ]

const dflt = await next(it2) ;
if ( dflt.production === 'yes' ) {
const it3 = iter(dflt.children);
await next(it3) ; // [
const anything3 = await next(it3);
dfltarg = await ast.materialize(anything3) ;
await next(it3) ; // ]
}

}
const parameters = await next(it); // [nargs][default]
const [ nargs , dflt ] = await parseDefinitionParameters( parameters ) ;
await next(it); // {
const anything1 = await next(it);
const begin = await ast.materialize(anything1) ;
Expand All @@ -498,68 +476,19 @@ export default {
const anything2 = await next(it);
const end = await ast.materialize(anything2) ;
await next(it); // }
variables.get('env').set(env, [ nargs , dfltarg , begin , end ]);
variables.get('env').set(env, [ nargs , dflt , begin , end ]);
return empty;
} ,
//"{envname}[nargs][default]{begin}{end}" : recurse( 'environment-definition' , '{envname}[nargs][default]{begin}{end}' ) ,
"*{envname}[nargs][default]{begin}{end}" : recurse( 'environment-definition' , '*{envname}[nargs][default]{begin}{end}' ) ,
} ,
"arguments-for-environment-definition" : {
"yes" : recurse('arguments-for-environment-definition' , 'yes' ) ,
"no" : () => empty ,
"definition-parameters" : {
"yes" : err('definition-parameters' , 'yes' ) ,
"no" : err('definition-parameters' , 'no' ) ,
} ,
"default-argument-for-environment-definition" : {
"yes" : recurse('default-argument-for-environment-definition' , 'yes' ) ,
"no" : () => empty ,
"default-argument-for-definition" : {
"yes" : err('default-argument-for-definition' , 'yes' ) ,
"no" : err('default-argument-for-definition' , 'no' ) ,
} ,
//"envdef" : {
//"{envname}[nargs][default]{begin}{end}": async ( tree , _ , { variables } ) => {
//do not know what to do with '*' at the moment
//const it = iter(tree.children) ;
//await next(it); // *
//const envtext = await next(it);
//const env = envtext.buffer;
//const envdefargs = await next(it);
//let nargs = 0;
//let defaultarg = null;
//if (envdefargs.production === 'yes') {
//const it2 = iter(envdefargs.children);
//await next(it2) ; // [
//const text = await next(it2) ;
//nargs = parseInt(text.buffer, 10);
//await next(it2) ; // ]
//const envdefdefault = await next(it2) ;
//if (envdefdefault.production === 'yes') {
//const it3 = iter(envdefdefault.children);
//await next(it3) ; // [
//const defaultargtree = await next(it2) ;
//defaultarg = await ast.materialize(defaultargtree) ;
//await next(it3) ; // ]
//}
//}
//await next(it); // {
//const begintree = await next(it);
//const begin = await ast.materialize(begintree) ;
//await next(it); // }
//await next(it); // {
//const endtree = await next(it);
//const end = await ast.materialize(endtree) ;
//variables.get('env').set(env, [ nargs , defaultarg , begin , end ]);
//await next(it); // }
//return empty;
//} ,
//"*{envname}[nargs][default]{begin}{end}": recurse("envdef", "*{envname}[nargs][default]{begin}{end}"),
//} ,

//"envdefargs": {
//"yes" : recurse( "envdefargs" , "yes" ) ,
//"no" : recurse( "envdefargs" , "no" ) ,
//} ,

//"envdefdefault": {
//"yes" : recurse( "envdefdefault" , "yes" ) ,
//"no" : recurse( "envdefdefault" , "no" ) ,
//} ,

"cmd*": {
"yes" : err( "cmd*" , "yes" ) ,
Expand Down
6 changes: 6 additions & 0 deletions test/src/all.js
Original file line number Diff line number Diff line change
Expand Up @@ -227,3 +227,9 @@ test( transformFile , `${transformedInputFiledir}/${filename}` , `${transformedO

// argument escaping
//test( transform , '\\newcommand\\x[1]{\\def\\#1[1]{##1}}\\x{test}' , '\\def\\test[1]{#1}' ) ;

// default arguments with newcommand and renewcommand
test( transform , '\\newcommand{\\price}[2][17.5]{\\pounds #2 excl VAT @ #1\\%}\\price{100}' , '\\pounds 100 excl VAT @ 17.5\\%') ;
test( transform , '\\newcommand{\\price}[2][17.5]{\\pounds #2 excl VAT @ #1\\%}\\price[20]{1000}' , '\\pounds 1000 excl VAT @ 20\\%') ;
test( transform , '\\renewcommand{\\price}[2][17.5]{\\pounds #2 excl VAT @ #1\\%}\\price{100}' , '\\pounds 100 excl VAT @ 17.5\\%') ;
test( transform , '\\renewcommand{\\price}[2][17.5]{\\pounds #2 excl VAT @ #1\\%}\\price[20]{1000}' , '\\pounds 1000 excl VAT @ 20\\%') ;

0 comments on commit b1875de

Please sign in to comment.