8 Commits

Author SHA1 Message Date
dependabot[bot] 08f4dfabe7 deps(deps): bump the go-modules group with 2 updates
Bumps the go-modules group with 2 updates: [golang.org/x/net](https://github.com/golang/net) and [golang.org/x/text](https://github.com/golang/text).


Updates `golang.org/x/net` from 0.56.0 to 0.57.0
- [Commits](https://github.com/golang/net/compare/v0.56.0...v0.57.0)

Updates `golang.org/x/text` from 0.38.0 to 0.40.0
- [Release notes](https://github.com/golang/text/releases)
- [Commits](https://github.com/golang/text/compare/v0.38.0...v0.40.0)

---
updated-dependencies:
- dependency-name: golang.org/x/net
  dependency-version: 0.57.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: go-modules
- dependency-name: golang.org/x/text
  dependency-version: 0.40.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: go-modules
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-07-13 05:06:54 +00:00
dependabot[bot] 43a83e4004 ci(deps): bump docker/login-action from 3 to 4
Bumps [docker/login-action](https://github.com/docker/login-action) from 3 to 4.
- [Release notes](https://github.com/docker/login-action/releases)
- [Commits](https://github.com/docker/login-action/compare/v3...v4)

---
updated-dependencies:
- dependency-name: docker/login-action
  dependency-version: '4'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-06-26 19:41:57 +02:00
dependabot[bot] d966bd1aa4 ci(deps): bump softprops/action-gh-release from 2 to 3
Bumps [softprops/action-gh-release](https://github.com/softprops/action-gh-release) from 2 to 3.
- [Release notes](https://github.com/softprops/action-gh-release/releases)
- [Changelog](https://github.com/softprops/action-gh-release/blob/master/CHANGELOG.md)
- [Commits](https://github.com/softprops/action-gh-release/compare/v2...v3)

---
updated-dependencies:
- dependency-name: softprops/action-gh-release
  dependency-version: '3'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-06-26 19:41:39 +02:00
kjanat 144125d355 fix: resolve golangci-lint CI failures, simplify CI, tidy docs (#29)
* fix(lint): resolve golangci-lint failures and modernize string handling

CI's golangci-lint (v2.12.2) job was failing with 14 issues, which blocked
the dependent test job. This addresses all of them:

- goconst: extract repeated string literals into constants
  - format aliases ("md", "word", "htm") in the exporter factory
  - "section" lesson type shared by markdown and HTML exporters
  - default Articulate Rise base URL and host in the parser
  - reuse existing itemType* constants in the markdown switch
- staticcheck (QF1012): replace buf.WriteString(fmt.Sprintf(...)) with
  fmt.Fprintf(...) in the markdown exporter

Also drop the hardcoded `go: "1.24"` from .golangci.yml so the target Go
version is autodetected from go.mod.

* ci: drop test matrix, run a single Go version from go.mod

The test job ran a 1.24.x/1.25.x matrix, but go.mod requires go 1.25.0, so the
1.24 entry just auto-downloaded the 1.25 toolchain and tested the same thing
twice. Replace the matrix with a single job that sources its Go version from
go.mod via go-version-file, and reference the resolved version through the
setup-go step output in summaries, artifact names, and Codecov flags.

* docs: remove emojis from README

* ci: pin modernize tool to gopls v0.21.x for Go 1.25 compatibility

The autofix workflow's `task modernize` step installed the modernize
analyzer from gopls@latest, which as of v0.22.0 requires Go 1.26. The
project targets Go 1.25 (go.mod) and CI runs with GOTOOLCHAIN=local, so
the install failed. Pin to the v0.21.x line, which supports Go >= 1.25.

* ci: keep modernize@latest, fetch its toolchain via GOTOOLCHAIN=auto

Replaces the earlier v0.21.0 pin. The modernize analyzer (gopls v0.22+)
requires Go 1.26, which the project doesn't target yet — and bumping the
module to 1.26 isn't viable because the current golangci-lint release is
built with Go 1.25 and refuses to lint a newer target. Instead, let the
modernize task fetch the toolchain it needs on demand via GOTOOLCHAIN=auto
(setup-go pins GOTOOLCHAIN=local in CI), so we stay on the latest analyzer
without touching the module's Go version.

Also bump golang.org/x/image v0.34.0 -> v0.42.0 via `go get -u ./...`.

* ci: set GOTOOLCHAIN=auto inline for the modernize task

A task-level env: entry does not override GOTOOLCHAIN when setup-go has
already exported GOTOOLCHAIN=local job-wide, so the autofix job still
failed. Set GOTOOLCHAIN=auto inline on the modernize command itself, which
reliably overrides the inherited value and lets Go fetch the toolchain the
modernize analyzer requires.

* ci: bump to Go 1.26 and address PR review feedback

The autofix failure is fixed properly by moving to Go 1.26 instead of the
GOTOOLCHAIN workaround. The official golangci-lint v2.12.2 binary is built
with go1.26.2 and lints a Go 1.26 target fine (the earlier "not ready"
claim was from a locally go-installed binary compiled with Go 1.25), and
the Dockerfiles already use golang:1.26-alpine, so this also aligns the
module with the images.

- go.mod: go 1.25.0 -> 1.26.0, drop the toolchain pin (keeps the lint
  target at the go directive).
- Taskfile: revert modernize to plain modernize@latest; on Go 1.26 the
  GOTOOLCHAIN dance and its comments are unnecessary.
- ci.yml: pass the resolved Go version through an env var (GO_VERSION)
  instead of interpolating steps.setup-go.outputs.go-version directly into
  shell scripts (script-injection hygiene); grant the dependency-review job
  pull-requests: write so it can post its summary.
- parser.go: derive defaultBaseURL from riseHost instead of duplicating the
  host string; drop the redundant per-const comments.
- .golangci.yml: remove the redundant go-version comment.
- regenerate internal/exporters/output.docx.
2026-06-15 21:46:57 +02:00
dependabot[bot] 9ea51458c3 docker(deps): bump golang in the docker group across 1 directory
Bumps the docker group with 1 update in the / directory: golang.


Updates `golang` from 1.25-alpine to 1.26-alpine

---
updated-dependencies:
- dependency-name: golang
  dependency-version: 1.26-alpine
  dependency-type: direct:production
  dependency-group: docker
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-06-15 18:50:58 +02:00
dependabot[bot] 9b31fcda9e ci(deps): bump docker/setup-qemu-action from 3 to 4
Bumps [docker/setup-qemu-action](https://github.com/docker/setup-qemu-action) from 3 to 4.
- [Release notes](https://github.com/docker/setup-qemu-action/releases)
- [Commits](https://github.com/docker/setup-qemu-action/compare/v3...v4)

---
updated-dependencies:
- dependency-name: docker/setup-qemu-action
  dependency-version: '4'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-06-15 18:50:37 +02:00
dependabot[bot] 6e5c6aa086 ci(deps): bump actions/dependency-review-action from 4 to 5
Bumps [actions/dependency-review-action](https://github.com/actions/dependency-review-action) from 4 to 5.
- [Release notes](https://github.com/actions/dependency-review-action/releases)
- [Commits](https://github.com/actions/dependency-review-action/compare/v4...v5)

---
updated-dependencies:
- dependency-name: actions/dependency-review-action
  dependency-version: '5'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-06-15 18:50:33 +02:00
dependabot[bot] 6ba44a75eb deps(deps): bump the go-modules group with 2 updates
Bumps the go-modules group with 2 updates: [golang.org/x/net](https://github.com/golang/net) and [golang.org/x/text](https://github.com/golang/text).


Updates `golang.org/x/net` from 0.50.0 to 0.56.0
- [Commits](https://github.com/golang/net/compare/v0.50.0...v0.56.0)

Updates `golang.org/x/text` from 0.34.0 to 0.38.0
- [Release notes](https://github.com/golang/text/releases)
- [Commits](https://github.com/golang/text/compare/v0.34.0...v0.38.0)

---
updated-dependencies:
- dependency-name: golang.org/x/net
  dependency-version: 0.56.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: go-modules
- dependency-name: golang.org/x/text
  dependency-version: 0.38.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: go-modules
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-06-15 18:50:19 +02:00
14 changed files with 93 additions and 76 deletions
+27 -21
View File
@@ -35,21 +35,24 @@ jobs:
runs-on: ubuntu-latest
permissions:
contents: write
strategy:
matrix:
go:
- 1.24.x
- 1.25.x
steps:
- uses: actions/checkout@v6
- name: Set up Go ${{ matrix.go }}
- name: Set up Go
id: setup-go
uses: actions/setup-go@v6
with:
go-version: ${{ matrix.go }}
go-version-file: go.mod
check-latest: true
# Expose the resolved Go version as an env var so it is never
# interpolated directly into a shell script (avoids script injection).
- name: Export Go version
env:
GO_VERSION: ${{ steps.setup-go.outputs.go-version }}
run: echo "GO_VERSION=$GO_VERSION" >> "$GITHUB_ENV"
- name: Install Task
uses: go-task/setup-task@v1
@@ -70,7 +73,7 @@ jobs:
{
cat << EOF
## 🔧 Test Environment
- **Go Version:** ${{ matrix.go }}
- **Go Version:** $GO_VERSION
- **OS:** ubuntu-latest
- **Timestamp:** $(date -u)
@@ -90,7 +93,7 @@ jobs:
# Generate test summary
{
cat << EOF
## 🧪 Test Results (Go ${{ matrix.go }})
## 🧪 Test Results (Go $GO_VERSION)
| Metric | Value |
| ----------- | ------------------------------------------------------------- |
@@ -152,7 +155,7 @@ jobs:
{
cat << EOF
## 📊 Code Coverage (Go ${{ matrix.go }})
## 📊 Code Coverage (Go $GO_VERSION)
**Total Coverage: $COVERAGE**
@@ -213,7 +216,7 @@ jobs:
if: failure()
uses: actions/upload-artifact@v6
with:
name: test-results-go-${{ matrix.go }}
name: test-results-go-${{ env.GO_VERSION }}
path: |
test-output.log
coverage/
@@ -223,7 +226,7 @@ jobs:
run: |
{
cat << EOF
## 🔍 Static Analysis (Go ${{ matrix.go }})
## 🔍 Static Analysis (Go $GO_VERSION)
EOF
@@ -267,9 +270,10 @@ jobs:
- name: Job Summary
if: always()
run: |
cat >> "$GITHUB_STEP_SUMMARY" << 'EOF'
## 📋 Job Summary (Go ${{ matrix.go }})
{
echo "## 📋 Job Summary (Go $GO_VERSION)"
echo ""
cat << 'EOF'
| Step | Status |
| --------------- | --------------------------------------------------------------- |
| Dependencies | Success |
@@ -279,12 +283,13 @@ jobs:
| Static Analysis | ${{ job.status == 'success' && 'Clean' || 'Issues' }} |
| Code Formatting | ${{ job.status == 'success' && 'Clean' || 'Issues' }} |
EOF
} >> "$GITHUB_STEP_SUMMARY"
- name: Upload coverage reports to Codecov
uses: codecov/codecov-action@v5
with:
files: ./coverage/coverage.out
flags: Go ${{ matrix.go }}
flags: Go ${{ env.GO_VERSION }}
slug: kjanat/articulate-parser
token: ${{ secrets.CODECOV_TOKEN }}
@@ -292,7 +297,7 @@ jobs:
if: ${{ !cancelled() }}
uses: codecov/test-results-action@v1
with:
flags: Go ${{ matrix.go }}
flags: Go ${{ env.GO_VERSION }}
token: ${{ secrets.CODECOV_TOKEN }}
docker-test:
@@ -348,13 +353,14 @@ jobs:
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: write
if: github.event_name == 'pull_request'
steps:
- name: "Checkout Repository"
uses: actions/checkout@v6
- name: "Dependency Review"
uses: actions/dependency-review-action@v4
uses: actions/dependency-review-action@v5
with:
fail-on-severity: moderate
comment-summary-in-pr: always
@@ -375,20 +381,20 @@ jobs:
uses: actions/checkout@v6
- name: Login to Docker Hub
uses: docker/login-action@v3
uses: docker/login-action@v4
with:
username: ${{ vars.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Log in to GitHub Container Registry
uses: docker/login-action@v3
uses: docker/login-action@v4
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
uses: docker/setup-qemu-action@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
+1 -1
View File
@@ -20,7 +20,7 @@ jobs:
uses: actions/checkout@v6
- name: "Dependency Review"
uses: actions/dependency-review-action@v4
uses: actions/dependency-review-action@v5
with:
fail-on-severity: moderate
comment-summary-in-pr: always
+4 -4
View File
@@ -62,7 +62,7 @@ jobs:
done
- name: Create Release
uses: softprops/action-gh-release@v2
uses: softprops/action-gh-release@v3
with:
files: |
build/articulate-parser-linux-amd64
@@ -91,20 +91,20 @@ jobs:
uses: actions/checkout@v6
- name: Login to Docker Hub
uses: docker/login-action@v3
uses: docker/login-action@v4
with:
username: ${{ vars.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Log in to GitHub Container Registry
uses: docker/login-action@v3
uses: docker/login-action@v4
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
uses: docker/setup-qemu-action@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
-5
View File
@@ -8,11 +8,6 @@ run:
# Timeout for total work
timeout: 5m
# Skip directories (not allowed in config v2, will use issues exclude instead)
# Go version
go: "1.24"
# Include test files
tests: true
+1 -1
View File
@@ -1,5 +1,5 @@
# Build stage
FROM golang:1.25-alpine AS builder
FROM golang:1.26-alpine AS builder
# Install git and ca-certificates (needed for fetching dependencies and HTTPS)
RUN apk add --no-cache git ca-certificates tzdata file
+1 -1
View File
@@ -2,7 +2,7 @@
# Uses Alpine instead of scratch for debugging
# Build stage - same as production
FROM golang:1.25-alpine AS builder
FROM golang:1.26-alpine AS builder
# Install git and ca-certificates (needed for fetching dependencies and HTTPS)
RUN apk add --no-cache git ca-certificates tzdata file
+7 -7
View File
@@ -78,12 +78,12 @@ flowchart TD
The system follows **Clean Architecture** principles with clear separation of concerns:
- **🎯 Entry Point**: Command-line interface handles user input and coordinates operations
- **🏗️ Application Layer**: Core business logic with dependency injection
- **📋 Interface Layer**: Contracts defining behavior without implementation details
- **🔧 Service Layer**: Concrete implementations of parsing and utility services
- **📤 Export Layer**: Factory pattern for format-specific exporters
- **📊 Data Layer**: Domain models representing course structure
- **Entry Point**: Command-line interface handles user input and coordinates operations
- **Application Layer**: Core business logic with dependency injection
- **Interface Layer**: Contracts defining behavior without implementation details
- **Service Layer**: Concrete implementations of parsing and utility services
- **Export Layer**: Factory pattern for format-specific exporters
- **Data Layer**: Domain models representing course structure
## Features
@@ -206,7 +206,7 @@ Then run:
The application is available as a Docker image from GitHub Container Registry.
### 🐳 Docker Image Information
### Docker Image Information
- **Registry**: `ghcr.io/kjanat/articulate-parser`
- **Platforms**: linux/amd64, linux/arm64
+4 -6
View File
@@ -1,16 +1,14 @@
module github.com/kjanat/articulate-parser
go 1.24.0
toolchain go1.25.5
go 1.26.0
require (
github.com/fumiama/go-docx v0.0.0-20250506085032-0c30fd09304b
golang.org/x/net v0.50.0
golang.org/x/text v0.34.0
golang.org/x/net v0.57.0
golang.org/x/text v0.40.0
)
require (
github.com/fumiama/imgsz v0.0.4 // indirect
golang.org/x/image v0.34.0 // indirect
golang.org/x/image v0.42.0 // indirect
)
+6 -6
View File
@@ -2,9 +2,9 @@ github.com/fumiama/go-docx v0.0.0-20250506085032-0c30fd09304b h1:/mxSugRc4SgN7Xg
github.com/fumiama/go-docx v0.0.0-20250506085032-0c30fd09304b/go.mod h1:ssRF0IaB1hCcKIObp3FkZOsjTcAHpgii70JelNb4H8M=
github.com/fumiama/imgsz v0.0.4 h1:Lsasu2hdSSFS+vnD+nvR1UkiRMK7hcpyYCC0FzgSMFI=
github.com/fumiama/imgsz v0.0.4/go.mod h1:bISOQVTlw9sRytPwe8ir7tAaEmyz9hSNj9n8mXMBG0E=
golang.org/x/image v0.34.0 h1:33gCkyw9hmwbZJeZkct8XyR11yH889EQt/QH4VmXMn8=
golang.org/x/image v0.34.0/go.mod h1:2RNFBZRB+vnwwFil8GkMdRvrJOFd1AzdZI6vOY+eJVU=
golang.org/x/net v0.50.0 h1:ucWh9eiCGyDR3vtzso0WMQinm2Dnt8cFMuQa9K33J60=
golang.org/x/net v0.50.0/go.mod h1:UgoSli3F/pBgdJBHCTc+tp3gmrU4XswgGRgtnwWTfyM=
golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk=
golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA=
golang.org/x/image v0.42.0 h1:1gSs6ehNWXLbkHBIPcWztk3D/6aIA/8hauiAYtlodVY=
golang.org/x/image v0.42.0/go.mod h1:rrpelvGFt+kLPAjPM4HeWPgrl0FtafueU//e5N0qk/Q=
golang.org/x/net v0.57.0 h1:K5+3DljvIuDG9/Jv9rvyMywYNFCQ9RSUY6OOTTkT+tE=
golang.org/x/net v0.57.0/go.mod h1:KpXc8iv+r3XplLAG/f7Jsf9RPszJzdR0f58q9vGOuEU=
golang.org/x/text v0.40.0 h1:Ub2Z6/xjgF1WrYQz2nuITOEegKFtiIy+rieRJ5lHZKs=
golang.org/x/text v0.40.0/go.mod h1:hpnzDAfGV753zIKo+wk3u1bVKCGPbrnF7+7LBF/UHVY=
+13 -4
View File
@@ -13,6 +13,11 @@ const (
FormatMarkdown = "markdown"
FormatDocx = "docx"
FormatHTML = "html"
// Format aliases accepted by CreateExporter.
formatAliasMarkdown = "md"
formatAliasDocx = "word"
formatAliasHTML = "htm"
)
// Factory implements the ExporterFactory interface.
@@ -41,11 +46,11 @@ func NewFactory(htmlCleaner *services.HTMLCleaner) interfaces.ExporterFactory {
// Format strings are case-insensitive (e.g., "markdown", "DOCX").
func (f *Factory) CreateExporter(format string) (interfaces.Exporter, error) {
switch strings.ToLower(format) {
case FormatMarkdown, "md":
case FormatMarkdown, formatAliasMarkdown:
return NewMarkdownExporter(f.htmlCleaner), nil
case FormatDocx, "word":
case FormatDocx, formatAliasDocx:
return NewDocxExporter(f.htmlCleaner), nil
case FormatHTML, "htm":
case FormatHTML, formatAliasHTML:
return NewHTMLExporter(f.htmlCleaner), nil
default:
return nil, fmt.Errorf("unsupported export format: %s", format)
@@ -55,5 +60,9 @@ func (f *Factory) CreateExporter(format string) (interfaces.Exporter, error) {
// SupportedFormats returns a list of all supported export formats,
// including both primary format names and their aliases.
func (f *Factory) SupportedFormats() []string {
return []string{FormatMarkdown, "md", FormatDocx, "word", FormatHTML, "htm"}
return []string{
FormatMarkdown, formatAliasMarkdown,
FormatDocx, formatAliasDocx,
FormatHTML, formatAliasHTML,
}
}
+4 -1
View File
@@ -21,6 +21,9 @@ const (
itemTypeDivider = "divider"
)
// lessonTypeSection identifies a lesson that acts as a section header.
const lessonTypeSection = "section"
// templateData represents the data structure passed to the HTML template.
type templateData struct {
Course models.CourseInfo
@@ -74,7 +77,7 @@ func prepareTemplateData(course *models.Course, htmlCleaner *services.HTMLCleane
Description: lesson.Description,
}
if lesson.Type != "section" {
if lesson.Type != lessonTypeSection {
lessonCounter++
section.Number = lessonCounter
section.Items = prepareItems(lesson.Items, htmlCleaner)
+17 -17
View File
@@ -40,35 +40,35 @@ func (e *MarkdownExporter) Export(course *models.Course, outputPath string) erro
var buf bytes.Buffer
// Write course header
buf.WriteString(fmt.Sprintf("# %s\n\n", course.Course.Title))
fmt.Fprintf(&buf, "# %s\n\n", course.Course.Title)
if course.Course.Description != "" {
buf.WriteString(fmt.Sprintf("%s\n\n", e.htmlCleaner.CleanHTML(course.Course.Description)))
fmt.Fprintf(&buf, "%s\n\n", e.htmlCleaner.CleanHTML(course.Course.Description))
}
// Add metadata
buf.WriteString("## Course Information\n\n")
buf.WriteString(fmt.Sprintf("- **Course ID**: %s\n", course.Course.ID))
buf.WriteString(fmt.Sprintf("- **Share ID**: %s\n", course.ShareID))
buf.WriteString(fmt.Sprintf("- **Navigation Mode**: %s\n", course.Course.NavigationMode))
fmt.Fprintf(&buf, "- **Course ID**: %s\n", course.Course.ID)
fmt.Fprintf(&buf, "- **Share ID**: %s\n", course.ShareID)
fmt.Fprintf(&buf, "- **Navigation Mode**: %s\n", course.Course.NavigationMode)
if course.Course.ExportSettings != nil {
buf.WriteString(fmt.Sprintf("- **Export Format**: %s\n", course.Course.ExportSettings.Format))
fmt.Fprintf(&buf, "- **Export Format**: %s\n", course.Course.ExportSettings.Format)
}
buf.WriteString("\n---\n\n")
// Process lessons
lessonCounter := 0
for _, lesson := range course.Course.Lessons {
if lesson.Type == "section" {
buf.WriteString(fmt.Sprintf("# %s\n\n", lesson.Title))
if lesson.Type == lessonTypeSection {
fmt.Fprintf(&buf, "# %s\n\n", lesson.Title)
continue
}
lessonCounter++
buf.WriteString(fmt.Sprintf("## Lesson %d: %s\n\n", lessonCounter, lesson.Title))
fmt.Fprintf(&buf, "## Lesson %d: %s\n\n", lessonCounter, lesson.Title)
if lesson.Description != "" {
buf.WriteString(fmt.Sprintf("%s\n\n", e.htmlCleaner.CleanHTML(lesson.Description)))
fmt.Fprintf(&buf, "%s\n\n", e.htmlCleaner.CleanHTML(lesson.Description))
}
// Process lesson items
@@ -100,19 +100,19 @@ func (e *MarkdownExporter) processItemToMarkdown(buf *bytes.Buffer, item models.
itemType := strings.ToLower(item.Type)
switch itemType {
case "text":
case itemTypeText:
e.processTextItem(buf, item, headingPrefix)
case "list":
case itemTypeList:
e.processListItem(buf, item)
case "multimedia":
case itemTypeMultimedia:
e.processMultimediaItem(buf, item, headingPrefix)
case "image":
case itemTypeImage:
e.processImageItem(buf, item, headingPrefix)
case "knowledgecheck":
case itemTypeKnowledgeCheck:
e.processKnowledgeCheckItem(buf, item, headingPrefix)
case "interactive":
case itemTypeInteractive:
e.processInteractiveItem(buf, item, headingPrefix)
case "divider":
case itemTypeDivider:
e.processDividerItem(buf)
default:
e.processUnknownItem(buf, item, headingPrefix)
Binary file not shown.
+8 -2
View File
@@ -15,6 +15,12 @@ import (
"github.com/kjanat/articulate-parser/internal/models"
)
// Default endpoint configuration for the Articulate Rise API.
const (
riseHost = "rise.articulate.com"
defaultBaseURL = "https://" + riseHost
)
// shareIDRegex is compiled once at package init for extracting share IDs from URIs.
var shareIDRegex = regexp.MustCompile(`/share/([a-zA-Z0-9_-]+)`)
@@ -37,7 +43,7 @@ func NewArticulateParser(logger interfaces.Logger, baseURL string, timeout time.
logger = NewNoOpLogger()
}
if baseURL == "" {
baseURL = "https://rise.articulate.com"
baseURL = defaultBaseURL
}
if timeout == 0 {
timeout = 30 * time.Second
@@ -132,7 +138,7 @@ func (p *ArticulateParser) extractShareID(uri string) (string, error) {
}
// Validate that it's an Articulate Rise domain
if parsedURL.Host != "rise.articulate.com" {
if parsedURL.Host != riseHost {
return "", fmt.Errorf("invalid domain for Articulate Rise URI: %s", parsedURL.Host)
}