Created
March 18, 2012 03:05
-
-
Save adbrowne/2068290 to your computer and use it in GitHub Desktop.
Replacing variables in javascript files with Cassette IAssetTransformer
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
public class ConstantsGenerator : IAssetTransformer | |
{ | |
private const char ConstantStartToken = '#'; | |
private const char OpeningBraceToken = '{'; | |
private const char ClosingBraceToken = '}'; | |
private readonly Dictionary<string, string> values; | |
public ConstantsGenerator(Dictionary<string, string> values) | |
{ | |
this.values = values; | |
} | |
public Func<Stream> Transform(Func<Stream> openSourceStream, IAsset asset) | |
{ | |
return delegate | |
{ | |
using (var input = new StreamReader(new BufferedStream(openSourceStream()))) | |
{ | |
var outputStream = new MemoryStream(); | |
var writer = new StreamWriter(outputStream); | |
TransformStream(input, writer); | |
writer.Flush(); | |
outputStream.Position = 0; | |
return outputStream; | |
} | |
}; | |
} | |
private void TransformStream(StreamReader input, StreamWriter writer) | |
{ | |
while (!input.EndOfStream) | |
{ | |
var currentChar = (char)input.Read(); | |
var nextChar = (char)input.Peek(); | |
if (currentChar == ConstantStartToken && nextChar == OpeningBraceToken) | |
{ | |
ReadVariable(input, writer); | |
} | |
else | |
{ | |
writer.Write(currentChar); | |
} | |
} | |
} | |
private enum ReadState | |
{ | |
Continue, | |
Eos, | |
Complete | |
} | |
private void ReadVariable(StreamReader input, StreamWriter writer) | |
{ | |
var variableName = new StringBuilder(); | |
//throw away starting brace | |
input.Read(); | |
var state = ReadState.Continue; | |
while (state == ReadState.Continue) | |
{ | |
if(input.EndOfStream) | |
{ | |
state = ReadState.Eos; | |
} | |
else | |
{ | |
var currentChar = (char)input.Read(); | |
if (currentChar != ClosingBraceToken) | |
{ | |
variableName.Append(currentChar); | |
} | |
if(currentChar == ClosingBraceToken) | |
{ | |
state = ReadState.Complete; | |
} | |
} | |
} | |
if (state == ReadState.Complete) | |
{ | |
var key = variableName.ToString().Trim(); | |
if (values.ContainsKey(key)) | |
{ | |
WriteValue(writer, key); | |
} | |
else | |
{ | |
WriteVariableAsInput(writer, variableName); | |
} | |
} | |
else if(state == ReadState.Eos) | |
{ | |
WriteVariableCharactersAsRead(writer, variableName); | |
} | |
} | |
private void WriteValue(StreamWriter writer, string key) | |
{ | |
string variableValue = values[key]; | |
writer.Write(variableValue); | |
} | |
private static void WriteVariableAsInput(StreamWriter writer, StringBuilder variableName) | |
{ | |
writer.Write(ConstantStartToken); | |
writer.Write(OpeningBraceToken); | |
writer.Write(variableName.ToString()); | |
writer.Write(ClosingBraceToken); | |
} | |
private static void WriteVariableCharactersAsRead(StreamWriter writer, StringBuilder variableName) | |
{ | |
writer.Write(ConstantStartToken); | |
writer.Write(OpeningBraceToken); | |
writer.Write(variableName.ToString()); | |
} | |
} |
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
//From CassetteConfiguration | |
bundles.AddPerSubDirectory("js", (Action<ScriptBundle>) (b => b.Processor = new ScriptPipeline().Prepend(new ReplaceConstants(constants)))); |
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
public class ReplaceConstants : IBundleProcessor<ScriptBundle> | |
{ | |
private readonly Dictionary<string, string> values; | |
public ReplaceConstants(Dictionary<string, string> values) | |
{ | |
this.values = values; | |
} | |
public void Process(ScriptBundle bundle, CassetteSettings settings) | |
{ | |
foreach (var asset in bundle.Assets) | |
{ | |
if (asset.SourceFile.FullPath.EndsWith("constants.js")) | |
{ | |
asset.AddAssetTransformer(new ConstantsGenerator(values)); | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment