mirror of
https://github.com/rust-lang/mdBook.git
synced 2025-12-27 11:25:45 -05:00
Use embedded SVG instead of fonts for icons
The [downsides of icon fonts] are well-documented, and also, why ship all of the icons when it only uses 14? [downsides of icon fonts]: https://speakerdeck.com/ninjanails/death-to-icon-fonts
This commit is contained in:
committed by
Eric Huss
parent
7b3e6973be
commit
2dc8c5e686
7
Cargo.lock
generated
7
Cargo.lock
generated
@@ -622,6 +622,12 @@ version = "1.0.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
|
||||
|
||||
[[package]]
|
||||
name = "font-awesome-as-a-crate"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "932dcfbd51320af5f27f1ba02d2e567dec332cac7d2c221ba45d8e767264c4dc"
|
||||
|
||||
[[package]]
|
||||
name = "form_urlencoded"
|
||||
version = "1.2.1"
|
||||
@@ -1352,6 +1358,7 @@ dependencies = [
|
||||
"ammonia",
|
||||
"anyhow",
|
||||
"elasticlunr-rs",
|
||||
"font-awesome-as-a-crate",
|
||||
"handlebars",
|
||||
"hex",
|
||||
"log",
|
||||
|
||||
@@ -33,6 +33,7 @@ clap = { version = "4.5.41", features = ["cargo", "wrap_help"] }
|
||||
clap_complete = "4.5.55"
|
||||
elasticlunr-rs = "3.0.2"
|
||||
env_logger = "0.11.8"
|
||||
font-awesome-as-a-crate = "0.3.0"
|
||||
futures-util = "0.3.31"
|
||||
handlebars = "6.3.2"
|
||||
hex = "0.4.3"
|
||||
|
||||
@@ -11,6 +11,7 @@ rust-version.workspace = true
|
||||
ammonia = { workspace = true, optional = true }
|
||||
anyhow.workspace = true
|
||||
elasticlunr-rs = { workspace = true, optional = true }
|
||||
font-awesome-as-a-crate.workspace = true
|
||||
handlebars.workspace = true
|
||||
hex.workspace = true
|
||||
log.workspace = true
|
||||
|
||||
@@ -56,7 +56,7 @@ html.sidebar-visible #menu-bar {
|
||||
#menu-bar.bordered {
|
||||
border-block-end-color: var(--table-border-color);
|
||||
}
|
||||
#menu-bar i, #menu-bar .icon-button {
|
||||
#menu-bar .fa-svg, #menu-bar .icon-button {
|
||||
position: relative;
|
||||
padding: 0 8px;
|
||||
z-index: 10;
|
||||
@@ -65,7 +65,7 @@ html.sidebar-visible #menu-bar {
|
||||
transition: color 0.5s;
|
||||
}
|
||||
@media only screen and (max-width: 420px) {
|
||||
#menu-bar i, #menu-bar .icon-button {
|
||||
#menu-bar .fa-svg, #menu-bar .icon-button {
|
||||
padding: 0 5px;
|
||||
}
|
||||
}
|
||||
@@ -76,7 +76,7 @@ html.sidebar-visible #menu-bar {
|
||||
padding: 0;
|
||||
color: inherit;
|
||||
}
|
||||
.icon-button i {
|
||||
.icon-button .fa-svg {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
@@ -118,14 +118,14 @@ html:not(.js) .left-buttons button {
|
||||
.mobile-nav-chapters,
|
||||
.mobile-nav-chapters:visited,
|
||||
.menu-bar .icon-button,
|
||||
.menu-bar a i {
|
||||
.menu-bar a .fa-svg {
|
||||
color: var(--icons);
|
||||
}
|
||||
|
||||
.menu-bar i:hover,
|
||||
.menu-bar .fa-svg:hover,
|
||||
.menu-bar .icon-button:hover,
|
||||
.nav-chapters:hover,
|
||||
.mobile-nav-chapters i:hover {
|
||||
.mobile-nav-chapters .fa-svg:hover {
|
||||
color: var(--icons-hover);
|
||||
}
|
||||
|
||||
@@ -240,13 +240,10 @@ pre > .buttons :hover {
|
||||
border-color: var(--icons-hover);
|
||||
background-color: var(--theme-hover);
|
||||
}
|
||||
pre > .buttons i {
|
||||
margin-inline-start: 8px;
|
||||
}
|
||||
pre > .buttons button {
|
||||
cursor: inherit;
|
||||
margin: 0px 5px;
|
||||
padding: 4px 4px 3px 5px;
|
||||
padding: 2px 3px 0px 4px;
|
||||
font-size: 23px;
|
||||
|
||||
border-style: solid;
|
||||
@@ -365,6 +362,20 @@ mark.fade-out {
|
||||
background-color: var(--bg);
|
||||
}
|
||||
|
||||
#fa-spin {
|
||||
animation: rotating 2s linear infinite;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
@keyframes rotating {
|
||||
from {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
to {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
#searchbar {
|
||||
width: 100%;
|
||||
margin-block-start: var(--searchbar-margin-block-start);
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -278,3 +278,10 @@ sup {
|
||||
.result-no-output {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.fa-svg svg {
|
||||
width: 1em;
|
||||
height: 1em;
|
||||
fill: currentColor;
|
||||
margin-bottom: -0.1em;
|
||||
}
|
||||
|
||||
Binary file not shown.
Binary file not shown.
File diff suppressed because it is too large
Load Diff
|
Before Width: | Height: | Size: 434 KiB |
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -97,6 +97,7 @@ function playground_text(playground, hidden = true) {
|
||||
|
||||
if (all_available) {
|
||||
play_button.classList.remove('hidden');
|
||||
play_button.hidden = false;
|
||||
} else {
|
||||
play_button.classList.add('hidden');
|
||||
}
|
||||
@@ -207,26 +208,25 @@ function playground_text(playground, hidden = true) {
|
||||
|
||||
const buttons = document.createElement('div');
|
||||
buttons.className = 'buttons';
|
||||
buttons.innerHTML = '<button class="fa fa-eye" title="Show hidden lines" \
|
||||
buttons.innerHTML = '<button title="Show hidden lines" \
|
||||
aria-label="Show hidden lines"></button>';
|
||||
buttons.firstChild.innerHTML = document.getElementById('fa-eye').innerHTML;
|
||||
|
||||
// add expand button
|
||||
const pre_block = block.parentNode;
|
||||
pre_block.insertBefore(buttons, pre_block.firstChild);
|
||||
|
||||
pre_block.querySelector('.buttons').addEventListener('click', function(e) {
|
||||
if (e.target.classList.contains('fa-eye')) {
|
||||
e.target.classList.remove('fa-eye');
|
||||
e.target.classList.add('fa-eye-slash');
|
||||
e.target.title = 'Hide lines';
|
||||
e.target.setAttribute('aria-label', e.target.title);
|
||||
buttons.firstChild.addEventListener('click', function(e) {
|
||||
if (this.title === 'Show hidden lines') {
|
||||
this.innerHTML = document.getElementById('fa-eye-slash').innerHTML;
|
||||
this.title = 'Hide lines';
|
||||
this.setAttribute('aria-label', e.target.title);
|
||||
|
||||
block.classList.remove('hide-boring');
|
||||
} else if (e.target.classList.contains('fa-eye-slash')) {
|
||||
e.target.classList.remove('fa-eye-slash');
|
||||
e.target.classList.add('fa-eye');
|
||||
e.target.title = 'Show hidden lines';
|
||||
e.target.setAttribute('aria-label', e.target.title);
|
||||
} else if (this.title === 'Hide lines') {
|
||||
this.innerHTML = document.getElementById('fa-eye').innerHTML;
|
||||
this.title = 'Show hidden lines';
|
||||
this.setAttribute('aria-label', e.target.title);
|
||||
|
||||
block.classList.add('hide-boring');
|
||||
}
|
||||
@@ -266,10 +266,11 @@ aria-label="Show hidden lines"></button>';
|
||||
}
|
||||
|
||||
const runCodeButton = document.createElement('button');
|
||||
runCodeButton.className = 'fa fa-play play-button';
|
||||
runCodeButton.className = 'play-button';
|
||||
runCodeButton.hidden = true;
|
||||
runCodeButton.title = 'Run this code';
|
||||
runCodeButton.setAttribute('aria-label', runCodeButton.title);
|
||||
runCodeButton.innerHTML = document.getElementById('fa-play').innerHTML;
|
||||
|
||||
buttons.insertBefore(runCodeButton, buttons.firstChild);
|
||||
runCodeButton.addEventListener('click', () => {
|
||||
@@ -289,9 +290,11 @@ aria-label="Show hidden lines"></button>';
|
||||
const code_block = pre_block.querySelector('code');
|
||||
if (window.ace && code_block.classList.contains('editable')) {
|
||||
const undoChangesButton = document.createElement('button');
|
||||
undoChangesButton.className = 'fa fa-history reset-button';
|
||||
undoChangesButton.className = 'reset-button';
|
||||
undoChangesButton.title = 'Undo changes';
|
||||
undoChangesButton.setAttribute('aria-label', undoChangesButton.title);
|
||||
undoChangesButton.innerHTML +=
|
||||
document.getElementById('fa-clock-rotate-left').innerHTML;
|
||||
|
||||
buttons.insertBefore(undoChangesButton, buttons.firstChild);
|
||||
|
||||
|
||||
@@ -33,7 +33,6 @@
|
||||
{{/if}}
|
||||
|
||||
<!-- Fonts -->
|
||||
<link rel="stylesheet" href="{{ resource "FontAwesome/css/font-awesome.css" }}">
|
||||
<link rel="stylesheet" href="{{ resource "fonts/fonts.css" }}">
|
||||
|
||||
<!-- Highlight.js Stylesheets -->
|
||||
@@ -145,10 +144,10 @@
|
||||
<div id="menu-bar" class="menu-bar sticky">
|
||||
<div class="left-buttons">
|
||||
<label id="sidebar-toggle" class="icon-button" for="sidebar-toggle-anchor" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
|
||||
<i class="fa fa-bars"></i>
|
||||
{{fa "solid" "bars"}}
|
||||
</label>
|
||||
<button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
|
||||
<i class="fa fa-paint-brush"></i>
|
||||
{{fa "solid" "paintbrush"}}
|
||||
</button>
|
||||
<ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
|
||||
<li role="none"><button role="menuitem" class="theme" id="default_theme">Auto</button></li>
|
||||
@@ -160,7 +159,7 @@
|
||||
</ul>
|
||||
{{#if search_enabled}}
|
||||
<button id="search-toggle" class="icon-button" type="button" title="Search (`/`)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="/ s" aria-controls="searchbar">
|
||||
<i class="fa fa-search"></i>
|
||||
{{fa "solid" "magnifying-glass"}}
|
||||
</button>
|
||||
{{/if}}
|
||||
</div>
|
||||
@@ -170,17 +169,17 @@
|
||||
<div class="right-buttons">
|
||||
{{#if print_enable}}
|
||||
<a href="{{ path_to_root }}print.html" title="Print this book" aria-label="Print this book">
|
||||
<i id="print-button" class="fa fa-print"></i>
|
||||
{{fa "solid" "print" "print-button"}}
|
||||
</a>
|
||||
{{/if}}
|
||||
{{#if git_repository_url}}
|
||||
<a href="{{git_repository_url}}" title="Git repository" aria-label="Git repository">
|
||||
<i id="git-repository-button" class="fa {{git_repository_icon}}"></i>
|
||||
{{fa git_repository_icon_class git_repository_icon}}
|
||||
</a>
|
||||
{{/if}}
|
||||
{{#if git_repository_edit_url}}
|
||||
<a href="{{git_repository_edit_url}}" title="Suggest an edit" aria-label="Suggest an edit" rel="edit">
|
||||
<i id="git-edit-button" class="fa fa-edit"></i>
|
||||
{{fa "solid" "pencil" "git-edit-button"}}
|
||||
</a>
|
||||
{{/if}}
|
||||
|
||||
@@ -193,7 +192,7 @@
|
||||
<div class="search-wrapper">
|
||||
<input type="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
|
||||
<div class="spinner-wrapper">
|
||||
<i class="fa fa-spinner fa-spin"></i>
|
||||
{{fa "solid" "spinner" "fa-spin"}}
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
@@ -224,19 +223,18 @@
|
||||
{{#if previous}}
|
||||
<a rel="prev" href="{{ path_to_root }}{{previous.link}}" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||||
{{#if (eq ../text_direction "rtl")}}
|
||||
<i class="fa fa-angle-right"></i>
|
||||
{{fa "solid" "angle-right"}}
|
||||
{{else}}
|
||||
<i class="fa fa-angle-left"></i>
|
||||
{{fa "solid" "angle-left"}}
|
||||
{{/if}}
|
||||
</a>
|
||||
{{/if}}
|
||||
|
||||
{{#if next}}
|
||||
<a rel="next prefetch" href="{{ path_to_root }}{{next.link}}" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
||||
{{#if (eq ../text_direction "rtl")}}
|
||||
<i class="fa fa-angle-left"></i>
|
||||
{{fa "solid" "angle-left"}}
|
||||
{{else}}
|
||||
<i class="fa fa-angle-right"></i>
|
||||
{{fa "solid" "angle-right"}}
|
||||
{{/if}}
|
||||
</a>
|
||||
{{/if}}
|
||||
@@ -250,9 +248,9 @@
|
||||
{{#if previous}}
|
||||
<a rel="prev" href="{{ path_to_root }}{{previous.link}}" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||||
{{#if (eq ../text_direction "rtl")}}
|
||||
<i class="fa fa-angle-right"></i>
|
||||
{{fa "solid" "angle-right"}}
|
||||
{{else}}
|
||||
<i class="fa fa-angle-left"></i>
|
||||
{{fa "solid" "angle-left"}}
|
||||
{{/if}}
|
||||
</a>
|
||||
{{/if}}
|
||||
@@ -260,9 +258,9 @@
|
||||
{{#if next}}
|
||||
<a rel="next prefetch" href="{{ path_to_root }}{{next.link}}" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
||||
{{#if (eq text_direction "rtl")}}
|
||||
<i class="fa fa-angle-left"></i>
|
||||
{{fa "solid" "angle-left"}}
|
||||
{{else}}
|
||||
<i class="fa fa-angle-right"></i>
|
||||
{{fa "solid" "angle-right"}}
|
||||
{{/if}}
|
||||
</a>
|
||||
{{/if}}
|
||||
@@ -270,6 +268,12 @@
|
||||
|
||||
</div>
|
||||
|
||||
<template id=fa-eye>{{fa "solid" "eye"}}</template>
|
||||
<template id=fa-eye-slash>{{fa "solid" "eye-slash"}}</template>
|
||||
<template id=fa-copy>{{fa "regular" "copy"}}</template>
|
||||
<template id=fa-play>{{fa "solid" "play"}}</template>
|
||||
<template id=fa-clock-rotate-left>{{fa "solid" "clock-rotate-left"}}</template>
|
||||
|
||||
{{#if live_reload_endpoint}}
|
||||
<!-- Livereload script (if served using the cli tool) -->
|
||||
<script>
|
||||
|
||||
@@ -28,7 +28,6 @@
|
||||
<link rel="stylesheet" href="{{ resource "css/print.css" }}" media="print">
|
||||
{{/if}}
|
||||
<!-- Fonts -->
|
||||
<link rel="stylesheet" href="{{ resource "FontAwesome/css/font-awesome.css" }}">
|
||||
<link rel="stylesheet" href="{{ resource "fonts/fonts.css" }}">
|
||||
<!-- Custom theme stylesheets -->
|
||||
{{#each additional_css}}
|
||||
|
||||
@@ -242,6 +242,7 @@ impl HtmlHandlebars {
|
||||
let rendered = fix_code_blocks(&rendered);
|
||||
let rendered = add_playground_pre(&rendered, playground_config, edition);
|
||||
let rendered = hide_lines(&rendered, code_config);
|
||||
let rendered = convert_fontawesome(&rendered);
|
||||
|
||||
rendered
|
||||
}
|
||||
@@ -271,6 +272,7 @@ impl HtmlHandlebars {
|
||||
no_section_label: html_config.no_section_label,
|
||||
}),
|
||||
);
|
||||
handlebars.register_helper("fa", Box::new(helpers::fontawesome::fa_helper));
|
||||
}
|
||||
|
||||
fn emit_redirects(
|
||||
@@ -635,9 +637,19 @@ fn make_data(
|
||||
|
||||
let git_repository_icon = match html_config.git_repository_icon {
|
||||
Some(ref git_repository_icon) => git_repository_icon,
|
||||
None => "fa-github",
|
||||
None => "fab-github",
|
||||
};
|
||||
let git_repository_icon_class = match git_repository_icon.split('-').next() {
|
||||
Some("fa") => "regular",
|
||||
Some("fas") => "solid",
|
||||
Some("fab") => "brands",
|
||||
_ => "regular",
|
||||
};
|
||||
data.insert("git_repository_icon".to_owned(), json!(git_repository_icon));
|
||||
data.insert(
|
||||
"git_repository_icon_class".to_owned(),
|
||||
json!(git_repository_icon_class),
|
||||
);
|
||||
|
||||
let mut chapters = vec![];
|
||||
|
||||
@@ -737,6 +749,54 @@ fn insert_link_into_header(
|
||||
)
|
||||
}
|
||||
|
||||
// Convert fontawesome `<i>` tags to inline SVG
|
||||
fn convert_fontawesome(html: &str) -> String {
|
||||
use font_awesome_as_a_crate as fa;
|
||||
|
||||
let regex = Regex::new(r##"<i([^>]+)class="([^"]+)"([^>]*)></i>"##).unwrap();
|
||||
regex
|
||||
.replace_all(html, |caps: &Captures<'_>| {
|
||||
let text = &caps[0];
|
||||
let before = &caps[1];
|
||||
let classes = &caps[2];
|
||||
let after = &caps[3];
|
||||
|
||||
let mut icon = String::new();
|
||||
let mut type_ = fa::Type::Regular;
|
||||
let mut other_classes = String::new();
|
||||
|
||||
for class in classes.split(" ") {
|
||||
if let Some(class) = class.strip_prefix("fa-") {
|
||||
icon = class.to_owned();
|
||||
} else if class == "fa" {
|
||||
type_ = fa::Type::Regular;
|
||||
} else if class == "fas" {
|
||||
type_ = fa::Type::Solid;
|
||||
} else if class == "fab" {
|
||||
type_ = fa::Type::Brands;
|
||||
} else {
|
||||
other_classes += " ";
|
||||
other_classes += class;
|
||||
}
|
||||
}
|
||||
|
||||
if icon.is_empty() {
|
||||
text.to_owned()
|
||||
} else if let Ok(svg) = fa::svg(type_, &icon) {
|
||||
format!(
|
||||
r#"<span{before}class="fa-svg{other_classes}"{after}>{svg}</span>"#,
|
||||
before = before,
|
||||
other_classes = other_classes,
|
||||
after = after,
|
||||
svg = svg
|
||||
)
|
||||
} else {
|
||||
text.to_owned()
|
||||
}
|
||||
})
|
||||
.into_owned()
|
||||
}
|
||||
|
||||
// The rust book uses annotations for rustdoc to test code snippets,
|
||||
// like the following:
|
||||
// ```rust,should_panic
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
use font_awesome_as_a_crate as fa;
|
||||
use handlebars::{
|
||||
Context, Handlebars, Helper, Output, RenderContext, RenderError, RenderErrorReason,
|
||||
};
|
||||
use log::trace;
|
||||
use std::str::FromStr;
|
||||
|
||||
pub(crate) fn fa_helper(
|
||||
h: &Helper<'_>,
|
||||
_r: &Handlebars<'_>,
|
||||
_ctx: &Context,
|
||||
_rc: &mut RenderContext<'_, '_>,
|
||||
out: &mut dyn Output,
|
||||
) -> Result<(), RenderError> {
|
||||
trace!("fa_helper (handlebars helper)");
|
||||
|
||||
let type_ = h
|
||||
.param(0)
|
||||
.and_then(|v| v.value().as_str())
|
||||
.and_then(|v| fa::Type::from_str(v).ok())
|
||||
.ok_or_else(|| {
|
||||
RenderErrorReason::Other(
|
||||
"Param 0 with String type is required for fontawesome helper.".to_owned(),
|
||||
)
|
||||
})?;
|
||||
|
||||
let name = h.param(1).and_then(|v| v.value().as_str()).ok_or_else(|| {
|
||||
RenderErrorReason::Other(
|
||||
"Param 1 with String type is required for fontawesome helper.".to_owned(),
|
||||
)
|
||||
})?;
|
||||
|
||||
trace!("fa_helper: {} {}", type_, name);
|
||||
|
||||
let name = name
|
||||
.strip_prefix("fa-")
|
||||
.or_else(|| name.strip_prefix("fab-"))
|
||||
.or_else(|| name.strip_prefix("fas-"))
|
||||
.unwrap_or(name);
|
||||
|
||||
if let Some(id) = h.param(2).and_then(|v| v.value().as_str()) {
|
||||
out.write(&format!("<span class=fa-svg id=\"{}\">", id))?;
|
||||
} else {
|
||||
out.write("<span class=fa-svg>")?;
|
||||
}
|
||||
out.write(
|
||||
fa::svg(type_, name)
|
||||
.map_err(|_| RenderErrorReason::Other(format!("Missing font {}", name)))?,
|
||||
)?;
|
||||
out.write("</span>")?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -1,2 +1,3 @@
|
||||
pub(crate) mod fontawesome;
|
||||
pub(crate) mod resources;
|
||||
pub(crate) mod toc;
|
||||
|
||||
@@ -62,28 +62,6 @@ impl StaticFiles {
|
||||
this.add_builtin("ayu-highlight.css", &theme.ayu_highlight_css);
|
||||
this.add_builtin("highlight.js", &theme.highlight_js);
|
||||
this.add_builtin("clipboard.min.js", &theme.clipboard_js);
|
||||
this.add_builtin("FontAwesome/css/font-awesome.css", theme::FONT_AWESOME);
|
||||
this.add_builtin(
|
||||
"FontAwesome/fonts/fontawesome-webfont.eot",
|
||||
theme::FONT_AWESOME_EOT,
|
||||
);
|
||||
this.add_builtin(
|
||||
"FontAwesome/fonts/fontawesome-webfont.svg",
|
||||
theme::FONT_AWESOME_SVG,
|
||||
);
|
||||
this.add_builtin(
|
||||
"FontAwesome/fonts/fontawesome-webfont.ttf",
|
||||
theme::FONT_AWESOME_TTF,
|
||||
);
|
||||
this.add_builtin(
|
||||
"FontAwesome/fonts/fontawesome-webfont.woff",
|
||||
theme::FONT_AWESOME_WOFF,
|
||||
);
|
||||
this.add_builtin(
|
||||
"FontAwesome/fonts/fontawesome-webfont.woff2",
|
||||
theme::FONT_AWESOME_WOFF2,
|
||||
);
|
||||
this.add_builtin("FontAwesome/fonts/FontAwesome.ttf", theme::FONT_AWESOME_TTF);
|
||||
if theme.fonts_css.is_none() {
|
||||
this.add_builtin("fonts/fonts.css", theme::fonts::CSS);
|
||||
for (file_name, contents) in theme::fonts::LICENSES.iter() {
|
||||
@@ -170,13 +148,7 @@ impl StaticFiles {
|
||||
let mut parts = filename.splitn(2, '.');
|
||||
let parts = parts.next().and_then(|p| Some((p, parts.next()?)));
|
||||
if let Some((name, suffix)) = parts {
|
||||
// FontAwesome already does its own cache busting with the ?v=4.7.0 thing,
|
||||
// and I don't want to have to patch its CSS file to use `{{ resource }}`
|
||||
if name != ""
|
||||
&& suffix != ""
|
||||
&& suffix != "txt"
|
||||
&& !name.starts_with("FontAwesome/fonts/")
|
||||
{
|
||||
if name != "" && suffix != "" && suffix != "txt" {
|
||||
let hex = hex::encode(&Sha256::digest(data)[..4]);
|
||||
let new_filename = format!("{}-{}.{}", name, hex, suffix);
|
||||
self.hash_map.insert(filename.clone(), new_filename.clone());
|
||||
|
||||
@@ -29,18 +29,6 @@ pub static TOMORROW_NIGHT_CSS: &[u8] = include_bytes!("../../front-end/css/tomor
|
||||
pub static HIGHLIGHT_CSS: &[u8] = include_bytes!("../../front-end/css/highlight.css");
|
||||
pub static AYU_HIGHLIGHT_CSS: &[u8] = include_bytes!("../../front-end/css/ayu-highlight.css");
|
||||
pub static CLIPBOARD_JS: &[u8] = include_bytes!("../../front-end/js/clipboard.min.js");
|
||||
pub static FONT_AWESOME: &[u8] = include_bytes!("../../front-end/css/font-awesome.min.css");
|
||||
pub static FONT_AWESOME_EOT: &[u8] =
|
||||
include_bytes!("../../front-end/fonts/fontawesome-webfont.eot");
|
||||
pub static FONT_AWESOME_SVG: &[u8] =
|
||||
include_bytes!("../../front-end/fonts/fontawesome-webfont.svg");
|
||||
pub static FONT_AWESOME_TTF: &[u8] =
|
||||
include_bytes!("../../front-end/fonts/fontawesome-webfont.ttf");
|
||||
pub static FONT_AWESOME_WOFF: &[u8] =
|
||||
include_bytes!("../../front-end/fonts/fontawesome-webfont.woff");
|
||||
pub static FONT_AWESOME_WOFF2: &[u8] =
|
||||
include_bytes!("../../front-end/fonts/fontawesome-webfont.woff2");
|
||||
pub static FONT_AWESOME_OTF: &[u8] = include_bytes!("../../front-end/fonts/FontAwesome.otf");
|
||||
|
||||
/// The `Theme` struct should be used instead of the static variables because
|
||||
/// the `new()` method will look if the user has a theme directory in their
|
||||
|
||||
@@ -103,7 +103,7 @@ additional-css = ["custom.css", "custom2.css"]
|
||||
additional-js = ["custom.js"]
|
||||
no-section-label = false
|
||||
git-repository-url = "https://github.com/rust-lang/mdBook"
|
||||
git-repository-icon = "fa-github"
|
||||
git-repository-icon = "fab-github"
|
||||
edit-url-template = "https://github.com/rust-lang/mdBook/edit/master/guide/{path}"
|
||||
site-url = "/example-book/"
|
||||
cname = "myproject.rs"
|
||||
@@ -139,7 +139,7 @@ The following configuration options are available:
|
||||
- **git-repository-url:** A url to the git repository for the book. If provided
|
||||
an icon link will be output in the menu bar of the book.
|
||||
- **git-repository-icon:** The FontAwesome icon class to use for the git
|
||||
repository link. Defaults to `fa-github` which looks like <i class="fa fa-github"></i>.
|
||||
repository link. Defaults to `fab-github` which looks like <i class="fa fab-github"></i>.
|
||||
If you are not using GitHub, another option to consider is `fa-code-fork` which looks like <i class="fa fa-code-fork"></i>.
|
||||
- **edit-url-template:** Edit url template, when provided shows a
|
||||
"Suggest an edit" button (which looks like <i class="fa fa-edit"></i>) for directly jumping to editing the currently
|
||||
|
||||
@@ -363,3 +363,18 @@ fatigue," where people are trained to ignore them because they usually don't
|
||||
matter for what they're doing.
|
||||
|
||||
</div>
|
||||
|
||||
## Font-Awesome icons
|
||||
|
||||
mdBook includes a copy of [Font Awesome Free's](https://fontawesome.com)
|
||||
MIT-licensed SVG files. It emulates the `<i>` syntax, but converts the results
|
||||
to inline SVG. Only the regular, solid, and brands icons are included; paid
|
||||
features like the light icons are not.
|
||||
|
||||
For example, given this HTML syntax:
|
||||
|
||||
```hbs
|
||||
The result looks like this: <i class="fas fa-print"></i>
|
||||
```
|
||||
|
||||
The result looks like this: <i class="fas fa-print"></i>
|
||||
|
||||
@@ -86,3 +86,25 @@ and accounts for files that are renamed with a hash in their filename.
|
||||
```handlebars
|
||||
<link rel="stylesheet" href="{{ resource "css/chrome.css" }}">
|
||||
```
|
||||
|
||||
### fa
|
||||
|
||||
mdBook includes a copy of [Font Awesome Free's](https://fontawesome.com)
|
||||
MIT-licensed SVG files. It accepts three positional arguments:
|
||||
|
||||
1. Type: one of "solid", "regular", and "brands" (light and duotone are not
|
||||
currently supported)
|
||||
2. Icon: anything chosen from the
|
||||
[free icon set](https://fontawesome.com/icons?d=gallery&m=free)
|
||||
3. ID (optional): if included, an HTML ID attribute will be added to the
|
||||
icon's wrapping `<span>` tag
|
||||
|
||||
For example, this handlebars syntax will become this HTML:
|
||||
|
||||
```handlebars
|
||||
{{fa "solid" "print" "print-button"}}
|
||||
```
|
||||
|
||||
```html
|
||||
<span class=fa-svg id="print-button"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M448 192V77.25c0-8.49-3.37-16.62-9.37-22.63L393.37 9.37c-6-6-14.14-9.37-22.63-9.37H96C78.33 0 64 14.33 64 32v160c-35.35 0-64 28.65-64 64v112c0 8.84 7.16 16 16 16h48v96c0 17.67 14.33 32 32 32h320c17.67 0 32-14.33 32-32v-96h48c8.84 0 16-7.16 16-16V256c0-35.35-28.65-64-64-64zm-64 256H128v-96h256v96zm0-224H128V64h192v48c0 8.84 7.16 16 16 16h48v96zm48 72c-13.25 0-24-10.75-24-24 0-13.26 10.75-24 24-24s24 10.74 24 24c0 13.25-10.75 24-24 24z"/></svg></span>
|
||||
```
|
||||
|
||||
@@ -30,12 +30,12 @@ The icons displayed will depend on the settings of how the book was generated.
|
||||
|
||||
| Icon | Description |
|
||||
|------|-------------|
|
||||
| <i class="fa fa-bars"></i> | Opens and closes the chapter listing sidebar. |
|
||||
| <i class="fa fa-paint-brush"></i> | Opens a picker to choose a different color theme. |
|
||||
| <i class="fa fa-search"></i> | Opens a search bar for searching within the book. |
|
||||
| <i class="fa fa-print"></i> | Instructs the web browser to print the entire book. |
|
||||
| <i class="fa fa-github"></i> | Opens a link to the website that hosts the source code of the book. |
|
||||
| <i class="fa fa-edit"></i> | Opens a page to directly edit the source of the page you are currently reading. |
|
||||
| <i class="fas fa-bars"></i> | Opens and closes the chapter listing sidebar. |
|
||||
| <i class="fas fa-paintbrush"></i> | Opens a picker to choose a different color theme. |
|
||||
| <i class="fas fa-magnifying-glass"></i> | Opens a search bar for searching within the book. |
|
||||
| <i class="fas fa-print"></i> | Instructs the web browser to print the entire book. |
|
||||
| <i class="fab fa-github"></i> | Opens a link to the website that hosts the source code of the book. |
|
||||
| <i class="fas fa-pencil"></i> | Opens a page to directly edit the source of the page you are currently reading. |
|
||||
|
||||
Tapping the menu bar will scroll the page to the top.
|
||||
|
||||
@@ -59,9 +59,9 @@ Code blocks may contain several different icons for interacting with them:
|
||||
| Icon | Description |
|
||||
|------|-------------|
|
||||
| <i class="fa fa-copy"></i> | Copies the code block into your local clipboard, to allow pasting into another application. |
|
||||
| <i class="fa fa-play"></i> | For Rust code examples, this will execute the sample code and display the compiler output just below the example (see [playground]). |
|
||||
| <i class="fas fa-play"></i> | For Rust code examples, this will execute the sample code and display the compiler output just below the example (see [playground]). |
|
||||
| <i class="fa fa-eye"></i> | For Rust code examples, this will toggle visibility of "hidden" lines. Sometimes, larger examples will hide lines which are not particularly relevant to what is being illustrated (see [hiding code lines]). |
|
||||
| <i class="fa fa-history"></i> | For [editable code examples][editor], this will undo any changes you have made. |
|
||||
| <i class="fas fa-clock-rotate-left"></i> | For [editable code examples][editor], this will undo any changes you have made. |
|
||||
|
||||
Here's an example:
|
||||
|
||||
|
||||
Reference in New Issue
Block a user