pub mod agent;
pub mod diagnostic;
pub mod error;
mod escape;
mod hex;
mod lower;
pub mod model;
pub mod musicxml;
pub mod options;
pub mod parse;
pub mod source;
pub mod syntax;
mod text;
pub mod to_abc;
pub use agent::{AgentTopic, agent_topics, find_agent_topic};
pub use diagnostic::{Diagnostic, RecoveryNote, Severity, Span, SpecReference};
pub use error::{CromaError, Result};
pub use model::{
Accidental, AccidentalMark, AccidentalPolicy, AccidentalScope, BarlineKind, ChordEvent,
ChordMemberEvent, Event, EventAttachments, Fraction, KeySignatureModel, Measure, MeasureId,
MeterModel, NoteEvent, Part, Pitch, Rational, RestEvent, RestVisibility, Score, ScoreMetadata,
Staff, StaffId, TimedEvent, TimedEventKind, Tune, TupletAttachment, TupletRole, Voice,
};
pub use options::{
AbcSpecVersion, DiagnosticOptions, ExportOptions, LowerOptions, MusicXmlWriteOptions,
ParseMode, ParseOptions, TupletDisplay,
};
pub use parse::field::{
DecorationDelimiter, FieldState, LineBreakMode, ParsedAbcFields, ParsedField,
};
pub use parse::{AbcDocument, ParseReport};
pub use source::{LineColumn, LineColumnSpan, LineEnding, SourceLine, SourceText};
pub use syntax::{
BarlineSyntax, LengthSyntax, MusicItem, MusicLine, MusicToken, MusicTokenKind,
ParsedMusicDocument, ParsedTuneMusic,
};
pub use to_abc::{AbcWriteOptions, write_abc};
#[cfg(feature = "musicxml-reader")]
pub use musicxml::read::read_musicxml;
#[cfg(feature = "musicxml-reader")]
pub use musicxml::read::complete_score_for_abc;
#[cfg(test)]
pub(crate) mod test_support;
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct MusicXmlExport {
pub musicxml: String,
pub diagnostics: Vec<Diagnostic>,
}
pub fn abc_to_musicxml(source: &str) -> Result<String> {
export_musicxml(source).map(|export| export.musicxml)
}
pub fn export_musicxml(source: &str) -> Result<MusicXmlExport> {
export_musicxml_with_options(source, ExportOptions::default())
}
pub fn parse_document(source: &str, options: ParseOptions) -> ParseReport<AbcDocument> {
parse::parse_document(source, options)
}
pub fn lower_score(document: &AbcDocument, _options: LowerOptions) -> ParseReport<Option<Score>> {
let report = parse::parse_tune_report_from_document(document);
ParseReport {
value: report.value.map(|tune| tune.score),
diagnostics: report.diagnostics,
}
}
pub fn write_musicxml(score: &Score) -> MusicXmlExport {
write_musicxml_with_options(score, MusicXmlWriteOptions::default())
}
pub fn write_musicxml_with_options(score: &Score, options: MusicXmlWriteOptions) -> MusicXmlExport {
let report = musicxml::write_score_partwise_with_options(score, options);
MusicXmlExport {
musicxml: report.value,
diagnostics: report.diagnostics,
}
}
pub fn export_musicxml_with_options(
source: &str,
options: ExportOptions,
) -> Result<MusicXmlExport> {
let parse_report = parse_document(source, options.parse_options());
if parse_report.has_errors() {
return Err(CromaError::from_diagnostics(parse_report.diagnostics));
}
let ParseReport {
value: document,
mut diagnostics,
} = parse_report;
let tune_report = parse::parse_tune_report_from_document(&document);
diagnostics.extend(tune_report.diagnostics);
let Some(tune) = tune_report.value else {
return Err(CromaError::from_diagnostics(diagnostics));
};
let write_report = musicxml::write_score_partwise_with_options(&tune.score, options.write);
diagnostics.extend(write_report.diagnostics);
Ok(MusicXmlExport {
musicxml: write_report.value,
diagnostics,
})
}
#[cfg(test)]
#[path = "totality_tests.rs"]
mod totality_tests;
#[cfg(test)]
#[path = "lib_tests.rs"]
mod tests;