Info¶
YAML is a human-friendly data serialization standard for all programming languages including ctr
. The data structure of ctr
is a composition of Objects, Strings, Numbers, and Arrays which makes it a match made in heaven for YAML. Long story made short, if you are unfamiliar with YAML it is similar to JSON just with syntaxical freedom plus comments; alternatively, it can be formatted just like JSON.
Syntax¶
Description: The ctr
parsing process of YAML is dead simple. A YAML file is a composition of Objects and ctr
phrases each Object as a separate ctr
style instance in which the Object key represents the root CSS selector, and the Object value represents the CSS style properties.
<#selector>:
<prop>: <value>
<#selector> {
<prop>: <value>;
}
<#selectorOne>:
<prop>: <value>
<#selectorTwo>:
<prop>: <value>
<#selectorOne> {
<prop>: <value>;
}
<#selectorTwo> {
<prop>: <value>;
}
//The JS equivalent to the above YAML
ctr.create({
'<#selectorOne>': {
'<prop>': '<value>'
},
'<#selectorTwo>': {
'<prop>': '<value>'
}
});
<#selectorOne> {
<prop>: <value>;
}
<#selectorTwo> {
<prop>: <value>;
}
Notes:
- It may be helpful it you cruz on over to the JS-YAML demo, a YAML JavaScript parser so you can see how YAML is parsed into Javascript
- Don’t over-mystify what is happening here; all
ctr
does is parse the YAML into a JS Object and uses the Object to create a style via thecreate
method
Data Structure¶
Description: The difference between data structures in Stylus compared to YAML is minuscule. There are three big tickets, comments, curly brackets, and Arrays.
Comments: A #
in YAML denotes a comment compared to Stylus which uses //
.
ctr('<#selector>', {
// My Comment
width: 200px
color: #eee
})
<#selector>:
# My Comment
width: 200px
# Gotcha, need to wrap hex values in a string
color: '#eee'
Notes
- The biggest “gotcha” is hex color codes which are parsed as comments to avoid this gotcha you must stringify all hex color codes
Curly Brackets Omit: Brackets can be omitted.
ctr('<#selector>', {
width: 200px
font-size: 12px
hover: {
on: {
height: 400px
}
}
})
<#selector>:
width: 200px
font-size: 12px
hover:
on:
height: 400px
Curly Brackets Keep: The conversion from Stylus is not one to one, and the typical Javascript Object syntax conventions must be followed in YAML.
ctr('<#selector>', {
width: 200px
font-size: 12px
hover: {
on: {
height: 400px
}
non: {
height: 200px
}
}
})
<#selector>: {
width: 200px,
font-size: 12px,
hover: {
on: {
height: 400px
},
non: {
height: 200px
}
}
}
Notes
- For monolithic styles, brackets can be advantageous
Arrays: In Stylus Arrays are called Lists which allows for the omission of square brackets. However, this is not the case in YAML and to define an Array square brackets must be used.
ctr('<#selector>', {
width: 200px
hover: {
option: {
shorthand: {
//stylus automatically does this for you
height: 10s ease-in 4s
}
}
on: {
height: 400px
}
non: {
height: 200px
}
}
})
<#selector>:
width: 200px
hover:
on:
height: 400px
non:
height: 200px
option:
shorthand:
# Needs to use [ & ] to signify its an array
height: [10s, ease-in, 4s]
File Variables¶
Description: Currently, js-yaml does not support node anchors aka variables. Nevertheless, a variable Object can be defined through an Object with the key of $$
. The variables defined in this Object are similar to variables set through the setVariable
method. However, unlike global variables, the set YAML variables are only available to the YAML styles defined in the file. Also, global YAML variables can work hand-in-hand with local variables in each YAML style.
# variable Object
$$:
<propOne>: <valueOne>
<objectKey>:
<propTwo>: <valueTwo>
.test:
width: $<propOne>$
font-size: $<objectKey>.<propTwo>$
.test {
width: <valueOne>;
font-size: <valueTwo>;
}
Notes
- Variable lookup is performed through lodash’s
_.get
Function using dot notation:$<path>.<to>.<var>$
- If a variable is not found
ctr
will throw you a warning and the value will be$var-not-found$
- Variable priority:
local > YAML variables > setVariable
- Tests:
__tests__/cases-js/yaml/variable
Key Modifier¶
Description: There are instances in CSS when it makes sense to have key duplication although this is problematic since key duplication in an Object is not possible. To solve this issue an Object key modifier can be used in the following fashion <selector>:::<modifier>
and ctr
will remove the modifier upon processing the style.
.test:::one:
width: 200px
.test:::two:
height: 400px
.test {
width: 200px;
}
.test {
height: 400px;
}
Notes
- I would shy away from using modifiers since they are more or less of an anti-pattern but follow your heart
- Tests:
__tests__/cases-styl-yml
every.yml
test in directory uses key modifers
yaml¶
Description: The yaml
method alivates many of the pain points involved with having to require
a YAML file which cannot be done nativley. Essentially the method is a wrapper around fs
and the YAML parser js-YAML to read and convert YAML files into Javascript Objects.
Parameters
yaml()
yaml(<filePath>, [<option> | <transformFn>])
yaml(<filePath>, <option>, <transformFn>)
Arguments
<filePath>
String | [Strings] | (True | Undefined)
String
- Absolute path: Should work absolutely, no questions asked
- Relative path: Should work in most V8 environments, uses
Error.prepareStackTrace
to obtain the last Functions caller path which should be thectr
instance
[Strings]
- An Array of YAML file paths
True | Undefined
argumentless- Uses
Error.prepareStackTrace
to obtain the last Functions caller path which should be thectr
instance, and then looks for a YAML file with the same path but with the extension ofyml
oryaml
- Uses
<option>
Object
option
Object
ctr
specific options can be defined in the root of the<option>
Object or defined in an Object with the key ofoption
transform | yamlTransform
Function
- Refers to
setYamlTransform
, same thing assetYamlTransform(<data>, {once: true})
- Refers to
requireWatch
Function
- A ctr-loader specific option to pass the
requireWatch
Function that in turn adds the YAML file(s) to webpack’s dependency watch list
- A ctr-loader specific option to pass the
Example
const ctr = new CTR();
// Absolute or relative file path
ctr.yaml('./<filePath>.yml');
const ctrResult = ctr.getResult();
const ctr = new CTR();
// All other ctr methods work with yaml
// Set's all hover states to have duration of 2s
ctr.setOption({
hover: {
duration: '2s'
}
});
// Any hover states will have a duration of 2s
ctr.yaml('./<filePath>.yml');
const ctrResult = ctr.getResult();
Notes
- Like everything in
ctr
, there is a boat load of tests you can checkout to get a better understanding - Tests:
__tests__/cases-js/yaml
all tests use theyaml
method
setYamlTransform¶
Description: The setYamlTransform
method creates and sets a hook to transform the raw Object results of the parsed YAML before the data is rendered.
Parameters
setYamlTransform({<reset>: false, <once>: false})
setYamlTransform(<transform>, {<reset>: false, <once>: false})
Arguments
<transform>
Function | [Function, Function, ...]
- A single argument of the resulting prased YAML Object is passed to the transform Function(s)
- Functions are applied in the order they were received
- Must return an Object value otherwise disregarded
<once>
Boolean | false
- Sets the transforms to be applied once to the following instance and then disregarded
<reset>
Boolean | false
- Resets all transforms set through
setYamlTransform
- Resets all transforms set through
Example
//set transform
ctr.setYamlTransform(function (yamlObj) {
// uppercase selector key
return Object.keys(yamlObj).reduce(function (prv, key) {
prv[key.toUpperCase()] = yamlObj[key];
return prv;
}, {});
});
//process yaml file
ctr.yaml('./test-data.yml');
const ctrResult = ctr.getResult();
// .TEST-DATA {
// color: #f00;
// width: 200px;
// }
# The YAML style data
# filePath: ./test-data.yml
.test-data:
color: red
width: 200px
Notes
- Differs from
setTransform
in that it alters the data before it is rendered - Tests:
__tests__/cases-js/yaml/set-yaml-transform