// Group: Loading Functions // __________________________________________________________________________ /* Function: Load * Attempts to load any project information it can find in <Menu.txt>. Unlike <Project_txt.Load()>, this doesn't take an * <ErrorList>. Loading <Menu.txt> is done when it can provide a benefit but it failing to load is not an error. */ public bool Load(Path path, out ProjectConfig projectConfig) { projectConfig = new ProjectConfig(PropertySource.OldMenuFile); using (var configFile = new ConfigFile()) { ErrorList ignored = new Errors.ErrorList(); bool openResult = configFile.Open(path, PropertySource.OldMenuFile, ConfigFile.FileFormatFlags.CondenseIdentifierWhitespace | ConfigFile.FileFormatFlags.SupportsBraces | ConfigFile.FileFormatFlags.MakeIdentifiersLowercase, ignored); if (openResult == false) { return(false); } Regex.Config.Subtitle subtitleRegex = new Regex.Config.Subtitle(); Regex.Config.Timestamp timestampRegex = new Regex.Config.Timestamp(); string lcIdentifier, value; while (configFile.Get(out lcIdentifier, out value)) { var propertyLocation = new PropertyLocation(PropertySource.OldMenuFile, path, configFile.LineNumber); if (lcIdentifier == "title") { projectConfig.ProjectInfo.Title = value.ConvertCopyrightAndTrademark(); projectConfig.ProjectInfo.TitlePropertyLocation = propertyLocation; } else if (subtitleRegex.IsMatch(lcIdentifier)) { projectConfig.ProjectInfo.Subtitle = value.ConvertCopyrightAndTrademark(); projectConfig.ProjectInfo.SubtitlePropertyLocation = propertyLocation; } else if (lcIdentifier == "footer" || lcIdentifier == "copyright") { projectConfig.ProjectInfo.Copyright = value.ConvertCopyrightAndTrademark(); projectConfig.ProjectInfo.CopyrightPropertyLocation = propertyLocation; } else if (timestampRegex.IsMatch(lcIdentifier)) { projectConfig.ProjectInfo.TimestampCode = value; projectConfig.ProjectInfo.TimestampCodePropertyLocation = propertyLocation; } // Otherwise just ignore the entry. } configFile.Close(); } return(true); }
/* Function: GetProjectInfoProperty * If the passed identifier is a project info property like Title, adds it to <currentProjectInfo> and returns true. If it is a recognized * project info property but there's a syntax error in the value, it will add an error to <errorList> and still return true. It only returns * false for unrecognized identifiers. */ protected bool GetProjectInfoProperty(string lcIdentifier, string value, PropertyLocation propertyLocation, ProjectInfo projectInfo) { if (lcIdentifier == "title") { projectInfo.Title = value.ConvertCopyrightAndTrademark(); projectInfo.TitlePropertyLocation = propertyLocation; return(true); } else if (subtitleRegex.IsMatch(lcIdentifier)) { projectInfo.Subtitle = value.ConvertCopyrightAndTrademark(); projectInfo.SubtitlePropertyLocation = propertyLocation; return(true); } else if (lcIdentifier == "copyright") { projectInfo.Copyright = value.ConvertCopyrightAndTrademark(); projectInfo.CopyrightPropertyLocation = propertyLocation; return(true); } else if (timestampRegex.IsMatch(lcIdentifier)) { projectInfo.TimestampCode = value; projectInfo.TimestampCodePropertyLocation = propertyLocation; return(true); } else if (lcIdentifier == "style") { projectInfo.StyleName = value; projectInfo.StyleNamePropertyLocation = propertyLocation; return(true); } else { return(false); } }
/* Function: GetTargetProperty * If the passed identifier is a valid keyword for <currentTarget>, applies the property and returns true. This does not cover * the <ProjectInfo> settings for output targets, use <GetProjectInfoProperty()> for that instead. If the value is invalid it will * add an error to <errorList> and still return true. It will only return false if the identifier is unrecognized. */ protected bool GetTargetProperty(string lcIdentifier, string value, PropertyLocation propertyLocation, Target target) { if (lcIdentifier == "name") { if (target is Targets.SourceFolder && (target as Targets.SourceFolder).Type == Files.InputType.Source) { (target as Targets.SourceFolder).Name = value; (target as Targets.SourceFolder).NamePropertyLocation = propertyLocation; } else { errorList.Add(Locale.Get("NaturalDocs.Engine", "Project.txt.NameOnlyAppliesToSourceFolders"), propertyLocation.FileName, propertyLocation.LineNumber); } return(true); } else { return(false); } }
/* Function: GetTargetHeader * If the passed identifier starts a target like "Source Folder", adds a new target for it in <projectConfig> and returns true. If * it is a recognized target header but there is a syntax error in the value, it will add an error to <errorList> and still return true. * It only returns false for unrecognized identifiers. */ protected bool GetTargetHeader(string lcIdentifier, string value, PropertyLocation propertyLocation, out Target newTarget) { // Source folder System.Text.RegularExpressions.Match match = sourceFolderRegex.Match(lcIdentifier); if (match.Success) { var target = new Targets.SourceFolder(propertyLocation); target.Folder = value; target.FolderPropertyLocation = propertyLocation; if (target.Folder.IsRelative) { target.Folder = propertyLocation.FileName.ParentFolder + "/" + target.Folder; } int number = 0; if (int.TryParse(match.Groups[1].Value, out number)) { target.Number = number; target.NumberPropertyLocation = propertyLocation; } projectConfig.InputTargets.Add(target); newTarget = target; return(true); } // Image folder match = imageFolderRegex.Match(lcIdentifier); if (match.Success) { var target = new Targets.ImageFolder(propertyLocation); target.Folder = value; target.FolderPropertyLocation = propertyLocation; if (target.Folder.IsRelative) { target.Folder = propertyLocation.FileName.ParentFolder + "/" + target.Folder; } int number = 0; if (int.TryParse(match.Groups[1].Value, out number)) { target.Number = number; target.NumberPropertyLocation = propertyLocation; } projectConfig.InputTargets.Add(target); newTarget = target; return(true); } // HTML output folder else if (htmlOutputFolderRegex.IsMatch(lcIdentifier)) { var target = new Targets.HTMLOutputFolder(propertyLocation); target.Folder = value; target.FolderPropertyLocation = propertyLocation; if (target.Folder.IsRelative) { target.Folder = propertyLocation.FileName.ParentFolder + "/" + target.Folder; } projectConfig.OutputTargets.Add(target); newTarget = target; return(true); } // Ignored source folder else if (ignoredSourceFolderRegex.IsMatch(lcIdentifier)) { var target = new Targets.IgnoredSourceFolder(propertyLocation); target.Folder = value; target.FolderPropertyLocation = propertyLocation; if (target.Folder.IsRelative) { target.Folder = propertyLocation.FileName.ParentFolder + "/" + target.Folder; } projectConfig.FilterTargets.Add(target); newTarget = target; return(true); } // Ignored source folder pattern else if (ignoredSourceFolderPatternRegex.IsMatch(lcIdentifier)) { var target = new Targets.IgnoredSourceFolderPattern(propertyLocation); target.Pattern = value; target.PatternPropertyLocation = propertyLocation; projectConfig.FilterTargets.Add(target); newTarget = target; return(true); } else { newTarget = null; return(false); } }
/* Function: GetGlobalProperty * If the passed identifier is a global property like Tab Width, adds it to <projectConfig> and returns true. If it is a recognized * global property but has a syntax error in the value, it will add an error to <errorList> and still return true. It only returns * false on unrecognized identifiers. */ protected bool GetGlobalProperty(string lcIdentifier, string value, PropertyLocation propertyLocation) { if (tabWidthRegex.IsMatch(lcIdentifier)) { int tabWidth = 0; if (Int32.TryParse(value, out tabWidth) == true) { projectConfig.TabWidth = tabWidth; projectConfig.TabWidthPropertyLocation = propertyLocation; } else { errorList.Add(Locale.Get("NaturalDocs.Engine", "Error.TabWidthMustBeANumber"), propertyLocation.FileName, propertyLocation.LineNumber); } return(true); } else if (documentedOnlyRegex.IsMatch(lcIdentifier)) { if (yesRegex.IsMatch(value)) { projectConfig.DocumentedOnly = true; projectConfig.DocumentedOnlyPropertyLocation = propertyLocation; } else if (noRegex.IsMatch(value)) { projectConfig.DocumentedOnly = false; projectConfig.DocumentedOnlyPropertyLocation = propertyLocation; } else { errorList.Add(Locale.Get("NaturalDocs.Engine", "Project.txt.UnrecognizedValue(keyword, value)", "Documented Only", value), propertyLocation.FileName, propertyLocation.LineNumber); } return(true); } else if (autoGroupRegex.IsMatch(lcIdentifier)) { if (yesRegex.IsMatch(value)) { projectConfig.AutoGroup = true; projectConfig.AutoGroupPropertyLocation = propertyLocation; } else if (noRegex.IsMatch(value)) { projectConfig.AutoGroup = false; projectConfig.AutoGroupPropertyLocation = propertyLocation; } else { errorList.Add(Locale.Get("NaturalDocs.Engine", "Project.txt.UnrecognizedValue(keyword, value)", "Auto Group", value), propertyLocation.FileName, propertyLocation.LineNumber); } return(true); } else { return(false); } }
// Group: Loading Functions // __________________________________________________________________________ /* Function: Load * Attempts to parse <Project.txt> and return it as a <ProjectConfig>. Any syntax errors found will be added to the * <ErrorList>. The <ProjectConfig> object will always exist, even if all its properties are empty. */ public bool Load(Path path, out ProjectConfig projectConfig, ErrorList errorList) { projectConfig = new ProjectConfig(PropertySource.ProjectFile); this.errorList = errorList; this.projectConfig = projectConfig; int originalErrorCount = errorList.Count; using (var configFile = new ConfigFile()) { // We don't condense value whitespace because some things like title, subtitle, and copyright may want multiple spaces. bool openResult = configFile.Open(path, PropertySource.ProjectFile, ConfigFile.FileFormatFlags.CondenseIdentifierWhitespace | ConfigFile.FileFormatFlags.MakeIdentifiersLowercase, errorList); if (openResult == false) { return(false); } string lcIdentifier, value; Target currentTarget = null; ProjectInfo currentProjectInfo = projectConfig.ProjectInfo; while (configFile.Get(out lcIdentifier, out value)) { var propertyLocation = new PropertyLocation(PropertySource.ProjectFile, configFile.FileName, configFile.LineNumber); Target target = null; if (GetGlobalProperty(lcIdentifier, value, propertyLocation)) { currentTarget = null; currentProjectInfo = projectConfig.ProjectInfo; } else if (GetTargetHeader(lcIdentifier, value, propertyLocation, out target)) { currentTarget = target; if (target is Targets.Output) { currentProjectInfo = (target as Targets.Output).ProjectInfo; } else { currentProjectInfo = projectConfig.ProjectInfo; } } else if (GetProjectInfoProperty(lcIdentifier, value, propertyLocation, currentProjectInfo)) { } else if (currentTarget != null && GetTargetProperty(lcIdentifier, value, propertyLocation, currentTarget)) { } else { errorList.Add( message: Locale.Get("NaturalDocs.Engine", "ConfigFile.NotAValidIdentifier(identifier)", lcIdentifier), propertyLocation: propertyLocation ); } } configFile.Close(); } return(errorList.Count == originalErrorCount); }
// Group: Functions // __________________________________________________________________________ public Target(PropertyLocation propertyLocation) { this.propertyLocation = propertyLocation; }