From d4653d544683c3a9e90e5263ffacfdc6f08f8f80 Mon Sep 17 00:00:00 2001 From: sagi Date: Tue, 16 Jun 2026 20:12:42 +0300 Subject: [PATCH 01/11] Add expiramental repository card for the main repo should add also for the book --- LearnixOS | 2 +- mdbook-rust-analyzer-highlight | 2 +- src/Introduction.md | 48 ++++++++++++++++++++++++++++++++++ 3 files changed, 50 insertions(+), 2 deletions(-) diff --git a/LearnixOS b/LearnixOS index 2aa1118..5f65b1a 160000 --- a/LearnixOS +++ b/LearnixOS @@ -1 +1 @@ -Subproject commit 2aa11188faeefd13c777ec48432e8a71878b3826 +Subproject commit 5f65b1aceee11a23aa29baac2adb9ba16bcd95cd diff --git a/mdbook-rust-analyzer-highlight b/mdbook-rust-analyzer-highlight index e535f10..5ea49f9 160000 --- a/mdbook-rust-analyzer-highlight +++ b/mdbook-rust-analyzer-highlight @@ -1 +1 @@ -Subproject commit e535f10d4e1f17f1464db0c33f4ad03bbf8893be +Subproject commit 5ea49f95702eca8deee9a9e4f9915a1c1237f294 diff --git a/src/Introduction.md b/src/Introduction.md index d3cf391..83ecc1d 100644 --- a/src/Introduction.md +++ b/src/Introduction.md @@ -62,3 +62,51 @@ As a last note, I hope you will invest your precious time in reading this book, [^2]: Software that includes many parts that are not needed and unwanted. [^3]: [CISA Report](https://www.cisa.gov/resources-tools/resources/product-security-bad-practices) [^4]: [White House Report](https://bidenwhitehouse.archives.gov/wp-content/uploads/2024/02/Final-ONCD-Technical-Report.pdf) + +
+ +
+

Connecting to GitHub API...

+
+ +
From e17134891ca58b0e4360b844abec9fbf558863e2 Mon Sep 17 00:00:00 2001 From: sagi Date: Tue, 16 Jun 2026 20:12:52 +0300 Subject: [PATCH 02/11] Add css and js --- theme/github-box.css | 143 +++++++++++++++++++++++++++++++++++++++++++ theme/github-card.js | 79 ++++++++++++++++++++++++ 2 files changed, 222 insertions(+) create mode 100644 theme/github-box.css create mode 100644 theme/github-card.js diff --git a/theme/github-box.css b/theme/github-box.css new file mode 100644 index 0000000..f60878f --- /dev/null +++ b/theme/github-box.css @@ -0,0 +1,143 @@ +/* src/custom-github.css */ +.github-repo-box { + /* Default Light Mode Colors */ + --gh-bg: #ffffff; + --gh-border: #d0d7de; + --gh-text: #24292f; + --gh-link: #0969da; + --gh-muted: #57606a; + --gh-btn-bg: #f6f8fa; + --gh-btn-border: rgba(27, 31, 36, 0.15); + --gh-btn-hover: #f3f4f6; + + font-family: + -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, + sans-serif; + border: 1px solid var(--gh-border); + border-top: 4px solid var(--gh-link); /* Nice top accent line */ + border-radius: 8px; + padding: 24px; + max-width: 800px; /* Made much wider */ + width: 100%; + background-color: var(--gh-bg); + color: var(--gh-text); + margin: 2em 0; + box-sizing: border-box; + box-shadow: 0 3px 6px rgba(140, 149, 159, 0.15); +} + +/* mdBook Dark Mode Overrides */ +html.coal .github-repo-box, +html.navy .github-repo-box, +html.ayu .github-repo-box { + --gh-bg: #0d1117; + --gh-border: #30363d; + --gh-text: #c9d1d9; + --gh-link: #58a6ff; + --gh-muted: #8b949e; + --gh-btn-bg: #21262d; + --gh-btn-border: rgba(240, 246, 252, 0.1); + --gh-btn-hover: #30363d; + box-shadow: 0 3px 6px rgba(0, 0, 0, 0.5); +} + +/* Header: Title and Buttons */ +.github-repo-box .repo-header { + display: flex; + justify-content: space-between; + align-items: flex-start; + flex-wrap: wrap; + gap: 16px; + margin-bottom: 12px; +} + +.github-repo-box .repo-title-group { + display: flex; + align-items: center; + gap: 8px; + font-size: 18px; + font-weight: 600; + color: var(--gh-muted); +} + +.github-repo-box .repo-title-group a { + color: var(--gh-link) !important; + text-decoration: none; + word-break: break-all; +} + +.github-repo-box .repo-title-group a:hover { + text-decoration: underline; +} + +.github-repo-box .repo-actions { + display: flex; + gap: 8px; +} + +.github-repo-box .github-btn { + display: inline-flex; + align-items: center; + gap: 6px; + padding: 5px 12px; + font-size: 12px; + font-weight: 600; + line-height: 20px; + color: var(--gh-text) !important; + background-color: var(--gh-btn-bg); + border: 1px solid var(--gh-btn-border); + border-radius: 6px; + text-decoration: none; + cursor: pointer; + transition: background-color 0.2s; +} + +.github-repo-box .github-btn:hover { + background-color: var(--gh-btn-hover); + text-decoration: none; +} + +/* Body: Description */ +.github-repo-box .repo-description { + font-size: 15px; + color: var(--gh-muted); + margin: 0 0 20px 0; + line-height: 1.5; +} + +/* Footer: Stats Grid */ +.github-repo-box .repo-footer { + display: flex; + align-items: center; + flex-wrap: wrap; + gap: 24px; +} + +.github-repo-box .stat-item { + display: flex; + align-items: center; + gap: 6px; + font-size: 13px; + color: var(--gh-muted) !important; + text-decoration: none; + transition: color 0.2s; +} + +a.stat-item:hover { + color: var(--gh-link) !important; + text-decoration: none; +} + +.github-repo-box .icon { + display: inline-block; + overflow: visible !important; + vertical-align: text-bottom; +} + +.language-color { + width: 12px; + height: 12px; + border-radius: 50%; + background-color: var(--gh-muted); + display: inline-block; +} diff --git a/theme/github-card.js b/theme/github-card.js new file mode 100644 index 0000000..8d06e85 --- /dev/null +++ b/theme/github-card.js @@ -0,0 +1,79 @@ +document.querySelectorAll(".github-repo-box").forEach((box) => { + const repoPath = box.getAttribute("data-repo"); + if (!repoPath) return; + + // Fetch 1: Standard Repo Data + fetch(`https://api.github.com/repos/${repoPath}`) + .then((res) => res.json()) + .then((data) => { + box.querySelector(".repo-title-text").textContent = data.full_name; + box.querySelector(".repo-description").textContent = + data.description || "No description provided."; + box.querySelector(".repo-stars-count").textContent = + data.stargazers_count.toLocaleString(); + box.querySelector(".repo-forks-count").textContent = + data.forks_count.toLocaleString(); + box.querySelector(".repo-issues-count").textContent = + data.open_issues_count.toLocaleString(); + + if (data.language) { + box.querySelector(".repo-language-text").textContent = data.language; + box.querySelector(".repo-language").style.display = "flex"; + + const langColors = { + Rust: "#dea584", + "C++": "#f34b7d", + C: "#555555", + JavaScript: "#f1e05a", + Python: "#3572A5", + }; + if (langColors[data.language]) { + box.querySelector(".language-color").style.backgroundColor = + langColors[data.language]; + } + } + + const owner = repoPath.split("/")[0]; + box.querySelector(".repo-title-link").href = data.html_url; + box.querySelector(".btn-star").href = data.html_url; + box.querySelector(".btn-sponsor").href = + `https://github.com/sponsors/${owner}`; + box.querySelector(".link-stars").href = `${data.html_url}/stargazers`; + box.querySelector(".link-forks").href = + `${data.html_url}/network/members`; + box.querySelector(".link-commits").href = `${data.html_url}/commits/main`; + box.querySelector(".link-issues").href = `${data.html_url}/issues`; + }) + .catch((err) => { + box.querySelector(".repo-description").textContent = + "Failed to load repository data."; + console.error(err); + }); + + // Fetch 2: The Commits Trick + fetch(`https://api.github.com/repos/${repoPath}/commits?per_page=1`) + .then((res) => { + // If repo is completely empty, it might throw a 409 + if (!res.ok) throw new Error("Commits fetch failed"); + + const link = res.headers.get("link"); + if (link) { + // Extract the last page number from the header + const match = link.match(/page=(\d+)>; rel="last"/); + if (match) { + box.querySelector(".repo-commits-count").textContent = parseInt( + match[1], + ).toLocaleString(); + } + } else { + // If there is no pagination header, there's exactly 1 commit (or 0) + res.json().then((commits) => { + box.querySelector(".repo-commits-count").textContent = + commits.length.toString(); + }); + } + }) + .catch((err) => { + box.querySelector(".repo-commits-count").textContent = "0"; + }); +}); From f3568452c5cc477d3e43a0459452fe90f371b59b Mon Sep 17 00:00:00 2001 From: sagi Date: Thu, 18 Jun 2026 08:29:57 +0300 Subject: [PATCH 03/11] Add mdbook github repository card preprocessor --- book.toml | 16 ++- mdbook-repository-card/Cargo.toml | 11 ++ mdbook-repository-card/rustfmt.toml | 4 + mdbook-repository-card/src/main.rs | 152 ++++++++++++++++++++++++++++ 4 files changed, 181 insertions(+), 2 deletions(-) create mode 100644 mdbook-repository-card/Cargo.toml create mode 100644 mdbook-repository-card/rustfmt.toml create mode 100644 mdbook-repository-card/src/main.rs diff --git a/book.toml b/book.toml index 51a7e1b..d17bac7 100644 --- a/book.toml +++ b/book.toml @@ -14,18 +14,30 @@ inlay-hint-config = "inlay_config.json" after = ["mdbook-rust-analyzer-highlight"] command = "cargo run --release --manifest-path mdbook-gh-issue-preview/Cargo.toml" +[preprocessor.github-repository-card] +after = ["gh-issue-preview"] +command = "cargo run --release --manifest-path mdbook-repository-card/Cargo.toml" +username = "sagi21805" +repository = "LearnixOS" [output.html] git-repository-url = "https://github.com/sagi21805/LearnixOS" default-theme = "navy" preferred-dark-theme = "navy" -additional-css = ["theme/whichlang.css", "theme/hlrs.css", "theme/gh-issue.css", "theme/tags.css"] +additional-css = [ + "theme/whichlang.css", + "theme/hlrs.css", + "theme/gh-issue.css", + "theme/tags.css", + "theme/github-box.css", +] additional-js = [ "theme/whichlang.js", "theme/filepath-links.js", "theme/giscuss.js", "theme/tags.js", - "theme/highlight.js" + "theme/highlight.js", + "theme/github-card.js", ] mathjax-support = true diff --git a/mdbook-repository-card/Cargo.toml b/mdbook-repository-card/Cargo.toml new file mode 100644 index 0000000..c91a0ed --- /dev/null +++ b/mdbook-repository-card/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "mdbook-repository-card" +version = "0.1.0" +edition = "2024" + +[dependencies] +mdbook-preprocessor = "0.5.3" +regex = "1.12.2" +serde = "1.0.228" +serde_json = "1.0.148" +toml = "0.5.11" diff --git a/mdbook-repository-card/rustfmt.toml b/mdbook-repository-card/rustfmt.toml new file mode 100644 index 0000000..5facbea --- /dev/null +++ b/mdbook-repository-card/rustfmt.toml @@ -0,0 +1,4 @@ +max_width = 65 +comment_width = 65 +wrap_comments = true +format_strings = false diff --git a/mdbook-repository-card/src/main.rs b/mdbook-repository-card/src/main.rs new file mode 100644 index 0000000..98d2fc0 --- /dev/null +++ b/mdbook-repository-card/src/main.rs @@ -0,0 +1,152 @@ +use std::{io, process}; + +use mdbook_preprocessor::{ + Preprocessor, PreprocessorContext, book::Book, errors::Error, +}; +use regex::Regex; +use toml::value::Table; + +pub struct GithubRepositoryCard; + +static HTML: &str = r##" +
+ +
+

Connecting to GitHub API...

+
+ +
+"##; + +impl Preprocessor for GithubRepositoryCard { + fn name(&self) -> &str { + "github-repository-card" + } + + fn run( + &self, + ctx: &PreprocessorContext, + mut book: Book, + ) -> Result { + let conf_raw = ctx.config.get::(&format!( + "preprocessor.{}", + self.name() + ))?; + + let mut username = ""; + let mut repository = ""; + + if let Some(conf) = &conf_raw { + username = conf + .get("username") + .and_then(|v| v.as_str()) + .unwrap_or_default(); + repository = conf + .get("repository") + .and_then(|v| v.as_str()) + .unwrap_or_default(); + } + + if username.is_empty() || repository.is_empty() { + eprintln!( + "[ERROR]: Configuration for username or repository is missing. Please specify both in the preprocessor configuration under `username` and `repository`." + ); + return Ok(book); + } + + let re = Regex::new(r"---").unwrap(); + + let html = HTML + .replace("{username}", username) + .replace("{repository}", repository); + + book.for_each_mut(|item| { + if let mdbook_preprocessor::book::BookItem::Chapter( + chapter, + ) = item + { + chapter.content = re + .replace_all( + &chapter.content, + |_caps: ®ex::Captures| { + format!("---\n\n{}\n\n", html) + }, + ) + .to_string(); + } + }); + + Ok(book) + } +} + +fn main() { + let preprocessor = GithubRepositoryCard; + + if std::env::args().len() > 1 { + if std::env::args().nth(1).unwrap() == "supports" { + process::exit(0); + } + } + + if let Err(e) = handle_preprocessing(&preprocessor) { + eprintln!("{}", e); + process::exit(1); + } +} + +fn handle_preprocessing( + pre: &impl Preprocessor, +) -> Result<(), mdbook_preprocessor::errors::Error> { + let (ctx, book) = + mdbook_preprocessor::parse_input(io::stdin())?; + let processed_book = pre.run(&ctx, book)?; + serde_json::to_writer(io::stdout(), &processed_book)?; + Ok(()) +} From 50212a54385fef7bf6c14006e30219b91eee21a2 Mon Sep 17 00:00:00 2001 From: sagi Date: Thu, 18 Jun 2026 08:30:17 +0300 Subject: [PATCH 04/11] Add card and quote for every chapter --- src/Introduction.md | 48 ------------------- ...3-implementing-the-bitfields-proc-macro.md | 4 ++ 2 files changed, 4 insertions(+), 48 deletions(-) diff --git a/src/Introduction.md b/src/Introduction.md index 83ecc1d..d3cf391 100644 --- a/src/Introduction.md +++ b/src/Introduction.md @@ -62,51 +62,3 @@ As a last note, I hope you will invest your precious time in reading this book, [^2]: Software that includes many parts that are not needed and unwanted. [^3]: [CISA Report](https://www.cisa.gov/resources-tools/resources/product-security-bad-practices) [^4]: [White House Report](https://bidenwhitehouse.archives.gov/wp-content/uploads/2024/02/Final-ONCD-Technical-Report.pdf) - -
- -
-

Connecting to GitHub API...

-
- -
diff --git a/src/ch02-03-implementing-the-bitfields-proc-macro.md b/src/ch02-03-implementing-the-bitfields-proc-macro.md index 83c9112..d9cc7e6 100644 --- a/src/ch02-03-implementing-the-bitfields-proc-macro.md +++ b/src/ch02-03-implementing-the-bitfields-proc-macro.md @@ -1,5 +1,9 @@ # Writing the Bitflags Macro +_"In Lisp, you don't just write your program down toward the language, you also build the language up toward your program." - Paul Graham_ + +--- + As you may recall from the previous chapter, we used a proc-macro that was called `bitfields`. In this chapter, we are going to learn about Rust's procedural macros and even implement one ourselves. > Another great resource for this subject is the great video [Comprehending Proc Macros](https://youtu.be/SMCRQj9Hbx8?si=p-JUX0rLronBG_Nz) by Logan Smith From 5587003c59ce81e57c32e246eda2a90781ea6a99 Mon Sep 17 00:00:00 2001 From: sagi Date: Thu, 18 Jun 2026 08:39:07 +0300 Subject: [PATCH 05/11] Update submodules commits. --- LearnixOS | 2 +- mdbook-rust-analyzer-highlight | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/LearnixOS b/LearnixOS index 5f65b1a..3609866 160000 --- a/LearnixOS +++ b/LearnixOS @@ -1 +1 @@ -Subproject commit 5f65b1aceee11a23aa29baac2adb9ba16bcd95cd +Subproject commit 3609866209360021de3b841b23c191859484c052 diff --git a/mdbook-rust-analyzer-highlight b/mdbook-rust-analyzer-highlight index 5ea49f9..e535f10 160000 --- a/mdbook-rust-analyzer-highlight +++ b/mdbook-rust-analyzer-highlight @@ -1 +1 @@ -Subproject commit 5ea49f95702eca8deee9a9e4f9915a1c1237f294 +Subproject commit e535f10d4e1f17f1464db0c33f4ad03bbf8893be From 9d123f08f9d3aa583538015c890b58ca7c103527 Mon Sep 17 00:00:00 2001 From: sagi Date: Thu, 18 Jun 2026 08:40:48 +0300 Subject: [PATCH 06/11] Update submodule commit --- mdbook-gh-issue-preview | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mdbook-gh-issue-preview b/mdbook-gh-issue-preview index aefede6..1438276 160000 --- a/mdbook-gh-issue-preview +++ b/mdbook-gh-issue-preview @@ -1 +1 @@ -Subproject commit aefede6bcbf00415445992bd9876d383a096e1be +Subproject commit 1438276d76c62d819ed1bfc9e487dc4351c25530 From 23a67f732bca8ae2585bfb32a8a0ec638e373d1f Mon Sep 17 00:00:00 2001 From: sagi Date: Thu, 18 Jun 2026 11:01:58 +0300 Subject: [PATCH 07/11] Add support for patreon button --- book.toml | 1 + mdbook-repository-card/src/main.rs | 27 +++++++++++++++++++++++++-- theme/github-box.css | 19 +++++++++++++++---- 3 files changed, 41 insertions(+), 6 deletions(-) diff --git a/book.toml b/book.toml index d17bac7..db1b170 100644 --- a/book.toml +++ b/book.toml @@ -19,6 +19,7 @@ after = ["gh-issue-preview"] command = "cargo run --release --manifest-path mdbook-repository-card/Cargo.toml" username = "sagi21805" repository = "LearnixOS" +patreon_url = "https://patreon.com/LearnixOS?utm_medium=unknown&utm_source=join_link&utm_campaign=creatorshare_creator&utm_content=copyLink" [output.html] git-repository-url = "https://github.com/sagi21805/LearnixOS" diff --git a/mdbook-repository-card/src/main.rs b/mdbook-repository-card/src/main.rs index 98d2fc0..518d21f 100644 --- a/mdbook-repository-card/src/main.rs +++ b/mdbook-repository-card/src/main.rs @@ -20,7 +20,7 @@ static HTML: &str = r##"
- + {patreon} Sponsor @@ -64,6 +64,16 @@ static HTML: &str = r##"
"##; +static PATREON: &str = r##" + + + Patreon + +"##; + impl Preprocessor for GithubRepositoryCard { fn name(&self) -> &str { "github-repository-card" @@ -81,6 +91,7 @@ impl Preprocessor for GithubRepositoryCard { let mut username = ""; let mut repository = ""; + let mut patreon_url = ""; if let Some(conf) = &conf_raw { username = conf @@ -91,6 +102,10 @@ impl Preprocessor for GithubRepositoryCard { .get("repository") .and_then(|v| v.as_str()) .unwrap_or_default(); + patreon_url = conf + .get("patreon_url") + .and_then(|v| v.as_str()) + .unwrap_or_default(); } if username.is_empty() || repository.is_empty() { @@ -100,11 +115,19 @@ impl Preprocessor for GithubRepositoryCard { return Ok(book); } + let patreon = if !patreon_url.is_empty() { + PATREON.replace("{patreon_url}", &patreon_url) + } else { + eprintln!("[INFO]: Patreon url was not specified."); + String::from("") + }; + let re = Regex::new(r"---").unwrap(); let html = HTML .replace("{username}", username) - .replace("{repository}", repository); + .replace("{repository}", repository) + .replace("{patreon}", &patreon); book.for_each_mut(|item| { if let mdbook_preprocessor::book::BookItem::Chapter( diff --git a/theme/github-box.css b/theme/github-box.css index f60878f..38c55f4 100644 --- a/theme/github-box.css +++ b/theme/github-box.css @@ -1,6 +1,4 @@ -/* src/custom-github.css */ .github-repo-box { - /* Default Light Mode Colors */ --gh-bg: #ffffff; --gh-border: #d0d7de; --gh-text: #24292f; @@ -26,7 +24,6 @@ box-shadow: 0 3px 6px rgba(140, 149, 159, 0.15); } -/* mdBook Dark Mode Overrides */ html.coal .github-repo-box, html.navy .github-repo-box, html.ayu .github-repo-box { @@ -41,7 +38,6 @@ html.ayu .github-repo-box { box-shadow: 0 3px 6px rgba(0, 0, 0, 0.5); } -/* Header: Title and Buttons */ .github-repo-box .repo-header { display: flex; justify-content: space-between; @@ -58,6 +54,8 @@ html.ayu .github-repo-box { font-size: 18px; font-weight: 600; color: var(--gh-muted); + flex: 1 1 45%; + min-width: 250px; } .github-repo-box .repo-title-group a { @@ -72,7 +70,16 @@ html.ayu .github-repo-box { .github-repo-box .repo-actions { display: flex; + flex-wrap: wrap; + grid-template-columns: repeat(auto-fit, minmax(100px, 1fr)); gap: 8px; + flex: 1 1 45%; + min-width: 250px; +} + +.github-repo-box .github-btn { + flex: 1 1 90px; + justify-content: center; } .github-repo-box .github-btn { @@ -141,3 +148,7 @@ a.stat-item:hover { background-color: var(--gh-muted); display: inline-block; } + +.github-repo-box .btn-patreon svg { + fill: #ff424d; +} From 47545a0a78ad5a56f0c9795c7b3e8a8a8f60bcc6 Mon Sep 17 00:00:00 2001 From: sagi Date: Thu, 18 Jun 2026 11:19:26 +0300 Subject: [PATCH 08/11] Replacing #![repository_card] instead of --- --- mdbook-repository-card/Cargo.toml | 2 +- mdbook-repository-card/src/main.rs | 5 +++-- src/Help.md | 4 ++++ src/Introduction.md | 2 ++ src/Roadmap.md | 4 ++++ src/ch01-00-getting-started.md | 2 ++ src/ch01-01-making-stand-alone-binary.md | 2 ++ src/ch01-02-booting-our-binary.md | 2 ++ src/ch01-03-debugging-methods.md | 2 ++ src/ch02-00-a-minimal-bootloader.md | 2 ++ src/ch02-01-legacy-legacy-legacy.md | 2 ++ src/ch02-02-entering-protected-mode.md | 2 ++ src/ch02-03-implementing-the-bitfields-proc-macro.md | 2 ++ src/ch02-03-what-is-memory-paging.md | 2 ++ src/ch02-04-booting-the-kernel.md | 2 ++ src/ch03-00-printing-to-screen.md | 2 ++ src/ch04-00-memory-management.md | 4 +++- src/ch05-00-interrupts-and-exceptions.md | 4 +++- src/ch05-01-utilizing-the-idt.md | 4 +++- 19 files changed, 45 insertions(+), 6 deletions(-) diff --git a/mdbook-repository-card/Cargo.toml b/mdbook-repository-card/Cargo.toml index c91a0ed..f4f99df 100644 --- a/mdbook-repository-card/Cargo.toml +++ b/mdbook-repository-card/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "mdbook-repository-card" +name = "mdbook-repository_card" version = "0.1.0" edition = "2024" diff --git a/mdbook-repository-card/src/main.rs b/mdbook-repository-card/src/main.rs index 518d21f..40a3112 100644 --- a/mdbook-repository-card/src/main.rs +++ b/mdbook-repository-card/src/main.rs @@ -122,7 +122,7 @@ impl Preprocessor for GithubRepositoryCard { String::from("") }; - let re = Regex::new(r"---").unwrap(); + let re = Regex::new(r"#!\[repository_card\]").unwrap(); let html = HTML .replace("{username}", username) @@ -138,7 +138,8 @@ impl Preprocessor for GithubRepositoryCard { .replace_all( &chapter.content, |_caps: ®ex::Captures| { - format!("---\n\n{}\n\n", html) + eprintln!("Caps: {:?}", _caps); + format!("{}", html) }, ) .to_string(); diff --git a/src/Help.md b/src/Help.md index bc50715..1ba3707 100644 --- a/src/Help.md +++ b/src/Help.md @@ -1,5 +1,9 @@ # Huge thanks for being here! +--- + +#![repository_card] + Taking the time to read through this project means the world to me. I hope you learned something valuable! I work on this project in most of my free time! diff --git a/src/Introduction.md b/src/Introduction.md index d3cf391..752d61b 100644 --- a/src/Introduction.md +++ b/src/Introduction.md @@ -4,6 +4,8 @@ _"If you can't explain it simply, you don't understand it well enough." - Albert --- +#![repository_card] + Imagine you need to write some code to read from a file. You write a single, elegant line of Python with open("my_file.txt") as f: diff --git a/src/Roadmap.md b/src/Roadmap.md index 3a7e2f9..02d8d02 100644 --- a/src/Roadmap.md +++ b/src/Roadmap.md @@ -1,5 +1,9 @@ # Roadmap +--- + +#![repository_card] + This document specifies the planned topics and features that will be developed in the LearnixOS and covered by this book. Each topic has a corresponding issue both in the book and in the OS repository. The status of each topic can be tracked using the links provided in the tables below. diff --git a/src/ch01-00-getting-started.md b/src/ch01-00-getting-started.md index c34e5c2..bb4044d 100644 --- a/src/ch01-00-getting-started.md +++ b/src/ch01-00-getting-started.md @@ -4,6 +4,8 @@ _"the journey of a thousand miles begins with one step." - lao tzu_ --- +#![repository_card] + Let's start our Operating System journey! There is a lot to learn, but every journey has to start somewhere :) In this chapter we discuss: diff --git a/src/ch01-01-making-stand-alone-binary.md b/src/ch01-01-making-stand-alone-binary.md index 463c1fd..dea349f 100644 --- a/src/ch01-01-making-stand-alone-binary.md +++ b/src/ch01-01-making-stand-alone-binary.md @@ -4,6 +4,8 @@ _"Machines take me by surprise with great frequency." - Alan Turing_ --- +#![repository_card] + The first step in making our operating system is making a program that can be compiled, and executed, without any dependency. This is not a straightforward task, because every program that we use in our daily life uses at least one, very important dependency: `The Standard Library`. Sometimes, this library is provided by the operating system itself, for example, libc for the Linux kernel, or the WinAPI for the Windows operating system, and most of the time it is wrapped around by our programming languages. diff --git a/src/ch01-02-booting-our-binary.md b/src/ch01-02-booting-our-binary.md index a15e565..17e2cf6 100644 --- a/src/ch01-02-booting-our-binary.md +++ b/src/ch01-02-booting-our-binary.md @@ -4,6 +4,8 @@ _"There is no elevator to success - you have to take the stairs." - Zig Ziglar_ --- +#![repository_card] + In the previous section, we created a standalone binary, which is not linked to any standard library. But if you looked closely, and inspected the binary, you would see that we used a build target that is called `x86_64-unknown-none`, which is a generic target that doesn't specify any operating system or vendor, but it still specifies the architecture as `x86_64`, which is the architecture of most modern computers. ## Understanding Rust Targets diff --git a/src/ch01-03-debugging-methods.md b/src/ch01-03-debugging-methods.md index 1453638..3e0af6f 100644 --- a/src/ch01-03-debugging-methods.md +++ b/src/ch01-03-debugging-methods.md @@ -4,6 +4,8 @@ _"If debugging is the process of removing bugs, then programming must be the pro --- +#![repository_card] + Debugging is a crucial part of a good operating system, and especially at the start of its development. We still don't have good debugging methods like printing, so we need to use other methods. By far the most annoying bug is the triple fault, which will be explained extensively in the [Interrupts](ch05-00-interrupts-and-exceptions.md) Chapter. In short, this is an error that is not recoverable, and the CPU will reset itself, and it looks like this: diff --git a/src/ch02-00-a-minimal-bootloader.md b/src/ch02-00-a-minimal-bootloader.md index 0d2faf4..e224dc1 100644 --- a/src/ch02-00-a-minimal-bootloader.md +++ b/src/ch02-00-a-minimal-bootloader.md @@ -4,6 +4,8 @@ _"From a small spark may burst a mighty flame." - Dante Alighieri_ --- +#![repository_card] + Writing a bootloader is not an easy task, and it can include a lot of [things](http://wiki.osdev.org/Rolling_Your_Own_Bootloader#A_list_of_things_you_might_want_to_do). In this chapter we will write the minimal needed bootloader to load our kernel, and obtain information that is necessary for it. diff --git a/src/ch02-01-legacy-legacy-legacy.md b/src/ch02-01-legacy-legacy-legacy.md index 98dff0c..36ac043 100644 --- a/src/ch02-01-legacy-legacy-legacy.md +++ b/src/ch02-01-legacy-legacy-legacy.md @@ -4,6 +4,8 @@ _"Compatibility means deliberately repeating other people's mistakes." - David W --- +#![repository_card] + When writing our bootloader, and especially in the first stages, we encounter a lot of legacy that needs to be handled. This legacy may come in multiple shapes, like bios interrupts, magic numbers and things that need to be initialized. Most of this work will be covered in this chapter. diff --git a/src/ch02-02-entering-protected-mode.md b/src/ch02-02-entering-protected-mode.md index 0993634..69b8190 100644 --- a/src/ch02-02-entering-protected-mode.md +++ b/src/ch02-02-entering-protected-mode.md @@ -4,6 +4,8 @@ _"With great power comes great responsibility." - Voltaire / Spider-Man_ --- +#![repository_card] + As you may recall from previous chapters, our BIOS only loads the first sector to RAM, which leaves about just shy of 512 bytes[^1]. After we read from disk, it will enable us to write much more code, because we will not be limited to 512 bytes. But just before we do that, we don't want to limit ourselves to only 16bit instructions. diff --git a/src/ch02-03-implementing-the-bitfields-proc-macro.md b/src/ch02-03-implementing-the-bitfields-proc-macro.md index d9cc7e6..f629091 100644 --- a/src/ch02-03-implementing-the-bitfields-proc-macro.md +++ b/src/ch02-03-implementing-the-bitfields-proc-macro.md @@ -4,6 +4,8 @@ _"In Lisp, you don't just write your program down toward the language, you also --- +#![repository_card] + As you may recall from the previous chapter, we used a proc-macro that was called `bitfields`. In this chapter, we are going to learn about Rust's procedural macros and even implement one ourselves. > Another great resource for this subject is the great video [Comprehending Proc Macros](https://youtu.be/SMCRQj9Hbx8?si=p-JUX0rLronBG_Nz) by Logan Smith diff --git a/src/ch02-03-what-is-memory-paging.md b/src/ch02-03-what-is-memory-paging.md index a0d392c..ddbf486 100644 --- a/src/ch02-03-what-is-memory-paging.md +++ b/src/ch02-03-what-is-memory-paging.md @@ -3,6 +3,8 @@ _"The purpose of abstraction is not to be vague, but to create a new semantic level in which one can be absolutely precise." - Edsger W. Dijkstra_ --- + +#![repository_card] In the previous section, we talked about the global descriptor table, and how segments are used to divide memory into logical parts so it is easier to manage. Although this system worked in older 32bit operating systems, it will not be good for our operating system, but why is that? diff --git a/src/ch02-04-booting-the-kernel.md b/src/ch02-04-booting-the-kernel.md index 718d474..6c5c88e 100644 --- a/src/ch02-04-booting-the-kernel.md +++ b/src/ch02-04-booting-the-kernel.md @@ -4,6 +4,8 @@ _"A small thing. Yet it holds everything together." - J.R.R. Tolkien, paraphrase --- +#![repository_card] + In the previous section we talked about memory paging, what it is, and how to initialize page tables. So, logically the only thing that is left to do, is to toggle on paging. After that we can also toggle [`long mode`](https://en.wikipedia.org/wiki/Long_mode), which is another mode in the CPU, just like `protected mode` which will let us run 64-bit instructions. diff --git a/src/ch03-00-printing-to-screen.md b/src/ch03-00-printing-to-screen.md index e037b3d..2ea3f26 100644 --- a/src/ch03-00-printing-to-screen.md +++ b/src/ch03-00-printing-to-screen.md @@ -4,6 +4,8 @@ _"The most effective debugging tool is still and careful thought, coupled with j --- +#![repository_card] + Printing is an important aspect of an operating system, especially in early development because it is our way to gain a visual output from our operating system. This will massively improve the interaction with our OS, and not only will it give us a huge advantage in debugging, but it will also grant us the ability to display a shell, which we will do in the upcoming chapters. ## Why didn't we print until now? diff --git a/src/ch04-00-memory-management.md b/src/ch04-00-memory-management.md index 4c48d33..8bb8276 100644 --- a/src/ch04-00-memory-management.md +++ b/src/ch04-00-memory-management.md @@ -4,6 +4,8 @@ _"The art of programming is the art of organizing complexity." - Edsger W. Dijks --- +#![repository_card] + To Be Continued... -Latest Development is at [LearnixOS](https://github.com/learnix-os/LearnixOS/) \ No newline at end of file +Latest Development is at [LearnixOS](https://github.com/learnix-os/LearnixOS/) diff --git a/src/ch05-00-interrupts-and-exceptions.md b/src/ch05-00-interrupts-and-exceptions.md index 85784ff..015f5fd 100644 --- a/src/ch05-00-interrupts-and-exceptions.md +++ b/src/ch05-00-interrupts-and-exceptions.md @@ -4,6 +4,8 @@ _"In the middle of difficulty lies opportunity." - Albert Einstein_ --- +#![repository_card] + To Be Continued... -Latest Development is at [LearnixOS](https://github.com/learnix-os/LearnixOS/) \ No newline at end of file +Latest Development is at [LearnixOS](https://github.com/learnix-os/LearnixOS/) diff --git a/src/ch05-01-utilizing-the-idt.md b/src/ch05-01-utilizing-the-idt.md index e763bf3..d21d8e8 100644 --- a/src/ch05-01-utilizing-the-idt.md +++ b/src/ch05-01-utilizing-the-idt.md @@ -4,6 +4,8 @@ _"What we call chaos is just patterns we haven't recognized." - Chuck Palahniuk_ --- +#![repository_card] + To Be Continued... -Latest Development is at [LearnixOS](https://github.com/learnix-os/LearnixOS/) \ No newline at end of file +Latest Development is at [LearnixOS](https://github.com/learnix-os/LearnixOS/) From a4206b1480d86e4cc5bcd670ded23a670095d884 Mon Sep 17 00:00:00 2001 From: sagi Date: Thu, 18 Jun 2026 11:20:44 +0300 Subject: [PATCH 09/11] Update for ci test --- mdbook-rust-analyzer-highlight | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mdbook-rust-analyzer-highlight b/mdbook-rust-analyzer-highlight index e535f10..670d3e1 160000 --- a/mdbook-rust-analyzer-highlight +++ b/mdbook-rust-analyzer-highlight @@ -1 +1 @@ -Subproject commit e535f10d4e1f17f1464db0c33f4ad03bbf8893be +Subproject commit 670d3e11bbccac97c550aa30288e35ea8e4df543 From 59b86fc9e0562829a647292eafe121a558836bab Mon Sep 17 00:00:00 2001 From: sagi Date: Thu, 18 Jun 2026 11:37:28 +0300 Subject: [PATCH 10/11] Update version so would hopefuly be in ci --- ...2-03-implementing-the-bitfields-proc-macro.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/ch02-03-implementing-the-bitfields-proc-macro.md b/src/ch02-03-implementing-the-bitfields-proc-macro.md index f629091..b6dcaad 100644 --- a/src/ch02-03-implementing-the-bitfields-proc-macro.md +++ b/src/ch02-03-implementing-the-bitfields-proc-macro.md @@ -283,13 +283,13 @@ _There are a lot of types on the `syn` crate, and we will only cover some of the The top level type for the AST is `syn::File`, which represents a complete Rust source file. ```rust -#![source_file!("/syn-2.0.117/src/file.rs", 6:86)] +#![source_file!("/syn-2.0.118/src/file.rs", 6:86)] ``` Ok, we can see that `syn::File` is made out of a list of `syn::Attribute` and `syn::Item`. But this doesn't tell us much, so let's also explore them. ```rust -#![source_file!("/syn-2.0.117/src/attr.rs", 23:183)] +#![source_file!("/syn-2.0.118/src/attr.rs", 23:183)] ``` So we can see an attribute, like `#[derive(Debug)]`, is represented by `syn::Attribute`. Currently, we will not dive deeper into `Attribute`, but we will cover more of it when we will use it in our macro implementation. @@ -297,13 +297,13 @@ So we can see an attribute, like `#[derive(Debug)]`, is represented by `syn::Att Now let's see `syn::Item`. ```rust -#![source_file!("/syn-2.0.117/src/item.rs", 22:101)] +#![source_file!("/syn-2.0.118/src/item.rs", 22:101)] ``` As you can see, we have a lot of items, and I hope that you can start and recognize some of them. As an example, let's cover `ItemConst`. ```rust -#![source_file!("/syn-2.0.117/src/item.rs", 103:118)] +#![source_file!("/syn-2.0.118/src/item.rs", 103:118)] ``` If you have noticed closely, the order of the fields in the struct definition is the same as the order in the source code. This makes it really easy to map the AST back to the source code. @@ -313,7 +313,7 @@ Also, as a side note, keywords like `const`, `struct` and punctuation like `:` a The last type that we are going to cover is `syn::Expr`, which represents an expression from the source code. Because most of Rust's syntax is represented as expressions, `syn::Expr` is a very large type. ```rust -#![source_file!("/syn-2.0.117/src/expr.rs", 37:269)] +#![source_file!("/syn-2.0.118/src/expr.rs", 37:269)] ``` These types are very powerful and help us express language in a structured way. As a quick example, let's see how `syn::ItemStruct` is represented in the AST. In this example, we have the exact same struct that we showed its `TokenStream` representation. @@ -380,7 +380,7 @@ The most important thing about Syn is that we can use the types that it offers t But how would Syn know to parse our custom syntax into the AST types it offers? This is where the `Parse` trait comes in. When Syn wants to parse our custom syntax, it will call the `parse` method from the `Parse` trait and pass in the token stream to parse. ```rust -#![trait!("/syn-2.0.117/src/parse.rs", Parse)] +#![trait!("/syn-2.0.118/src/parse.rs", Parse)] ``` We will go deeper into this when we create our own custom `Parse` implementation. One important thing to understand is that all of syn's types implement `Parse` themselves, so most of the time, implementing `Parse` for types that are built from syn's AST types is easy. @@ -652,7 +652,7 @@ We will start off easy by parsing the `FlagType` attribute. Because every elemen If you were wondering why we are calling the `parse` function on the input instead of on the type itself. It is because the `ParseStream` implements this very convenient `parse` function that allows us to parse a single token from the stream at a time. ```rust -#![impl_method!("/syn-2.0.117/src/parse.rs", ParseBuffer::parse)] +#![impl_method!("/syn-2.0.118/src/parse.rs", ParseBuffer::parse)] ``` Next, let's parse something that takes a little more effort, our `FlagPermission`. @@ -692,7 +692,7 @@ Although we implemented `Parse` for `FlagAttribute`, we are not going to create For that, we are going to use the `Meta` part of our `syn::Attribute`. ```rust -#![source_file!("/syn-2.0.117/src/attr.rs", 455:486)] +#![source_file!("/syn-2.0.118/src/attr.rs", 455:486)] ``` In our case, we are going to have a `Meta::List`, which contains a `TokenStream` of the attribute's contents, hence the implementation of the `Parse` trait. From 21af58b9ee3ff6926179d9d5b3f666a9329fed25 Mon Sep 17 00:00:00 2001 From: sagi Date: Thu, 18 Jun 2026 11:46:52 +0300 Subject: [PATCH 11/11] Remove debug print --- mdbook-repository-card/src/main.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/mdbook-repository-card/src/main.rs b/mdbook-repository-card/src/main.rs index 40a3112..4779c4b 100644 --- a/mdbook-repository-card/src/main.rs +++ b/mdbook-repository-card/src/main.rs @@ -138,7 +138,6 @@ impl Preprocessor for GithubRepositoryCard { .replace_all( &chapter.content, |_caps: ®ex::Captures| { - eprintln!("Caps: {:?}", _caps); format!("{}", html) }, )