Back to snippets
seo_content_optimizer_with_brand_voice_analyzer_and_templates.py
pythonGenerated for task: content-creator: Create SEO-optimized marketing content with consistent brand voice. Includes brand
Agent Votes
0
0
seo_content_optimizer_with_brand_voice_analyzer_and_templates.py
1# SKILL.md
2
3---
4name: content-creator
5description: Create SEO-optimized marketing content with consistent brand voice. Includes brand voice analyzer, SEO optimizer, content frameworks, and social media templates. Use when writing blog posts, creating social media content, analyzing brand voice, optimizing SEO, planning content calendars, or when user mentions content creation, brand voice, SEO optimization, social media marketing, or content strategy.
6license: MIT
7metadata:
8 version: 1.0.0
9 author: Alireza Rezvani
10 category: marketing
11 domain: content-marketing
12 updated: 2025-10-20
13 python-tools: brand_voice_analyzer.py, seo_optimizer.py
14 tech-stack: SEO, social-media-platforms
15---
16
17# Content Creator
18
19Professional-grade brand voice analysis, SEO optimization, and platform-specific content frameworks.
20
21## Keywords
22content creation, blog posts, SEO, brand voice, social media, content calendar, marketing content, content strategy, content marketing, brand consistency, content optimization, social media marketing, content planning, blog writing, content frameworks, brand guidelines, social media strategy
23
24## Quick Start
25
26### For Brand Voice Development
271. Run `scripts/brand_voice_analyzer.py` on existing content to establish baseline
282. Review `references/brand_guidelines.md` to select voice attributes
293. Apply chosen voice consistently across all content
30
31### For Blog Content Creation
321. Choose template from `references/content_frameworks.md`
332. Research keywords for topic
343. Write content following template structure
354. Run `scripts/seo_optimizer.py [file] [primary-keyword]` to optimize
365. Apply recommendations before publishing
37
38### For Social Media Content
391. Review platform best practices in `references/social_media_optimization.md`
402. Use appropriate template from `references/content_frameworks.md`
413. Optimize based on platform-specific guidelines
424. Schedule using `assets/content_calendar_template.md`
43
44## Core Workflows
45
46### Establishing Brand Voice (First Time Setup)
47
48When creating content for a new brand or client:
49
501. **Analyze Existing Content** (if available)
51 ```bash
52 python scripts/brand_voice_analyzer.py existing_content.txt
53 ```
54
552. **Define Voice Attributes**
56 - Review brand personality archetypes in `references/brand_guidelines.md`
57 - Select primary and secondary archetypes
58 - Choose 3-5 tone attributes
59 - Document in brand guidelines
60
613. **Create Voice Sample**
62 - Write 3 sample pieces in chosen voice
63 - Test consistency using analyzer
64 - Refine based on results
65
66### Creating SEO-Optimized Blog Posts
67
681. **Keyword Research**
69 - Identify primary keyword (search volume 500-5000/month)
70 - Find 3-5 secondary keywords
71 - List 10-15 LSI keywords
72
732. **Content Structure**
74 - Use blog template from `references/content_frameworks.md`
75 - Include keyword in title, first paragraph, and 2-3 H2s
76 - Aim for 1,500-2,500 words for comprehensive coverage
77
783. **Optimization Check**
79 ```bash
80 python scripts/seo_optimizer.py blog_post.md "primary keyword" "secondary,keywords,list"
81 ```
82
834. **Apply SEO Recommendations**
84 - Adjust keyword density to 1-3%
85 - Ensure proper heading structure
86 - Add internal and external links
87 - Optimize meta description
88
89### Social Media Content Creation
90
911. **Platform Selection**
92 - Identify primary platforms based on audience
93 - Review platform-specific guidelines in `references/social_media_optimization.md`
94
952. **Content Adaptation**
96 - Start with blog post or core message
97 - Use repurposing matrix from `references/content_frameworks.md`
98 - Adapt for each platform following templates
99
1003. **Optimization Checklist**
101 - Platform-appropriate length
102 - Optimal posting time
103 - Correct image dimensions
104 - Platform-specific hashtags
105 - Engagement elements (polls, questions)
106
107### Content Calendar Planning
108
1091. **Monthly Planning**
110 - Copy `assets/content_calendar_template.md`
111 - Set monthly goals and KPIs
112 - Identify key campaigns/themes
113
1142. **Weekly Distribution**
115 - Follow 40/25/25/10 content pillar ratio
116 - Balance platforms throughout week
117 - Align with optimal posting times
118
1193. **Batch Creation**
120 - Create all weekly content in one session
121 - Maintain consistent voice across pieces
122 - Prepare all visual assets together
123
124## Key Scripts
125
126### brand_voice_analyzer.py
127Analyzes text content for voice characteristics, readability, and consistency.
128
129**Usage**: `python scripts/brand_voice_analyzer.py <file> [json|text]`
130
131**Returns**:
132- Voice profile (formality, tone, perspective)
133- Readability score
134- Sentence structure analysis
135- Improvement recommendations
136
137### seo_optimizer.py
138Analyzes content for SEO optimization and provides actionable recommendations.
139
140**Usage**: `python scripts/seo_optimizer.py <file> [primary_keyword] [secondary_keywords]`
141
142**Returns**:
143- SEO score (0-100)
144- Keyword density analysis
145- Structure assessment
146- Meta tag suggestions
147- Specific optimization recommendations
148
149## Reference Guides
150
151### When to Use Each Reference
152
153**references/brand_guidelines.md**
154- Setting up new brand voice
155- Ensuring consistency across content
156- Training new team members
157- Resolving voice/tone questions
158
159**references/content_frameworks.md**
160- Starting any new content piece
161- Structuring different content types
162- Creating content templates
163- Planning content repurposing
164
165**references/social_media_optimization.md**
166- Platform-specific optimization
167- Hashtag strategy development
168- Understanding algorithm factors
169- Setting up analytics tracking
170
171## Best Practices
172
173### Content Creation Process
1741. Always start with audience need/pain point
1752. Research before writing
1763. Create outline using templates
1774. Write first draft without editing
1785. Optimize for SEO
1796. Edit for brand voice
1807. Proofread and fact-check
1818. Optimize for platform
1829. Schedule strategically
183
184### Quality Indicators
185- SEO score above 75/100
186- Readability appropriate for audience
187- Consistent brand voice throughout
188- Clear value proposition
189- Actionable takeaways
190- Proper visual formatting
191- Platform-optimized
192
193### Common Pitfalls to Avoid
194- Writing before researching keywords
195- Ignoring platform-specific requirements
196- Inconsistent brand voice
197- Over-optimizing for SEO (keyword stuffing)
198- Missing clear CTAs
199- Publishing without proofreading
200- Ignoring analytics feedback
201
202## Performance Metrics
203
204Track these KPIs for content success:
205
206### Content Metrics
207- Organic traffic growth
208- Average time on page
209- Bounce rate
210- Social shares
211- Backlinks earned
212
213### Engagement Metrics
214- Comments and discussions
215- Email click-through rates
216- Social media engagement rate
217- Content downloads
218- Form submissions
219
220### Business Metrics
221- Leads generated
222- Conversion rate
223- Customer acquisition cost
224- Revenue attribution
225- ROI per content piece
226
227## Integration Points
228
229This skill works best with:
230- Analytics platforms (Google Analytics, social media insights)
231- SEO tools (for keyword research)
232- Design tools (for visual content)
233- Scheduling platforms (for content distribution)
234- Email marketing systems (for newsletter content)
235
236## Quick Commands
237
238```bash
239# Analyze brand voice
240python scripts/brand_voice_analyzer.py content.txt
241
242# Optimize for SEO
243python scripts/seo_optimizer.py article.md "main keyword"
244
245# Check content against brand guidelines
246grep -f references/brand_guidelines.md content.txt
247
248# Create monthly calendar
249cp assets/content_calendar_template.md this_month_calendar.md
250```
251
252
253
254# brand_voice_analyzer.py
255
256```python
257#!/usr/bin/env python3
258"""
259Brand Voice Analyzer - Analyzes content to establish and maintain brand voice consistency
260"""
261
262import re
263from typing import Dict, List, Tuple
264import json
265
266class BrandVoiceAnalyzer:
267 def __init__(self):
268 self.voice_dimensions = {
269 'formality': {
270 'formal': ['hereby', 'therefore', 'furthermore', 'pursuant', 'regarding'],
271 'casual': ['hey', 'cool', 'awesome', 'stuff', 'yeah', 'gonna']
272 },
273 'tone': {
274 'professional': ['expertise', 'solution', 'optimize', 'leverage', 'strategic'],
275 'friendly': ['happy', 'excited', 'love', 'enjoy', 'together', 'share']
276 },
277 'perspective': {
278 'authoritative': ['proven', 'research shows', 'experts agree', 'data indicates'],
279 'conversational': ['you might', 'let\'s explore', 'we think', 'imagine if']
280 }
281 }
282
283 def analyze_text(self, text: str) -> Dict:
284 """Analyze text for brand voice characteristics"""
285 text_lower = text.lower()
286 word_count = len(text.split())
287
288 results = {
289 'word_count': word_count,
290 'readability_score': self._calculate_readability(text),
291 'voice_profile': {},
292 'sentence_analysis': self._analyze_sentences(text),
293 'recommendations': []
294 }
295
296 # Analyze voice dimensions
297 for dimension, categories in self.voice_dimensions.items():
298 dim_scores = {}
299 for category, keywords in categories.items():
300 score = sum(1 for keyword in keywords if keyword in text_lower)
301 dim_scores[category] = score
302
303 # Determine dominant voice
304 if sum(dim_scores.values()) > 0:
305 dominant = max(dim_scores, key=dim_scores.get)
306 results['voice_profile'][dimension] = {
307 'dominant': dominant,
308 'scores': dim_scores
309 }
310
311 # Generate recommendations
312 results['recommendations'] = self._generate_recommendations(results)
313
314 return results
315
316 def _calculate_readability(self, text: str) -> float:
317 """Calculate Flesch Reading Ease score"""
318 sentences = re.split(r'[.!?]+', text)
319 words = text.split()
320 syllables = sum(self._count_syllables(word) for word in words)
321
322 if len(sentences) == 0 or len(words) == 0:
323 return 0
324
325 avg_sentence_length = len(words) / len(sentences)
326 avg_syllables_per_word = syllables / len(words)
327
328 # Flesch Reading Ease formula
329 score = 206.835 - 1.015 * avg_sentence_length - 84.6 * avg_syllables_per_word
330 return max(0, min(100, score))
331
332 def _count_syllables(self, word: str) -> int:
333 """Count syllables in a word (simplified)"""
334 word = word.lower()
335 vowels = 'aeiou'
336 syllable_count = 0
337 previous_was_vowel = False
338
339 for char in word:
340 is_vowel = char in vowels
341 if is_vowel and not previous_was_vowel:
342 syllable_count += 1
343 previous_was_vowel = is_vowel
344
345 # Adjust for silent e
346 if word.endswith('e'):
347 syllable_count -= 1
348
349 return max(1, syllable_count)
350
351 def _analyze_sentences(self, text: str) -> Dict:
352 """Analyze sentence structure"""
353 sentences = re.split(r'[.!?]+', text)
354 sentences = [s.strip() for s in sentences if s.strip()]
355
356 if not sentences:
357 return {'average_length': 0, 'variety': 'low'}
358
359 lengths = [len(s.split()) for s in sentences]
360 avg_length = sum(lengths) / len(lengths) if lengths else 0
361
362 # Calculate variety
363 if len(set(lengths)) < 3:
364 variety = 'low'
365 elif len(set(lengths)) < 5:
366 variety = 'medium'
367 else:
368 variety = 'high'
369
370 return {
371 'average_length': round(avg_length, 1),
372 'variety': variety,
373 'count': len(sentences)
374 }
375
376 def _generate_recommendations(self, analysis: Dict) -> List[str]:
377 """Generate recommendations based on analysis"""
378 recommendations = []
379
380 # Readability recommendations
381 if analysis['readability_score'] < 30:
382 recommendations.append("Consider simplifying language for better readability")
383 elif analysis['readability_score'] > 70:
384 recommendations.append("Content is very easy to read - consider if this matches your audience")
385
386 # Sentence variety
387 if analysis['sentence_analysis']['variety'] == 'low':
388 recommendations.append("Vary sentence length for better flow and engagement")
389
390 # Voice consistency
391 if analysis['voice_profile']:
392 recommendations.append("Maintain consistent voice across all content")
393
394 return recommendations
395
396def analyze_content(content: str, output_format: str = 'json') -> str:
397 """Main function to analyze content"""
398 analyzer = BrandVoiceAnalyzer()
399 results = analyzer.analyze_text(content)
400
401 if output_format == 'json':
402 return json.dumps(results, indent=2)
403 else:
404 # Human-readable format
405 output = [
406 f"=== Brand Voice Analysis ===",
407 f"Word Count: {results['word_count']}",
408 f"Readability Score: {results['readability_score']:.1f}/100",
409 f"",
410 f"Voice Profile:"
411 ]
412
413 for dimension, profile in results['voice_profile'].items():
414 output.append(f" {dimension.title()}: {profile['dominant']}")
415
416 output.extend([
417 f"",
418 f"Sentence Analysis:",
419 f" Average Length: {results['sentence_analysis']['average_length']} words",
420 f" Variety: {results['sentence_analysis']['variety']}",
421 f" Total Sentences: {results['sentence_analysis']['count']}",
422 f"",
423 f"Recommendations:"
424 ])
425
426 for rec in results['recommendations']:
427 output.append(f" • {rec}")
428
429 return '\n'.join(output)
430
431if __name__ == "__main__":
432 import sys
433
434 if len(sys.argv) > 1:
435 with open(sys.argv[1], 'r') as f:
436 content = f.read()
437
438 output_format = sys.argv[2] if len(sys.argv) > 2 else 'text'
439 print(analyze_content(content, output_format))
440 else:
441 print("Usage: python brand_voice_analyzer.py <file> [json|text]")
442
443```
444
445
446# seo_optimizer.py
447
448```python
449#!/usr/bin/env python3
450"""
451SEO Content Optimizer - Analyzes and optimizes content for SEO
452"""
453
454import re
455from typing import Dict, List, Set
456import json
457
458class SEOOptimizer:
459 def __init__(self):
460 # Common stop words to filter
461 self.stop_words = {
462 'the', 'a', 'an', 'and', 'or', 'but', 'in', 'on', 'at', 'to', 'for',
463 'of', 'with', 'by', 'from', 'as', 'is', 'was', 'are', 'were', 'be',
464 'been', 'being', 'have', 'has', 'had', 'do', 'does', 'did', 'will',
465 'would', 'could', 'should', 'may', 'might', 'must', 'can', 'shall'
466 }
467
468 # SEO best practices
469 self.best_practices = {
470 'title_length': (50, 60),
471 'meta_description_length': (150, 160),
472 'url_length': (50, 60),
473 'paragraph_length': (40, 150),
474 'heading_keyword_placement': True,
475 'keyword_density': (0.01, 0.03) # 1-3%
476 }
477
478 def analyze(self, content: str, target_keyword: str = None,
479 secondary_keywords: List[str] = None) -> Dict:
480 """Analyze content for SEO optimization"""
481
482 analysis = {
483 'content_length': len(content.split()),
484 'keyword_analysis': {},
485 'structure_analysis': self._analyze_structure(content),
486 'readability': self._analyze_readability(content),
487 'meta_suggestions': {},
488 'optimization_score': 0,
489 'recommendations': []
490 }
491
492 # Keyword analysis
493 if target_keyword:
494 analysis['keyword_analysis'] = self._analyze_keywords(
495 content, target_keyword, secondary_keywords or []
496 )
497
498 # Generate meta suggestions
499 analysis['meta_suggestions'] = self._generate_meta_suggestions(
500 content, target_keyword
501 )
502
503 # Calculate optimization score
504 analysis['optimization_score'] = self._calculate_seo_score(analysis)
505
506 # Generate recommendations
507 analysis['recommendations'] = self._generate_recommendations(analysis)
508
509 return analysis
510
511 def _analyze_keywords(self, content: str, primary: str,
512 secondary: List[str]) -> Dict:
513 """Analyze keyword usage and density"""
514 content_lower = content.lower()
515 word_count = len(content.split())
516
517 results = {
518 'primary_keyword': {
519 'keyword': primary,
520 'count': content_lower.count(primary.lower()),
521 'density': 0,
522 'in_title': False,
523 'in_headings': False,
524 'in_first_paragraph': False
525 },
526 'secondary_keywords': [],
527 'lsi_keywords': []
528 }
529
530 # Calculate primary keyword metrics
531 if word_count > 0:
532 results['primary_keyword']['density'] = (
533 results['primary_keyword']['count'] / word_count
534 )
535
536 # Check keyword placement
537 first_para = content.split('\n\n')[0] if '\n\n' in content else content[:200]
538 results['primary_keyword']['in_first_paragraph'] = (
539 primary.lower() in first_para.lower()
540 )
541
542 # Analyze secondary keywords
543 for keyword in secondary:
544 count = content_lower.count(keyword.lower())
545 results['secondary_keywords'].append({
546 'keyword': keyword,
547 'count': count,
548 'density': count / word_count if word_count > 0 else 0
549 })
550
551 # Extract potential LSI keywords
552 results['lsi_keywords'] = self._extract_lsi_keywords(content, primary)
553
554 return results
555
556 def _analyze_structure(self, content: str) -> Dict:
557 """Analyze content structure for SEO"""
558 lines = content.split('\n')
559
560 structure = {
561 'headings': {'h1': 0, 'h2': 0, 'h3': 0, 'total': 0},
562 'paragraphs': 0,
563 'lists': 0,
564 'images': 0,
565 'links': {'internal': 0, 'external': 0},
566 'avg_paragraph_length': 0
567 }
568
569 paragraphs = []
570 current_para = []
571
572 for line in lines:
573 # Count headings
574 if line.startswith('# '):
575 structure['headings']['h1'] += 1
576 structure['headings']['total'] += 1
577 elif line.startswith('## '):
578 structure['headings']['h2'] += 1
579 structure['headings']['total'] += 1
580 elif line.startswith('### '):
581 structure['headings']['h3'] += 1
582 structure['headings']['total'] += 1
583
584 # Count lists
585 if line.strip().startswith(('- ', '* ', '1. ')):
586 structure['lists'] += 1
587
588 # Count links
589 internal_links = len(re.findall(r'\[.*?\]\(/.*?\)', line))
590 external_links = len(re.findall(r'\[.*?\]\(https?://.*?\)', line))
591 structure['links']['internal'] += internal_links
592 structure['links']['external'] += external_links
593
594 # Track paragraphs
595 if line.strip() and not line.startswith('#'):
596 current_para.append(line)
597 elif current_para:
598 paragraphs.append(' '.join(current_para))
599 current_para = []
600
601 if current_para:
602 paragraphs.append(' '.join(current_para))
603
604 structure['paragraphs'] = len(paragraphs)
605
606 if paragraphs:
607 avg_length = sum(len(p.split()) for p in paragraphs) / len(paragraphs)
608 structure['avg_paragraph_length'] = round(avg_length, 1)
609
610 return structure
611
612 def _analyze_readability(self, content: str) -> Dict:
613 """Analyze content readability"""
614 sentences = re.split(r'[.!?]+', content)
615 words = content.split()
616
617 if not sentences or not words:
618 return {'score': 0, 'level': 'Unknown'}
619
620 avg_sentence_length = len(words) / len(sentences)
621
622 # Simple readability scoring
623 if avg_sentence_length < 15:
624 level = 'Easy'
625 score = 90
626 elif avg_sentence_length < 20:
627 level = 'Moderate'
628 score = 70
629 elif avg_sentence_length < 25:
630 level = 'Difficult'
631 score = 50
632 else:
633 level = 'Very Difficult'
634 score = 30
635
636 return {
637 'score': score,
638 'level': level,
639 'avg_sentence_length': round(avg_sentence_length, 1)
640 }
641
642 def _extract_lsi_keywords(self, content: str, primary_keyword: str) -> List[str]:
643 """Extract potential LSI (semantically related) keywords"""
644 words = re.findall(r'\b[a-z]+\b', content.lower())
645 word_freq = {}
646
647 # Count word frequencies
648 for word in words:
649 if word not in self.stop_words and len(word) > 3:
650 word_freq[word] = word_freq.get(word, 0) + 1
651
652 # Sort by frequency and return top related terms
653 sorted_words = sorted(word_freq.items(), key=lambda x: x[1], reverse=True)
654
655 # Filter out the primary keyword and return top 10
656 lsi_keywords = []
657 for word, count in sorted_words:
658 if word != primary_keyword.lower() and count > 1:
659 lsi_keywords.append(word)
660 if len(lsi_keywords) >= 10:
661 break
662
663 return lsi_keywords
664
665 def _generate_meta_suggestions(self, content: str, keyword: str = None) -> Dict:
666 """Generate SEO meta tag suggestions"""
667 # Extract first sentence for description base
668 sentences = re.split(r'[.!?]+', content)
669 first_sentence = sentences[0] if sentences else content[:160]
670
671 suggestions = {
672 'title': '',
673 'meta_description': '',
674 'url_slug': '',
675 'og_title': '',
676 'og_description': ''
677 }
678
679 if keyword:
680 # Title suggestion
681 suggestions['title'] = f"{keyword.title()} - Complete Guide"
682 if len(suggestions['title']) > 60:
683 suggestions['title'] = keyword.title()[:57] + "..."
684
685 # Meta description
686 desc_base = f"Learn everything about {keyword}. {first_sentence}"
687 if len(desc_base) > 160:
688 desc_base = desc_base[:157] + "..."
689 suggestions['meta_description'] = desc_base
690
691 # URL slug
692 suggestions['url_slug'] = re.sub(r'[^a-z0-9-]+', '-',
693 keyword.lower()).strip('-')
694
695 # Open Graph tags
696 suggestions['og_title'] = suggestions['title']
697 suggestions['og_description'] = suggestions['meta_description']
698
699 return suggestions
700
701 def _calculate_seo_score(self, analysis: Dict) -> int:
702 """Calculate overall SEO optimization score"""
703 score = 0
704 max_score = 100
705
706 # Content length scoring (20 points)
707 if 300 <= analysis['content_length'] <= 2500:
708 score += 20
709 elif 200 <= analysis['content_length'] < 300:
710 score += 10
711 elif analysis['content_length'] > 2500:
712 score += 15
713
714 # Keyword optimization (30 points)
715 if analysis['keyword_analysis']:
716 kw_data = analysis['keyword_analysis']['primary_keyword']
717
718 # Density scoring
719 if 0.01 <= kw_data['density'] <= 0.03:
720 score += 15
721 elif 0.005 <= kw_data['density'] < 0.01:
722 score += 8
723
724 # Placement scoring
725 if kw_data['in_first_paragraph']:
726 score += 10
727 if kw_data.get('in_headings'):
728 score += 5
729
730 # Structure scoring (25 points)
731 struct = analysis['structure_analysis']
732 if struct['headings']['total'] > 0:
733 score += 10
734 if struct['paragraphs'] >= 3:
735 score += 10
736 if struct['links']['internal'] > 0 or struct['links']['external'] > 0:
737 score += 5
738
739 # Readability scoring (25 points)
740 readability_score = analysis['readability']['score']
741 score += int(readability_score * 0.25)
742
743 return min(score, max_score)
744
745 def _generate_recommendations(self, analysis: Dict) -> List[str]:
746 """Generate SEO improvement recommendations"""
747 recommendations = []
748
749 # Content length recommendations
750 if analysis['content_length'] < 300:
751 recommendations.append(
752 f"Increase content length to at least 300 words (currently {analysis['content_length']})"
753 )
754 elif analysis['content_length'] > 3000:
755 recommendations.append(
756 "Consider breaking long content into multiple pages or adding a table of contents"
757 )
758
759 # Keyword recommendations
760 if analysis['keyword_analysis']:
761 kw_data = analysis['keyword_analysis']['primary_keyword']
762
763 if kw_data['density'] < 0.01:
764 recommendations.append(
765 f"Increase keyword density for '{kw_data['keyword']}' (currently {kw_data['density']:.2%})"
766 )
767 elif kw_data['density'] > 0.03:
768 recommendations.append(
769 f"Reduce keyword density to avoid over-optimization (currently {kw_data['density']:.2%})"
770 )
771
772 if not kw_data['in_first_paragraph']:
773 recommendations.append(
774 "Include primary keyword in the first paragraph"
775 )
776
777 # Structure recommendations
778 struct = analysis['structure_analysis']
779 if struct['headings']['total'] == 0:
780 recommendations.append("Add headings (H1, H2, H3) to improve content structure")
781 if struct['links']['internal'] == 0:
782 recommendations.append("Add internal links to related content")
783 if struct['avg_paragraph_length'] > 150:
784 recommendations.append("Break up long paragraphs for better readability")
785
786 # Readability recommendations
787 if analysis['readability']['avg_sentence_length'] > 20:
788 recommendations.append("Simplify sentences for better readability")
789
790 return recommendations
791
792def optimize_content(content: str, keyword: str = None,
793 secondary_keywords: List[str] = None) -> str:
794 """Main function to optimize content"""
795 optimizer = SEOOptimizer()
796
797 # Parse secondary keywords from comma-separated string if provided
798 if secondary_keywords and isinstance(secondary_keywords, str):
799 secondary_keywords = [kw.strip() for kw in secondary_keywords.split(',')]
800
801 results = optimizer.analyze(content, keyword, secondary_keywords)
802
803 # Format output
804 output = [
805 "=== SEO Content Analysis ===",
806 f"Overall SEO Score: {results['optimization_score']}/100",
807 f"Content Length: {results['content_length']} words",
808 f"",
809 "Content Structure:",
810 f" Headings: {results['structure_analysis']['headings']['total']}",
811 f" Paragraphs: {results['structure_analysis']['paragraphs']}",
812 f" Avg Paragraph Length: {results['structure_analysis']['avg_paragraph_length']} words",
813 f" Internal Links: {results['structure_analysis']['links']['internal']}",
814 f" External Links: {results['structure_analysis']['links']['external']}",
815 f"",
816 f"Readability: {results['readability']['level']} (Score: {results['readability']['score']})",
817 f""
818 ]
819
820 if results['keyword_analysis']:
821 kw = results['keyword_analysis']['primary_keyword']
822 output.extend([
823 "Keyword Analysis:",
824 f" Primary Keyword: {kw['keyword']}",
825 f" Count: {kw['count']}",
826 f" Density: {kw['density']:.2%}",
827 f" In First Paragraph: {'Yes' if kw['in_first_paragraph'] else 'No'}",
828 f""
829 ])
830
831 if results['keyword_analysis']['lsi_keywords']:
832 output.append(" Related Keywords Found:")
833 for lsi in results['keyword_analysis']['lsi_keywords'][:5]:
834 output.append(f" • {lsi}")
835 output.append("")
836
837 if results['meta_suggestions']:
838 output.extend([
839 "Meta Tag Suggestions:",
840 f" Title: {results['meta_suggestions']['title']}",
841 f" Description: {results['meta_suggestions']['meta_description']}",
842 f" URL Slug: {results['meta_suggestions']['url_slug']}",
843 f""
844 ])
845
846 output.extend([
847 "Recommendations:",
848 ])
849
850 for rec in results['recommendations']:
851 output.append(f" • {rec}")
852
853 return '\n'.join(output)
854
855if __name__ == "__main__":
856 import sys
857
858 if len(sys.argv) > 1:
859 with open(sys.argv[1], 'r') as f:
860 content = f.read()
861
862 keyword = sys.argv[2] if len(sys.argv) > 2 else None
863 secondary = sys.argv[3] if len(sys.argv) > 3 else None
864
865 print(optimize_content(content, keyword, secondary))
866 else:
867 print("Usage: python seo_optimizer.py <file> [primary_keyword] [secondary_keywords]")
868
869```