From 03466aad8079174d2682abc5e056938ab6d30cd7 Mon Sep 17 00:00:00 2001 From: aitzol Date: Sat, 16 Aug 2025 17:21:22 +0200 Subject: [PATCH] v0.1.3 --- 7 | 297 -------------------------------------------------------------- 1 file changed, 297 deletions(-) delete mode 100644 7 diff --git a/7 b/7 deleted file mode 100644 index 12d13da..0000000 --- a/7 +++ /dev/null @@ -1,297 +0,0 @@ -use std::io; -use std::fs; -use std::path::Path; -use std::env; -use walkdir::WalkDir; -use std::process::Command; -use std::ffi::OsStr; -use colorize::AnsiColor; -use dirs; -use pandoc::PandocError; -use dokugile::template; -use rust_i18n::t; -use include_dir::{include_dir, Dir}; - -rust_i18n::i18n!("locales"); - -struct Project { - wiki_path: String, - doc_path: String, - doc_title: String, - output_dir: String, -} - -impl Project { - fn new(wiki_path: String, doc_path: String, doc_title:String, output_dir: String) -> Project { - Project { - wiki_path, - doc_path, - doc_title, - output_dir, - } - } -} - -fn main() { - const NAME: &str = env!("CARGO_PKG_NAME"); - const VERSION: &str = env!("CARGO_PKG_VERSION"); - const REPO: &str = env!("CARGO_PKG_REPOSITORY"); - println!("{} {}\n{}\n",NAME.b_magenta(), VERSION.b_magenta(), REPO.b_blue()); - - static ASSETS_DIR: Dir<'_> = include_dir!("$CARGO_MANIFEST_DIR/assets"); - let _ = set_lang(); - let mut wiki_path = String::new(); - let mut doc_path = String::new(); - let mut doc_title = String::new(); - let mut output_dir = String::new(); - let mut attempts: i8 = 0; - - while !Path::new(&doc_path).exists() || doc_title.trim().is_empty(){ - doc_path = String::new(); - let mut input = String::new(); - println!("{}:", t!("Project name")); - io::stdin().read_line(&mut input).expect(&t!("Failed to read line")); - let root = env::var("HOME").unwrap().to_string()+"/"; - let user_documents_path = dirs::document_dir().unwrap().display().to_string(); - let user_doc_dir = user_documents_path.split("/").collect::>().last().unwrap().to_string(); - - while !Path::new(&wiki_path).exists() { - let mut project_dir = String::new(); - println!("{}:[{}/Wiki] ", t!("Project location"), &user_doc_dir); - io::stdin().read_line(&mut project_dir).expect(&t!("Failed to read line")); - if project_dir.trim().is_empty() { project_dir = String::from(user_doc_dir.clone()+"/Wiki") }; - wiki_path = root.clone()+project_dir.trim(); - - if !Path::new(&wiki_path).exists(){ - let mut ans = String::new(); - println!("{}", t!("Do you want to create a new location called %{s} for the documents?(y/n)[Y]", s = &project_dir.trim().to_owned().green().bold())); - io::stdin().read_line(&mut ans).expect("Failed to read line"); - if ans.trim().is_empty() { ans = String::from("Y") }; - match ans.trim() { - "y" | "yes" | "Y" | "B" | "Bai" => { //let _ = fs::create_dir(&wiki_path); - let _ = mkdir(&wiki_path); - println!("{}.", t!("Location %{s} has been created", s = &project_dir.trim().to_owned().green().bold())); - }, - _ => continue, - }; - } - } - - if input.trim().is_empty(){ - attempts += 1; - } - if attempts == 3 { - //break - let cwd = env::current_dir().unwrap().display().to_string(); - let dir_name: Vec<&str> = cwd.split('/').collect(); - if input.trim().is_empty() { input = String::from(dir_name.clone()) }; - }; - - doc_title = input.to_string(); - output_dir = input.trim_end().to_owned()+"_html"; - doc_path.push_str(&wiki_path); - doc_path.push_str("/"); - doc_path.push_str(&doc_title.trim_end()); - //doc_path.push_str(&capitalize_first_letter(&doc_title.trim_end())); - let res_path = wiki_path.clone()+"/res"; - if !Path::new(&doc_path).exists() || !Path::new(&res_path).exists(){ - // extract assets to temporary directory - let _ = ASSETS_DIR.extract("/tmp/assets"); - let mut ans = String::new(); - if !Path::new(&doc_path).exists() { - println!("{}", t!("The project %{s} has not been found. Do you want to create it?(y/n)[Y]", s = &input.trim().to_owned().green().bold())); - io::stdin().read_line(&mut ans).expect(&t!("Failed to read line")); - } - if ans.trim().is_empty() { ans = String::from("Y") }; - match ans.trim() { - "y" | "yes" | "Y" | "B" | "Bai" => { - let _ = mkdir(&doc_path); - // create resources - for entry in WalkDir::new("/tmp/assets").into_iter().filter_map(|e| e.ok()) { - let input_entry = String::from(entry.path().strip_prefix("/tmp/assets").expect(&t!("Path not found")).display().to_string()); - let subdirs = wiki_path.to_string()+"/"+&input_entry; - let images = wiki_path.to_string()+"/"+&doc_title.trim()+"/"+&input_entry; - - if entry.path().is_dir(){ - match Path::new(&input_entry).to_str() { - Some("images") => { //create images directory - let _ = mkdir(&images); - }, - Some(..) => { //create resources and its subdirectories - let _ = mkdir(&subdirs); - }, - _ => continue - }; - }else if entry.path().is_file(){ - let source = String::from(entry.path().display().to_string()); - match Path::new(&input_entry).to_str() { - Some(d) if d.contains("images/")=>{ //copy sample-image to images folder - let _ = copy(&source, &images); - }, - Some(..) => { //copy files from all other directories - let _ = copy(&source, &subdirs); - }, - _ => continue - }; - } - } - println!("{}.", t!("Project %{s} has been created. Now you can edit index.md file and create content", s = &input.trim().to_owned().green().bold())); - //remove temporary created assets directory - let _ = fs::remove_dir_all(Path::new("/tmp/assets")); - }, - _ => continue, - }; - } - - let index = doc_path.to_string()+"/index.md"; - if !Path::new(&index).exists(){ - let _ = touch(&index, &template()); - }; - } - - let res = processing(Project::new(wiki_path.clone(), doc_path.clone(), doc_title, output_dir)); - match res { - Err(e) => println!("{}", t!("The operation failed with error %{s}", s = e)), - Ok(e) => println!("{}", e) - }; -} - -fn mkdir(dir: &String) -> std::io::Result<()>{ - let _ = fs::create_dir(dir)?; - Ok(()) -} - -fn touch(file: &String, content: &String) -> std::io::Result<()>{ - fs::write(file, content)?; - Ok(()) -} - -fn copy(source: &String, dest: &String) -> std::io::Result<()> { - fs::copy(source, dest)?; - Ok(()) -} -/* -fn capitalize_first_letter(s: &str) -> String { - s[0..1].to_uppercase() + &s[1..] -} -*/ - -fn processing(project: Project) -> Result{ - let mut md_count :i32 = 0; - let mut error = String::new(); - for entry in WalkDir::new(&project.doc_path).into_iter().filter_map(|e| e.ok()) { - if entry.path().is_dir(){ - let input_entry = String::from(entry.path().display().to_string()); - let doc_title: String = "/".to_string()+&project.doc_title.trim_end(); - let output_dir: String = "/".to_string()+ &project.output_dir.trim_end(); - //replace project-directory to project-directory_html(e.g. "Test" to "Test_html") - let new_entry = input_entry.replace(&doc_title, &output_dir); - //create output _html directory and subdirectories except images dir - match &entry.path().file_name() { - Some(p) if *p != "images"=> { - let _ = mkdir(&new_entry); - }, - _ => continue, - }; - }else if entry.path().is_file(){ - if let Some(extension) = entry.path().extension().and_then(OsStr::to_str) { - //filter md files - match extension { - "md" => { - //md_count += 1; - println!("{}", t!("found... %{s}", s = entry.path().display())); - let conv = md_to_html(entry.path(), &project.doc_title, &project.output_dir, &project.wiki_path); - match conv { - Ok(()) => md_count += 1, - Err(e) => { //println!("{}", e); - error = e.to_string(); - break; - }, - }; - }, - _ => (), - }; - }; - }; - }; - - if error.is_empty() { - if md_count == 0 { - println!("{}", t!("No markdown files found!")); - println!("{}", t!("Pleade edit first your documents in markdown format and come back to convert them to html. Bye!")); - }else{ - println!("{}", t!("Processed markdown files.. %{s}", s = md_count)); - } - let mut index = project.wiki_path.to_owned()+"/"+&project.output_dir.trim_end(); - index.push_str("/index.html"); - sanitize(Path::new(&index)); - //Ok("Success") - let link = String::from("file://".to_owned()+&index).b_blue(); - let message:String = String::from(t!("Congrats! Check your documentation at.. %{s}", s = &link)); - Ok(message) - }else{ - //Err(std::stringify!(error)) - Err(error) - } -} - -fn md_to_html(input_file: &Path, doc_title: &String, output_dir: &String, wiki_path: &String) -> Result<(), PandocError>{ - let page_title: String = "pagetitle=".to_string()+*&doc_title.trim_end(); - let doc_title: String = "/".to_string()+*&doc_title.trim_end(); - let output_dir: String = "/".to_string()+ *&output_dir.trim_end(); - let output_file = input_file.display().to_string().replace(&doc_title, &output_dir).replace(".md", ".html"); - let base_path = wiki_path.to_owned()+&doc_title; - let res_path = wiki_path.to_owned()+&"/res:".to_string(); - let mut pandoc = pandoc::new(); - pandoc.add_input(&input_file); - pandoc.arg("resource-path", &res_path); //for css and javascript resources - pandoc.arg("resource-path", &base_path); //for image search - pandoc.arg("include-after-body", "buttons.html"); - pandoc.arg("css", "css/theme.css"); - pandoc.arg("css", "css/sidebar.css"); - pandoc.arg("css", "css/buttons.css"); - pandoc.arg("embed-resources", "true"); - pandoc.arg("standalone", "true"); - pandoc.arg("shift-heading-level-by", "-1"); - pandoc.set_number_sections(); - pandoc.set_toc(); - pandoc.arg("toc-depth", "4"); - pandoc.arg("metadata", &page_title); - pandoc.set_output(pandoc::OutputKind::File(output_file.into())); - //pandoc.execute().unwrap(); - - match pandoc.execute() { - Ok(..) => Ok(()), - Err(PandocError::PandocNotFound) => Err(PandocError::PandocNotFound), - Err(PandocError::IoErr(e)) => Err(PandocError::IoErr(e)), - Err(PandocError::Err(e)) => Err(PandocError::Err(e)), - Err(PandocError::NoInputSpecified) => Err(PandocError::NoInputSpecified), - Err(PandocError::BadUtf8Conversion(e)) => Err(PandocError::BadUtf8Conversion(e)), - Err(PandocError::NoOutputSpecified) => Err(PandocError::NoOutputSpecified) - } -} - -fn sanitize(index: &Path){ - if index.exists(){ - //convert page links from ".md" to ".html" in the index.html file - Command::new("sed") - .args(["-i", r"-e s/\.md/\.html/g", &index.display().to_string()]) - .status() - .expect(&t!("sed command failed start")); - }else{ - println!("{}", t!("Please consider renaming your main page to index.md and restart the document conversion again. See you later!")); - }; -} - -fn set_lang(){ - let default = String::from("en_US"); // default locale - let locales = rust_i18n::available_locales!(); // available locales - let lang:String = match env::var("LANG") { // find out user's lang - Ok(val) => match val { - v if !v.is_empty() && locales.iter().any(|e| v.contains(e)) => v[..5].to_string(), - _ => default - } , - Err(..) => default, - }; - rust_i18n::set_locale(&lang); // set user lang -}