Skip to content

Commit

Permalink
more work
Browse files Browse the repository at this point in the history
  • Loading branch information
martinmr committed Jul 30, 2024
1 parent 7f0f782 commit 77c6329
Show file tree
Hide file tree
Showing 4 changed files with 105 additions and 13 deletions.
9 changes: 8 additions & 1 deletion src/data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,9 @@ use std::{collections::BTreeMap, path::Path};
use ts_rs::TS;
use ustr::Ustr;

use self::course_generator::{
use crate::data::course_generator::{
knowledge_base::KnowledgeBaseConfig,
literacy::LiteracyConfig,
music_piece::MusicPieceConfig,
transcription::{TranscriptionConfig, TranscriptionLink, TranscriptionPreferences},
};
Expand Down Expand Up @@ -249,6 +250,9 @@ pub enum CourseGenerator {
/// and for future extensibility.
KnowledgeBase(KnowledgeBaseConfig),

/// The configuration for generating a literacy course.
Literacy(LiteracyConfig),

Check failure on line 254 in src/data.rs

View workflow job for this annotation

GitHub Actions / Code Coverage

the trait bound `LiteracyConfig: TS` is not satisfied

/// The configuration for generating a music piece course.
MusicPiece(MusicPieceConfig),

Expand Down Expand Up @@ -291,6 +295,9 @@ impl GenerateManifests for CourseGenerator {
CourseGenerator::KnowledgeBase(config) => {
config.generate_manifests(course_root, course_manifest, preferences)
}
CourseGenerator::Literacy(config) => {
config.generate_manifests(course_root, course_manifest, preferences)
}
CourseGenerator::MusicPiece(config) => {
config.generate_manifests(course_root, course_manifest, preferences)
}
Expand Down
7 changes: 2 additions & 5 deletions src/data/course_generator/knowledge_base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -562,12 +562,9 @@ impl GenerateManifests for KnowledgeBaseConfig {
course_manifest: &CourseManifest,
_preferences: &UserPreferences,
) -> Result<GeneratedCourse> {
// Store the lessons and their exercises in a map of short lesson ID to a tuple of the
// lesson and its exercises.
// Create the lessons by iterating through all the directories in the course root,
// processing only those whose name fits the pattern `<SHORT_LESSON_ID>.lesson`.
let mut lessons = UstrMap::default();

// Iterate through all the directories in the course root, processing only those whose name
// fits the pattern `<SHORT_LESSON_ID>.lesson`.
for entry in read_dir(course_root)? {
// Ignore the entry if it's not a directory.
let entry = entry?;
Expand Down
99 changes: 94 additions & 5 deletions src/data/course_generator/literacy.rs
Original file line number Diff line number Diff line change
@@ -1,25 +1,114 @@
use anyhow::Result;
use anyhow::{Context, Result};
use serde::{Deserialize, Serialize};
use std::path::Path;
use std::{fs, path::Path};
use ustr::Ustr;

use crate::data::{CourseManifest, GenerateManifests, GeneratedCourse, UserPreferences};
use crate::data::{
CourseGenerator, CourseManifest, ExerciseManifest, GenerateManifests, GeneratedCourse,
LessonManifest, UserPreferences,
};

/// The metadata key indicating this is a literacy course. Its value should be set to "true".
pub const COURSE_METADATA: &str = "literacy_course";

/// The extension of files containing examples.
pub const EXAMPLE_SUFFIX: &str = ".example.md";

/// The extension of files containing exceptions.
pub const EXCEPTION_SUFFIX: &str = ".exception.md";

/// The configuration to create a course that teaches literacy based on the provided material.
/// Material can be of two types.
///
/// 1. Examples. For example, they can be words that share the same spelling and pronunciation (e.g.
/// "cat", "bat", "hat"), sentences that share similar words, or sentences from the same book or
/// article (for more advanced courses).
/// 2. Exceptions. For example, they can be words that share the same spelling but have different
/// pronunciations (e.g. "cow" and "crow").
///
/// All examples and exceptions accept markdown syntax. Examples and exceptions can be declared in
/// the configuration or in separate files in the course's directory. Files that end with the
/// extensions ".examples.md" and ".exceptions.md" will be considered as examples and exceptions,
/// respectively.
#[derive(Clone, Debug, Default, Deserialize, PartialEq, Serialize)]
pub struct LiteracyConfig {
/// The dependencies on other literacy courses. Specifying these dependencies here instead of
/// the [CourseManifest] allows Trane to generate more fine-grained dependencies.
#[serde(default)]
pub literacy_dependencies: Vec<Ustr>,

/// Inlined examples to use in the course.
#[serde(default)]
inline_examples: Vec<String>,

/// Inlined exceptions to use in the course.
#[serde(default)]
inline_exceptions: Vec<String>,

/// Whether to generate an optional lesson that asks the student to write the material based on
/// the tutor's dictation.
#[serde(default)]
pub generate_dictation: bool,
}

impl LiteracyConfig {
fn generate_lesson_manifests(
&self,
course_manifest: &CourseManifest,
examples: &[String],

Check warning on line 58 in src/data/course_generator/literacy.rs

View workflow job for this annotation

GitHub Actions / Code Coverage

unused variable: `examples`
exceptions: &[String],

Check warning on line 59 in src/data/course_generator/literacy.rs

View workflow job for this annotation

GitHub Actions / Code Coverage

unused variable: `exceptions`
) -> Vec<(LessonManifest, Vec<ExerciseManifest>)> {
let generate_dictation =

Check warning on line 61 in src/data/course_generator/literacy.rs

View workflow job for this annotation

GitHub Actions / Code Coverage

unused variable: `generate_dictation`
if let Some(CourseGenerator::Literacy(config)) = &course_manifest.generator_config {
config.generate_dictation
} else {
false
};
let lessons = Vec::new();
lessons
}
}

impl GenerateManifests for LiteracyConfig {
fn generate_manifests(
&self,
course_root: &Path,
course_manifest: &CourseManifest,
preferences: &UserPreferences,
_preferences: &UserPreferences,
) -> Result<GeneratedCourse> {
unimplemented!()
// Collect all the examples and exceptions. First, gather the inlined ones. Then, gather the
// examples and exceptions from the files in the courses's root directory.
let mut examples = self.inline_examples.clone();
let mut exceptions = self.inline_exceptions.clone();
for entry in fs::read_dir(course_root)? {
// Ignore entries that are not a file.
let entry = entry.context("Failed to read entry when generating literacy course")?;
let path = entry.path();
if !path.is_file() {
continue;
}

// Check that the file name ends is either an example or exception file.
let file_name = path.file_name().unwrap_or_default().to_str().unwrap();
if file_name.ends_with(EXAMPLE_SUFFIX) {
let example = fs::read_to_string(&path).context("Failed to read example file")?;
examples.push(example);
} else if file_name.ends_with(EXCEPTION_SUFFIX) {
let exception =
fs::read_to_string(&path).context("Failed to read exception file")?;
exceptions.push(exception);
}
}

// Generate the manifests for all the lessons and exercises and metadata to indicate this is
// a literacy course.
let lessons = self.generate_lesson_manifests(course_manifest, &examples, &exceptions);
let mut metadata = course_manifest.metadata.clone().unwrap_or_default();
metadata.insert(COURSE_METADATA.to_string(), vec!["true".to_string()]);
Ok(GeneratedCourse {
lessons,
updated_metadata: Some(metadata),
updated_instructions: None,
})
}
}
3 changes: 1 addition & 2 deletions src/data/course_generator/transcription/constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,7 @@ pub const ADVANCED_TRANSCRIPTION_DESCRIPTION: &str = indoc! {"
Refer to the lesson instructions for more details.
"};

/// The metadata key indicating the lesson belongs to a transcription course. Its value should be
/// set to "true".
/// The metadata key indicating this is a transcription course. Its value should be set to "true".
pub const COURSE_METADATA: &str = "transcription_course";

/// The metadata key indicating the type of the transcription lesson. Its value should be set to
Expand Down

0 comments on commit 77c6329

Please sign in to comment.