Last active
December 18, 2015 20:38
-
-
Save stasm/5841373 to your computer and use it in GitHub Desktop.
An example L20n file with its AST (in JSON and Yaml)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"type": "LOL", | |
"body": [ | |
{ | |
"type": "Entity", | |
"id": { | |
"type": "Identifier", | |
"name": "hello" | |
}, | |
"value": { | |
"type": "String", | |
"content": "Hello, world!", | |
"isNotComplex": true | |
}, | |
"index": [], | |
"attrs": [], | |
"local": false | |
}, | |
{ | |
"type": "Comment", | |
"content": " ------------------------------------------------------------------------- " | |
}, | |
{ | |
"type": "Entity", | |
"id": { | |
"type": "Identifier", | |
"name": "l20n" | |
}, | |
"value": { | |
"type": "String", | |
"content": "L20n", | |
"isNotComplex": true | |
}, | |
"index": [], | |
"attrs": [], | |
"local": false | |
}, | |
{ | |
"type": "Entity", | |
"id": { | |
"type": "Identifier", | |
"name": "intro" | |
}, | |
"value": { | |
"type": "Hash", | |
"content": [ | |
{ | |
"type": "HashItem", | |
"key": { | |
"type": "Identifier", | |
"name": "dev" | |
}, | |
"value": { | |
"type": "String", | |
"content": "You're using a dev build of {{ l20n }} (with AMD modules)." | |
}, | |
"default": false | |
}, | |
{ | |
"type": "HashItem", | |
"key": { | |
"type": "Identifier", | |
"name": "prod" | |
}, | |
"value": { | |
"type": "String", | |
"content": "\n You're using a production-ready single-file version of {{ l20n }}\n (built with make build and found in dist/html).\n " | |
}, | |
"default": false | |
}, | |
{ | |
"type": "HashItem", | |
"key": { | |
"type": "Identifier", | |
"name": "unknown" | |
}, | |
"value": { | |
"type": "String", | |
"content": "You're using an unknown version of {{ l20n }}." | |
}, | |
"default": true | |
} | |
] | |
}, | |
"index": [ | |
{ | |
"type": "VariableExpression", | |
"id": { | |
"type": "Identifier", | |
"name": "build" | |
} | |
} | |
], | |
"attrs": [], | |
"local": false | |
}, | |
{ | |
"type": "Comment", | |
"content": " ------------------------------------------------------------------------- " | |
}, | |
{ | |
"type": "Entity", | |
"id": { | |
"type": "Identifier", | |
"name": "screenWidth" | |
}, | |
"value": { | |
"type": "String", | |
"content": "\n The label of the button below changes depending on the \n available screen width (currently: {{ @screen.width.px }}px).\n" | |
}, | |
"index": [], | |
"attrs": [], | |
"local": false | |
}, | |
{ | |
"type": "Macro", | |
"id": { | |
"type": "Identifier", | |
"name": "formFactor" | |
}, | |
"args": [ | |
{ | |
"type": "VariableExpression", | |
"id": { | |
"type": "Identifier", | |
"name": "n" | |
} | |
} | |
], | |
"expression": { | |
"type": "ConditionalExpression", | |
"test": { | |
"type": "BinaryExpression", | |
"operator": { | |
"type": "BinaryOperator", | |
"token": "<" | |
}, | |
"left": { | |
"type": "PropertyExpression", | |
"expression": { | |
"type": "PropertyExpression", | |
"expression": { | |
"type": "VariableExpression", | |
"id": { | |
"type": "Identifier", | |
"name": "n" | |
} | |
}, | |
"property": { | |
"type": "Identifier", | |
"name": "width" | |
}, | |
"computed": false | |
}, | |
"property": { | |
"type": "Identifier", | |
"name": "px" | |
}, | |
"computed": false | |
}, | |
"right": { | |
"type": "Number", | |
"value": 480 | |
} | |
}, | |
"consequent": { | |
"type": "String", | |
"content": "portraitPhone", | |
"isNotComplex": true | |
}, | |
"alternate": { | |
"type": "ConditionalExpression", | |
"test": { | |
"type": "BinaryExpression", | |
"operator": { | |
"type": "BinaryOperator", | |
"token": "<" | |
}, | |
"left": { | |
"type": "PropertyExpression", | |
"expression": { | |
"type": "PropertyExpression", | |
"expression": { | |
"type": "VariableExpression", | |
"id": { | |
"type": "Identifier", | |
"name": "n" | |
} | |
}, | |
"property": { | |
"type": "Identifier", | |
"name": "width" | |
}, | |
"computed": false | |
}, | |
"property": { | |
"type": "Identifier", | |
"name": "px" | |
}, | |
"computed": false | |
}, | |
"right": { | |
"type": "Number", | |
"value": 768 | |
} | |
}, | |
"consequent": { | |
"type": "String", | |
"content": "landscapePhone", | |
"isNotComplex": true | |
}, | |
"alternate": { | |
"type": "ConditionalExpression", | |
"test": { | |
"type": "BinaryExpression", | |
"operator": { | |
"type": "BinaryOperator", | |
"token": "<" | |
}, | |
"left": { | |
"type": "PropertyExpression", | |
"expression": { | |
"type": "PropertyExpression", | |
"expression": { | |
"type": "VariableExpression", | |
"id": { | |
"type": "Identifier", | |
"name": "n" | |
} | |
}, | |
"property": { | |
"type": "Identifier", | |
"name": "width" | |
}, | |
"computed": false | |
}, | |
"property": { | |
"type": "Identifier", | |
"name": "px" | |
}, | |
"computed": false | |
}, | |
"right": { | |
"type": "Number", | |
"value": 980 | |
} | |
}, | |
"consequent": { | |
"type": "String", | |
"content": "landscapeTablet", | |
"isNotComplex": true | |
}, | |
"alternate": { | |
"type": "ConditionalExpression", | |
"test": { | |
"type": "BinaryExpression", | |
"operator": { | |
"type": "BinaryOperator", | |
"token": "<" | |
}, | |
"left": { | |
"type": "PropertyExpression", | |
"expression": { | |
"type": "PropertyExpression", | |
"expression": { | |
"type": "VariableExpression", | |
"id": { | |
"type": "Identifier", | |
"name": "n" | |
} | |
}, | |
"property": { | |
"type": "Identifier", | |
"name": "width" | |
}, | |
"computed": false | |
}, | |
"property": { | |
"type": "Identifier", | |
"name": "px" | |
}, | |
"computed": false | |
}, | |
"right": { | |
"type": "Number", | |
"value": 1200 | |
} | |
}, | |
"consequent": { | |
"type": "String", | |
"content": "desktop", | |
"isNotComplex": true | |
}, | |
"alternate": { | |
"type": "String", | |
"content": "large", | |
"isNotComplex": true | |
} | |
} | |
} | |
} | |
} | |
}, | |
{ | |
"type": "Entity", | |
"id": { | |
"type": "Identifier", | |
"name": "button" | |
}, | |
"value": { | |
"type": "String", | |
"content": "", | |
"isNotComplex": true | |
}, | |
"index": [], | |
"attrs": [ | |
{ | |
"type": "Attribute", | |
"key": { | |
"type": "Identifier", | |
"name": "value" | |
}, | |
"value": { | |
"type": "Hash", | |
"content": [ | |
{ | |
"type": "HashItem", | |
"key": { | |
"type": "Identifier", | |
"name": "desktop" | |
}, | |
"value": { | |
"type": "String", | |
"content": "Create & insert a <p> element that will be dynamically localized", | |
"isNotComplex": true | |
}, | |
"default": true | |
}, | |
{ | |
"type": "HashItem", | |
"key": { | |
"type": "Identifier", | |
"name": "landscapeTablet" | |
}, | |
"value": { | |
"type": "String", | |
"content": "Create & insert a dynamically-localized <p>", | |
"isNotComplex": true | |
}, | |
"default": false | |
}, | |
{ | |
"type": "HashItem", | |
"key": { | |
"type": "Identifier", | |
"name": "landscapePhone" | |
}, | |
"value": { | |
"type": "String", | |
"content": "Insert a dynamically-localized <p>", | |
"isNotComplex": true | |
}, | |
"default": false | |
}, | |
{ | |
"type": "HashItem", | |
"key": { | |
"type": "Identifier", | |
"name": "portraitPhone" | |
}, | |
"value": { | |
"type": "String", | |
"content": "Insert a <p>", | |
"isNotComplex": true | |
}, | |
"default": false | |
} | |
] | |
}, | |
"index": [ | |
{ | |
"type": "CallExpression", | |
"callee": { | |
"type": "Identifier", | |
"name": "formFactor" | |
}, | |
"arguments": [ | |
{ | |
"type": "GlobalsExpression", | |
"id": { | |
"type": "Identifier", | |
"name": "screen" | |
} | |
} | |
] | |
} | |
], | |
"local": false | |
} | |
], | |
"local": false | |
}, | |
{ | |
"type": "Entity", | |
"id": { | |
"type": "Identifier", | |
"name": "currentWidth" | |
}, | |
"value": { | |
"type": "String", | |
"content": "Current width: {{ @screen.width.px }}px." | |
}, | |
"index": [], | |
"attrs": [], | |
"local": false | |
}, | |
{ | |
"type": "Comment", | |
"content": " ------------------------------------------------------------------------- " | |
}, | |
{ | |
"type": "Entity", | |
"id": { | |
"type": "Identifier", | |
"name": "_options" | |
}, | |
"value": { | |
"type": "Hash", | |
"content": [ | |
{ | |
"type": "HashItem", | |
"key": { | |
"type": "Identifier", | |
"name": "win" | |
}, | |
"value": { | |
"type": "String", | |
"content": "Settings", | |
"isNotComplex": true | |
}, | |
"default": false | |
}, | |
{ | |
"type": "HashItem", | |
"key": { | |
"type": "Identifier", | |
"name": "nix" | |
}, | |
"value": { | |
"type": "String", | |
"content": "Preferences", | |
"isNotComplex": true | |
}, | |
"default": true | |
} | |
] | |
}, | |
"index": [ | |
{ | |
"type": "GlobalsExpression", | |
"id": { | |
"type": "Identifier", | |
"name": "os" | |
} | |
} | |
], | |
"attrs": [], | |
"local": true | |
}, | |
{ | |
"type": "Entity", | |
"id": { | |
"type": "Identifier", | |
"name": "langNego" | |
}, | |
"value": { | |
"type": "Hash", | |
"content": [ | |
{ | |
"type": "HashItem", | |
"key": { | |
"type": "Identifier", | |
"name": "multi" | |
}, | |
"value": { | |
"type": "String", | |
"content": "\n In order to test language negotiation, go to your\n browser's {{ _options }} and change the Accept-Language\n header. Try setting French (fr) or Polish (pl) as your\n first choice and observe the language fallback at work \n in the web console.\n " | |
}, | |
"default": false | |
}, | |
{ | |
"type": "HashItem", | |
"key": { | |
"type": "Identifier", | |
"name": "single" | |
}, | |
"value": { | |
"type": "String", | |
"content": "\n In the single-locale mode, no locales have been registered.\n There is no language negotiation on the client side nor\n language fallback. This may be useful for server-side or\n build-time language negotiation scenarios.\n ", | |
"isNotComplex": true | |
}, | |
"default": false | |
} | |
] | |
}, | |
"index": [ | |
{ | |
"type": "VariableExpression", | |
"id": { | |
"type": "Identifier", | |
"name": "mode" | |
} | |
} | |
], | |
"attrs": [], | |
"local": false | |
}, | |
{ | |
"type": "Comment", | |
"content": " ------------------------------------------------------------------------- " | |
}, | |
{ | |
"type": "Macro", | |
"id": { | |
"type": "Identifier", | |
"name": "timeOfDay" | |
}, | |
"args": [ | |
{ | |
"type": "VariableExpression", | |
"id": { | |
"type": "Identifier", | |
"name": "h" | |
} | |
} | |
], | |
"expression": { | |
"type": "ConditionalExpression", | |
"test": { | |
"type": "BinaryExpression", | |
"operator": { | |
"type": "BinaryOperator", | |
"token": "<" | |
}, | |
"left": { | |
"type": "VariableExpression", | |
"id": { | |
"type": "Identifier", | |
"name": "h" | |
} | |
}, | |
"right": { | |
"type": "Number", | |
"value": 6 | |
} | |
}, | |
"consequent": { | |
"type": "String", | |
"content": "night", | |
"isNotComplex": true | |
}, | |
"alternate": { | |
"type": "ConditionalExpression", | |
"test": { | |
"type": "BinaryExpression", | |
"operator": { | |
"type": "BinaryOperator", | |
"token": "<" | |
}, | |
"left": { | |
"type": "VariableExpression", | |
"id": { | |
"type": "Identifier", | |
"name": "h" | |
} | |
}, | |
"right": { | |
"type": "Number", | |
"value": 12 | |
} | |
}, | |
"consequent": { | |
"type": "String", | |
"content": "morning", | |
"isNotComplex": true | |
}, | |
"alternate": { | |
"type": "ConditionalExpression", | |
"test": { | |
"type": "BinaryExpression", | |
"operator": { | |
"type": "BinaryOperator", | |
"token": "<" | |
}, | |
"left": { | |
"type": "VariableExpression", | |
"id": { | |
"type": "Identifier", | |
"name": "h" | |
} | |
}, | |
"right": { | |
"type": "Number", | |
"value": 18 | |
} | |
}, | |
"consequent": { | |
"type": "String", | |
"content": "afternoon", | |
"isNotComplex": true | |
}, | |
"alternate": { | |
"type": "String", | |
"content": "evening", | |
"isNotComplex": true | |
} | |
} | |
} | |
} | |
}, | |
{ | |
"type": "Entity", | |
"id": { | |
"type": "Identifier", | |
"name": "more" | |
}, | |
"value": { | |
"type": "String", | |
"content": "\n For more information, visit <a>L20n.org</a>.\n", | |
"isNotComplex": true | |
}, | |
"index": [], | |
"attrs": [], | |
"local": false | |
}, | |
{ | |
"type": "Entity", | |
"id": { | |
"type": "Identifier", | |
"name": "kthxbye" | |
}, | |
"value": { | |
"type": "Hash", | |
"content": [ | |
{ | |
"type": "HashItem", | |
"key": { | |
"type": "Identifier", | |
"name": "morning" | |
}, | |
"value": { | |
"type": "String", | |
"content": "Enjoy your morning!", | |
"isNotComplex": true | |
}, | |
"default": false | |
}, | |
{ | |
"type": "HashItem", | |
"key": { | |
"type": "Identifier", | |
"name": "afternoon" | |
}, | |
"value": { | |
"type": "String", | |
"content": "Have a great rest of the day!", | |
"isNotComplex": true | |
}, | |
"default": false | |
}, | |
{ | |
"type": "HashItem", | |
"key": { | |
"type": "Identifier", | |
"name": "evening" | |
}, | |
"value": { | |
"type": "String", | |
"content": "Have fun tonight!", | |
"isNotComplex": true | |
}, | |
"default": false | |
}, | |
{ | |
"type": "HashItem", | |
"key": { | |
"type": "Identifier", | |
"name": "night" | |
}, | |
"value": { | |
"type": "String", | |
"content": "Y U NO asleep‽", | |
"isNotComplex": true | |
}, | |
"default": false | |
} | |
] | |
}, | |
"index": [ | |
{ | |
"type": "CallExpression", | |
"callee": { | |
"type": "Identifier", | |
"name": "timeOfDay" | |
}, | |
"arguments": [ | |
{ | |
"type": "GlobalsExpression", | |
"id": { | |
"type": "Identifier", | |
"name": "hour" | |
} | |
} | |
] | |
} | |
], | |
"attrs": [], | |
"local": false | |
} | |
] | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<hello "Hello, world!"> | |
/* ------------------------------------------------------------------------- */ | |
<l20n "L20n"> | |
<intro[$build] { | |
dev: "You're using a dev build of {{ l20n }} (with AMD modules).", | |
prod: """ | |
You're using a production-ready single-file version of {{ l20n }} | |
(built with make build and found in dist/html). | |
""", | |
*unknown: "You're using an unknown version of {{ l20n }}." | |
}> | |
/* ------------------------------------------------------------------------- */ | |
<screenWidth """ | |
The label of the button below changes depending on the | |
available screen width (currently: {{ @screen.width.px }}px). | |
"""> | |
<formFactor($n) { | |
$n.width.px < 480 ? "portraitPhone" : | |
$n.width.px < 768 ? "landscapePhone" : | |
$n.width.px < 980 ? "landscapeTablet" : | |
$n.width.px < 1200 ? "desktop" : | |
"large" }> | |
<button "" | |
value[formFactor(@screen)]: { | |
*desktop: "Create & insert a <p> element that will be dynamically localized", | |
landscapeTablet: "Create & insert a dynamically-localized <p>", | |
landscapePhone: "Insert a dynamically-localized <p>", | |
portraitPhone: "Insert a <p>" | |
} | |
> | |
<currentWidth "Current width: {{ @screen.width.px }}px."> | |
/* ------------------------------------------------------------------------- */ | |
<_options[@os] { | |
win: "Settings", | |
*nix: "Preferences" | |
}> | |
<langNego[$mode] { | |
multi: """ | |
In order to test language negotiation, go to your | |
browser's {{ _options }} and change the Accept-Language | |
header. Try setting French (fr) or Polish (pl) as your | |
first choice and observe the language fallback at work | |
in the web console. | |
""", | |
single: """ | |
In the single-locale mode, no locales have been registered. | |
There is no language negotiation on the client side nor | |
language fallback. This may be useful for server-side or | |
build-time language negotiation scenarios. | |
""" | |
}> | |
/* ------------------------------------------------------------------------- */ | |
<timeOfDay($h) { | |
$h < 6 ? "night" : | |
$h < 12 ? "morning" : | |
$h < 18 ? "afternoon" : | |
"evening" }> | |
<more """ | |
For more information, visit <a>L20n.org</a>. | |
"""> | |
<kthxbye[timeOfDay(@hour)] { | |
morning: "Enjoy your morning!", | |
afternoon: "Have a great rest of the day!", | |
evening: "Have fun tonight!", | |
night: "Y U NO asleep‽" | |
}> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment