#![allow(unused)] use super::{
parse::{LinkTag, MetaTag},
wrapped::ColumnSpan,
};
use smallvec::SmallVec;
use std::cmp::Ordering;
use term_rustdoc::util::{hashmap, HashMap, XString};
#[derive(Clone, Default, Debug, Hash, PartialEq, Eq)]
pub struct SelectedRegion {
row_start: usize,
row_end: usize,
col_start: usize,
col_end: usize,
}
impl SelectedRegion {
pub fn row_start(&self) -> usize {
self.row_start
}
fn new_same_line(row: usize, col: ColumnSpan) -> Self {
let [start, end] = col.span();
SelectedRegion {
row_start: row,
row_end: row,
col_start: start,
col_end: end,
}
}
fn merge_continuous(&mut self, new: SelectedRegion) {
match self.row_start.cmp(&new.row_start) {
Ordering::Greater => {
self.row_start = new.row_start;
self.col_start = new.col_start;
}
Ordering::Equal => self.col_start = self.col_start.min(new.col_start),
Ordering::Less => {}
}
match self.row_end.cmp(&new.row_end) {
Ordering::Less => {
self.row_end = new.row_end;
self.col_end = new.col_end;
}
Ordering::Equal => self.col_end = self.col_end.max(new.col_end),
Ordering::Greater => {}
}
}
}
#[derive(Debug, Hash, PartialEq, Eq)]
#[allow(dead_code)]
pub enum RegionTag {
FootNote(XString),
FootNoteSrc(XString),
Link(usize),
LinkSrc(usize),
}
#[derive(Clone, Debug, Default)]
pub struct TargetRegion {
targets: SmallVec<[SelectedRegion; 1]>,
}
impl From<SelectedRegion> for TargetRegion {
fn from(region: SelectedRegion) -> Self {
TargetRegion {
targets: SmallVec::from([region]),
}
}
}
#[derive(Debug, Default)]
pub struct LinkedRegions {
tag: HashMap<RegionTag, TargetRegion>,
heading: Vec<(usize, SelectedRegion)>,
}
impl LinkedRegions {
pub fn new() -> LinkedRegions {
LinkedRegions {
tag: hashmap(8),
heading: Vec::with_capacity(8),
}
}
pub fn push_heading(&mut self, idx: usize, row: usize, col: ColumnSpan) {
let region = SelectedRegion::new_same_line(row, col);
if let Some((index, old)) = self.heading.last_mut() {
if *index == idx {
old.merge_continuous(region);
return;
}
}
self.heading.push((idx, region));
}
pub fn take_headings(&mut self) -> Vec<(usize, SelectedRegion)> {
std::mem::take(&mut self.heading)
}
}
pub fn region_tag(tag: MetaTag) -> Option<RegionTag> {
match tag {
MetaTag::Link(LinkTag::ReferenceLink(id)) => Some(RegionTag::Link(id)),
MetaTag::Link(LinkTag::Footnote(key)) => Some(RegionTag::FootNote(key)),
_ => None,
}
}