1
Fork 0
mirror of https://github.com/RGBCube/uutils-coreutils synced 2025-07-29 12:07:46 +00:00

Fix spelling, update comments, and add documentation for improved code clarity

fixes #5066
This commit is contained in:
n4n5 2024-07-07 12:20:41 +02:00 committed by GitHub
parent 33a04bed2f
commit fb48e7d280
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
23 changed files with 173 additions and 59 deletions

View file

@ -370,6 +370,6 @@ impl<'a> SplitIterator<'a> {
}
pub fn split(s: &NativeIntStr) -> Result<Vec<NativeIntString>, ParseError> {
let splitted_args = SplitIterator::new(s).split()?;
Ok(splitted_args)
let split_args = SplitIterator::new(s).split()?;
Ok(split_args)
}

View file

@ -3,7 +3,7 @@
// For the full copyright and license information, please view the LICENSE
// file that was distributed with this source code.
//
// spell-checker:ignore (words) splitted FFFD
// spell-checker:ignore (words) FFFD
#![forbid(unsafe_code)]
use std::{borrow::Cow, ffi::OsStr};
@ -27,7 +27,7 @@ pub enum ErrorType {
/// Provides a valid char or a invalid sequence of bytes.
///
/// Invalid byte sequences can't be splitted in any meaningful way.
/// Invalid byte sequences can't be split in any meaningful way.
/// Thus, they need to be consumed as one piece.
pub enum Chunk<'a> {
InvalidEncoding(&'a NativeIntStr),

View file

@ -4,6 +4,8 @@
// file that was distributed with this source code.
// cSpell:disable
//! Provides color handling for `ls` and other utilities.
/// The keywords COLOR, OPTIONS, and EIGHTBIT (honored by the
/// slackware version of dircolors) are recognized but ignored.
/// Global config options can be specified before TERM or COLORTERM entries
@ -223,6 +225,7 @@ pub static FILE_COLORS: &[(&str, &str)] = &[
(".rpmsave", "00;90"),
];
/// Below are the terminal color capabilities
pub static FILE_ATTRIBUTE_CODES: &[(&str, &str)] = &[
("normal", "no"),
("norm", "no"),

View file

@ -7,15 +7,24 @@
// spell-checker:ignore powf copysign prec inity
/// Base for number parsing
#[derive(Clone, Copy, PartialEq)]
pub enum Base {
/// Binary base
Binary = 2,
/// Octal base
Octal = 8,
/// Decimal base
Decimal = 10,
/// Hexadecimal base
Hexadecimal = 16,
}
impl Base {
/// Return the digit value of a character in the given base
pub fn digit(&self, c: char) -> Option<u64> {
fn from_decimal(c: char) -> u64 {
u64::from(c) - u64::from('0')

View file

@ -2,7 +2,9 @@
//
// For the full copyright and license information, please view the LICENSE
// file that was distributed with this source code.
/// Thin pipe-related wrappers around functions from the `nix` crate.
//! Thin pipe-related wrappers around functions from the `nix` crate.
use std::fs::File;
#[cfg(any(target_os = "linux", target_os = "android"))]
use std::io::IoSlice;

View file

@ -2,6 +2,9 @@
//
// For the full copyright and license information, please view the LICENSE
// file that was distributed with this source code.
//! Set of functions for escaping names according to different quoting styles.
use std::char::from_digit;
use std::ffi::OsStr;
use std::fmt;
@ -11,25 +14,44 @@ use std::fmt;
const SPECIAL_SHELL_CHARS_START: &[char] = &['~', '#'];
const SPECIAL_SHELL_CHARS: &str = "`$&*()|[]{};\\'\"<>?! ";
/// The quoting style to use when escaping a name.
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum QuotingStyle {
/// Escape the name as a literal string.
Shell {
/// Whether to escape characters in the name.
escape: bool,
/// Whether to always quote the name.
always_quote: bool,
/// Whether to show control characters.
show_control: bool,
},
/// Escape the name as a C string.
C {
/// The type of quotes to use.
quotes: Quotes,
},
/// Escape the name as a literal string.
Literal {
/// Whether to show control characters.
show_control: bool,
},
}
/// The type of quotes to use when escaping a name as a C string.
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum Quotes {
/// Do not use quotes.
None,
/// Use single quotes.
Single,
/// Use double quotes.
Double,
// TODO: Locale
}
@ -262,6 +284,7 @@ fn shell_with_escape(name: &str, quotes: Quotes) -> (String, bool) {
(escaped_str, must_quote)
}
/// Escape a name according to the given quoting style.
pub fn escape_name(name: &OsStr, style: &QuotingStyle) -> String {
match style {
QuotingStyle::Literal { show_control } => {

View file

@ -5,14 +5,20 @@
// spell-checker:ignore (ToDO) inval
//! A module for handling ranges of values.
use std::cmp::max;
use std::str::FromStr;
use crate::display::Quotable;
/// A range of values
#[derive(PartialEq, Eq, PartialOrd, Ord, Debug)]
pub struct Range {
/// The lower bound of the range
pub low: usize,
/// The upper bound of the range
pub high: usize,
}
@ -72,6 +78,7 @@ impl FromStr for Range {
}
impl Range {
/// Parse a list of ranges separated by commas and/or spaces
pub fn from_list(list: &str) -> Result<Vec<Self>, String> {
let mut ranges = Vec::new();
@ -106,6 +113,7 @@ impl Range {
}
}
/// Calculate the complement of the given ranges.
pub fn complement(ranges: &[Range]) -> Vec<Range> {
let mut prev_high = 0;
let mut complements = Vec::with_capacity(ranges.len() + 1);

View file

@ -41,11 +41,15 @@ use std::collections::VecDeque;
/// [`push_back`]: struct.RingBuffer.html#method.push_back
/// [`from_iter`]: struct.RingBuffer.html#method.from_iter
pub struct RingBuffer<T> {
/// The data stored in the ring buffer.
pub data: VecDeque<T>,
/// The maximum number of elements that the ring buffer can hold.
size: usize,
}
impl<T> RingBuffer<T> {
/// Create a new ring buffer with a maximum size of `size`.
pub fn new(size: usize) -> Self {
Self {
data: VecDeque::new(),
@ -53,6 +57,7 @@ impl<T> RingBuffer<T> {
}
}
/// Create a new ring buffer from an iterator.
pub fn from_iter(iter: impl Iterator<Item = T>, size: usize) -> Self {
let mut ring_buffer = Self::new(size);
for value in iter {

View file

@ -5,6 +5,11 @@
// spell-checker:ignore (vars/api) fcntl setrlimit setitimer rubout pollable sysconf
// spell-checker:ignore (vars/signals) ABRT ALRM CHLD SEGV SIGABRT SIGALRM SIGBUS SIGCHLD SIGCONT SIGDANGER SIGEMT SIGFPE SIGHUP SIGILL SIGINFO SIGINT SIGIO SIGIOT SIGKILL SIGMIGRATE SIGMSG SIGPIPE SIGPRE SIGPROF SIGPWR SIGQUIT SIGSEGV SIGSTOP SIGSYS SIGTALRM SIGTERM SIGTRAP SIGTSTP SIGTHR SIGTTIN SIGTTOU SIGURG SIGUSR SIGVIRT SIGVTALRM SIGWINCH SIGXCPU SIGXFSZ STKFLT PWR THR TSTP TTIN TTOU VIRT VTALRM XCPU XFSZ SIGCLD SIGPOLL SIGWAITING SIGAIOCANCEL SIGLWP SIGFREEZE SIGTHAW SIGCANCEL SIGLOST SIGXRES SIGJVM SIGRTMIN SIGRT SIGRTMAX TALRM AIOCANCEL XRES RTMIN RTMAX
//! This module provides a way to handle signals in a platform-independent way.
//! It provides a way to convert signal names to their corresponding values and vice versa.
//! It also provides a way to ignore the SIGINT signal and enable pipe errors.
#[cfg(unix)]
use nix::errno::Errno;
#[cfg(unix)]
@ -12,6 +17,7 @@ use nix::sys::signal::{
signal, SigHandler::SigDfl, SigHandler::SigIgn, Signal::SIGINT, Signal::SIGPIPE,
};
/// The default signal value.
pub static DEFAULT_SIGNAL: usize = 15;
/*
@ -27,6 +33,7 @@ Linux Programmer's Manual
*/
/// The list of all signals.
#[cfg(any(target_os = "linux", target_os = "android", target_os = "redox"))]
pub static ALL_SIGNALS: [&str; 32] = [
"EXIT", "HUP", "INT", "QUIT", "ILL", "TRAP", "ABRT", "BUS", "FPE", "KILL", "USR1", "SEGV",
@ -339,6 +346,7 @@ pub static ALL_SIGNALS: [&str; 37] = [
"VIRT", "TALRM",
];
/// Returns the signal number for a given signal name or value.
pub fn signal_by_name_or_value(signal_name_or_value: &str) -> Option<usize> {
if let Ok(value) = signal_name_or_value.parse() {
if is_signal(value) {
@ -352,20 +360,25 @@ pub fn signal_by_name_or_value(signal_name_or_value: &str) -> Option<usize> {
ALL_SIGNALS.iter().position(|&s| s == signal_name)
}
/// Returns true if the given number is a valid signal number.
pub fn is_signal(num: usize) -> bool {
num < ALL_SIGNALS.len()
}
/// Returns the signal name for a given signal value.
pub fn signal_name_by_value(signal_value: usize) -> Option<&'static str> {
ALL_SIGNALS.get(signal_value).copied()
}
/// Returns the default signal value.
#[cfg(unix)]
pub fn enable_pipe_errors() -> Result<(), Errno> {
// We pass the error as is, the return value would just be Ok(SigDfl), so we can safely ignore it.
// SAFETY: this function is safe as long as we do not use a custom SigHandler -- we use the default one.
unsafe { signal(SIGPIPE, SigDfl) }.map(|_| ())
}
/// Ignores the SIGINT signal.
#[cfg(unix)]
pub fn ignore_interrupts() -> Result<(), Errno> {
// We pass the error as is, the return value would just be Ok(SigIgn), so we can safely ignore it.

View file

@ -48,26 +48,30 @@
//! ```
use clap::ArgMatches;
// Available update mode
/// Available update mode
#[derive(Clone, Debug, Eq, PartialEq)]
pub enum UpdateMode {
// --update=`all`, ``
/// --update=`all`, ``
ReplaceAll,
// --update=`none`
/// --update=`none`
ReplaceNone,
// --update=`older`
// -u
/// --update=`older`
/// -u
ReplaceIfOlder,
}
pub mod arguments {
//! Pre-defined arguments for update functionality.
use crate::shortcut_value_parser::ShortcutValueParser;
use clap::ArgAction;
/// `--update` argument
pub static OPT_UPDATE: &str = "update";
/// `-u` argument
pub static OPT_UPDATE_NO_ARG: &str = "u";
// `--update` argument, defaults to `older` if no values are provided
/// `--update` argument, defaults to `older` if no values are provided
pub fn update() -> clap::Arg {
clap::Arg::new(OPT_UPDATE)
.long("update")
@ -80,7 +84,7 @@ pub mod arguments {
.action(clap::ArgAction::Set)
}
// `-u` argument
/// `-u` argument
pub fn update_no_args() -> clap::Arg {
clap::Arg::new(OPT_UPDATE_NO_ARG)
.short('u')

View file

@ -2,6 +2,9 @@
//
// For the full copyright and license information, please view the LICENSE
// file that was distributed with this source code.
//! Compare two version strings.
use std::cmp::Ordering;
/// Compares the non-digit parts of a version.
@ -58,6 +61,7 @@ fn remove_file_ending(a: &str) -> &str {
}
}
/// Compare two version strings.
pub fn version_cmp(mut a: &str, mut b: &str) -> Ordering {
let str_cmp = a.cmp(b);
if str_cmp == Ordering::Equal {

View file

@ -2,7 +2,8 @@
//
// For the full copyright and license information, please view the LICENSE
// file that was distributed with this source code.
// library ~ (core/bundler file)
//! library ~ (core/bundler file)
// #![deny(missing_docs)] //TODO: enable this
// * feature-gated external crates (re-shared as public internal modules)
#[cfg(feature = "libc")]

View file

@ -3,8 +3,6 @@
// For the full copyright and license information, please view the LICENSE
// file that was distributed with this source code.
// TODO fix broken links
#![allow(rustdoc::broken_intra_doc_links)]
//! Macros for the uucore utilities.
//!
//! This module bundles all macros used across the uucore utilities. These
@ -183,6 +181,7 @@ macro_rules! show_warning(
})
);
/// Print a warning message to stderr, prepending the utility name.
#[macro_export]
macro_rules! show_warning_caps(
($($args:tt)+) => ({

View file

@ -2,27 +2,28 @@
//
// For the full copyright and license information, please view the LICENSE
// file that was distributed with this source code.
/// Utilities for printing paths, with special attention paid to special
/// characters and invalid unicode.
///
/// For displaying paths in informational messages use `Quotable::quote`. This
/// will wrap quotes around the filename and add the necessary escapes to make
/// it copy/paste-able into a shell.
///
/// For writing raw paths to stdout when the output should not be quoted or escaped,
/// use `println_verbatim`. This will preserve invalid unicode.
///
/// # Examples
/// ```
/// use std::path::Path;
/// use uucore::display::{Quotable, println_verbatim};
///
/// let path = Path::new("foo/bar.baz");
///
/// println!("Found file {}", path.quote()); // Prints "Found file 'foo/bar.baz'"
/// println_verbatim(path)?; // Prints "foo/bar.baz"
/// # Ok::<(), std::io::Error>(())
/// ```
//! Utilities for printing paths, with special attention paid to special
//! characters and invalid unicode.
//!
//! For displaying paths in informational messages use `Quotable::quote`. This
//! will wrap quotes around the filename and add the necessary escapes to make
//! it copy/paste-able into a shell.
//!
//! For writing raw paths to stdout when the output should not be quoted or escaped,
//! use `println_verbatim`. This will preserve invalid unicode.
//!
//! # Examples
//! ```rust
//! use std::path::Path;
//! use uucore::display::{Quotable, println_verbatim};
//!
//! let path = Path::new("foo/bar.baz");
//!
//! println!("Found file {}", path.quote()); // Prints "Found file 'foo/bar.baz'"
//! println_verbatim(path)?; // Prints "foo/bar.baz"
//! # Ok::<(), std::io::Error>(())
//! ```
use std::ffi::OsStr;
use std::io::{self, Write as IoWrite};

View file

@ -2,8 +2,6 @@
//
// For the full copyright and license information, please view the LICENSE
// file that was distributed with this source code.
// TODO fix broken links
#![allow(rustdoc::broken_intra_doc_links)]
//! All utils return exit with an exit code. Usually, the following scheme is used:
//! * `0`: succeeded
//! * `1`: minor problems
@ -287,11 +285,15 @@ where
/// ```
#[derive(Debug)]
pub struct USimpleError {
/// Exit code of the error.
pub code: i32,
/// Error message.
pub message: String,
}
impl USimpleError {
/// Create a new `USimpleError` with a given exit code and message.
#[allow(clippy::new_ret_no_self)]
pub fn new<S: Into<String>>(code: i32, message: S) -> Box<dyn UError> {
Box::new(Self {
@ -315,14 +317,19 @@ impl UError for USimpleError {
}
}
/// Wrapper type around [`std::io::Error`].
#[derive(Debug)]
pub struct UUsageError {
/// Exit code of the error.
pub code: i32,
/// Error message.
pub message: String,
}
impl UUsageError {
#[allow(clippy::new_ret_no_self)]
/// Create a new `UUsageError` with a given exit code and message.
pub fn new<S: Into<String>>(code: i32, message: S) -> Box<dyn UError> {
Box::new(Self {
code,
@ -383,6 +390,7 @@ pub struct UIoError {
impl UIoError {
#[allow(clippy::new_ret_no_self)]
/// Create a new `UIoError` with a given exit code and message.
pub fn new<S: Into<String>>(kind: std::io::ErrorKind, context: S) -> Box<dyn UError> {
Box::new(Self {
context: Some(context.into()),
@ -459,6 +467,7 @@ pub fn strip_errno(err: &std::io::Error) -> String {
/// Enables the conversion from [`std::io::Error`] to [`UError`] and from [`std::io::Result`] to
/// [`UResult`].
pub trait FromIo<T> {
/// Map the error context of an [`std::io::Error`] or [`std::io::Result`] to a custom error
fn map_err_context(self, context: impl FnOnce() -> String) -> T;
}
@ -642,6 +651,7 @@ pub struct ExitCode(pub i32);
impl ExitCode {
#[allow(clippy::new_ret_no_self)]
/// Create a new `ExitCode` with a given exit code.
pub fn new(code: i32) -> Box<dyn UError> {
Box::new(Self(code))
}
@ -694,6 +704,7 @@ pub struct ClapErrorWrapper {
/// Extension trait for `clap::Error` to adjust the exit code.
pub trait UClapError<T> {
/// Set the exit code for the program if `uumain` returns `Ok(())`.
fn with_exit_code(self, code: i32) -> T;
}

View file

@ -3,16 +3,16 @@
// For the full copyright and license information, please view the LICENSE
// file that was distributed with this source code.
/// Encapsulates differences between OSs regarding the access to
/// file handles / descriptors.
/// This is useful when dealing with lower level stdin/stdout access.
///
/// In detail:
/// On unix like OSs, file _descriptors_ are used in this context.
/// On windows OSs, file _handles_ are used.
///
/// Even though they are distinct classes, they share common functionality.
/// Access to this common functionality is provided in `OwnedFileDescriptorOrHandle`.
//! Encapsulates differences between OSs regarding the access to
//! file handles / descriptors.
//! This is useful when dealing with lower level stdin/stdout access.
//!
//! In detail:
//! On unix like OSs, file _descriptors_ are used in this context.
//! On windows OSs, file _handles_ are used.
//!
//! Even though they are distinct classes, they share common functionality.
//! Access to this common functionality is provided in `OwnedFileDescriptorOrHandle`.
#[cfg(not(windows))]
use std::os::fd::{AsFd, OwnedFd};

View file

@ -19,7 +19,10 @@ use std::fmt::Display;
#[derive(Clone, Copy, Debug, Default, PartialEq)]
pub enum LineEnding {
#[default]
/// Newline character (`\n`)
Newline = b'\n',
/// Null character (`\0`)
Nul = 0,
}

View file

@ -2,11 +2,12 @@
//
// For the full copyright and license information, please view the LICENSE
// file that was distributed with this source code.
/// Test if the program is running under WSL
// ref: <https://github.com/microsoft/WSL/issues/4555> @@ <https://archive.is/dP0bz>
// spell-checker:ignore (path) osrelease
//! Test if the program is running under WSL
//! ref: <https://github.com/microsoft/WSL/issues/4555> @@ <https://archive.is/dP0bz>
/// Test if the program is running under WSL version 1
pub fn is_wsl_1() -> bool {
#[cfg(target_os = "linux")]
{
@ -23,6 +24,7 @@ pub fn is_wsl_1() -> bool {
false
}
/// Test if the program is running under WSL version 2
pub fn is_wsl_2() -> bool {
#[cfg(target_os = "linux")]
{

View file

@ -10,10 +10,7 @@
//! and has value that can be parsed.
//! Otherwise returns None, so the calling utility would assume default behavior.
//!
//! NOTE: GNU (as of v9.4) recognizes three distinct values for POSIX version:
//! '199209' for POSIX 1003.2-1992, which would define Obsolete mode
//! '200112' for POSIX 1003.1-2001, which is the minimum version for Traditional mode
//! '200809' for POSIX 1003.1-2008, which is the minimum version for Modern mode
//! NOTE: GNU (as of v9.4) recognizes three distinct values for POSIX version
//!
//! Utilities that rely on this module:
//! `sort` (TBD)
@ -23,10 +20,16 @@
//!
use std::env;
/// '199209' for POSIX 1003.2-1992, which would define Obsolete mode
pub const OBSOLETE: usize = 199209;
/// '200112' for POSIX 1003.1-2001, which is the minimum version for Traditional mode
pub const TRADITIONAL: usize = 200112;
/// '200809' for POSIX 1003.1-2008, which is the minimum version for Modern mode
pub const MODERN: usize = 200809;
/// Returns the value of the `_POSIX2_VERSION` environment variable if it is defined
pub fn posix_version() -> Option<usize> {
env::var("_POSIX2_VERSION")
.ok()

View file

@ -2,9 +2,10 @@
//
// For the full copyright and license information, please view the LICENSE
// file that was distributed with this source code.
// spell-checker:ignore (ToDO) hdsf ghead gtail ACDBK hexdigit
//! Parser for sizes in SI or IEC units (multiples of 1000 or 1024 bytes).
use std::error::Error;
use std::fmt;
use std::num::IntErrorKind;
@ -35,21 +36,25 @@ enum NumberSystem {
}
impl<'parser> Parser<'parser> {
/// Change allow_list of the parser - whitelist for the suffix
pub fn with_allow_list(&mut self, allow_list: &'parser [&str]) -> &mut Self {
self.allow_list = Some(allow_list);
self
}
/// Change default_unit of the parser - when no suffix is provided
pub fn with_default_unit(&mut self, default_unit: &'parser str) -> &mut Self {
self.default_unit = Some(default_unit);
self
}
/// Change b_byte_count of the parser - to treat "b" as a "byte count" instead of "block"
pub fn with_b_byte_count(&mut self, value: bool) -> &mut Self {
self.b_byte_count = value;
self
}
/// Change no_empty_numeric of the parser - to allow empty numeric strings
pub fn with_allow_empty_numeric(&mut self, value: bool) -> &mut Self {
self.no_empty_numeric = value;
self
@ -293,6 +298,7 @@ pub fn parse_size_u64(size: &str) -> Result<u64, ParseSizeError> {
Parser::default().parse_u64(size)
}
/// Same as `parse_size_u64()` - deprecated
#[deprecated = "Please use parse_size_u64(size: &str) -> Result<u64, ParseSizeError> OR parse_size_u128(size: &str) -> Result<u128, ParseSizeError> instead."]
pub fn parse_size(size: &str) -> Result<u64, ParseSizeError> {
parse_size_u64(size)
@ -310,11 +316,17 @@ pub fn parse_size_u128_max(size: &str) -> Result<u128, ParseSizeError> {
Parser::default().parse_u128_max(size)
}
/// Error type for parse_size
#[derive(Debug, PartialEq, Eq)]
pub enum ParseSizeError {
InvalidSuffix(String), // Suffix
ParseFailure(String), // Syntax
SizeTooBig(String), // Overflow
/// Suffix
InvalidSuffix(String),
/// Syntax
ParseFailure(String),
/// Overflow
SizeTooBig(String),
}
impl Error for ParseSizeError {

View file

@ -3,11 +3,16 @@
// For the full copyright and license information, please view the LICENSE
// file that was distributed with this source code.
// spell-checker:ignore abcdefgh abef
//! A parser that accepts shortcuts for values.
//! `ShortcutValueParser` is similar to clap's `PossibleValuesParser`
use clap::{
builder::{PossibleValue, TypedValueParser},
error::{ContextKind, ContextValue, ErrorKind},
};
/// A parser that accepts shortcuts for values.
#[derive(Clone)]
pub struct ShortcutValueParser(Vec<PossibleValue>);
@ -17,6 +22,7 @@ pub struct ShortcutValueParser(Vec<PossibleValue>);
/// Whereas `PossibleValuesParser` only accepts exact matches, `ShortcutValueParser` also accepts
/// shortcuts as long as they are unambiguous.
impl ShortcutValueParser {
/// Create a new `ShortcutValueParser` from a list of `PossibleValue`.
pub fn new(values: impl Into<Self>) -> Self {
values.into()
}

View file

@ -5,6 +5,9 @@
//
// spell-checker:ignore backticks uuhelp
//! A collection of procedural macros for uutils.
#![deny(missing_docs)]
use std::{fs::File, io::Read, path::PathBuf};
use proc_macro::{Literal, TokenStream, TokenTree};
@ -14,6 +17,7 @@ use quote::quote;
//* ref: <https://dev.to/naufraghi/procedural-macro-in-rust-101-k3f> @@ <http://archive.is/Vbr5e>
//* ref: [path construction from LitStr](https://oschwald.github.io/maxminddb-rust/syn/struct.LitStr.html) @@ <http://archive.is/8YDua>
/// A procedural macro to define the main function of a uutils binary.
#[proc_macro_attribute]
pub fn main(_args: TokenStream, stream: TokenStream) -> TokenStream {
let stream = proc_macro2::TokenStream::from(stream);

View file

@ -2,6 +2,7 @@
//
// For the full copyright and license information, please view the LICENSE
// file that was distributed with this source code.
#![deny(missing_docs)]
//! A collection of functions to parse the markdown code of help files.
//!