Skip to content

Instantly share code, notes, and snippets.

@can3p
Created June 29, 2011 06:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save can3p/1053285 to your computer and use it in GitHub Desktop.
Save can3p/1053285 to your computer and use it in GitHub Desktop.
Translate haml file according to bemto concept
#!/usr/bin/env node
/**
* Прототип прототипа, точно работать должен только на тестовом примере
* из поста. Для дальнейшей доработки нужно будет ближе ознакомиться со
* спецификацией haml и формализовать правила по трансляции имен классов =)
*
* .b-bl1
* .b-bl2_foo
* .__el
* .____el_bar
*/
var fs = require( 'fs' ),
fname = process.argv[2] || die( "specify file name to parse" );
var data = fs.readFileSync( fname, "utf-8" ),
indent = ' ', // 4 spaces, hardcoded
indentLength = indent.length,
indentRegex = /^( )+/,
classStack = [],
classRegex = /\.([a-z0-9_-]+)/i,
lastIndent = -1,
currentIndent = -1,
currentClass = '',
lines = data.replace( /\r\n/g, '\n' ).replace( '\r', '' ).split( '\n' );
function calcIndent( line ) {
var match = indentRegex.exec( line );
if( !match ) { return 0 }
return match[0].length / indentLength;
}
function extractClass( line ) {
var match = classRegex.exec( line );
if( !match ) { return '' }
return match[1];
}
function die( message, number ) {
console.log( ( number ? "line " + number + ": " : "" ) + message );
process.exit();
}
function processLine( line, number ) {
currentIndent = calcIndent( line );
currentClass = extractClass( line );
var resultLine = line;
if( currentIndent > lastIndent && currentIndent - lastIndent > 1 ) {
die( "too big indent jump", number )
} else {
classStack.length = currentIndent;
}
lastIndent = currentIndent;
//console.log( line );
//console.log( currentIndent, currentClass, classStack[ classStack.length - 2 ] || "none" );
var match, replaceClass, levelCount;
if( match = /^(__)+/.exec( currentClass ) ) {
levelCount = match[0].length / 2;
replaceClass = classStack[ classStack.length - levelCount ] ;
if( !replaceClass ) { die( "there is no parent class " + levelCount + " level(s) higher", number ); }
replaceClass += currentClass.replace( /^(__)+/, '__' );
if( match = /[^_](_[0-9a-z-]+)$/i.exec( replaceClass ) ) {
replaceClass = replaceClass.replace( match[1], '' ) + '.' + replaceClass;
}
resultLine = resultLine.replace( currentClass, replaceClass );
} else {
if( ( match = /^b-[^_]+/.exec( currentClass ) ) && match[0].length < currentClass.length ) {
resultLine = resultLine.replace( currentClass, match[0] + '.' + currentClass );
currentClass = match[0];
}
}
classStack.push( currentClass );
return resultLine;
}
//console.log( 'Input data: ');
//console.log( lines.join( '\n' ) );
for( var i = 0; i < lines.length; ++i ) {
lines[ i ] = processLine( lines[ i ], i + 1 );
}
//console.log( 'Results: ');
console.log( lines.join( '\n' ) );
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment