Skip to content

Single page support #301

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
budziq opened this issue May 27, 2017 · 14 comments
Closed

Single page support #301

budziq opened this issue May 27, 2017 · 14 comments
Labels
A-Rendering Area: Rendering C-enhancement Category: Enhancement or feature request S-Wishlist Status: Wishlist

Comments

@budziq
Copy link
Contributor

budziq commented May 27, 2017

Hi,

It would be great to have support for single page rendering and serving.
For instance if I'd like to prepare a nice CONTRIBUTING.md or README.md for my project locally.

From the user perspective all the mdbook commands would work identically as if the [dir] were given but the target path would be a single Markdown file.

I do not know yet how much work would it take (most likely mdbook is quite coupled to the book/chapters idea) but I would be willing to work on it if there is interest in such feature and someone to give some guidance around the codebase ;)

@azerupi
Copy link
Contributor

azerupi commented May 27, 2017

I have heard this desire from at least one other person and even though I have personally no use for it at the moment, it would certainly be a nice addition.

But before you dive in, I think it would be interesting to first think about what is needed and how it would look like. Write down a very informal idea with some requirements and expectations. With that we will have a better view of how it can be best implemented and what we would need to change in the current design.

For example, for a single markdown page I suppose you would drop the sidebar? What if the user supplies a list of markdown files? Would the sidebar reappear and in what order would the files be displayed? Would we look for a configuration file beside the file or would we just take a default?
Giving an answer to such questions will help us make a plan for the implementation :)

someone to give some guidance around the codebase

I am happy to help, don't hesitate to ask any question you have. Unfortunately it's that time of the year and I am supposed to study for my exams, so I might not always answer immediately. But I will do my best 😉

@budziq
Copy link
Contributor Author

budziq commented May 27, 2017

Write down a very informal idea with some requirements and expectations.

Definitely will do! I'll write something constructive later today when I'm not on mobile 😃

@budziq
Copy link
Contributor Author

budziq commented May 27, 2017

1. My original idea

mdbook serve [FLAGS] [OPTIONS] [dir|file]

Allow user to specify optional [file] instead of [dir] for serve and build subcommands (not sure about test yet). [file] and [dir] would be mutually exclusive.

  • generate a single rendered page from specified file (and serve it)
  • without sidebar
  • config would not be mandatory (load defaults) but used if already present.

2. Your idea with multiple files

mdbook serve [FLAGS] [OPTIONS] [dir| [file..]]

This would be an interesting extension but outside of the scope of what I need ATM
Allow user to specify optional [[file]..] list instead of [dir] for serve and build

  • Generate a book exactly as if SUMMARY.md would be filled with contents of [[file]..] list (all on root level).
  • sidebar would appear only if there is more than one page
  • title and sidebar entries would be filled with text from the first heading for given file (or filename if no heading present)
  • config file would not be mandatory (load defaults) but used if already present.

3. Initial ideas for implementation

  • update cli commands in mdbook.rs for [dir] to support filenames
  • rewrite / split book::init to understand that we might work in "file list mode"
    • possibly create two distinct constructors for book. book::new_from_dir book::new_from_files
    • possibly move book::init into one of the book constructors. Does it make sense as a stand alone method?
    • run parse_summary only in the [dir] mode
  • split parse::construct_bookitems into two variants parse::bookitems_from_summary parse::bookitems_from_listor just allow for adding these by hand with filenames
  • add BookItems from filenames

Rest of the flow should be similar. Does it make sense?

@azerupi Thanks for your time and good luck on the exams 👍

@budziq
Copy link
Contributor Author

budziq commented May 27, 2017

And don't wory about timing of your responses, there is no real urgency except or lack of something fun to tinker on 😄. I really appreciate your help.

@azerupi
Copy link
Contributor

azerupi commented May 28, 2017

Very nice write up, thanks!

Point 1. and 2. sound good, nothing to say about that :)

rewrite / split book::init to understand that we might work in "file list mode"

I don't think an init phase is necessary for files. If the file does not exists, we error and exit.

possibly move book::init into one of the book constructors. Does it make sense as a stand alone method?

I think that, in the long run, it would be better to provide more elementary methods like 'create config', 'create summary', ... And then actually implementing the init procedure in the CLI

possibly create two distinct constructors for book. book::new_from_dir book::new_from_files

I would use an empty / default constructor book::new and have builder methods to add files etc.

let mut book = MDBook::new()
book.add_chapter(...)

Anyways, it looks very sound in general :)

When you begin, I recommend that you make several scope-limited PRs as you go. For example, if you need to refactor some parts, make a separate PR. This will make it easier to review for me / us and allows us to give you some feedback about the direction you are going before you are too far along :)

@budziq
Copy link
Contributor Author

budziq commented May 28, 2017

Thanks for your time. I'll try to carve out some free time to work on it this week and send some minimal PR's for review :)

@azerupi azerupi added A-Rendering Area: Rendering S-Wishlist Status: Wishlist C-enhancement Category: Enhancement or feature request labels Jun 12, 2017
@heyakyra
Copy link

Maybe this should be renamed Single-File Input Mode? I just filed a separate ticket for a single page mode (as in rendered as a single page application) #982 so not sure the best way to distinguish these two

@heyakyra
Copy link

I have tried several ways to workaround this. A single introduction file doesn't allow the sidebar to be populated with links to the heading anchors.

both of these SUMMARY.md attempts simply break the build step (not surprising, just wish there was a reasonable workaround in the meantime)

# Table of Contents

- [Introduction](./Introduction.md)
- [Heading1](#heading1)
- [Heading2](#heading2)
- [Heading3](#heading3)
# Table of Contents

- [Introduction](./Introduction.md)
- [Heading1](./Introduction.md#heading1)
- [Heading2](./Introduction.md#heading2)
- [Heading3](./Introduction.md#heading3)

@Dylan-DPC-zz
Copy link

Closing this since we can carry on the discussion on the new issue. Thanks

@est31
Copy link
Member

est31 commented Jul 20, 2019

@Dylan-DPC no it's two different things. Please don't close. SPAs are a js heavy application coding pattern while this issue concerns having writing to a single html file, optimally without any js involved needing to view it.

I dislike the way the books are structured that there is forced interactivity. You have to click these buttons instead of just being able to scroll down the page. It makes quickly skimming what you want to find really hard. See also @bluss's opinion on this here.

@est31
Copy link
Member

est31 commented Jul 23, 2019

Ok I've agreed with @Dylan-DPC (who still seems to be a bit confused) to open a new issue here: #988

@Dylan-DPC-zz
Copy link

I'm not confused now :P but still prefer a new issue so that we don't notify everyone here and also so that we don't overlook it (because we rarely check old issues at the moment). Sorry for the trouble and thanks!

@heyakyra
Copy link

Errr... I believe #988 is a duplicate of #982, but this ticket was meant to be aboout the input being a single file.

@stephenlf-ems
Copy link

stephenlf-ems commented Apr 17, 2024

For those of you who still want a single-page input, you can use this bash script I wrote.

It takes three parameters: <FILEPATH>, <TITLE>, and optionally [OUTPUT-DIR]. It will quickly spin up a boilerplate mdbook project, copy the specified file to it, build it, then clean it up.

Installation

  1. Copy the contents of this script to mdbook-oneoff
  2. Make the script executable: chmod +x mdbook-oneoff
  3. Move the script to somewhere in PATH:

Example usage
mdbook-oneoff ./README.md 'Test Readme' ./mdbook-oneoff-build

This will output a directory mdbook-oneoff-build with the contents of the build process. The entrypoint to this directory is "index.html", like normal.

SCRIPT:

#!/bin/bash

USAGE='USAGE: mdbook-oneoff <FILEPATH> <TITLE> [OUTPUT-DIR]'

# Check that two parameters were supplied
[ -z "$2" ] && echo $USAGE && exit 1
TITLE=$2
# Check that <FILE> is a file
[ ! -f "$1" ] && echo $USAGE && exit 2
FILEPATH=$1
# Check that staging directory does not already exist
STAGING_DIR='./__mdbook-oneoff-delete-me__'
[ -d $STAGING_DIR ] && echo 'Please rmdir $STAGING_DIR' && exit 3
# Assign output_dir variable
OUTPUT_DIR=$3
    # If no parameter was supplied, use the default
[ -z $3 ] && OUTPUT_DIR='mdbook-oneoff-build'

mkdir $STAGING_DIR
cd $STAGING_DIR

# Init and clean up mdbook directory
mdbook init --force --ignore none
rm src/*
rmdir book

# Copy FILE into mdbook dir
cp ../$FILEPATH ./src
FILE=$(ls ./src)

# Set up SUMMARY and book.toml
printf '# SUMMARY\n' > ./src/SUMMARY.md
printf '[%s](%s)' "$TITLE" $FILE >> ./src/SUMMARY.md
printf '\ntitle = "%s"' "$TITLE" >> ./book.toml

# Build and clean up
mdbook build -d ../$OUTPUT_DIR
rm src/*
rmdir src
rm book.toml
cd ..
rmdir $STAGING_DIR

EDIT:

You can use monolith (cargo install monolith) to rebuild the output as a single HTML5 file.

Example

mdbook-oneoff ./README.md 'Test Readme' ./mdbook-oneoff-build
monolith ./mdbook-oneoff-build/index.html > README.html

This will convert a plain README.md into a beautiful, mdbook-rendered static HTML file at README.html.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-Rendering Area: Rendering C-enhancement Category: Enhancement or feature request S-Wishlist Status: Wishlist
Projects
None yet
Development

No branches or pull requests

6 participants