Back to snippets

seo_content_optimizer_with_brand_voice_analyzer_and_templates.py

python

Generated 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```
seo_content_optimizer_with_brand_voice_analyzer_and_templates.py - Raysurfer Public Snippets