///|
/// The level of a Markdown heading, from 1 (`#`) to 6 (`######`).
pub(all) enum HeadingLevel {
H1
H2
H3
H4
H5
H6
} derive(Eq, Compare, Hash, Debug)
///|
/// The level as a number from 1 to 6.
pub fn HeadingLevel::to_int(self : HeadingLevel) -> Int32 {
match self {
H1 => 1
H2 => 2
H3 => 3
H4 => 4
H5 => 5
H6 => 6
}
}
///|
/// The level for a number from 1 to 6, or `None` for any other number.
pub fn HeadingLevel::of_int(n : Int32) -> HeadingLevel? {
match n {
1 => Some(H1)
2 => Some(H2)
3 => Some(H3)
4 => Some(H4)
5 => Some(H5)
6 => Some(H6)
_ => None
}
}
///|
pub impl Show for HeadingLevel with fn output(self, logger) {
logger.write_object(self.to_int())
}
///|
/// Raised when a position or a range breaks its rules.
pub(all) suberror PositionError {
/// A line or a column is less than 1.
InvalidPosition(line~ : Int32, column~ : Int32)
/// The start of a range is after its end.
StartAfterEnd(start~ : TextPosition, end~ : TextPosition)
/// An offset is negative, or the start offset is after the end offset.
InvalidOffsets(start~ : Int32, end~ : Int32)
} derive(Eq, Debug)
///|
/// A position in a text: a line and a column, both counted from 1. Columns
/// count UTF-16 code units. Positions order by line, then by column.
struct TextPosition {
line : Int32
column : Int32
} derive(Eq, Compare, Hash, Debug)
///|
/// Checks a position. Raises `InvalidPosition` when the line or the column is
/// less than 1.
pub fn TextPosition::TextPosition(
line~ : Int32,
column~ : Int32,
) -> TextPosition raise PositionError {
if line < 1 || column < 1 {
raise InvalidPosition(line~, column~)
}
{ line, column, }
}
///|
pub fn TextPosition::line(self : TextPosition) -> Int32 {
self.line
}
///|
pub fn TextPosition::column(self : TextPosition) -> Int32 {
self.column
}
///|
/// The position as `line:column`.
pub fn TextPosition::to_string(self : TextPosition) -> String {
"\{self.line}:\{self.column}"
}
///|
pub impl Show for TextPosition with fn output(self, logger) {
logger.write_string(self.to_string())
}
///|
/// A range of source text: the positions of its first and last characters,
/// and the UTF-16 offsets of its start and of its end. The end offset is the
/// offset after the last character. An empty range starts and ends at the
/// same position and offset.
struct SourceRange {
start : TextPosition
end : TextPosition
start_offset : Int32
end_offset : Int32
} derive(Eq, Hash, Debug)
///|
/// Checks a range. Raises `StartAfterEnd` when `start` is after `end`, and
/// `InvalidOffsets` when an offset is negative or the start offset is after
/// the end offset.
pub fn SourceRange::SourceRange(
start~ : TextPosition,
end~ : TextPosition,
start_offset~ : Int32,
end_offset~ : Int32,
) -> SourceRange raise PositionError {
if start > end {
raise StartAfterEnd(start~, end~)
}
if start_offset < 0 || start_offset > end_offset {
raise InvalidOffsets(start=start_offset, end=end_offset)
}
{ start, end, start_offset, end_offset, }
}
///|
/// The position of the first character.
pub fn SourceRange::start(self : SourceRange) -> TextPosition {
self.start
}
///|
/// The position of the last character, or the start of an empty range.
pub fn SourceRange::end(self : SourceRange) -> TextPosition {
self.end
}
///|
/// The UTF-16 offset of the first character.
pub fn SourceRange::start_offset(self : SourceRange) -> Int32 {
self.start_offset
}
///|
/// The UTF-16 offset after the last character.
pub fn SourceRange::end_offset(self : SourceRange) -> Int32 {
self.end_offset
}
///|
/// Raised when a frontmatter payload is not one YAML mapping.
pub(all) suberror FrontmatterError {
/// The payload is not valid YAML. The position is relative to the payload.
InvalidYaml(at~ : TextPosition, message~ : String)
/// The payload is one YAML document that is not a mapping.
NotAMapping
/// The payload holds more than one YAML document.
MultipleDocuments(count~ : Int32)
} derive(Eq, Debug)
///|
pub extend HeadingLevel with Eq::{not_equal, equal}
///|
pub extend HeadingLevel with Compare::{op_lt, op_le, op_ge, compare, op_gt}
///|
pub extend HeadingLevel with Hash::{hash, hash_combine}
///|
pub extend HeadingLevel with @debug.Debug::{to_repr}
///|
pub extend HeadingLevel with Show::{to_string, output}
///|
pub extend PositionError with Eq::{not_equal, equal}
///|
pub extend PositionError with @debug.Debug::{to_repr}
///|
pub extend TextPosition with Eq::{not_equal, equal}
///|
pub extend TextPosition with Compare::{op_lt, op_le, op_ge, compare, op_gt}
///|
pub extend TextPosition with Hash::{hash, hash_combine}
///|
pub extend TextPosition with @debug.Debug::{to_repr}
///|
pub extend TextPosition with Show::{output}
///|
pub extend SourceRange with Eq::{not_equal, equal}
///|
pub extend SourceRange with Hash::{hash, hash_combine}
///|
pub extend SourceRange with @debug.Debug::{to_repr}
///|
pub extend FrontmatterError with Eq::{not_equal, equal}
///|
pub extend FrontmatterError with @debug.Debug::{to_repr}