Add a CLI option to open a web browser

This commit is contained in:
Matt Brubeck 2017-01-01 09:42:47 -08:00
parent 375502a6fa
commit 21bc3d47c8
5 changed files with 41 additions and 1 deletions

View File

@ -23,6 +23,7 @@ pulldown-cmark = "0.0.8"
log = "0.3" log = "0.3"
env_logger = "0.3" env_logger = "0.3"
toml = { version = "0.2", features = ["serde"] } toml = { version = "0.2", features = ["serde"] }
open = "1.1"
# Watch feature # Watch feature
notify = { version = "2.5.5", optional = true } notify = { version = "2.5.5", optional = true }

View File

@ -21,6 +21,11 @@ current working directory.
mdbook build path/to/book mdbook build path/to/book
``` ```
#### --open
When you use the `--open` (`-o`) option, mdbook will open the rendered book in
your default web browser after building it.
------------------- -------------------
***note:*** *make sure to run the build command in the root directory and not in the source directory* ***note:*** *make sure to run the build command in the root directory and not in the source directory*

View File

@ -26,6 +26,11 @@ mdbook server path/to/book -p 8000 -i 127.0.0.1 -a 192.168.1.100
If you were to want live reloading for this you would need to proxy the websocket calls through nginx as well from `192.168.1.100:<WS_PORT>` to `127.0.0.1:<WS_PORT>`. The `-w` flag allows for the websocket port to be configured. If you were to want live reloading for this you would need to proxy the websocket calls through nginx as well from `192.168.1.100:<WS_PORT>` to `127.0.0.1:<WS_PORT>`. The `-w` flag allows for the websocket port to be configured.
#### --open
When you use the `--open` (`-o`) option, mdbook will open the book in your
your default web browser after starting the server.
----- -----
***note:*** *the `serve` command has not gotten a lot of testing yet, there could be some rough edges. If you discover a problem, please report it [on Github](https://github.com/azerupi/mdBook/issues)* ***note:*** *the `serve` command has not gotten a lot of testing yet, there could be some rough edges. If you discover a problem, please report it [on Github](https://github.com/azerupi/mdBook/issues)*

View File

@ -12,6 +12,10 @@ current working directory.
mdbook watch path/to/book mdbook watch path/to/book
``` ```
#### --open
When you use the `--open` (`-o`) option, mdbook will open the rendered book in
your default web browser.
----- -----

View File

@ -5,6 +5,7 @@ extern crate clap;
#[macro_use] #[macro_use]
extern crate log; extern crate log;
extern crate env_logger; extern crate env_logger;
extern crate open;
// Dependencies for the Watch feature // Dependencies for the Watch feature
#[cfg(feature = "watch")] #[cfg(feature = "watch")]
@ -24,6 +25,7 @@ extern crate ws;
use std::env; use std::env;
use std::error::Error; use std::error::Error;
use std::ffi::OsStr;
use std::io::{self, Write}; use std::io::{self, Write};
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
@ -59,9 +61,11 @@ fn main() {
.arg_from_usage("--force 'skip confirmation prompts'")) .arg_from_usage("--force 'skip confirmation prompts'"))
.subcommand(SubCommand::with_name("build") .subcommand(SubCommand::with_name("build")
.about("Build the book from the markdown files") .about("Build the book from the markdown files")
.arg_from_usage("-o, --open 'Open the compiled book in a web browser'")
.arg_from_usage("[dir] 'A directory for your book{n}(Defaults to Current Directory when ommitted)'")) .arg_from_usage("[dir] 'A directory for your book{n}(Defaults to Current Directory when ommitted)'"))
.subcommand(SubCommand::with_name("watch") .subcommand(SubCommand::with_name("watch")
.about("Watch the files for changes") .about("Watch the files for changes")
.arg_from_usage("-o, --open 'Open the compiled book in a web browser'")
.arg_from_usage("[dir] 'A directory for your book{n}(Defaults to Current Directory when ommitted)'")) .arg_from_usage("[dir] 'A directory for your book{n}(Defaults to Current Directory when ommitted)'"))
.subcommand(SubCommand::with_name("serve") .subcommand(SubCommand::with_name("serve")
.about("Serve the book at http://localhost:3000. Rebuild and reload on change.") .about("Serve the book at http://localhost:3000. Rebuild and reload on change.")
@ -69,7 +73,8 @@ fn main() {
.arg_from_usage("-p, --port=[port] 'Use another port{n}(Defaults to 3000)'") .arg_from_usage("-p, --port=[port] 'Use another port{n}(Defaults to 3000)'")
.arg_from_usage("-w, --websocket-port=[ws-port] 'Use another port for the websocket connection (livereload){n}(Defaults to 3001)'") .arg_from_usage("-w, --websocket-port=[ws-port] 'Use another port for the websocket connection (livereload){n}(Defaults to 3001)'")
.arg_from_usage("-i, --interface=[interface] 'Interface to listen on{n}(Defaults to localhost)'") .arg_from_usage("-i, --interface=[interface] 'Interface to listen on{n}(Defaults to localhost)'")
.arg_from_usage("-a, --address=[address] 'Address that the browser can reach the websocket server from{n}(Defaults to the interface addres)'")) .arg_from_usage("-a, --address=[address] 'Address that the browser can reach the websocket server from{n}(Defaults to the interface address)'")
.arg_from_usage("-o, --open 'Open the book server in a web browser'"))
.subcommand(SubCommand::with_name("test") .subcommand(SubCommand::with_name("test")
.about("Test that code samples compile")) .about("Test that code samples compile"))
.get_matches(); .get_matches();
@ -163,6 +168,10 @@ fn build(args: &ArgMatches) -> Result<(), Box<Error>> {
try!(book.build()); try!(book.build());
if args.is_present("open") {
open(book.get_dest().join("index.html"));
}
Ok(()) Ok(())
} }
@ -173,6 +182,11 @@ fn watch(args: &ArgMatches) -> Result<(), Box<Error>> {
let book_dir = get_book_dir(args); let book_dir = get_book_dir(args);
let mut book = MDBook::new(&book_dir).read_config(); let mut book = MDBook::new(&book_dir).read_config();
if args.is_present("open") {
try!(book.build());
open(book.get_dest().join("index.html"));
}
trigger_on_change(&mut book, |event, book| { trigger_on_change(&mut book, |event, book| {
if let Some(path) = event.path { if let Some(path) = event.path {
println!("File changed: {:?}\nBuilding book...\n", path); println!("File changed: {:?}\nBuilding book...\n", path);
@ -199,6 +213,7 @@ fn serve(args: &ArgMatches) -> Result<(), Box<Error>> {
let ws_port = args.value_of("ws-port").unwrap_or("3001"); let ws_port = args.value_of("ws-port").unwrap_or("3001");
let interface = args.value_of("interface").unwrap_or("localhost"); let interface = args.value_of("interface").unwrap_or("localhost");
let public_address = args.value_of("address").unwrap_or(interface); let public_address = args.value_of("address").unwrap_or(interface);
let open_browser = args.is_present("open");
let address = format!("{}:{}", interface, port); let address = format!("{}:{}", interface, port);
let ws_address = format!("{}:{}", interface, ws_port); let ws_address = format!("{}:{}", interface, ws_port);
@ -239,6 +254,10 @@ fn serve(args: &ArgMatches) -> Result<(), Box<Error>> {
println!("\nServing on {}", address); println!("\nServing on {}", address);
if open_browser {
open(format!("http://{}", address));
}
trigger_on_change(&mut book, move |event, book| { trigger_on_change(&mut book, move |event, book| {
if let Some(path) = event.path { if let Some(path) = event.path {
println!("File changed: {:?}\nBuilding book...\n", path); println!("File changed: {:?}\nBuilding book...\n", path);
@ -278,6 +297,12 @@ fn get_book_dir(args: &ArgMatches) -> PathBuf {
} }
} }
fn open<P: AsRef<OsStr>>(path: P) {
if let Err(e) = open::that(path) {
println!("Error opening web browser: {}", e);
}
}
// Calls the closure when a book source file is changed. This is blocking! // Calls the closure when a book source file is changed. This is blocking!
#[cfg(feature = "watch")] #[cfg(feature = "watch")]