mirror of
https://github.com/kjanat/articulate-parser.git
synced 2026-10-13 01:35:27 +02:00
- Add interfaces.HTMLCleaner interface for better testability - Add CleanAndTrim() method to simplify repeated pattern - Move item/lesson type constants to models/item_types.go - Update all exporters to use interface instead of concrete type - Replace strings.TrimSpace(CleanHTML(...)) with CleanAndTrim()
121 lines
3.1 KiB
Go
121 lines
3.1 KiB
Go
package exporters
|
|
|
|
import (
|
|
"strings"
|
|
|
|
"golang.org/x/text/cases"
|
|
"golang.org/x/text/language"
|
|
|
|
"github.com/kjanat/articulate-parser/internal/interfaces"
|
|
"github.com/kjanat/articulate-parser/internal/models"
|
|
)
|
|
|
|
// templateData represents the data structure passed to the HTML template.
|
|
type templateData struct {
|
|
Course models.CourseInfo
|
|
ShareID string
|
|
Sections []templateSection
|
|
CSS string
|
|
}
|
|
|
|
// templateSection represents a course section or lesson.
|
|
type templateSection struct {
|
|
Type string
|
|
Title string
|
|
Number int
|
|
Description string
|
|
Items []templateItem
|
|
}
|
|
|
|
// templateItem represents a course item with preprocessed data.
|
|
type templateItem struct {
|
|
Type string
|
|
TypeTitle string
|
|
Items []templateSubItem
|
|
}
|
|
|
|
// templateSubItem represents a sub-item with preprocessed data.
|
|
type templateSubItem struct {
|
|
Heading string
|
|
Paragraph string
|
|
Title string
|
|
Caption string
|
|
CleanText string
|
|
Answers []models.Answer
|
|
Feedback string
|
|
Media *models.Media
|
|
}
|
|
|
|
// prepareTemplateData converts a Course model into template-friendly data.
|
|
func prepareTemplateData(course *models.Course, htmlCleaner interfaces.HTMLCleaner) *templateData {
|
|
data := &templateData{
|
|
Course: course.Course,
|
|
ShareID: course.ShareID,
|
|
Sections: make([]templateSection, 0, len(course.Course.Lessons)),
|
|
CSS: defaultCSS,
|
|
}
|
|
|
|
lessonCounter := 0
|
|
for _, lesson := range course.Course.Lessons {
|
|
section := templateSection{
|
|
Type: lesson.Type,
|
|
Title: lesson.Title,
|
|
Description: lesson.Description,
|
|
}
|
|
|
|
if lesson.Type != models.LessonTypeSection {
|
|
lessonCounter++
|
|
section.Number = lessonCounter
|
|
section.Items = prepareItems(lesson.Items, htmlCleaner)
|
|
}
|
|
|
|
data.Sections = append(data.Sections, section)
|
|
}
|
|
|
|
return data
|
|
}
|
|
|
|
// prepareItems converts model Items to template Items.
|
|
func prepareItems(items []models.Item, htmlCleaner interfaces.HTMLCleaner) []templateItem {
|
|
result := make([]templateItem, 0, len(items))
|
|
|
|
for _, item := range items {
|
|
tItem := templateItem{
|
|
Type: strings.ToLower(item.Type),
|
|
Items: make([]templateSubItem, 0, len(item.Items)),
|
|
}
|
|
|
|
// Set type title for unknown items
|
|
if tItem.Type != models.ItemTypeText && tItem.Type != models.ItemTypeList && tItem.Type != models.ItemTypeKnowledgeCheck &&
|
|
tItem.Type != models.ItemTypeMultimedia && tItem.Type != models.ItemTypeImage && tItem.Type != models.ItemTypeInteractive &&
|
|
tItem.Type != models.ItemTypeDivider {
|
|
caser := cases.Title(language.English)
|
|
tItem.TypeTitle = caser.String(item.Type)
|
|
}
|
|
|
|
// Process sub-items
|
|
for _, subItem := range item.Items {
|
|
tSubItem := templateSubItem{
|
|
Heading: subItem.Heading,
|
|
Paragraph: subItem.Paragraph,
|
|
Title: subItem.Title,
|
|
Caption: subItem.Caption,
|
|
Answers: subItem.Answers,
|
|
Feedback: subItem.Feedback,
|
|
Media: subItem.Media,
|
|
}
|
|
|
|
// Clean HTML for list items
|
|
if tItem.Type == models.ItemTypeList && subItem.Paragraph != "" {
|
|
tSubItem.CleanText = htmlCleaner.CleanHTML(subItem.Paragraph)
|
|
}
|
|
|
|
tItem.Items = append(tItem.Items, tSubItem)
|
|
}
|
|
|
|
result = append(result, tItem)
|
|
}
|
|
|
|
return result
|
|
}
|