add option -no-indent to remove indentation

This commit is contained in:
Emir Salkic 2022-07-14 15:07:06 +02:00
parent da166e051d
commit 4c50a25662
3 changed files with 59 additions and 4 deletions

View File

@ -1,6 +1,6 @@
use crate::errors::*; use crate::errors::*;
use crate::utils::{ use crate::utils::{
take_anchored_lines, take_lines, take_rustdoc_include_anchored_lines, take_anchored_lines, take_lines, take_remove_indent, take_rustdoc_include_anchored_lines,
take_rustdoc_include_lines, take_rustdoc_include_lines,
}; };
use regex::{CaptureMatches, Captures, Regex}; use regex::{CaptureMatches, Captures, Regex};
@ -134,6 +134,7 @@ where
enum LinkType<'a> { enum LinkType<'a> {
Escaped, Escaped,
Include(PathBuf, RangeOrAnchor), Include(PathBuf, RangeOrAnchor),
IncludeNoIndent(PathBuf, RangeOrAnchor),
Playground(PathBuf, Vec<&'a str>), Playground(PathBuf, Vec<&'a str>),
RustdocInclude(PathBuf, RangeOrAnchor), RustdocInclude(PathBuf, RangeOrAnchor),
Title(&'a str), Title(&'a str),
@ -205,6 +206,7 @@ impl<'a> LinkType<'a> {
match self { match self {
LinkType::Escaped => None, LinkType::Escaped => None,
LinkType::Include(p, _) => Some(return_relative_path(base, &p)), LinkType::Include(p, _) => Some(return_relative_path(base, &p)),
LinkType::IncludeNoIndent(p, _) => Some(return_relative_path(base, &p)),
LinkType::Playground(p, _) => Some(return_relative_path(base, &p)), LinkType::Playground(p, _) => Some(return_relative_path(base, &p)),
LinkType::RustdocInclude(p, _) => Some(return_relative_path(base, &p)), LinkType::RustdocInclude(p, _) => Some(return_relative_path(base, &p)),
LinkType::Title(_) => None, LinkType::Title(_) => None,
@ -250,12 +252,15 @@ fn parse_range_or_anchor(parts: Option<&str>) -> RangeOrAnchor {
} }
fn parse_include_path(path: &str) -> LinkType<'static> { fn parse_include_path(path: &str) -> LinkType<'static> {
let mut parts = path.splitn(2, ':'); let mut parts = path.splitn(3, ':');
let path = parts.next().unwrap().into(); let path = parts.next().unwrap().into();
let range_or_anchor = parse_range_or_anchor(parts.next()); let range_or_anchor = parse_range_or_anchor(parts.next());
LinkType::Include(path, range_or_anchor) match parts.next() {
Some(_some) => LinkType::IncludeNoIndent(path, range_or_anchor),
None => LinkType::Include(path, range_or_anchor),
}
} }
fn parse_rustdoc_include_path(path: &str) -> LinkType<'static> { fn parse_rustdoc_include_path(path: &str) -> LinkType<'static> {
@ -342,6 +347,22 @@ impl<'a> Link<'a> {
) )
}) })
} }
LinkType::IncludeNoIndent(ref pat, ref range_or_anchor) => {
let target = base.join(pat);
let s = fs::read_to_string(&target)
.map(|s| match range_or_anchor {
RangeOrAnchor::Range(range) => take_lines(&s, range.clone()),
RangeOrAnchor::Anchor(anchor) => take_anchored_lines(&s, anchor),
})
.with_context(|| {
format!(
"Could not read file for link {} ({})",
self.link_text,
target.display(),
)
});
take_remove_indent(s)
}
LinkType::RustdocInclude(ref pat, ref range_or_anchor) => { LinkType::RustdocInclude(ref pat, ref range_or_anchor) => {
let target = base.join(pat); let target = base.join(pat);

View File

@ -14,7 +14,7 @@ use std::fmt::Write;
use std::path::Path; use std::path::Path;
pub use self::string::{ pub use self::string::{
take_anchored_lines, take_lines, take_rustdoc_include_anchored_lines, take_anchored_lines, take_lines, take_remove_indent, take_rustdoc_include_anchored_lines,
take_rustdoc_include_lines, take_rustdoc_include_lines,
}; };

View File

@ -1,3 +1,4 @@
use anyhow::Error;
use regex::Regex; use regex::Regex;
use std::ops::Bound::{Excluded, Included, Unbounded}; use std::ops::Bound::{Excluded, Included, Unbounded};
use std::ops::RangeBounds; use std::ops::RangeBounds;
@ -114,6 +115,39 @@ pub fn take_rustdoc_include_anchored_lines(s: &str, anchor: &str) -> String {
output output
} }
pub fn take_remove_indent(s: Result<String, Error>) -> Result<String, Error> {
match s {
Err(_) => s,
Ok(_str) => Ok(take_format_remove_indent(_str.as_str())),
}
}
fn take_format_remove_indent(str: &str) -> String {
let mut output = Vec::<String>::new();
let mut min_indent = usize::MAX;
for line in str.lines() {
for (index, c) in line.chars().enumerate() {
if !c.is_whitespace() && min_indent > index {
min_indent = index;
break;
}
}
}
for line in str.lines() {
let formatted: String = line
.chars()
.take(0)
.chain(line.chars().skip(min_indent))
.collect();
output.push(formatted);
}
output.join("\n")
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::{ use super::{