crystal icon indicating copy to clipboard operation
crystal copied to clipboard

Include static assets in doc generator

Open straight-shoota opened this issue 2 years ago • 7 comments

The doc generator currently only renders the Readme file from the repository. It does not allow to link to any assets included in the repository because they won't be included in the generator output.

An example for that would be an image file used in the Readme (#13755).

I think the easiest implementation would be to copy the contents of a specific directory (proposal: /doc) into the generator output: FileUtils.cp_r("doc", @output_dir).

straight-shoota avatar Aug 18 '23 07:08 straight-shoota

I think this could possibly be implemented in this way:

  • Have the docs generator find all links in the markdown
  • Select links that point to files in the repository
  • For each link, verify it's a file (not a symlink), that it's not too big (50MB? 100MB?), and (maybe) that it's an image
  • copy those images to /docs/assets and override the link in the generated docs to the new place, modifying the filename if there are duplicates

What do you think about this? My thought is that it allows people to put images wherever and link to them however, while also allowing a consistent place in the output. This also adds some security through not allowing images that are too big and (possibly) only allowing images. This is also backwards compatible with how images are called now, without needing people to change their READMEs.

If you think this is a good idea I could start trying to implement it.

nobodywasishere avatar Sep 25 '23 09:09 nobodywasishere

Yeah, I suppose that could work as well. It's quite a bit more complex than exposing the contents of a well-defined location, though.

So I'm wondering what the benefits over that approach would be. I suppose there's more flexibility as you can put assets anywhere in the repo (even use assets from dependencies in lib/). This still allows users to put all assets into one folder, but that's not a technical requirement.

A limitation is that only assets linked in the docs would be made available. That's probably not much of an issue. But there could be use cases where you might want an unreferenced assets in the doc output.

I'm not sure about filtering by size or file type. That certainly makes sense for hosting 3rd party code. But it could easily be implemented outside the doc generator, to keep it simple.

I also would prefer to keep the original paths. Altering them seems to add unnecessary overhead and confusion.

straight-shoota avatar Sep 25 '23 10:09 straight-shoota

That makes sense and works for me. So the process would be this, right?

  • Have the docs generator find all links in the markdown
  • Select links that point to files in the current directory, leaving the others as-is
  • Copy those images, preserving the paths, into /docs, creating folders as necessary

Example:

  • Link in markdown ![](./doc/image.png)
  • Found by doc generator
  • Check if it's a relative link (it is)
  • Copy image to /docs/doc/image.png

nobodywasishere avatar Sep 25 '23 13:09 nobodywasishere

@nobodywasishere That solution seems nice at the first glance, yet due to its implicit (magic) nature, it will IMO end up as either too complex, or too simple to cover all of the use cases. Explicit way requires less code and it's more reliable. IIRC that's how it's being done in ExDoc for example, and that's the direction I'd go in.

Sija avatar Sep 25 '23 13:09 Sija

Hi,

What if it works for any markdown links not using a URI, i.e. without file://, http://, etc.

An use case for this would be a documentation that want to have a link to a CSV file, a text file or some other file that isn't an image but is useful for the documentation to show to the user.

So I think that using /docs/assets for the destination directory would be a better fit, and a 3rd party hosting service could just check the file sizes there to decide what to host or not host.

How path resolutions are going to work? I imagine that:

  • Relative paths are relative to the current file where it's located.
  • Absolute paths are relative to project root directory

I think it also needs to keep the directory structure of the source image to avoid files with same name to be overwritten, e.g.:

# [Nice chart](/assets/doc/nicechart.png)
def foo
end

Would copy the nicechar.png to the ugly location /docs/assets/assets/doc/nicechart.png (assuming the generated docs assets directory is /docs/assets)

I imagine people putting this doc images in their repositories in places like /assets/doc/, since we can't put anything under /docs because it's the doc output directory.

hugopl avatar Sep 25 '23 15:09 hugopl

@Sija I can definitely see that and agree, and think it would be good do define/implement a more consistent doc format similar to what's done with exdoc. Copying images from /doc to /docs/doc would mesh well with #13184 if/when that gets implemented, making sure images are available consistently between GitHub and the generated docs. If not /doc maybe /guides or /pages like what exdoc uses.

nobodywasishere avatar Sep 26 '23 22:09 nobodywasishere

This issue has been mentioned on Crystal Forum. There might be relevant details there:

https://forum.crystal-lang.org/t/add-image-at-crystal-docs-generation-time/6755/2

crysbot avatar Apr 10 '24 16:04 crysbot