/* WebPageParser.cpp Written by Matthew Fisher */ #include "Main.h" void WebPageParser::ParseLine(const WebPageParameters &PageParameters, const String &Line, ofstream &OutputFile) { if(Line.Length() > 0 && Line[0] == '@') { //@Include("Header.txt", HomeActive=@MenuActiveString) PersistentAssert(Line.Length() > 1, "Invalid command"); if(Line[1] == '@') { // // Assignment // String VariableName, Value; Line.PartitionAboutIndex(Line.FindFirstIndex('='), VariableName, Value); VariableName.PopFront(); VariableName.PopFront(); HandleAssignment(VariableName, Value); } else { String Command, ParameterString; Line.PartitionAboutIndex(Line.FindFirstIndex('('), Command, ParameterString); PersistentAssert(ParameterString.Last() == ')', "Invalid command"); ParameterString.PopEnd(); if(Command == "@Include") { HandleInclude(PageParameters, ParameterString, OutputFile); } else if(Command == "@Code") { HandleCode(PageParameters, ParameterString, OutputFile); } else { SignalError("Invalid command"); } } } else { String Result; SubstituteVariables(Line, Result); OutputFile << Result << endl; } } WebPageVariable* WebPageParser::GetVariable(const String &Name) { for(UINT VariableIndex = 0; VariableIndex < _Variables.Length(); VariableIndex++) { if(_Variables[VariableIndex].Name == Name) { return &_Variables[VariableIndex]; } } return NULL; } void WebPageParser::HandleInclude(const WebPageParameters &PageParameters, const String &Filename, ofstream &OutputFile) { Vector Lines; Utility::GetFileLines(PageParameters.SourceDirectory + String("\\") + Filename, Lines); for(UINT LineIndex = 0; LineIndex < Lines.Length(); LineIndex++) { ParseLine(PageParameters, Lines[LineIndex], OutputFile); } } bool WebPageParser::IsCodeFile(const String &Filename) { return (Filename.EndsWith(".cpp") || Filename.EndsWith(".h") || Filename.EndsWith(".inl") || Filename.EndsWith(".cs") || Filename.EndsWith(".vsh") || Filename.EndsWith(".psh") || Filename.EndsWith(".vs") || Filename.EndsWith(".ps")); } void WebPageParser::HandleCode(const WebPageParameters &PageParameters, const String &ParameterString, ofstream &OutputFile) { String CodeDirectory, OutputDirectory, FullOutputDirectory; ParameterString.PartitionAboutIndex(ParameterString.FindFirstIndex(','), CodeDirectory, OutputDirectory); String TempString, CodeFolderName; OutputDirectory.PartitionAboutIndex(OutputDirectory.FindLastIndex('/'), TempString, CodeFolderName); OutputFile << "

" << CodeFolderName << " Code Listing


" << endl; CodeDirectory = CodeDirectory + String("/"); OutputDirectory = OutputDirectory + String("/"); FullOutputDirectory = PageParameters.TargetDirectory + String("/") + OutputDirectory; Vector AllLines; UINT TotalLineCount = 0; Directory BaseCodeDirectory(CodeDirectory); for(UINT FileIndex = 0; FileIndex < BaseCodeDirectory.Files().Length(); FileIndex++) { const String &CurFilename = BaseCodeDirectory.Files()[FileIndex]; if(IsCodeFile(CurFilename)) { Utility::GetFileLines(CodeDirectory + CurFilename, AllLines); TotalLineCount += AllLines.Length(); HandleSingleCodeFile(PageParameters, CodeDirectory, CurFilename, FullOutputDirectory + CurFilename, OutputDirectory, 0, OutputFile); } } for(UINT DirectoryIndex = 0; DirectoryIndex < BaseCodeDirectory.Directories().Length(); DirectoryIndex++) { const String &SubDirectoryName = BaseCodeDirectory.Directories()[DirectoryIndex]; if(SubDirectoryName != "Debug" && SubDirectoryName != "Release" && SubDirectoryName != "DebugDLL" && SubDirectoryName != "ReleaseDLL" && SubDirectoryName != "DebugApp" && SubDirectoryName != "ReleaseApp" && SubDirectoryName != "ipch" && SubDirectoryName != "bin" && SubDirectoryName != "obj" && SubDirectoryName != "Properties" && SubDirectoryName != "Icons") { Directory SubDirectory(CodeDirectory + SubDirectoryName + String("/")); OutputFile << "\"x\""; OutputFile << "" << SubDirectoryName << "
" << endl; for(UINT FileIndex = 0; FileIndex < SubDirectory.Files().Length(); FileIndex++) { const String &CurFilename = SubDirectory.Files()[FileIndex]; if(IsCodeFile(CurFilename)) { Utility::GetFileLines(SubDirectory.DirectoryPath() + CurFilename, AllLines); TotalLineCount += AllLines.Length(); HandleSingleCodeFile(PageParameters, SubDirectory.DirectoryPath(), CurFilename, FullOutputDirectory + CurFilename, OutputDirectory, 1, OutputFile); } } } } OutputFile << "

Total lines of code: " << TotalLineCount << "
" << endl; } void WebPageParser::HandleSingleCodeFile(const WebPageParameters &PageParameters, const String &CodeDirectory, const String &CodeFilename, const String &FormattedFile, const String &OutputDirectory, UINT IndentCount, ofstream &OutputFile) { const String &RootDirectory = PageParameters.SourceToHTMLConverterDirectory; if(CopyAllCode && !FormattedFile.Contains("?")) { Utility::CopyFile(CodeDirectory + CodeFilename, RootDirectory + String("Temp.txt")); Utility::CopyFile(CodeDirectory + CodeFilename, FormattedFile); Console::WriteLine("Converting " + CodeFilename); Utility::RunCommand(RootDirectory + String("CPPtoHTML.exe"), "Temp.txt", true); Utility::CopyFile(RootDirectory + String("Temp.txt.html"), FormattedFile + String(".html")); Vector FileLines; String FormattedHTMLFilename = FormattedFile + String(".html"); Utility::GetFileLines(FormattedHTMLFilename, FileLines); ofstream FormattedHTMLFile(FormattedHTMLFilename.CString()); for(UINT LineIndex = 0; LineIndex < FileLines.Length(); LineIndex++) { String CurLine = FileLines[LineIndex]; FormattedHTMLFile << CurLine.FindAndReplace("Temp.txt", String("") + CodeFilename + String("")) << endl; } } //x MainControl.h, Web Version //\"x\" MainControl.h, Web Version String ImageName = "Unknown"; if(CodeFilename.EndsWith(".cpp")) { ImageName = "Source"; } else if(CodeFilename.EndsWith(".inl")) { ImageName = "Source"; } else if(CodeFilename.EndsWith(".vsh") || CodeFilename.EndsWith(".vs")) { ImageName = "Txt"; } else if(CodeFilename.EndsWith(".psh") || CodeFilename.EndsWith(".ps")) { ImageName = "Txt"; } else if(CodeFilename.EndsWith(".h")) { ImageName = "Header"; } else if(CodeFilename.EndsWith(".cs")) { ImageName = "CSharp"; } for(UINT IndentIndex = 0; IndentIndex < IndentCount; IndentIndex++) { OutputFile << "\"x\""; } OutputFile << "\"x\" " << CodeFilename << ", Web Version
" << endl; } void WebPageParser::HandleAssignment(const String &VariableName, const String &Value) { String DereferencedValue; SubstituteVariables(Value, DereferencedValue); WebPageVariable* Variable = GetVariable(VariableName); if(Variable == NULL) { _Variables.PushEnd(WebPageVariable(VariableName, DereferencedValue)); } else { Variable->Value = DereferencedValue; } } void WebPageParser::SubstituteVariables(const String &Line, String &Result) { // // all @'s must be preceeded by a ' '; if @ is the first symbol in a line it is a command // Result.FreeMemory(); for(UINT CharIndex = 0; CharIndex < Line.Length(); CharIndex++) { char PrevC = ' '; if(CharIndex != 0) { PrevC = Line[CharIndex - 1]; } char C = Line[CharIndex]; if(PrevC == ' ' && C == '@') { String VariableName; bool Done = false; for(CharIndex = CharIndex + 1; CharIndex < Line.Length() && !Done; CharIndex++) { C = Line[CharIndex]; if(isalpha(C)) { VariableName.PushEnd(C); } else { CharIndex--; Done = true; } } CharIndex--; WebPageVariable* Variable = GetVariable(VariableName); PersistentAssert(Variable != NULL, String("Variable ") + VariableName + String(" not found")); Result += Variable->Value; } else { Result.PushEnd(C); } } }