using System.Globalization; using System.Text; using System.Text.RegularExpressions; namespace File_Folder_Helper.Helpers; internal static partial class HelperCreateNoteFiles { [GeneratedRegex("[^a-z0-9-]")] private static partial Regex AlphaNumOnly(); private static void CleanExistingFiles(string directory, long ticks) { string check; string[] lines; string checkFile; string? fileDirectory; string checkDirectory; bool circularReference; string fileNameWithoutExtension; char altDrive = directory[0] is 'c' or 'C' ? 'D' : 'C'; string[] files = Directory.GetFiles(directory, "*.md", SearchOption.AllDirectories); string match = ",*** *** *** *** *** *** *** *** ***,*** *** *** *** *** *** *** *** ***,*** *** *** *** *** *** *** *** ***,,TODO:,*** *** *** *** *** *** *** *** ***,*** *** *** *** *** *** *** *** ***,,Notes:,*** *** *** *** *** *** *** *** ***,*** *** *** *** *** *** *** *** ***"; foreach (string file in files) { lines = File.ReadAllLines(file); if (lines.Length < 1) continue; circularReference = false; fileNameWithoutExtension = Path.GetFileNameWithoutExtension(file); for (int i = 0; i < lines.Length; i++) { if (!lines[i].Contains($"[[{fileNameWithoutExtension}]]")) continue; lines[i] = lines[i].Replace("[[", "__").Replace("]]", "__"); if (!circularReference) circularReference = true; } if (circularReference) File.WriteAllLines(file, lines); lines[0] = string.Empty; check = string.Join(',', lines); if (check != match) continue; fileDirectory = Path.GetDirectoryName(file); if (string.IsNullOrEmpty(fileDirectory)) continue; checkDirectory = $"{altDrive}:/{ticks}/{fileDirectory[3..]}"; if (!Directory.Exists(checkDirectory)) _ = Directory.CreateDirectory(checkDirectory); checkFile = $"{altDrive}:/{ticks}/{file[3..]}"; if (File.Exists(checkFile)) continue; File.Move(file, checkFile); } _ = HelperDeleteEmptyDirectories.DeleteEmptyDirectories(directory); } private static void CreateDailyNotes(string argsZero, long ticks) { string file; string directory; string weekOfYear; DateTime dateTime; string lastDirectory = string.Empty; DateTime startDateTime = DateTime.Now.AddDays(1); Calendar calendar = new CultureInfo("en-US").Calendar; double totalDays = new TimeSpan(DateTime.Now.AddDays(1000).Ticks - startDateTime.Ticks).TotalDays; int days = (int)Math.Ceiling(totalDays); for (int i = 0; i < days; i++) { dateTime = startDateTime.AddDays(i); weekOfYear = calendar.GetWeekOfYear(dateTime, CalendarWeekRule.FirstDay, DayOfWeek.Sunday).ToString("00"); directory = Path.Combine(argsZero, ticks.ToString(), dateTime.ToString("yyyy"), $"Week_{weekOfYear}"); if (!Directory.Exists(directory)) _ = Directory.CreateDirectory(directory); file = string.Concat(Path.Combine(directory, $"{dateTime:yyyy-MM-dd}.md")); if (File.Exists(file)) continue; File.WriteAllLines(file, new string[] { "---", "type: daily-note", $"created: {dateTime:yyyy-MM-dd}", "---", string.Empty, $"# {dateTime:yyyy-MM-dd dddd}", string.Empty, "```bash", string.Empty, "```", }); if (directory != lastDirectory) { Directory.SetCreationTime(directory, dateTime); Directory.SetLastWriteTime(directory, dateTime); } lastDirectory = directory; } } private static string? GetTags(string tagsText) { string? result; StringBuilder stringBuilder = new(); if (string.IsNullOrEmpty(tagsText)) result = null; else { string[] segments; _ = stringBuilder.AppendLine("tags:"); string[] tags = tagsText.Split(';', StringSplitOptions.RemoveEmptyEntries); foreach (string tag in tags) { segments = tag.Split(':'); _ = stringBuilder.AppendLine($"- '{segments.First()}'"); } result = stringBuilder.ToString().Trim(); } return result; } private static string? GetLinks(string type, string linksText) { string? result; StringBuilder stringBuilder = new(); if (!string.IsNullOrEmpty(linksText)) result = null; else { string linkLower; string[] segments; string[] links = linksText.Split(';', StringSplitOptions.RemoveEmptyEntries); foreach (string link in links) { segments = link.Split(':'); linkLower = AlphaNumOnly().Replace(segments.First().Trim().ToLower(), "-").Replace("--", "-"); if (segments.Length == 1) _ = stringBuilder.AppendLine($"- [[{type}/{linkLower}]]"); else if (segments.Length == 2) _ = stringBuilder.AppendLine($"- [{type}/{linkLower}]({segments.Last()})"); else continue; } result = stringBuilder.ToString().Trim(); } return result; } private static string? GetAttributes(string[] columns, string[]? headerColumns, int expectedCount) { string? result; if (headerColumns is null || columns.Length <= expectedCount) result = null; else { StringBuilder stringBuilder = new(); for (int j = expectedCount; j < columns.Length; j++) { if (headerColumns.Length <= j) continue; _ = stringBuilder.AppendLine($"{headerColumns[j].Trim()}: '{columns[j].Trim()}'"); } result = stringBuilder.ToString().Trim(); } return result; } private static void CreateImportFiles(long ticks, List importFiles) { bool csv; bool tsv; string file; string text; string type; string title; string? tags; string? links; string[] lines; int bodyKey = 5; int tagsKey = 3; int typeKey = 0; string fileName; string tagsText; int linksKey = 4; int titleKey = 1; string linksText; string[] columns; string? directory; string? attributes; int descriptionKey = 2; string[]? headerColumns; string destinationDirectory; List allLines = new(); DateTime dateTime = new(ticks); string csvHeader = "type,title,description,tags,links,body"; string tsvHeader = "type\ttitle\tdescription\ttags\tlinks\tbody"; int expectedCount = csvHeader.Length - csvHeader.Replace(",", string.Empty).Length + 1; foreach (string importFile in importFiles) { csv = false; tsv = false; headerColumns = null; directory = Path.GetDirectoryName(importFile); if (directory is null) continue; lines = File.ReadAllLines(importFile); for (int i = 0; i < lines.Length; i++) { if (i == 0) { if (lines[i].StartsWith(csvHeader)) { (csv, tsv) = (true, false); headerColumns = lines[i].Split(','); } else if (lines[i].StartsWith(tsvHeader)) { (csv, tsv) = (false, true); headerColumns = lines[i].Split('\t'); } else break; continue; } if (csv) columns = lines[i].Split(','); else if (tsv) columns = lines[i].Split('\t'); else continue; if (columns.Length < expectedCount) continue; title = columns[titleKey].Trim(); tagsText = columns[tagsKey].Trim(); linksText = columns[linksKey].Trim(); fileName = AlphaNumOnly().Replace(title.ToLower(), "-").Replace("--", "-"); type = AlphaNumOnly().Replace(columns[typeKey].Trim().ToLower(), "-").Replace("--", "-"); tags = GetTags(tagsText); links = GetLinks(type, linksText); attributes = GetAttributes(columns, headerColumns, expectedCount); destinationDirectory = Path.Combine(directory, type); if (!Directory.Exists(destinationDirectory)) _ = Directory.CreateDirectory(destinationDirectory); file = Path.Combine(destinationDirectory, $"{fileName}.md"); allLines.Clear(); allLines.Add("---"); allLines.Add($"type: \"{type}\""); allLines.Add($"title: \"{title}\""); allLines.Add($"description: \"{columns[descriptionKey].Trim()}\""); allLines.Add($"created: \"{dateTime:yyyy-MM-ddTHH:mm:ss.fffZ}\""); allLines.Add($"updated: \"{dateTime:yyyy-MM-ddTHH:mm:ss.fffZ}\""); if (!string.IsNullOrEmpty(tags)) allLines.Add(tags); if (!string.IsNullOrEmpty(attributes)) allLines.Add(attributes); allLines.Add("---"); allLines.Add(string.Empty); allLines.Add($"# {title}"); allLines.Add(string.Empty); if (!string.IsNullOrEmpty(links)) allLines.Add(links); allLines.Add(string.Empty); allLines.Add($"## Comment {dateTime:yyyy-MM-dd}"); allLines.Add(string.Empty); allLines.Add(columns[bodyKey].Trim()); allLines.Add(string.Empty); text = string.Join(Environment.NewLine, allLines); File.WriteAllText(file, text); } } } internal static void CreateNoteFiles(string argsZero) { long ticks = DateTime.Now.Ticks; List importFiles = new(); CleanExistingFiles(argsZero, ticks); importFiles.AddRange(Directory.GetFiles(argsZero, "*.csv", SearchOption.TopDirectoryOnly)); importFiles.AddRange(Directory.GetFiles(argsZero, "*.tsv", SearchOption.TopDirectoryOnly)); if (!importFiles.Any()) CreateDailyNotes(argsZero, ticks); else CreateImportFiles(ticks, importFiles); } }