Hi Branden, On Fri Dec 20, 2024 at 7:13 PM CET, G. Branden Robinson wrote: > At 2024-12-20T13:59:13+0100, onf wrote: > > [...] > > I kinda get where they are coming from with C++, though. Last time I > > tried patching groff, I was fascinated by the stark difference between > > groff's and neatroff's source code. > > [...] > groff was written fast and saw rapid and widespread uptake. As noted, > even BSD absorbed it. I don't wish to take anything away from the > magnitude of James Clark's achievement in cranking out a near-total > replacement for Unix troff, including macro packages, preprocessors, and > output drivers, plus documentation for all the extensions he added, > in...what, a year and half, tops?
Fair point. > Neatroff is not, as far as I can tell, nearly as widely used and it has > taken longer to gestate. These are not flaws--just differences. > > I take code readability seriously. My first impression of any part of > groff that I haven't dealt with before is frequently "okay, what the > hell is this doing?" > > My very first impression of neatroff's code when when I first looked at > it a few years ago was, "gosh, that's some smooth stuff." Neatroff is a > big winner here. Yeah. I feel like a lot of development effort could be spared if groff had the sort of code base that neatroff has. It's a pity it doesn't get the amount of attention that groff or mandoc is getting. > [...] > > but I feel like the language also has an influence; for instance, the > > presence of objects, each with its own methods, definitely made > > groff's source code harder to navigate for me. > > This doesn't _have_ to be the case. But there are warty bits for sure. > [...] I am not sure about that. Last time I tried messing around with groff's internals was when I was suggesting making .ne break line. Searching revealed that it's handled by the function need_space in div.cpp. Its source code looks like this: void need_space() { vunits n; if (!has_arg() || !get_vunits(&n, 'v')) n = curenv->get_vertical_spacing(); while (!tok.is_newline() && !tok.is_eof()) tok.next(); curdiv->need(n); tok.next(); } Let's say I want to check out the need method of curdiv. To do that, I first need to figure out what object it is. Searching for curdiv eventually reveals it being declared in div.cpp as type `diversion`. Searching for diversion::need then finally reveals the desired method. If I chose something other than curdiv, I would have to figure out which header files declares it to figure out where to search for its definition. In C, instead of curenv->get_vertical_spacing or curdiv->need, one would have env_get_vertical_spacing or div_need, so rather than having to figure out what kind of object am I dealing with, I would search for those functions directly. I'm not saying it's an insurmountable obstacle by any means, but it's annoying. The fact that groff's code style doesn't make function- I mean method declarations easily greppable doesn't help, either. What I'm trying to get at is that in a good C code base, if I wanted to locate the definition of function div_need, I would simply run: grep -En '^div_need' $(find -name '*.c') in the root directory and be done instead of having to dig through header files to figure out what object am I even looking for. ~ onf