typegen: restructure type links and callouts for new site
This commit is contained in:
		
							parent
							
								
									997eb9e876
								
							
						
					
					
						commit
						593634eb27
					
				
					 3 changed files with 138 additions and 123 deletions
				
			
		| 
						 | 
				
			
			@ -4,6 +4,7 @@ use anyhow::{anyhow, Context};
 | 
			
		|||
 | 
			
		||||
mod outform;
 | 
			
		||||
mod parse;
 | 
			
		||||
mod reformat;
 | 
			
		||||
mod resolver;
 | 
			
		||||
mod typespec;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,10 +1,11 @@
 | 
			
		|||
use std::borrow::Cow;
 | 
			
		||||
 | 
			
		||||
use anyhow::{anyhow, bail, Context};
 | 
			
		||||
use fancy_regex::Regex;
 | 
			
		||||
use serde::Deserialize;
 | 
			
		||||
 | 
			
		||||
use crate::typespec;
 | 
			
		||||
use crate::{
 | 
			
		||||
	reformat::{self, ReformatPass},
 | 
			
		||||
	typespec,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#[derive(Deserialize, Debug)]
 | 
			
		||||
pub struct ModuleInfoHeader {
 | 
			
		||||
| 
						 | 
				
			
			@ -625,7 +626,6 @@ impl From<InvokableParam<'_>> for typespec::FnParam {
 | 
			
		|||
 | 
			
		||||
fn parse_details(comment: Comment) -> String {
 | 
			
		||||
	let mut seen_content = false;
 | 
			
		||||
	let mut callout = false;
 | 
			
		||||
 | 
			
		||||
	let mut str = comment
 | 
			
		||||
		.text
 | 
			
		||||
| 
						 | 
				
			
			@ -642,127 +642,14 @@ fn parse_details(comment: Comment) -> String {
 | 
			
		|||
			seen_content |= any;
 | 
			
		||||
			filter
 | 
			
		||||
		})
 | 
			
		||||
		.map(|line| match callout {
 | 
			
		||||
			true => {
 | 
			
		||||
				if line.starts_with('>') {
 | 
			
		||||
					Cow::Borrowed(line[1..].strip_prefix(' ').unwrap_or(&line[1..]))
 | 
			
		||||
				} else {
 | 
			
		||||
					callout = false;
 | 
			
		||||
					Cow::Owned(format!("{{{{< /callout >}}}}\n{line}"))
 | 
			
		||||
				}
 | 
			
		||||
			},
 | 
			
		||||
			false => {
 | 
			
		||||
				if line.starts_with("> [!") {
 | 
			
		||||
					let code = line[4..].split_once(']');
 | 
			
		||||
 | 
			
		||||
					if let Some((code, line)) = code {
 | 
			
		||||
						let code = code.to_lowercase();
 | 
			
		||||
						callout = true;
 | 
			
		||||
						return Cow::Owned(format!("{{{{< callout type=\"{code}\" >}}}}\n{line}"))
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				return Cow::Borrowed(line);
 | 
			
		||||
			},
 | 
			
		||||
		})
 | 
			
		||||
		.map(|line| {
 | 
			
		||||
			if line.contains("@@") {
 | 
			
		||||
				let mut src: &str = &*line;
 | 
			
		||||
				let mut accum = String::new();
 | 
			
		||||
 | 
			
		||||
				while let Some(i) = src.find("@@") {
 | 
			
		||||
					accum += &src[..i];
 | 
			
		||||
					src = &src[i + 2..];
 | 
			
		||||
 | 
			
		||||
					let separators = [
 | 
			
		||||
						('$', true),
 | 
			
		||||
						(' ', false),
 | 
			
		||||
						(',', false),
 | 
			
		||||
						(';', false),
 | 
			
		||||
						(':', false),
 | 
			
		||||
					];
 | 
			
		||||
 | 
			
		||||
					let (mut end, mut ty) = src.chars().enumerate()
 | 
			
		||||
						.find_map(|(i, char)| {
 | 
			
		||||
							separators.iter()
 | 
			
		||||
								.find(|(sc, _)| char == *sc)
 | 
			
		||||
								.map(|(_, strip)| (i + if *strip { 1 } else { 0 }, &src[..i]))
 | 
			
		||||
						})
 | 
			
		||||
						.unwrap_or_else(|| (src.len(), src));
 | 
			
		||||
 | 
			
		||||
					// special case for . as it is contained in valid types as well
 | 
			
		||||
					if ty.ends_with('.') {
 | 
			
		||||
						end -= 1;
 | 
			
		||||
						ty = &ty[..ty.len() - 1];
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
					let (ty, member) = match ty.chars().next() {
 | 
			
		||||
						None => (None, None),
 | 
			
		||||
						Some(c) if c.is_lowercase() => (None, Some(ty)),
 | 
			
		||||
						Some(_) => {
 | 
			
		||||
							let mut split = ty.rsplit_once('.').unwrap_or(("", ty));
 | 
			
		||||
 | 
			
		||||
							let member = split
 | 
			
		||||
								.1
 | 
			
		||||
								.chars()
 | 
			
		||||
								.next()
 | 
			
		||||
								.unwrap()
 | 
			
		||||
								.is_lowercase()
 | 
			
		||||
								.then(|| {
 | 
			
		||||
									let prop = split.1;
 | 
			
		||||
									split = split.0.rsplit_once('.').unwrap_or(("", split.0));
 | 
			
		||||
									prop
 | 
			
		||||
								})
 | 
			
		||||
								.unwrap_or("");
 | 
			
		||||
 | 
			
		||||
							let (mut module, name) = split;
 | 
			
		||||
 | 
			
		||||
							if module.is_empty() {
 | 
			
		||||
								module = comment.module;
 | 
			
		||||
							}
 | 
			
		||||
 | 
			
		||||
							(Some((module, name)), Some(member))
 | 
			
		||||
						},
 | 
			
		||||
					};
 | 
			
		||||
 | 
			
		||||
					let (membertype, membername) = match member {
 | 
			
		||||
						None => ("", ""),
 | 
			
		||||
						Some(name) if name.ends_with("()") => ("func", &name[..name.len() - 2]),
 | 
			
		||||
						Some(name) if name.ends_with("(s)") => ("signal", &name[..name.len() - 3]),
 | 
			
		||||
						Some(name) if name.is_empty() => ("", ""),
 | 
			
		||||
						Some(name) => ("prop", name),
 | 
			
		||||
					};
 | 
			
		||||
 | 
			
		||||
					let ((linktype, module), name) = match ty {
 | 
			
		||||
						Some((module, name)) => {
 | 
			
		||||
							let module = match module {
 | 
			
		||||
								module if module.starts_with("Quickshell") => ("local", module.to_string()),
 | 
			
		||||
								module => ("qt", format!("qml.{module}")),
 | 
			
		||||
							};
 | 
			
		||||
 | 
			
		||||
							(module, name)
 | 
			
		||||
						},
 | 
			
		||||
						None => (("", String::new()), ""),
 | 
			
		||||
					};
 | 
			
		||||
 | 
			
		||||
					accum += &format!(
 | 
			
		||||
						r#"{{{{< qmltypelink type="{linktype}" module="{module}" name="{name}" mtype="{membertype}" mname="{membername}" >}}}}"#
 | 
			
		||||
					);
 | 
			
		||||
					src = &src[end..];
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				accum += src;
 | 
			
		||||
 | 
			
		||||
				return Cow::Owned(accum);
 | 
			
		||||
			} else {
 | 
			
		||||
				return line;
 | 
			
		||||
			}
 | 
			
		||||
		})
 | 
			
		||||
		.fold(String::new(), |accum, line| accum + line.as_ref() + "\n");
 | 
			
		||||
 | 
			
		||||
	if callout {
 | 
			
		||||
		str += "\n{{< /callout >}}";
 | 
			
		||||
	}
 | 
			
		||||
	let reformat_ctx = reformat::Context {
 | 
			
		||||
		module: comment.module,
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	crate::reformat::GfmQuoteBlocks::reformat(&reformat_ctx, &mut str);
 | 
			
		||||
	crate::reformat::TypeLinks::reformat(&reformat_ctx, &mut str);
 | 
			
		||||
 | 
			
		||||
	str
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										127
									
								
								typegen/src/reformat.rs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										127
									
								
								typegen/src/reformat.rs
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,127 @@
 | 
			
		|||
use std::borrow::Cow;
 | 
			
		||||
 | 
			
		||||
pub struct Context<'a> {
 | 
			
		||||
	pub module: &'a str,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub trait ReformatPass {
 | 
			
		||||
	fn reformat(context: &Context, text: &mut String);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub struct GfmQuoteBlocks;
 | 
			
		||||
 | 
			
		||||
impl ReformatPass for GfmQuoteBlocks {
 | 
			
		||||
	fn reformat(_: &Context, text: &mut String) {
 | 
			
		||||
		*text = text.replace("> [!INFO]", "> [!NOTE]");
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub struct TypeLinks;
 | 
			
		||||
 | 
			
		||||
impl ReformatPass for TypeLinks {
 | 
			
		||||
	fn reformat(context: &Context, text: &mut String) {
 | 
			
		||||
		let lines = text.lines().map(|line| {
 | 
			
		||||
			if line.contains("@@") {
 | 
			
		||||
				let mut src: &str = &*line;
 | 
			
		||||
				let mut accum = String::new();
 | 
			
		||||
 | 
			
		||||
				while let Some(i) = src.find("@@") {
 | 
			
		||||
					accum += &src[..i];
 | 
			
		||||
					src = &src[i + 2..];
 | 
			
		||||
 | 
			
		||||
					let separators = [
 | 
			
		||||
						('$', true),
 | 
			
		||||
						(' ', false),
 | 
			
		||||
						(',', false),
 | 
			
		||||
						(';', false),
 | 
			
		||||
						(':', false),
 | 
			
		||||
					];
 | 
			
		||||
 | 
			
		||||
					let (mut end, mut ty) = src
 | 
			
		||||
						.chars()
 | 
			
		||||
						.enumerate()
 | 
			
		||||
						.find_map(|(i, char)| {
 | 
			
		||||
							separators
 | 
			
		||||
								.iter()
 | 
			
		||||
								.find(|(sc, _)| char == *sc)
 | 
			
		||||
								.map(|(_, strip)| (i + if *strip { 1 } else { 0 }, &src[..i]))
 | 
			
		||||
						})
 | 
			
		||||
						.unwrap_or_else(|| (src.len(), src));
 | 
			
		||||
 | 
			
		||||
					// special case for . as it is contained in valid types as well
 | 
			
		||||
					if ty.ends_with('.') {
 | 
			
		||||
						end -= 1;
 | 
			
		||||
						ty = &ty[..ty.len() - 1];
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
					let (ty, member) = match ty.chars().next() {
 | 
			
		||||
						None => (None, None),
 | 
			
		||||
						Some(c) if c.is_lowercase() => (None, Some(ty)),
 | 
			
		||||
						Some(_) => {
 | 
			
		||||
							let mut split = ty.rsplit_once('.').unwrap_or(("", ty));
 | 
			
		||||
 | 
			
		||||
							let member = split
 | 
			
		||||
								.1
 | 
			
		||||
								.chars()
 | 
			
		||||
								.next()
 | 
			
		||||
								.unwrap()
 | 
			
		||||
								.is_lowercase()
 | 
			
		||||
								.then(|| {
 | 
			
		||||
									let prop = split.1;
 | 
			
		||||
									split = split.0.rsplit_once('.').unwrap_or(("", split.0));
 | 
			
		||||
									prop
 | 
			
		||||
								})
 | 
			
		||||
								.unwrap_or("");
 | 
			
		||||
 | 
			
		||||
							let (mut module, name) = split;
 | 
			
		||||
 | 
			
		||||
							if module.is_empty() {
 | 
			
		||||
								module = context.module;
 | 
			
		||||
							}
 | 
			
		||||
 | 
			
		||||
							(Some((module, name)), Some(member))
 | 
			
		||||
						},
 | 
			
		||||
					};
 | 
			
		||||
 | 
			
		||||
					let (membertype, membername) = match member {
 | 
			
		||||
						None => ("", ""),
 | 
			
		||||
						Some(name) if name.ends_with("()") => ("func", &name[..name.len() - 2]),
 | 
			
		||||
						Some(name) if name.ends_with("(s)") => ("signal", &name[..name.len() - 3]),
 | 
			
		||||
						Some(name) if name.is_empty() => ("", ""),
 | 
			
		||||
						Some(name) => ("prop", name),
 | 
			
		||||
					};
 | 
			
		||||
 | 
			
		||||
					accum += "TYPE";
 | 
			
		||||
 | 
			
		||||
					if let Some((module, name)) = ty {
 | 
			
		||||
						if module.starts_with("Quickshell") {
 | 
			
		||||
							accum += "99MQS";
 | 
			
		||||
						} else {
 | 
			
		||||
							accum += "99MQT_qml";
 | 
			
		||||
						}
 | 
			
		||||
 | 
			
		||||
						accum = module
 | 
			
		||||
							.split('.')
 | 
			
		||||
							.fold(accum, |accum, next| accum + "_" + next)
 | 
			
		||||
							+ "99N" + name;
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
					if !membername.is_empty() {
 | 
			
		||||
						accum += &format!("99V{membername}99T{membertype}");
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
					accum += "99TYPE";
 | 
			
		||||
					src = &src[end..];
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				accum += src;
 | 
			
		||||
 | 
			
		||||
				return Cow::Owned(accum);
 | 
			
		||||
			} else {
 | 
			
		||||
				return Cow::Borrowed(line);
 | 
			
		||||
			}
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		*text = lines.fold(String::new(), |accum, line| accum + line.as_ref() + "\n");
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue