spk121 / guile-gi

Bindings for GObject Introspection and libgirepository for Guile
GNU General Public License v3.0
58 stars 7 forks source link

Generated documentation #23

Closed spk121 closed 5 years ago

spk121 commented 5 years ago

There is some existing functionality to generate skeleton documentation from typelib files. This needs to be made relevant by matching the current state of the GOOPS types and the arg_map argument information.

LordYuuma commented 5 years ago

As a part of #29, I consider dropping the existent documentation (mainly because I consider dropping gig_typelib in favour of the newly created gig_repository once the latter is a feature superset of the former). With #29, it will be possible to use single GIBaseInfos from Scheme (well, you could do that before as well, but you had to load GIRepository first and even then, things would not have been meaningful in any way).

Given the pending rewrite, would it not make sense to define a method (document <GIBaseInfo>) in a newly written gig_document.c and pull all the other documenation function scattered throughout the library there?

By the way, what is the relation of this issue to #24?

spk121 commented 5 years ago

That would probably be fine. The disadvantage would be that you are putting distance between the various conversion functions and the documentation functions that describe those conversions, so it might be easier to get out of sync, but, the advantage would be that the C modules would have a better separation of concerns. So either way is fine by me.

The primary goal of this task vs #24 are similar, of course. This task is for someone who's frustrated enough to read the manual. #24 is for someone who. at the REPL, is trying to TAB TAB their way to working code.

For the offline docs, the standard organization is OO style: a type or class and related methods or generics. I'd imagine most Gtk users are used to the output of GTK-Doc, so replicating that could be the goal. You'd want to document the entire contents of a typelib, so the future update to typelib-describe still needs to pull in everything. Alphabetize the methods, etc.

For the REPL, most users are comfortable with

But as far as what the difference between the two would be in a presumptive gig_document.c, the docstring generation functionality would be nearly the same for both cases, I think.

LordYuuma commented 5 years ago

Hmm. So unless we can use one format for both outputs (doesn't seem likely) or transform one into the other (seems likelier), this and #24 need different code. (I'm pretty sure you don't want to read raw GTK-Doc in the REPL). Alright.

I think the SoC trumps considerations of proximity. Also, even as things are now, we already got out of sync, so proximity doesn't seem to be that helpful in this regard either. This is probably the habit to not document stuff at all out of laziness ;)

As far as the actual workings of gig_document.c is concerned, I'd really prefer it if we could document <GBaseInfo>s in it. This would make injecting documentation for #24 easier. The whole typelib can still be documented in a Scheme module using standard functionality, such as map and string-join. I'd also like it, if the documentation primitive rather than building a string displays/formats to the standard output port. The result can still be made a string in Scheme, but the inner handling in C would be somewhat easier without string_append everywhere.

spk121 commented 5 years ago

Oh, I don't want to output GtkDoc, exactly. I want to end up with a product that seems familiar to readers of GtkDoc-generated documentation. GtkDoc itself is an odd tool. Plain text is fine for now, but, later, maybe something more elaborate in the Guile ecosystem, like sxml + an external tool, or stexi, or skribilo, or shtml.

I think you might be giving away flexibility by just doing printf to stdio. In terms of I/O, there are some other options that could be considered w.r.t to string generation

LordYuuma commented 5 years ago

So what about the docstrings included in the libraries? They use GtkDoc markup, don't they? I mean, we could simply not care at all about the C documentation, but I think that is valuable information – more valuable than just knowing the argument types of a method.

I didn't mean printf to stdio, I meant scm_displayet al. to SCM_UNDEFINED (i.e. the standard current output port).

spk121 commented 5 years ago

I think you're thinking I saying something specific when I'm saying something general. I just want to the autogenerated offline documentation to be GtkDoc-like in its look and feel without using their tooling. I'm not suggesting that we should discard any of the documentation information that a typelib file provides.

Well, scm_display and scm_simple_format is my least favourite of the options. I'm going to predict that you end up with less readable code than other options.

LordYuuma commented 5 years ago

That's mostly because I find it bizarre to talk about the look and feel of unprocessed GtkDoc. The people reading that are the same people writing it, but most people – them included – are probably more comfortable with the resulting devhelp pages or whatever.

To be perfectly honest, I don't find the current documentation code readable either. fopencookie looks nice, but needs cookie support. GIO output streams look nice, but we would have to define an output stream for SCM ports if we wanted to use that and that's some boilerplate I do really want to avoid. Another option would be define a mini function, that does g_strdup_printf, scm_from_utf8_string and scm_display in one go. (I really wish, there was scm_take_utf8_string, but we have to g_free afterwards as well.)

Edit: Perhaps it would not be a bad idea to convert SCM ports to GIO streams, though. That conversion could potentially be useful in other situations, such as log handlers.

spk121 commented 5 years ago

Again, what I'm saying is that it would be nice if the output of the offline documentation, while Guile specific, felt familiar to people who are accustomed with the type of documentation you find in Devhelp or what you see here, https://developer.gnome.org/glib/2.60/glib-The-Main-Event-Loop.html

Some boilerplate code of some fashion needs to be created regardless of the route chosen. So I don't think you can appeal avoiding boilerplate as a discriminant for any method. But I'm not arguing for or against any particular implementation except for the fact that I prefer printf formats like %8s over ice-9 format formats like ~8,,,,s

Also, if there needs to be an scm_take_utf8_string in core Guile, I could just make one. Andy Wingo wouldn't care, especially since he's planning to incorporate Mark Weaver's patches to change the string representation from codepoints to UTF-8 sometime in Guile 3.0. I wrote a fair bit of Guile's core string code anyway. Literally, everything that people hate about Guile strings beginning with 2.0.x is all my fault. haha.

LordYuuma commented 5 years ago

I vaguely understand, what you mean, but the exact degree of similarity is what makes me a bit uneasy. If just one thing is off, you can throw away the entire tooling and won't get such nice-looking pages. And if we go for a different format (say, Texinfo), you'd have to convert all the GtkDoc markup to that as well, otherwise things will look weird.

The amount of boilerplate to implement scm_printf(SCM port, const gchar *fmt, ...) is significantly less than defining a new GObject class, though (at least when using g_strdup_printf to implement it). %8s and ~8a are not that different, but explicitly making everything an SCM just to use simple_format might be a bit overkill.

scm_take_utf8_string (and scm_take_utf8_symbol) would be very helpful. There are a few instances, in which we open dynamic winds just for string conversions. In a similar manner, scm_peek_*_string, i.e. an analogous function to scm_to_*_string, which is const and doesn't need freeing would also be helpful.

LordYuuma commented 5 years ago

After digging around, I've found out, that we can't simply use the docstrings in the gir, because the typelib doesn't have them. Yay. As a workaround, the documentation will have to be a two step process. The first will be done in C: We generate an XML, that mimics GIR in basic structure, but has an additional <scheme> field for all scheme stuff (argmaps etc.)

The second will be done in Scheme. Using this basic XML, and some SXML magic, we match the previously generated doc with the GIR one. Finally, we use more SXML magic to generate DocBook XML (which is the format internally used by GtkDoc). Now let's see, what weird SXPath code I can come up with, that actually does that.

spk121 commented 5 years ago

As an aside, digging in the Guile source, there are comments around some of the various scm_take_{locale,latin1}_{symbol,string} that imply the devs have considered deprecating them, since the GC has no way of rehosting non-GC-malloc strings. Given that, I don't think I should push an scm_take_utf8_string

LordYuuma commented 5 years ago

Sounds like a pain. Then what about a set of scm_move_*_{symbol,string}, which does use GC allocation, but also takes an scm_t_pointer_finalizer to free the original string immediately afterwards?

LordYuuma commented 5 years ago

I love how git rebase lets me pretend I always did the right thing, but Travis still says "No, you didn't. Stop lying to yourself and the world."

Anyway, we have some pretty nice documentation right now. It takes ages to generate with both GIRs and typelibs loaded, but at least it's not outdated :) Check out dev-document sometime. It's rebased on master and documented, so it should be mergeable.