Skip to content

Instantly share code, notes, and snippets.

@stasm
Last active December 18, 2015 20:38
Show Gist options
  • Save stasm/5841373 to your computer and use it in GitHub Desktop.
Save stasm/5841373 to your computer and use it in GitHub Desktop.
An example L20n file with its AST (in JSON and Yaml)
{
"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
}
]
}
<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