rust-lang / mdBook

Create book from markdown files. Like Gitbook but implemented in Rust
https://rust-lang.github.io/mdBook/
Mozilla Public License 2.0
17.3k stars 1.59k forks source link

Support in-repo links, with verification and output-dependent conversion #431

Open behnam opened 6 years ago

behnam commented 6 years ago

While updating the new Cargo manual and preparing it for a release, I realized one big part of the work I was doing was to make sure the internal links are valid, after moving many pages around.

This made me realize that we don't have link verification for in-repo links, and partly it's because of the fact that the MD source files are linking to the HTML output files, but not to the respective MD source files.

Also, there's the fact that if there's ever any other output type, the internal links will be broken.

So, wondering if supporting in-repo links as link-to-source, plus link verification and output-dependent conversion, is something that's already in the plans for mdbook.

Example

Input

index.md

See the [first chapter](first/index.md).

This would error if first/index.md doesn't exist.

Output

If no errors, it converts the link to the HTML file.

index.html

[...]
<p>See the <a href="first/index.html">first chapter</a>.</p>
[...]
behnam commented 6 years ago

By the way, a side benefit of this is that the links will work in github rendering of the MD files, allowing easier source view and transition between pages.

oberien commented 6 years ago

I'm absolutely voting for this issue. I definitely want people to be able to browse the markdown files easily on github with all link pointing to the respective markdown files. To achieve this, I'm currently using a small bash-script, which copies the whole directory, replaces all links to point to their respective html page, and then call mdbook it. Unfortunately such a wrapper script does not allow usage of mdbook watch, which means that I can't use livereload, which is an absolute pity.

The disadvantage of my approach is that I need the exact same structure in the SUMMARY.md that I have on the filesystem. A proper solution should map those paths correctly, so that the fs structure and book structure can be different.

If anyone is interested, this is the relevant part of the script:

  mkdir -p build-dir
  cp -r src build-dir
  cd build-dir/src

  for f in **/*.md; do
    if [ $f == "SUMMARY.md" ]; then
      continue
    fi
    dir=`dirname $f`
    sed -i "s/\(\](\|]: \)\([^\/][a-zA-Z\.\/\-]\+\)\.md\(#[a-z]\+)\?\)\?/\1${dir//\//\\\/}\/\2\.html\3/g" $f
  done

  cd ..

  $MDBOOK build

  rm -r ../book
  mv book ..
  cd ..
  rm -r build-dir
Michael-F-Bryan commented 6 years ago

We're pretty much done extracting out the preprocessing into its own stage (#532), and once that lands it shouldn't be long before we have a proper solution which can understand the book structure. This is an issue which annoys me as well, so I'm keen to deal with it before the next release!

My mdbook-linkcheck backend includes a check for the exact case where you use a foo.md link instead of foo.html. If you want to try that out, feel free. Unfortunately alternate backends aren't available on crates.io yet because pulldown_cmark needs to make another release.

The disadvantage of my approach is that I need the exact same structure in the SUMMARY.md that I have on the filesystem. A proper solution should map those paths correctly, so that the fs structure and book structure can be different.

The HTML renderer replicates the source file structure when rendering (technically reusing the chapter's path field), so while it's still implementation-defined behaviour you should be okay with what you're doing at the moment.

simonsan commented 3 years ago

Any updates or workarounds for this? We currently suffer as well from this issue :-(

camelid commented 3 years ago

I thought this was implemented already? I know that the rustc-dev-guide uses ./foo.md-style links.

simonsan commented 3 years ago

We had to work around by naming them index.md instead of intro.md to get linked to an index.html in the top-level of the TOC.

ZeWaka commented 3 years ago

Any updates or workarounds for this? We currently suffer as well from this issue :-(

For anyone who comes across this in the future: https://github.com/Michael-F-Bryan/mdbook-linkcheck

tv42 commented 3 years ago

Linking to md files works, and it seems mdbook has settled on using README.md as the source name for index.html.

Perhaps those two should be split into their own issues and this one closed?

Michael-F-Bryan commented 3 years ago

The special name "README.md" is not documented.

@tv42, it's documented under the index preprocessor.

I don't see any kind of link checking existing in mdbook itself.

You are correct. The mdbook project deliberately chose to let the ecosystem develop plugins for these sorts of things instead of trying to include it all within the one project.

I believe The Rust Programming Language uses its own script for validating links, while a fair few other projects use the mdbook-linkcheck linked earlier.

tv42 commented 3 years ago

Ah, the index preprocessor. I feel like the documentation belongs somewhere near SUMMARY.md, just like {{#include}} is in https://rust-lang.github.io/mdBook/format/mdbook.html not in the links preprocessor at https://rust-lang.github.io/mdBook/format/configuration/preprocessors.html

tv42 commented 3 years ago

And if the project has decided link checking will not be part of the core, then that sounds like this issue is done (barring the wish for better & discoverable documentation).

Volker-Weissmann commented 2 years ago

mdbook-linkcheck exists, but it needs to be enabled by default. Otherwise, we will never be able to find and fix all 404 links.

Ev1lT3rm1nal commented 1 year ago

Any updates?

Trolldemorted commented 2 months ago

The mdbook project deliberately chose to let the ecosystem develop plugins for these sorts of things instead of trying to include it all within the one project.

Is there a chance that this decision is revisited? Consistency enforcement should be a core feature, not a plugin.