killercup / grock

Grock converts your nicely commented code into a gorgeous documentation where comments and code live happily next to each other.
http://killercup.github.io/grock/
MIT License
38 stars 13 forks source link

Would there be any interest in turning this into an angular or react app? #25

Closed JimtotheB closed 9 years ago

JimtotheB commented 9 years ago

I would really like to have a proper collapsible file browser on the side, and load all of the content in with xhr. If there is any interest I would be happy to fork it and put it in.

killercup commented 9 years ago

You are very welcome to send a PR that adds another output style!

Currently, both the thin and the solarized style use the same JS to render the sidebar from the data in toc.js.

I would really like to have a proper collapsible file browser on the side, and load all of the content in with xhr

Although I'm fairly certain this can be added to the current behavior.coffee quite easily (a few $.fn.toggleClass' and a $.load), I wouldn't mind if you use React or Angular instead. Maybe you want to add some other features as well?

By the way, I originally planned the possibility to have grock use external npm modules as styles. It may make sense to implement that now, so you can develop and update this independently from grock.

JimtotheB commented 9 years ago

@killercup I honestly didn't look at it hard enough yet to realize that the styles were more than just CSS, It is awesome that it should be fairly simple to add an additional output format.

Although I'm fairly certain this can be added to the current behavior.coffee quite easily (a few $.fn.toggleClass' and a $.load), I wouldn't mind if you use React or Angular instead.

Im probably going to use angular as it is what I am most familiar with. The two issues Im having with the current styles, the sidebar and full page reload can be solved fairly easily. But I have a few other features in mind as well.

Im assuming now, that I can pretty easily output a standalone index.html page on the same level as toc.js? I plan on just stripping all of the <head> and <body> tags (among other things) from the html output and using the paths in toc.js to load them as partials into an angular.js view.

By the way, I originally planned the possibility to have grock use external npm modules as styles. It may make sense to implement that now, so you can develop and update this independently from grock.

That sounds like a great Idea, Im assuming I will be able to fork this, write it into the current styles directory and eventually port it over into its own module?

killercup commented 9 years ago

Great!

Im probably going to use angular as it is what I am most familiar with.

But wouldn't this also be a wonderful chance to learn something new? :)

(Angular is quite nice for stuff like this, though. I've done a few things with it.)

I plan on just stripping all of the and tags (among other things) from the html output and using the paths in toc.js to load them as partials into an angular.js view.

Oh no, don't do that! That would make all the documentation output into a single page app dependent on JS—and without any reason!

Just save the whole HTML pages. Then, load them via AJAX and the relevant parts. (This is how jQuery's $('#main').load("src/test.js.html #main") works, see "Loading Page Fragments" in the docs. I'm sure Angular can do something like this as well.)

Im assuming I will be able to fork this, write it into the current styles directory and eventually port it over into its own module?

Yes, in theory you could just publish your new style directory as a npm module and it'll work.

JimtotheB commented 9 years ago

But wouldn't this also be a wonderful chance to learn something new? :)

In theory, in reality I have a day job, and a kid, lol.

Oh no, don't do that! That would make all the documentation output into a single page app dependent on JS—and without any reason!

Nah, Ill be using ui.router which is basically a state machine for routes, it fully supports html5 history api, so in this case it will be changing the address bar. This makes everything fully linkable, and not technically a SPA.

dependent on JS—and without any reason!

This would be targeted at internal developer use (at least in my case), if it was for public consumption by all means I would expect them to pick a lighter style.

In my case, the motivation initially was the lack of a collapsible file browser. Im documenting our entire app with this, counting backend, frontend and tests, our app is 1300 or so files in 176 directories, being worked on by 4 people. So its a bit of a pain in the ass to click on a file above the one you are in currently and have the page reload taking you back to the top. Im sure I could use jQuery, but I havent written any in about a year, and I really don't want to drag myself back into it.

killercup commented 9 years ago

First off, just go ahead and create your style, I'd be happy to have it!


ui.router […] This makes everything fully linkable, and not technically a SPA.

Yes. What I'm suggesting works perfectly well with ui.router. I'm not sure I made myself clear, though. Let me give you an example to show where I'd see an issue.

Let imagine grock's own documentation were to use such a style.

When accessing the index page, a full HTML file, angular and your style's scripts would load and everything would be fine. The page index.html (with the contents of the Readme fiel) has a link to bin/grock.html in the sidebar. You click on it, and your browser's address bar shows you http://killercup.github.io/grock/bin/grock.html. You copy that link and open it in a new tab.

Above, you said:

I plan on just stripping all of the and tags (among other things) from the html output and using the paths in toc.js to load them as partials into an angular.js view.

So, when you visit the http://killercup.github.io/grock/bin/grock.html, you will get the inner part of the page, basically just the body. To solve this, you will have to have a real server (not just static stuff) in front of it that redirects all request to your index file where ui router then takes over.

What I'm suggesting is this: Make each rendered file a full angular app (it's the same script tags anyway) and when retrieving pages via ajax, strip out everything but the body. Then, each page can be accessed.

This approach is also taken by the PJAX library that was popular a few years back (Rails 4 includes something similar IIRC).


Im documenting our entire app with this, counting backend, frontend and tests, our app is 1300 or so files in 176 directories, being worked on by 4 people.

That's so cool! I'm very glad my little project helps you and your team! How well is this working for you? Is it fast enough? Are there any features you're missing?

(From the size of your documentation a real search feature might be cool… Maybe using lunr.js?)

JimtotheB commented 9 years ago

To solve this, you will have to have a real server (not just static stuff)

@killercup I head slapped at this, you are 100% right, I got so exited I overlooked it.

For my immediate purposes, I could work around this by just running a real server in gulp (Our application actually does exactly this, and I wrote it, so I dunno how I overlooked it o_O).

But, I want to make something everyone can use so your suggestion of bootstrapping an angular app on every page is most likely the way to go.

That's so cool! I'm very glad my little project helps you and your team! How well is this working for you? Is it fast enough? Are there any features you're missing?

It is fast as hell as far as I can tell, It builds the entire project from scratch in about 4-5 seconds, on a 2014 13" MBP.

The only feature Im missing, (and this would help a whole set of users) is referenced in #15, I really really wish I could pipe to grock.generator() and have it just build that file (in the correct path, as well as the deps), +100 if it returned a vinyl object of the html file it built.

currently I was doing this in my gulpfile.

gulp.task "watchDocs", ["browserify-watch"], ->
    watch "source/**/*.coffee", name: "buildDocs", verbose: true, (event)->
      grock.generator(
        glob: [event.path]
        style: "solarized"
      )

But I had to abandon it because it segfaults the gulp process when the gulp-connect server tries to reload every one of those files (with an oom, Im assuming.)

If I could do this natively I would be a happy camper. I saw the proposed solution to handling streams in #15 which seems easy enough, but will all of the other stuff that has to happen (building deps, etc) I realized I wouldn't have the time to dig into it.

gulp.task "watchDocs",  ->
    watch "source/**/*.coffee", name: "buildDocs", verbose: true
      .pipe grock.generator(
        glob: [event.path]
        style: "solarized"
      )
      .pipe connect.reload()

Other than that it does everything I want it to do and it does it fast.

killercup commented 9 years ago

It is fast as hell as far as I can tell, It builds the entire project from scratch in about 4-5 seconds, on a 2014 13" MBP.

Nice! The original groc was quite slow on my machine (2010 MacBook Pro), and one of the reasons for creating grock was to improve its performance (and using streams).

[...] I really really wish I could pipe to grock.generator() and have it just build that file (in the correct path, as well as the deps) [...]

Wow, I didn't realize this was such a big thing to have. I've only ever run grock as part of a deployment process, never with watch while developing.

If you have a look at generator.coffee, you'll see this huge generator function that parses a bunch of settings, prepares some files, does all the processing and then outputs the files plus additional stuff (like the toc). It might be possible to extract this part so you can return a stream you can pipe into.

You'll need to find a solution for the last steps, renderFileTree and copying assets, in a watch call, though.

If you would like to refactor this into a bunch of functions, I'd be very grateful.

JimtotheB commented 9 years ago

never with watch while developing

Heh, dual monitors ftw, Its nice to just have the docs page up and refreshing itself when you are writing documentation.

You'll need to find a solution for the last steps, renderFileTree and copying assets, in a watch call, though.

I suppose checking for existence before continuing would be helpful. If they aren't there they can just be created before continuing on with the file stream.

It might be possible to extract this part so you can return a stream you can pipe into

Seems like the first parameter could be a file object and if it exists and is a vinyl file use that rather than the vinyl file you are creating?

Ehh Had to go back and look at the couple of gulp plugins I wrote about a year ago, seems as though it would have to optionally return a through ( is there a better lib than through2 now?) stream?

killercup commented 9 years ago

I suppose checking for existence before continuing would be helpful. If they aren't there they can just be created before continuing on with the file stream.

@PaperElectron, that works for assets, but not for the file tree representation (which ends up as the toc.js mentioned above). You'll ned to cache the 'tree' (I'm quite certain it's actually a flat Object<Path, Toc>), update the parts relating to the changed files, and write the whole thing to disk (each watch iteration needs to update the toc.js).

Seems like the first parameter could be a file object and if it exists and is a vinyl file use that rather than the vinyl file you are creating?

It's hard to argue without seeing the code, but I think it'll be a stream of vinyl objects. The current generator does it's own call to .src but you'd supply it with one from you gulp.src() call before the .pipe(grock()).

JimtotheB commented 9 years ago

I was wrong about the file as a parameter, I edited my comment above.

that works for assets, but not for the file tree representation

I just tried to run grock twice from the cli passing in two different absolute paths. I don't know what I expected, but it did indeed rewrite toc.js. I suppose reading it in and comparing paths, before rewriting it has some hang up Im missing?

killercup commented 9 years ago

it did indeed rewrite toc.js

Yes, at the end of the stream of files this writes all file information it has seen into toc.js.

IIRC, the stream generated by gulp.watch doesn't end, so there won't be a toc.js.

killercup commented 9 years ago

Hey, I'll just close this issue for now. If you have something actionable (a bug, specific feature request), feel free to open a new one. Or, even better, send a pull request :)