USMC Veteran • Digital Marketer • Metal Engraver • Branding • Leader
Resourceful and mission-driven Marine Corps veteran with a diverse skill set through trial and error in digital marketing, manual machining, leadership, and full-stack web development. Known for discipline, adaptability, willingness to learn, and creative problem-solving. I combine traditional craftsmanship with modern tech to build solutions that work in the real world. Trutfully I am a reviewer of hotels and places to stay who enjoys job satisfaction and great people. I care about your brand, if you do also.
Let AI handle lead capture, personalized content creation, email/SMS follow-ups, social scheduling & analytics — all custom-built for you.
⚡ Get Your Custom AI Agent Now#AIAutomation #DigitalMarketing #MarketingAutomation #SaaS
I help brands grow with clarity, creativity, and conversion-focused strategy. From ideation to execution, I build marketing systems that turn attention into action — combining strategy, design, content, SEO, ads, automation, and analytics into one streamlined approach.
I collaborate with founders, agencies, and growth-minded teams that want results—not just reports. Whether you're launching, scaling, or rebranding, I bring the full-stack firepower to move your business forward.
📬 Looking for a marketing partner, not just a freelancer?
Let’s talk about how I can bring results to your next project.
As a dedicated 1099 independent contractor, I bring flexibility, professionalism, and a results-driven approach to every project. I actively collaborate with clients across various industries, delivering tailored solutions with a focus on quality and efficiency.
Click the header to expand or collapse this project description.
Click the header to expand or collapse this project description.
This C# program transforms WordPress XML exports into static HTML pages. It processes post content, cleans up unnecessary tags, detects topics for styling, and generates individual HTML files with gradient backgrounds. The tool also packages all pages into a ZIP archive for easy distribution.
usingSystem;<using System;> <using System.IO;> <using System.IO.Compression;> <using System.Linq;> <using System.Text;> <using System.Text.RegularExpressions;> <using System.Xml.Linq;> <using System.Collections.Generic;> <using System.Security.Cryptography;> class Program { // ----------------------------- // Gradient mappings // ----------------------------- static Dictionary<string, string> TopicGradients = new() { { "tech", "linear-gradient(135deg,#0f2027 0%,#203a43 50%,#2c5364 100%)" }, { "marketing", "linear-gradient(135deg,#ff9a9e 0%,#fecfef 50%,#f6d365 100%)" }, { "web", "linear-gradient(135deg,#84fab0 0%,#8fd3f4 100%)" }, { "news", "linear-gradient(135deg,#f6d365 0%,#fda085 100%)" }, { "reviews", "linear-gradient(135deg,#fbc2eb 0%,#a6c1ee 100%)" }, { "finance", "linear-gradient(135deg,#d4fc79 0%,#96e6a1 100%)> }, { "default", "linear-gradient(135deg,#e0c3fc 0%,#8ec5fc 100%)" } }; static List<string> FallbackGradients = new() { "linear-gradient(135deg,#ff9a9e,#fad0c4)", "linear-gradient(135deg,#a18cd1,#fbc2eb)", "linear-gradient(135deg,#f6d365,#fda085)", "linear-gradient(135deg,#84fab0,#8fd3f4)", "linear-gradient(135deg,#fccb90,#d57eeb)", "linear-gradient(135deg,#e0c3fc,#8ec5fc)" }; static HashSet<string> StopWords = new() { "the","a","an","and","or","of","in","on","for","to","with","is","by","from","at","be","this","that" }; // Back + TTS block static string BackTtsCode = @" <!-- 🔙 Back Button --> <button onclick="window.location.href='https://thy.scot/blog/k/k'" class="back-button">← Back</button> <!-- 🗣️ Text-to-Speech Button --> <button id="tts-toggle" class="tts-button">▶ Play</button> <!-- 💬 TTS JavaScript --> <script> const ttsBtn = document.getElementById('tts-toggle'); const synth = window.speechSynthesis; let utterance; let isSpeaking = false; let isPaused = false; function collectTextContent() { let fullText = ''; const semanticAreas = document.querySelectorAll('section, article, main'); if (semanticAreas.length) { semanticAreas.forEach(area => { const headings = [...area.querySelectorAll('h1,h2,h3,h4,h5,h6')]; const paras = [...area.querySelectorAll('p, li')]; headings.forEach(h => fullText += h.innerText.trim() + '. '); paras.forEach(p => fullText += p.innerText.trim() + ' '); }); } else { const exclusions = ['IMG', 'FIGURE', 'PICTURE', 'NOSCRIPT']; document.body.querySelectorAll('h1,h2,h3,h4,h5,h6,p,li').forEach(el => { if (!exclusions.includes(el.tagName) && el.offsetParent !== null) { fullText += el.innerText.trim() + ' '; } }); } return fullText.replace(/\\s+/g, ' ').trim(); } function speakText(text) { if (synth.speaking) synth.cancel(); utterance = new SpeechSynthesisUtterance(text); utterance.rate = 0.71; synth.speak(utterance); isSpeaking = true; ttsBtn.textContent = '⏸ Pause'; utterance.onend = () => { isSpeaking = false; ttsBtn.textContent = '▶ Play'; }; } ttsBtn.addEventListener('click', () => { if (isSpeaking && !synth.paused) { synth.pause(); isPaused = true; isSpeaking = false; ttsBtn.textContent = '▶ Resume'; } else if (isPaused) { synth.resume(); isPaused = false; isSpeaking = true; ttsBtn.textContent = '⏸ Pause'; } else { const text = collectTextContent(); speakText(text); } }); </script> <style> :root { --content-bg: rgba(255,255,255,0.88); --accent: #f5cb5c; } body { font-family: 'Georgia', serif; } .page { max-width:900px; margin:auto; background:var(--content-bg); padding:2rem; border-radius:12px; } .tts-button, .back-button { display: block; width: 89%; margin: 1.5rem auto; background: var(--accent); color: #111; font-weight: bold; padding: 0.8rem 1.2rem; font-size: 1rem; border: none; border-radius: 8px; cursor: pointer; transition: background 0.3s, transform 0.2s ease; text-align: center; } .tts-button:hover, .back-button:hover { transform: scale(1.03); } </style> "; static void Main() { Console.OutputEncoding = Encoding.UTF8; Console.WriteLine("Enter path to WordPress XML export:"); string xmlPath = Console.ReadLine() ?? ""; if (!File.Exists(xmlPath)) { Console.WriteLine("File not found."); return; } string outputDir = Path.Combine(Path.GetDirectoryName(xmlPath)!, "exported_html"); Directory.CreateDirectory(outputDir); XDocument doc = XDocument.Load(xmlPath); XNamespace contentNS = "http://purl.org/rss/1.0/modules/content/"; XNamespace wpNS = "http://wordpress.org/export/1.2/"; var posts = doc.Descendants("item") .Where(i => (string?)i.Element(wpNS + "status") == "publish" && (string?)i.Element(wpNS + "post_type") == "post"); int count = 0; Dictionary<string, int> filenameCounts = new(); foreach (var post in posts) { string title = (string?)post.Element("title") ?? "Untitled"; string rawContent = (string?)post.Element(contentNS + "encoded") ?? ""; string cleaned = CleanContent(rawContent); // Topic detection string topic = post.Elements("category") .Select(c => (string?)c ?? "") .FirstOrDefault(c => !string.IsNullOrWhiteSpace(c)) ?? GetFirstKeyword(title); string gradient = ChooseGradient(topic); // Filename slug string baseSlug = MakeSlug(title); if (!filenameCounts.ContainsKey(baseSlug)) filenameCounts[baseSlug] = 0; filenameCounts[baseSlug]++; string slug = filenameCounts[baseSlug] > 1 ? $"{baseSlug}-{filenameCounts[baseSlug]}" : baseSlug; string html = $@"<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>{System.Net.WebUtility.HtmlEncode(title)}</title> <style> html,body{{background:{gradient};margin:0;padding:0;}} </style> </head> <body> <div class="page"> <h1>{System.Net.WebUtility.HtmlEncode(title)}</h1> {cleaned} </div> {BackTtsCode} </body> </html>"; string filePath = Path.Combine(outputDir, slug + ".html"); File.WriteAllText(filePath, html, Encoding.UTF8); count++; } Console.WriteLine($"Exported {count} posts to {outputDir}"); string zipPath = Path.Combine(Path.GetDirectoryName(xmlPath)!, "html_export.zip"); if (File.Exists(zipPath)) File.Delete(zipPath); ZipFile.CreateFromDirectory(outputDir, zipPath); Console.WriteLine($"ZIP created at {zipPath}"); } static string CleanContent(string html) { html = Regex.Replace(html, @"<script[\\s\\S]*?</script>", "", RegexOptions.IgnoreCase); html = Regex.Replace(html, @"<style[\\s\\S]*?</style>", "", RegexOptions.IgnoreCase); html = Regex.Replace(html, @"<figure[\\s\\S]*?</figure>", "", RegexOptions.IgnoreCase); html = Regex.Replace(html, @"<iframe[\\s\\S]*?</iframe>", "", RegexOptions.IgnoreCase); html = Regex.Replace(html, @"<img[^>]*>", "", RegexOptions.IgnoreCase); html = Regex.Replace(html, @"\\[[^\\]]+\\]", "", RegexOptions.IgnoreCase); html = Regex.Replace(html, @"<!--[\\s\\S]*?-->", "", RegexOptions.IgnoreCase); return html.Trim(); } static string GetFirstKeyword(string text) { var words = Regex.Matches(text.ToLower(), @"[a-z0-9]+") .Cast() .Select(m => m.Value) .Where(w => !StopWords.Contains(w)) .ToList(); return words.FirstOrDefault() ?? "general"; } static string ChooseGradient(string topic) { topic = topic?.ToLower().Trim() ?? "default"; foreach (var key in TopicGradients.Keys.Where(k => k != "default")) { if (topic.Contains(key)) return TopicGradients[key]; } // fallback stable hash int hash = BitConverter.ToInt32(SHA256.HashData(Encoding.UTF8.GetBytes(topic)), 0); return FallbackGradients[Math.Abs(hash) % FallbackGradients.Count]; } static string MakeSlug(string title, int maxWords = 4) { var words = Regex.Matches(title.ToLower(), @"[a-z0-9]+") .Cast () .Select(m => m.Value) .Where(w => !StopWords.Contains(w)) .Take(maxWords) .ToList(); if (!words.Any()) words = Regex.Matches(title.ToLower(), @"[a-z0-9]+").Select(m => m.Value).ToList(); return string.Join("-", words); } }
Click the header to expand or collapse this project description.
Click the header to expand or collapse this project description.
Click the header to expand or collapse this project description.