Sophie

Sophie

distrib > Mageia > 6 > x86_64 > media > core-updates > by-pkgid > 878cdd00a13d17a73c6619a777ef5d74 > files > 282

rust-doc-1.19.0-1.mga6.x86_64.rpm

<!DOCTYPE HTML>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Cargo Workspaces - The Rust Programming Language</title>
        <meta content="text/html; charset=utf-8" http-equiv="Content-Type">
        <meta name="description" content="">
        <meta name="viewport" content="width=device-width, initial-scale=1">

        <base href="">

        <link rel="stylesheet" href="book.css">
        <link href='https://fonts.googleapis.com/css?family=Open+Sans:300italic,400italic,600italic,700italic,800italic,400,300,600,700,800' rel='stylesheet' type='text/css'>

        <link rel="shortcut icon" href="favicon.png">

        <!-- Font Awesome -->
        <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css">

        <link rel="stylesheet" href="highlight.css">
        <link rel="stylesheet" href="tomorrow-night.css">
        <style>
            .page-wrapper.has-warning > .nav-chapters {
              /* add height for warning content & margin */
              top: 120px;
            }

            p.warning {
                background-color: rgb(242, 222, 222);
                border-bottom-color: rgb(238, 211, 215);
                border-bottom-left-radius: 4px;
                border-bottom-right-radius: 4px;
                border-bottom-style: solid;
                border-bottom-width: 0.666667px;
                border-image-outset: 0 0 0 0;
                border-image-repeat: stretch stretch;
                border-image-slice: 100% 100% 100% 100%;
                border-image-source: none;
                border-image-width: 1 1 1 1;
                border-left-color: rgb(238, 211, 215);
                border-left-style: solid;
                border-left-width: 0.666667px;
                border-right-color: rgb(238, 211, 215);
                border-right-style: solid;
                border-right-width: 0.666667px;
                border-top-color: rgb(238, 211, 215);
                border-top-left-radius: 4px;
                border-top-right-radius: 4px;
                border-top-style: solid;
                border-top-width: 0.666667px;
                color: rgb(185, 74, 72);
                margin-bottom: 0px;
                margin-left: 0px;
                margin-right: 0px;
                margin-top: 30px;
                padding-bottom: 8px;
                padding-left: 14px;
                padding-right: 35px;
                padding-top: 8px;
            }
            p.warning strong {
                color: rgb(185, 74, 72)
            }
            p.warning a {
                color: rgb(0, 136, 204)
            }
        </style>

        <!-- MathJax -->
        <script type="text/javascript" src="https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>

        <!-- Fetch JQuery from CDN but have a local fallback -->
        <script src="https://code.jquery.com/jquery-2.1.4.min.js"></script>
        <script>
            if (typeof jQuery == 'undefined') {
                document.write(unescape("%3Cscript src='jquery.js'%3E%3C/script%3E"));
            }
        </script>
    </head>
    <body class="light">
        <!-- Set the theme before any content is loaded, prevents flash -->
        <script type="text/javascript">
            var theme = localStorage.getItem('theme');
            if (theme == null) { theme = 'light'; }
            $('body').removeClass().addClass(theme);
        </script>

        <!-- Hide / unhide sidebar before it is displayed -->
        <script type="text/javascript">
            var sidebar = localStorage.getItem('sidebar');
            if (sidebar === "hidden") { $("html").addClass("sidebar-hidden") }
            else if (sidebar === "visible") { $("html").addClass("sidebar-visible") }
        </script>

        <div id="sidebar" class="sidebar">
            <ul class="chapter"><li><a href="ch01-00-introduction.html"><strong>1.</strong> Introduction</a></li><li><ul class="section"><li><a href="ch01-01-installation.html"><strong>1.1.</strong> Installation</a></li><li><a href="ch01-02-hello-world.html"><strong>1.2.</strong> Hello, World!</a></li></ul></li><li><a href="ch02-00-guessing-game-tutorial.html"><strong>2.</strong> Guessing Game Tutorial</a></li><li><a href="ch03-00-common-programming-concepts.html"><strong>3.</strong> Common Programming Concepts</a></li><li><ul class="section"><li><a href="ch03-01-variables-and-mutability.html"><strong>3.1.</strong> Variables and Mutability</a></li><li><a href="ch03-02-data-types.html"><strong>3.2.</strong> Data Types</a></li><li><a href="ch03-03-how-functions-work.html"><strong>3.3.</strong> How Functions Work</a></li><li><a href="ch03-04-comments.html"><strong>3.4.</strong> Comments</a></li><li><a href="ch03-05-control-flow.html"><strong>3.5.</strong> Control Flow</a></li></ul></li><li><a href="ch04-00-understanding-ownership.html"><strong>4.</strong> Understanding Ownership</a></li><li><ul class="section"><li><a href="ch04-01-what-is-ownership.html"><strong>4.1.</strong> What is Ownership?</a></li><li><a href="ch04-02-references-and-borrowing.html"><strong>4.2.</strong> References &amp; Borrowing</a></li><li><a href="ch04-03-slices.html"><strong>4.3.</strong> Slices</a></li></ul></li><li><a href="ch05-00-structs.html"><strong>5.</strong> Using Structs to Structure Related Data</a></li><li><ul class="section"><li><a href="ch05-01-defining-structs.html"><strong>5.1.</strong> Defining and Instantiating Structs</a></li><li><a href="ch05-02-example-structs.html"><strong>5.2.</strong> An Example Program Using Structs</a></li><li><a href="ch05-03-method-syntax.html"><strong>5.3.</strong> Method Syntax</a></li></ul></li><li><a href="ch06-00-enums.html"><strong>6.</strong> Enums and Pattern Matching</a></li><li><ul class="section"><li><a href="ch06-01-defining-an-enum.html"><strong>6.1.</strong> Defining an Enum</a></li><li><a href="ch06-02-match.html"><strong>6.2.</strong> The <code>match</code> Control Flow Operator</a></li><li><a href="ch06-03-if-let.html"><strong>6.3.</strong> Concise Control Flow with <code>if let</code></a></li></ul></li><li><a href="ch07-00-modules.html"><strong>7.</strong> Modules</a></li><li><ul class="section"><li><a href="ch07-01-mod-and-the-filesystem.html"><strong>7.1.</strong> <code>mod</code> and the Filesystem</a></li><li><a href="ch07-02-controlling-visibility-with-pub.html"><strong>7.2.</strong> Controlling Visibility with <code>pub</code></a></li><li><a href="ch07-03-importing-names-with-use.html"><strong>7.3.</strong> Importing Names with <code>use</code></a></li></ul></li><li><a href="ch08-00-common-collections.html"><strong>8.</strong> Common Collections</a></li><li><ul class="section"><li><a href="ch08-01-vectors.html"><strong>8.1.</strong> Vectors</a></li><li><a href="ch08-02-strings.html"><strong>8.2.</strong> Strings</a></li><li><a href="ch08-03-hash-maps.html"><strong>8.3.</strong> Hash Maps</a></li></ul></li><li><a href="ch09-00-error-handling.html"><strong>9.</strong> Error Handling</a></li><li><ul class="section"><li><a href="ch09-01-unrecoverable-errors-with-panic.html"><strong>9.1.</strong> Unrecoverable Errors with <code>panic!</code></a></li><li><a href="ch09-02-recoverable-errors-with-result.html"><strong>9.2.</strong> Recoverable Errors with <code>Result</code></a></li><li><a href="ch09-03-to-panic-or-not-to-panic.html"><strong>9.3.</strong> To <code>panic!</code> or Not To <code>panic!</code></a></li></ul></li><li><a href="ch10-00-generics.html"><strong>10.</strong> Generic Types, Traits, and Lifetimes</a></li><li><ul class="section"><li><a href="ch10-01-syntax.html"><strong>10.1.</strong> Generic Data Types</a></li><li><a href="ch10-02-traits.html"><strong>10.2.</strong> Traits: Defining Shared Behavior</a></li><li><a href="ch10-03-lifetime-syntax.html"><strong>10.3.</strong> Validating References with Lifetimes</a></li></ul></li><li><a href="ch11-00-testing.html"><strong>11.</strong> Testing</a></li><li><ul class="section"><li><a href="ch11-01-writing-tests.html"><strong>11.1.</strong> Writing tests</a></li><li><a href="ch11-02-running-tests.html"><strong>11.2.</strong> Running tests</a></li><li><a href="ch11-03-test-organization.html"><strong>11.3.</strong> Test Organization</a></li></ul></li><li><a href="ch12-00-an-io-project.html"><strong>12.</strong> An I/O Project</a></li><li><ul class="section"><li><a href="ch12-01-accepting-command-line-arguments.html"><strong>12.1.</strong> Accepting Command Line Arguments</a></li><li><a href="ch12-02-reading-a-file.html"><strong>12.2.</strong> Reading a File</a></li><li><a href="ch12-03-improving-error-handling-and-modularity.html"><strong>12.3.</strong> Improving Error Handling and Modularity</a></li><li><a href="ch12-04-testing-the-librarys-functionality.html"><strong>12.4.</strong> Testing the Library's Functionality</a></li><li><a href="ch12-05-working-with-environment-variables.html"><strong>12.5.</strong> Working with Environment Variables</a></li><li><a href="ch12-06-writing-to-stderr-instead-of-stdout.html"><strong>12.6.</strong> Writing to <code>stderr</code> instead of <code>stdout</code></a></li></ul></li><li><a href="ch13-00-functional-features.html"><strong>13.</strong> Functional Language Features in Rust</a></li><li><ul class="section"><li><a href="ch13-01-closures.html"><strong>13.1.</strong> Closures</a></li><li><a href="ch13-02-iterators.html"><strong>13.2.</strong> Iterators</a></li><li><a href="ch13-03-improving-our-io-project.html"><strong>13.3.</strong> Improving our I/O Project</a></li><li><a href="ch13-04-performance.html"><strong>13.4.</strong> Performance</a></li></ul></li><li><a href="ch14-00-more-about-cargo.html"><strong>14.</strong> More about Cargo and Crates.io</a></li><li><ul class="section"><li><a href="ch14-01-release-profiles.html"><strong>14.1.</strong> Release Profiles</a></li><li><a href="ch14-02-publishing-to-crates-io.html"><strong>14.2.</strong> Publishing a Crate to Crates.io</a></li><li><a href="ch14-03-cargo-workspaces.html" class="active"><strong>14.3.</strong> Cargo Workspaces</a></li><li><a href="ch14-04-installing-binaries.html"><strong>14.4.</strong> Installing Binaries from Crates.io with <code>cargo install</code></a></li><li><a href="ch14-05-extending-cargo.html"><strong>14.5.</strong> Extending Cargo with Custom Commands</a></li></ul></li><li><a href="ch15-00-smart-pointers.html"><strong>15.</strong> Smart Pointers</a></li><li><ul class="section"><li><a href="ch15-01-box.html"><strong>15.1.</strong> <code>Box&lt;T&gt;</code> Points to Data on the Heap and Has a Known Size</a></li><li><a href="ch15-02-deref.html"><strong>15.2.</strong> The <code>Deref</code> Trait Allows Access to the Data Through a Reference</a></li><li><a href="ch15-03-drop.html"><strong>15.3.</strong> The <code>Drop</code> Trait Runs Code on Cleanup</a></li><li><a href="ch15-04-rc.html"><strong>15.4.</strong> <code>Rc&lt;T&gt;</code>, the Reference Counted Smart Pointer</a></li><li><a href="ch15-05-interior-mutability.html"><strong>15.5.</strong> <code>RefCell&lt;T&gt;</code> and the Interior Mutability Pattern</a></li><li><a href="ch15-06-reference-cycles.html"><strong>15.6.</strong> Creating Reference Cycles and Leaking Memory is Safe</a></li></ul></li><li><a href="ch16-00-concurrency.html"><strong>16.</strong> Fearless Concurrency</a></li><li><ul class="section"><li><a href="ch16-01-threads.html"><strong>16.1.</strong> Threads</a></li><li><a href="ch16-02-message-passing.html"><strong>16.2.</strong> Message Passing</a></li><li><a href="ch16-03-shared-state.html"><strong>16.3.</strong> Shared State</a></li><li><a href="ch16-04-extensible-concurrency-sync-and-send.html"><strong>16.4.</strong> Extensible Concurrency: <code>Sync</code> and <code>Send</code></a></li></ul></li><li><a href="ch17-00-oop.html"><strong>17.</strong> Is Rust an Object-Oriented Programming Language?</a></li><li><ul class="section"><li><a href="ch17-01-what-is-oo.html"><strong>17.1.</strong> What Does Object-Oriented Mean?</a></li><li><a href="ch17-02-trait-objects.html"><strong>17.2.</strong> Trait Objects for Using Values of Different Types</a></li><li><a href="ch17-03-oo-design-patterns.html"><strong>17.3.</strong> Object-Oriented Design Pattern Implementations</a></li></ul></li><li><a href="ch18-00-patterns.html"><strong>18.</strong> Patterns Match the Structure of Values</a></li><li><ul class="section"><li><a href="ch18-01-all-the-places-for-patterns.html"><strong>18.1.</strong> All the Places Patterns May be Used</a></li><li><a href="ch18-02-refutability.html"><strong>18.2.</strong> Refutability: Whether a Pattern Might Fail to Match</a></li><li><a href="ch18-03-pattern-syntax.html"><strong>18.3.</strong> All the Pattern Syntax</a></li></ul></li><li><a href="ch19-00-advanced-features.html"><strong>19.</strong> Advanced Features</a></li><li><ul class="section"><li><a href="ch19-01-unsafe-rust.html"><strong>19.1.</strong> Unsafe Rust</a></li><li><a href="ch19-02-advanced-lifetimes.html"><strong>19.2.</strong> Advanced Lifetimes</a></li><li><a href="ch19-03-advanced-traits.html"><strong>19.3.</strong> Advanced Traits</a></li><li><a href="ch19-04-advanced-types.html"><strong>19.4.</strong> Advanced Types</a></li><li><a href="ch19-05-advanced-functions-and-closures.html"><strong>19.5.</strong> Advanced Functions &amp; Closures</a></li></ul></li><li><a href="ch20-00-final-project-a-web-server.html"><strong>20.</strong> Final Project: Building a Multithreaded Web Server</a></li><li><ul class="section"><li><a href="ch20-01-single-threaded.html"><strong>20.1.</strong> A Single Threaded Web Server</a></li><li><a href="ch20-02-slow-requests.html"><strong>20.2.</strong> How Slow Requests Affect Throughput</a></li><li><a href="ch20-03-designing-the-interface.html"><strong>20.3.</strong> Designing the Thread Pool Interface</a></li><li><a href="ch20-04-storing-threads.html"><strong>20.4.</strong> Creating the Thread Pool and Storing Threads</a></li><li><a href="ch20-05-sending-requests-via-channels.html"><strong>20.5.</strong> Sending Requests to Threads Via Channels</a></li><li><a href="ch20-06-graceful-shutdown-and-cleanup.html"><strong>20.6.</strong> Graceful Shutdown and Cleanup</a></li></ul></li><li><a href="appendix-00.html"><strong>21.</strong> Appendix</a></li><li><ul class="section"><li><a href="appendix-01-keywords.html"><strong>21.1.</strong> A - Keywords</a></li><li><a href="appendix-02-operators.html"><strong>21.2.</strong> B - Operators</a></li><li><strong>21.3.</strong> C - Derivable Traits</li><li><strong>21.4.</strong> D - Nightly Rust</li><li><strong>21.5.</strong> E - Macros</li><li><strong>21.6.</strong> F - Translations</li><li><a href="appendix-07-newest-features.html"><strong>21.7.</strong> G - Newest Features</a></li></ul></li></ul>
        </div>

        <div id="page-wrapper" class="page-wrapper has-warning">

            <div class="page">
                <header><p class="warning">You are reading a <strong>draft</strong> of the next edition of TRPL. For more, go <a href="../index.html">here</a>.</p></header>
                <div id="menu-bar" class="menu-bar">
                    <div class="left-buttons">
                        <i id="sidebar-toggle" class="fa fa-bars"></i>
                        <i id="theme-toggle" class="fa fa-paint-brush"></i>
                    </div>

                    <h1 class="menu-title">The Rust Programming Language</h1>

                    <div class="right-buttons">
                        <i id="print-button" class="fa fa-print" title="Print this book"></i>
                    </div>
                </div>


                <div id="content" class="content">
                    <a class="header" href="ch14-03-cargo-workspaces.html#cargo-workspaces" id="cargo-workspaces"><h2>Cargo Workspaces</h2></a>
<p>In Chapter 12, we built a package that included both a binary crate and a
library crate. But what if the library crate continues to get bigger and we
want to split our package up further into multiple library crates? As packages
grow, separating out major components can be quite useful. In this situation,
Cargo has a feature called <em>workspaces</em> that can help us manage multiple
related packages that are developed in tandem.</p>
<p>A <em>workspace</em> is a set of packages that will all share the same <em>Cargo.lock</em>
and output directory. Let's make a project using a workspace where the code
will be trivial so that we can concentrate on the structure of a workspace.
We'll have a binary that uses two libraries: one that will provide an <code>add_one</code>
method and a second that will provide an <code>add_two</code> method. Let's start by
creating a new crate for the binary:</p>
<pre><code class="language-text">$ cargo new --bin adder
     Created binary (application) `adder` project
$ cd adder
</code></pre>
<p>We need to modify the binary package's <em>Cargo.toml</em> to tell Cargo the <code>adder</code>
package is a workspace. Add this at the bottom of the file:</p>
<pre><code class="language-toml">[workspace]
</code></pre>
<p>Like many Cargo features, workspaces support convention over configuration: we
don't need to say anything more than this as long as we follow the convention.
The convention is that any crates that we depend on as sub-directories will be
part of the workspace. Let's add a path dependency to the <code>adder</code> crate by
changing the <code>[dependencies]</code> section of <em>Cargo.toml</em> to look like this:</p>
<pre><code class="language-toml">[dependencies]
add-one = { path = &quot;add-one&quot; }
</code></pre>
<p>If we add dependencies that don't have a <code>path</code> specified, those will be normal
dependencies that aren't in this workspace.</p>
<p>Next, generate the <code>add-one</code> crate within the <code>adder</code> directory:</p>
<pre><code class="language-text">$ cargo new add-one
     Created library `add-one` project
</code></pre>
<p>Your <code>adder</code> directory should now have these directories and files:</p>
<pre><code class="language-text">├── Cargo.toml
├── add-one
│   ├── Cargo.toml
│   └── src
│       └── lib.rs
└── src
    └── main.rs
</code></pre>
<p>In <em>add-one/src/lib.rs</em>, let's add an implementation of an <code>add_one</code> function:</p>
<p><span class="filename">Filename: add-one/src/lib.rs</span></p>
<pre><pre class="playpen"><code class="language-rust"># #![allow(unused_variables)]
#fn main() {
pub fn add_one(x: i32) -&gt; i32 {
    x + 1
}

#}</code></pre></pre>
<p>Open up <em>src/main.rs</em> for <code>adder</code> and add an <code>extern crate</code> line to bring the
new <code>add-one</code> library crate into scope, and change the <code>main</code> function to use
the <code>add_one</code> function:</p>
<pre><code class="language-rust ignore">extern crate add_one;

fn main() {
    let num = 10;
    println!(&quot;Hello, world! {} plus one is {}!&quot;, num, add_one::add_one(num));
}
</code></pre>
<p>Let's build it!</p>
<pre><code class="language-text">$ cargo build
   Compiling add-one v0.1.0 (file:///projects/adder/add-one)
   Compiling adder v0.1.0 (file:///projects/adder)
    Finished dev [unoptimized + debuginfo] target(s) in 0.68 secs
</code></pre>
<p>Note that running <code>cargo build</code> in the <em>adder</em> directory built both that crate
and the <code>add-one</code> crate in <em>adder/add-one</em>, but created only one <em>Cargo.lock</em>
and one <em>target</em> directory, both in the <em>adder</em> directory. See if you can add
an <code>add-two</code> crate in the same way.</p>
<p>Let's now say that we'd like to use the <code>rand</code> crate in our <code>add-one</code> crate.
As usual, we'll add it to the <code>[dependencies]</code> section in the <code>Cargo.toml</code> for
that crate:</p>
<p><span class="filename">Filename: add-one/Cargo.toml</span></p>
<pre><code class="language-toml">[dependencies]

rand = &quot;0.3.14&quot;
</code></pre>
<p>And if we add <code>extern crate rand;</code> to <em>add-one/src/lib.rs</em> then run <code>cargo build</code>, it will succeed:</p>
<pre><code class="language-text">$ cargo build
    Updating registry `https://github.com/rust-lang/crates.io-index`
 Downloading rand v0.3.14
   ...snip...
   Compiling rand v0.3.14
   Compiling add-one v0.1.0 (file:///projects/adder/add-one)
   Compiling adder v0.1.0 (file:///projects/adder)
    Finished dev [unoptimized + debuginfo] target(s) in 10.18 secs
</code></pre>
<p>The top level <em>Cargo.lock</em> now reflects the fact that <code>add-one</code> depends
on <code>rand</code>. However, even though <code>rand</code> is used somewhere in the
workspace, we can't use it in other crates in the workspace unless we add
<code>rand</code> to their <em>Cargo.toml</em> as well. If we add <code>extern crate rand;</code> to
<em>src/main.rs</em> for the top level <code>adder</code> crate, for example, we'll get an error:</p>
<pre><code class="language-text">$ cargo build
   Compiling adder v0.1.0 (file:///projects/adder)
error[E0463]: can't find crate for `rand`
 --&gt; src/main.rs:1:1
  |
1 | extern crate rand;
  | ^^^^^^^^^^^^^^^^^^^ can't find crate
</code></pre>
<p>To fix this, edit <em>Cargo.toml</em> for the top level and indicate that <code>rand</code> is a
dependency for the <code>adder</code> crate.</p>
<p>For another enhancement, let's add a test of the <code>add_one::add_one</code> function
within that crate:</p>
<p><span class="filename">Filename: add-one/src/lib.rs</span></p>
<pre><pre class="playpen"><code class="language-rust"># #![allow(unused_variables)]
#fn main() {
pub fn add_one(x: i32) -&gt; i32 {
    x + 1
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn it_works() {
        assert_eq!(3, add_one(2));
    }
}

#}</code></pre></pre>
<p>Now run <code>cargo test</code> in the top-level <em>adder</em> directory:</p>
<pre><code class="language-text">$ cargo test
   Compiling adder v0.1.0 (file:///projects/adder)
    Finished dev [unoptimized + debuginfo] target(s) in 0.27 secs
     Running target/debug/adder-f0253159197f7841

running 0 tests

test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured
</code></pre>
<p>Wait a second, zero tests? We just added one! If we look at the output, we can
see that <code>cargo test</code> in a workspace only runs the tests for the top level
crate. To run tests for the other crates, we need to use the <code>-p</code> argument to
indicate we want to run tests for a particular package:</p>
<pre><code class="language-text">$ cargo test -p add-one
    Finished dev [unoptimized + debuginfo] target(s) in 0.0 secs
     Running target/debug/deps/add_one-abcabcabc

running 1 test
test tests::it_works ... ok

test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured

   Doc-tests add-one

running 0 tests

test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured
</code></pre>
<p>Similarly, if you choose to publish the workspace to crates.io, each crate in
the workspace will get published separately.</p>
<p>As your project grows, consider a workspace: smaller components are easier to
understand individually than one big blob of code. Keeping the crates in a
workspace can make coordination among them easier if they work together and are
often changed at the same time.</p>

                </div>

                <!-- Mobile navigation buttons -->
                
                    <a href="ch14-02-publishing-to-crates-io.html" class="mobile-nav-chapters previous">
                        <i class="fa fa-angle-left"></i>
                    </a>
                

                
                    <a href="ch14-04-installing-binaries.html" class="mobile-nav-chapters next">
                        <i class="fa fa-angle-right"></i>
                    </a>
                

            </div>

            
                <a href="ch14-02-publishing-to-crates-io.html" class="nav-chapters previous" title="You can navigate through the chapters using the arrow keys">
                    <i class="fa fa-angle-left"></i>
                </a>
            

            
                <a href="ch14-04-installing-binaries.html" class="nav-chapters next" title="You can navigate through the chapters using the arrow keys">
                    <i class="fa fa-angle-right"></i>
                </a>
            

        </div>


        <!-- Local fallback for Font Awesome -->
        <script>
            if ($(".fa").css("font-family") !== "FontAwesome") {
                $('<link rel="stylesheet" type="text/css" href="_FontAwesome/css/font-awesome.css">').prependTo('head');
            }
        </script>

        <!-- Livereload script (if served using the cli tool) -->
        

        <script src="highlight.js"></script>
        <script src="book.js"></script>
    </body>
</html>