src/templates/bemto_core.pug
//- bemto
//- Copyright(c) 2012 Roman Komarov <kizu@kizu.ru>
//- MIT Licensed
//- Some global variables
-
$bemto_chain = [];
$bemto_chain_contexts = ['block'];
//- Block
mixin b($options)
-
$get_context = function ($ctx) { $ctx = empty($ctx['context']) ? '' : $ctx['context']; return is_string($ctx) ? $ctx : $ctx[0]; };
$settings = $get_bemto_settings();
//- TODO: should we make it generic way for other settings too?
if is_array($options) && isset($options['prefix'])
- $settings['prefix'] = $options['prefix']
//- Rewriting the class for elements and modifiers
-
$tag = $options ? (is_string($options) ? $options : (isset($options['tag']) ? $options['tag'] : '')) : '';
$options = (array) ($options ?: []);
$isElement = $options && isset($options['isElement']) && $options['isElement'];
$tagMetadata = $options && isset($options['metadata']) ? $options['metadata'] : null;
$block_sets_context = false;
if !empty($attributes['class'])
//- Creating and normalizing bemto classes
- $bemto_classes = $attributes['class']
if is_array($bemto_classes)
- $bemto_classes = implode(' ', $bemto_classes)
- $bemto_classes = explode(' ', $bemto_classes)
- $bemto_objects = []
- $is_first_object = true
- $new_context = []
each $klass, $i in $bemto_classes
- $bemto_object = []
- $bemto_objects_count = count($bemto_objects)
- $sets_context = false
//- Catching the optional tag class
- if (preg_match('/^[A-Z-]+[A-Z0-9-]?$/', $klass))
- $tag = strtolower($klass)
- continue
//- Use block as a context for the first class if we're at element
if $is_first_object && $isElement
- $bemto_object['context'] = count($bemto_chain) ? $bemto_chain[count($bemto_chain) - 1] : null
//- If the class is a modifier, add it to the previous object
//- FIXME: `+b._mod._mod` — raw classes should be treated as raw ones
- if (preg_match('/^(?!' . $settings['element'] . '[A-Za-z0-9])' . $settings['modifier'] . '(.+)$/', $klass, $modifier_class) && $bemto_objects_count && isset($bemto_objects[$bemto_objects_count - 1]['name']) && $bemto_objects[$bemto_objects_count - 1]['name'])
if (!isset($bemto_objects[$bemto_objects_count - 1]['modifiers'])) || (!$bemto_objects[$bemto_objects_count - 1]['modifiers'])
- $bemto_objects[$bemto_objects_count - 1]['modifiers'] = []
- $bemto_objects[$bemto_objects_count - 1]['modifiers'][] = $modifier_class[1]
- continue
//- Use block as a context for the following classes if we have element delimiter at the start
- if (preg_match('/^(?!' . $settings['modifier'] . '[A-Za-z0-9])' . $settings['element'] . '(.+)$/', $klass, $element_class))
- $bemto_object['context'] = count($bemto_chain) ? $bemto_chain[count($bemto_chain) - 1] : null
- $klass = $element_class[1]
//- Set custom context for nested items
- if (preg_match('/^(.*[A-Za-z0-9])(?!' . $settings['modifier'] . '$)' . $settings['element'] . '$/', $klass, $name_with_context))
- $klass = $name_with_context[1]
- $bemto_object['is_context'] = true
- $sets_context = true
- $block_sets_context = true
- $isElement = false
//- Apply the modifier from the classname if exist
- if (preg_match('/^(.*?[A-Za-z0-9])(?!' . $settings['element'] . '[A-Za-z0-9])' . $settings['modifier'] . '(.+)$/', $klass, $name_with_modifier))
- $klass = $name_with_modifier[1]
if (!isset($bemto_object['modifiers'])) || (!$bemto_object['modifiers'])
- $bemto_object['modifiers'] = []
- $bemto_object['modifiers'][] = $name_with_modifier[2]
- $found_prefix = ''
- $prefix_regex_string = '()?'
if $settings['prefix']
- $prefix = $settings['prefix']
if is_string($prefix)
- $prefix = ['' => $prefix]
- $prefix_regex_test = []
if is_array($prefix)
each $value, $key in $prefix
if is_string($key) && ($key !== '') && (!in_array($key, $prefix_regex_test))
- $prefix_regex_test[] = $key
if is_string($value) && ($value !== '') && (!in_array($value, $prefix_regex_test))
- $prefix_regex_test[] = $value
- $prefix_regex_string = '(' . implode('|', $prefix_regex_test) . ')?'
- if (preg_match('/^' . $prefix_regex_string . '([A-Za-z0-9]+.*)$/', $klass, $name_with_prefix))
- $klass = $name_with_prefix[2]
- $found_prefix = $name_with_prefix[1] ?: ''
- $found_prefix = isset($prefix[$found_prefix]) ? $prefix[$found_prefix] : null
if ($found_prefix === null) || ($found_prefix === true)
- $found_prefix = $name_with_prefix[1]
- $bemto_object['prefix'] = strtr($found_prefix ?: '', ['-' => '%DASH%', '_' => '%UNDERSCORE%'])
- if ($sets_context && preg_match('/^[a-zA-Z0-9]+.*/', $klass))
- $new_context[] = isset($bemto_object['context']) && $bemto_object['context'] ? ($get_context($bemto_object) . $settings['element'] . $klass) : ($bemto_object['prefix'] . $klass)
- $bemto_object['name'] = $klass
- $is_first_object = false
if isset($bemto_object['context']) && count($bemto_object['context']) > 1
each $subcontext in $bemto_object['context']
- $sub_object = copyValue($bemto_object)
- $sub_object['context'] = [$subcontext]
- $bemto_objects[] = $sub_object
else
- $bemto_objects[] = $bemto_object
//- If no custom context is set, use the first proper object
- if (!$isElement && !count($new_context) && isset($bemto_objects[0]) && $bemto_objects[0] && isset($bemto_objects[0]['name']) && preg_match('/^[a-zA-Z0-9]+.*/', $bemto_objects[0]['name']))
- $bemto_objects[0]['is_context'] = true
- $new_context[] = isset($bemto_objects[0]['context']) && $bemto_objects[0]['context'] ? ($get_context($bemto_objects[0]) . $settings['element'] . $bemto_objects[0]['name']) : ($bemto_objects[0]['prefix'] . $bemto_objects[0]['name'])
- $block_sets_context = true
if count($new_context)
//- Use only the block's name for context if we're at strict setting
if $settings['flat_elements']
each $subcontext, $i in $new_context
- if ( preg_match('/^(.*?[A-Za-z0-9])(?!' . $settings['modifier'] . '[A-Za-z0-9])' . $settings['element'] . '.+$/', $subcontext, $context_with_element))
- $new_context[$i] = $context_with_element[1]
- $bemto_chain[] = $new_context
//- Rendering the classes
if count($bemto_objects)
- $new_classes = []
each $bemto_object in $bemto_objects
if isset($bemto_object['name']) && $bemto_object['name']
- $start = $bemto_object['prefix']
if isset($bemto_object['context']) && $bemto_object['context']
- $start = $get_context($bemto_object) . $settings['output_element']
- $new_classes[] = $start . $bemto_object['name']
if !empty($bemto_object['modifiers'])
each $modifier in $bemto_object['modifiers']
- $new_classes[] = $start . $bemto_object['name'] . $settings['output_modifier'] . $modifier
- $delimiter = isset($settings['class_delimiter']) && $settings['class_delimiter'] ? (' ' . $settings['class_delimiter'] . ' ') : ' '
- $attributes['class'] = strtr(implode($delimiter, $new_classes), ['%DASH%' => '-', '%UNDERSCORE%' => '_'])
else
- $attributes['class'] = null
- $__pug_bemto_chain_splice = (!$isElement && $block_sets_context);
if $block
+bemto_tag($tag, $tagMetadata)&attributes($attributes): block
else
+bemto_tag($tag, $tagMetadata)&attributes($attributes)
//- Closing actions (remove the current block from the chain)
if $__pug_bemto_chain_splice
- $bemto_chain = array_splice($bemto_chain, 0, -1)
- $bemto_chain_contexts = array_splice($bemto_chain_contexts, 0, -1)
//- Element
mixin e($options)
unless $options
- $options = []
else if is_string($options)
- $options = ['tag' => $options]
- $options['isElement'] = true
if $block
+b($options)&attributes($attributes): block
else
+b($options)&attributes($attributes)