Metadata-Version: 2.2
Name: pylearnspec
Version: 0.5.0
Summary: Python parser and validator for the LearnSpec suite (LearnMD, QuizMD, FlashMD, TrackMD, DiagramMD, MediaMD, GlossaryMD, BadgeMD, CertMD, NuggetMD)
Author-email: learnspec <hello@learnspec.org>
License: MIT
Project-URL: Homepage, https://github.com/learnspec/pylearnspec
Project-URL: Repository, https://github.com/learnspec/pylearnspec
Keywords: learnspec,quizmd,learnmd,flashmd,trackmd,diagrammd,mediamd,glossarymd,badgemd,certmd,nuggetmd,parser,education,assessment
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Education
Classifier: Topic :: Text Processing :: Markup :: Markdown
Requires-Python: >=3.9
Description-Content-Type: text/markdown
Requires-Dist: pyyaml>=6.0
Provides-Extra: dev
Requires-Dist: pytest>=8.0; extra == "dev"
Requires-Dist: pytest-cov>=5.0; extra == "dev"

# pylearnspec

Python parser and validator for the [LearnSpec](https://learnspec.org) suite of open standards:

| Format | API |
|---|---|
| **LearnMD** — instructional content | `parse_learn`, `validate_learn` |
| **QuizMD** — assessments | `parse_quiz`, `validate_quiz` |
| **FlashMD** — flashcards | `parse_flash`, `validate_flash` |
| **NuggetMD** — micro-learning nuggets | `parse_nugget`, `validate_nugget` |
| **TrackMD** — learning paths | `parse_track`, `validate_track` |
| **DiagramMD** — diagrams | `parse_diagram`, `validate_diagram` |
| **MediaMD** — media catalogues | `parse_media`, `validate_media` |
| **GlossaryMD** — glossaries | `parse_glossary`, `validate_glossary` |
| **BadgeMD** — micro-credentials | `parse_badge`, `validate_badge` |
| **CertMD** — macro-credentials | `parse_cert`, `validate_cert` |

## Install

```bash
pip install pylearnspec
```

## Quick start

### Parse a QuizMD file

```python
from pylearnspec import parse_quiz

with open("my-quiz.quiz.md") as f:
    quiz = parse_quiz(f.read())

print(quiz.title)
print(f"{len(quiz.questions)} questions")

for q in quiz.questions:
    print(f"  Q{q.number} ({q.q_type}): {q.title}")
```

### Parse a LearnMD file

```python
from pylearnspec import parse_learn

with open("my-lesson.learn.md") as f:
    lesson = parse_learn(f.read())

print(lesson.title)
for section in lesson.sections:
    print(f"  {'#' * section.depth} {section.title}")
```

### Validate

```python
from pylearnspec import validate_quiz, validate_learn

# Lenient mode (default)
diagnostics = validate_quiz(content)

# Strict mode (for CI)
diagnostics = validate_quiz(content, strict=True)

for d in diagnostics:
    print(f"[{d.level}] {d.message}")
```

### JSON output

Both `Quiz` and `Lesson` objects have a `.to_dict()` method for JSON serialization:

```python
import json
from pylearnspec import parse_quiz

quiz = parse_quiz(content)
print(json.dumps(quiz.to_dict(), indent=2))
```

## Supported features

### QuizMD

- Frontmatter (Level 1) and per-question `quiz` blocks (Level 2)
- Question types: MCQ, multi-select, true/false, open answer, match, order
- Per-choice and global feedback (`[!correct]`, `[!incorrect]`)
- `!import` directives
- Validation (lenient and strict modes)

### LearnMD

- Frontmatter metadata (lang, estimated_time, tags)
- Section hierarchy (## modules, ### lessons)
- Special fenced blocks: `summary`, `example`, `note`, `tip`, `warning`, `quiz`, etc.
- GFM callout detection (`> [!tip]`, `> [!warning]`, etc.)
- `!import` directives (`.learn.md` and `.quiz.md`)
- Validation (lenient and strict modes)

### LearnSpec suite (v0.2)

Every format follows the same shape:

- YAML frontmatter with the universal fields (`lang` required, `license`, `spec_version`, `created`, `updated`)
- Cross-format directives `!import`, `!ref`, `!checkpoint` (when applicable) — see `pylearnspec.common.directives`
- `parse_<format>(content)` returns a typed dataclass with a `.to_dict()` method
- `validate_<format>(content, strict=False)` returns a list of `Diagnostic(level, message)`

## Development

```bash
pip install -e ".[dev]"
pytest
```

## License

MIT
