diff --git a/AppSettings.cs b/AppSettings.cs index edd49a5..a05613e 100644 --- a/AppSettings.cs +++ b/AppSettings.cs @@ -1,37 +1,37 @@ -using System; +using System; using System.Collections.Generic; using System.Configuration; using System.Text; namespace DotnetFoundationWeb { - public static class AppSettings - { - public static string ContactEmail { get; set; } = ConfigurationManager.AppSettings["ContactEmail"]; + public static class AppSettings + { + public static string ContactEmail { get; set; } = ConfigurationManager.AppSettings["ContactEmail"]; - public static string Title { get; set; } = ConfigurationManager.AppSettings["SiteTitle"]; - - public static string Description { get; set; } = ConfigurationManager.AppSettings["SiteDescription"]; + public static string Title { get; set; } = ConfigurationManager.AppSettings["SiteTitle"]; - public static string BaseRef { get; set; } = ConfigurationManager.AppSettings["BaseRef"]; + public static string Description { get; set; } = ConfigurationManager.AppSettings["SiteDescription"]; - public static string ServerUrl { get; set; } = ConfigurationManager.AppSettings["ServerUrl"]; + public static string BaseRef { get; set; } = ConfigurationManager.AppSettings["BaseRef"]; - public static bool IsCampaignOpen { get; set; } - = String.Equals(ConfigurationManager.AppSettings["IsCampaignOpen"], "true", StringComparison.OrdinalIgnoreCase); + public static string ServerUrl { get; set; } = ConfigurationManager.AppSettings["ServerUrl"]; - public static string AzureSearchQueryKey { get; set; } = ConfigurationManager.AppSettings["AzureSearchQueryKey"]; + public static bool IsCampaignOpen { get; set; } + = String.Equals(ConfigurationManager.AppSettings["IsCampaignOpen"], "true", StringComparison.OrdinalIgnoreCase); - public static string ContributionsCounter { get; set; } = ConfigurationManager.AppSettings["ContributionsCounter"]; + public static string AzureSearchQueryKey { get; set; } = ConfigurationManager.AppSettings["AzureSearchQueryKey"]; - public static string CompaniesCounter { get; set; } = ConfigurationManager.AppSettings["CompaniesCounter"]; + public static string ContributionsCounter { get; set; } = ConfigurationManager.AppSettings["ContributionsCounter"]; - public static string ActiveProjectsCounter { get; set; } = ConfigurationManager.AppSettings["ActiveProjectsCounter"]; + public static string CompaniesCounter { get; set; } = ConfigurationManager.AppSettings["CompaniesCounter"]; - public static string ResourcesCounter { get; set; } = ConfigurationManager.AppSettings["ResourcesCounter"]; + public static string ActiveProjectsCounter { get; set; } = ConfigurationManager.AppSettings["ActiveProjectsCounter"]; - public static string GoogleAnalytics { get; set; } = ConfigurationManager.AppSettings["GoogleAnalytics"]; + public static string ResourcesCounter { get; set; } = ConfigurationManager.AppSettings["ResourcesCounter"]; - public static string Lang { get; set; } = ConfigurationManager.AppSettings["Lang"]; - } + public static string GoogleAnalytics { get; set; } = ConfigurationManager.AppSettings["GoogleAnalytics"]; + + public static string Lang { get; set; } = ConfigurationManager.AppSettings["Lang"]; + } } diff --git a/Program.cs b/Program.cs index 1daa6e3..c9ca557 100644 --- a/Program.cs +++ b/Program.cs @@ -12,43 +12,44 @@ using Statiq.Web; namespace DotnetFoundationWeb { - public static class Program - { - public static async Task Main(string[] args) + public static class Program { - Func formatter = null; - if (!string.IsNullOrWhiteSpace(AppSettings.ServerUrl)) - { - var formatterString = AppSettings.ServerUrl + "/{0}"; - formatter = f => string.Format(formatterString, f); - } + public static async Task Main(string[] args) + { + Func formatter = null; + if (!string.IsNullOrWhiteSpace(AppSettings.ServerUrl)) + { + var formatterString = AppSettings.ServerUrl + "/{0}"; + formatter = f => string.Format(formatterString, f); + } - return await Bootstrapper.Factory - .CreateWeb(args) - .AddSetting(Keys.Host, "dotnetfoundation.org") - .AddSetting(Keys.LinksUseHttps, true) - .AddSetting(WebKeys.MirrorResources, true) - .AddSetting(WebKeys.ExcludedPaths, "api/node_modules") - .BuildPipeline( - "GenerateProjectsJson", - builder => builder - .WithDependencies(nameof(Statiq.Web.Pipelines.Content)) - .WithProcessModules( - new ReplaceDocuments(nameof(Statiq.Web.Pipelines.Content)), - new FlattenTree(), - new FilterSources("projects/data/*.md"), - new ExecuteConfig(Config.FromContext(ctx => - JsonSerializer.Serialize(ctx.Inputs.Select(x => new { - Title = x.GetString("Title"), - Keywords = x.GetString("Keywords"), - Link = x.GetLink(), - Content = x.GetContentStringAsync().GetAwaiter().GetResult() - }) - ))) - ) - .WithOutputWriteFiles("projects/projects.json") - ) - .RunAsync(); + return await Bootstrapper.Factory + .CreateWeb(args) + .AddSetting(Keys.Host, "dotnetfoundation.org") + .AddSetting(Keys.LinksUseHttps, true) + .AddSetting(WebKeys.MirrorResources, true) + .AddSetting(WebKeys.ExcludedPaths, "api/node_modules") + .BuildPipeline( + "GenerateProjectsJson", + builder => builder + .WithDependencies(nameof(Statiq.Web.Pipelines.Content)) + .WithProcessModules( + new ReplaceDocuments(nameof(Statiq.Web.Pipelines.Content)), + new FlattenTree(), + new FilterSources("projects/data/*.md"), + new ExecuteConfig(Config.FromContext(ctx => + JsonSerializer.Serialize(ctx.Inputs.Select(x => new + { + Title = x.GetString("Title"), + Keywords = x.GetString("Keywords"), + Link = x.GetLink(), + Content = x.GetContentStringAsync().GetAwaiter().GetResult() + }) + ))) + ) + .WithOutputWriteFiles("projects/projects.json") + ) + .RunAsync(); + } } - } } diff --git a/Utils/StringUtils.cs b/Utils/StringUtils.cs index 2558798..2bc8328 100644 --- a/Utils/StringUtils.cs +++ b/Utils/StringUtils.cs @@ -6,80 +6,80 @@ using HtmlAgilityPack; namespace DotnetFoundationWeb.Utils { - public static class StringUtils - { - public static IEnumerable Descendants(HtmlNode root) + public static class StringUtils { - return new[] { root }.Concat(root.ChildNodes.SelectMany(child => child.Descendants())); - } - - public static IEnumerable TextDescendants(HtmlNode root) - { - return root.Descendants().Where(n => n.NodeType == HtmlNodeType.Text && !String.IsNullOrWhiteSpace(n.InnerText)); - } - - public static string TruncateHtml(string html, int maxCharacters) - { - html = html.Replace("

", "").Replace("

", ""); - if (string.IsNullOrEmpty(html) || html.Length <= maxCharacters) return html; - - var doc = new HtmlDocument(); - doc.LoadHtml(html); - if (doc.DocumentNode.InnerText.Length <= maxCharacters) return html; - - var textNodes = new LinkedList(TextDescendants(doc.DocumentNode)); - var preceedingText = 0; - var lastNode = textNodes.First; - while (preceedingText <= maxCharacters && lastNode != null) - { - var nodeTextLength = lastNode.Value.InnerText.Length; - if (preceedingText + nodeTextLength > maxCharacters) + public static IEnumerable Descendants(HtmlNode root) { - var truncatedText = TruncateWords(lastNode.Value.InnerText, maxCharacters - preceedingText); - - if (String.IsNullOrWhiteSpace(truncatedText) && lastNode.Previous != null) - { - // Put the ellipsis in the previous node and remove the empty node. - lastNode.Previous.Value.InnerHtml = lastNode.Previous.Value.InnerText.Trim() + "…"; - lastNode.Value.InnerHtml = String.Empty; - lastNode = lastNode.Previous; - } - else - { - lastNode.Value.InnerHtml = truncatedText + "…"; - } - - break; + return new[] { root }.Concat(root.ChildNodes.SelectMany(child => child.Descendants())); } - if (preceedingText + nodeTextLength == maxCharacters) break; + public static IEnumerable TextDescendants(HtmlNode root) + { + return root.Descendants().Where(n => n.NodeType == HtmlNodeType.Text && !String.IsNullOrWhiteSpace(n.InnerText)); + } - preceedingText += nodeTextLength; - lastNode = lastNode.Next; - } + public static string TruncateHtml(string html, int maxCharacters) + { + html = html.Replace("

", "").Replace("

", ""); + if (string.IsNullOrEmpty(html) || html.Length <= maxCharacters) return html; - // Remove all the nodes after lastNode - if (lastNode != null) RemoveFollowingNodes(lastNode.Value); + var doc = new HtmlDocument(); + doc.LoadHtml(html); + if (doc.DocumentNode.InnerText.Length <= maxCharacters) return html; - return doc.DocumentNode.InnerHtml; + var textNodes = new LinkedList(TextDescendants(doc.DocumentNode)); + var preceedingText = 0; + var lastNode = textNodes.First; + while (preceedingText <= maxCharacters && lastNode != null) + { + var nodeTextLength = lastNode.Value.InnerText.Length; + if (preceedingText + nodeTextLength > maxCharacters) + { + var truncatedText = TruncateWords(lastNode.Value.InnerText, maxCharacters - preceedingText); + + if (String.IsNullOrWhiteSpace(truncatedText) && lastNode.Previous != null) + { + // Put the ellipsis in the previous node and remove the empty node. + lastNode.Previous.Value.InnerHtml = lastNode.Previous.Value.InnerText.Trim() + "…"; + lastNode.Value.InnerHtml = String.Empty; + lastNode = lastNode.Previous; + } + else + { + lastNode.Value.InnerHtml = truncatedText + "…"; + } + + break; + } + + if (preceedingText + nodeTextLength == maxCharacters) break; + + preceedingText += nodeTextLength; + lastNode = lastNode.Next; + } + + // Remove all the nodes after lastNode + if (lastNode != null) RemoveFollowingNodes(lastNode.Value); + + return doc.DocumentNode.InnerHtml; + } + + private static void RemoveFollowingNodes(HtmlNode lastNode) + { + while (lastNode.NextSibling != null) lastNode.NextSibling.Remove(); + if (lastNode.ParentNode != null) RemoveFollowingNodes(lastNode.ParentNode); + } + + private static string TruncateWords(string value, int length) + { + if (String.IsNullOrWhiteSpace(value) || length <= 0) return String.Empty; + if (length > value.Length) return value; + + var endIndex = length; + while (Char.IsLetterOrDigit(value[endIndex - 1]) && Char.IsLetterOrDigit(value[endIndex]) && endIndex > 1) endIndex--; + + if (endIndex == 1) return String.Empty; + return value.Substring(0, endIndex).Trim(); + } } - - private static void RemoveFollowingNodes(HtmlNode lastNode) - { - while (lastNode.NextSibling != null) lastNode.NextSibling.Remove(); - if (lastNode.ParentNode != null) RemoveFollowingNodes(lastNode.ParentNode); - } - - private static string TruncateWords(string value, int length) - { - if (String.IsNullOrWhiteSpace(value) || length <= 0) return String.Empty; - if (length > value.Length) return value; - - var endIndex = length; - while (Char.IsLetterOrDigit(value[endIndex - 1]) && Char.IsLetterOrDigit(value[endIndex]) && endIndex > 1) endIndex--; - - if (endIndex == 1) return String.Empty; - return value.Substring(0, endIndex).Trim(); - } - } }