'Rust manpages' -> UNIX-style manpages for Rust (still WIP, just letting you know of the progress) --- Thoughts?

The URL leads to a pastebin for a Ruby script I have been writing for the past 2-3 days. It’s called mk_rustman.rb on my system. They will turn JSON files for Rust docs into UNIX manpages, with Groff ROFF macros for man (groff_man).

The script may be rewritten, or I may change the language. I wish to use:

1- An interpreted language; 2- A dynamically typed language

I will choose a fast language, because the JSON file for Core is very large. Ruby has not been very fast so far, but there’s an alternative implementation of Ruby I may try. Another candidate is F#. Does anyone know a dynamic but functional scripting language? Not a giant programing language like OCaml, something small that is functional.

Anyways.

Let me explain the JSON files first.

If you install rust-doc on your system:


<span style="color:#323232;">sudo apt-get install rust-doc
</span>

And:


<span style="color:#323232;">exa /usr/share/doc/rust/json
</span><span style="color:#323232;">or
</span><span style="color:#323232;">ls /usr/share/doc/rust/json
</span>

You shall see these:


<span style="color:#323232;">alloc.json.gz  core.json.gz  proc_macro.json.gz  std.json.gz  test.json.gz
</span>

All these JSON files have an ‘index’ object, this ‘index’ object is made up of sub-objects indexed by their ID:


<span style="color:#323232;">zcat /usr/share/doc/rust/json/std.json.gz | jq '.index' | head -n 48
</span>

<span style="color:#323232;">{
</span><span style="color:#323232;">  "a:1:8659:4267-0:638:4291": {
</span><span style="color:#323232;">    "id": "a:1:8659:4267-0:638:4291",
</span><span style="color:#323232;">    "crate_id": 0,
</span><span style="color:#323232;">    "name": null,
</span><span style="color:#323232;">    "span": null,
</span><span style="color:#323232;">    "visibility": "default",
</span><span style="color:#323232;">    "docs": null,
</span><span style="color:#323232;">    "links": {},
</span><span style="color:#323232;">    "attrs": [],
</span><span style="color:#323232;">    "deprecation": null,
</span><span style="color:#323232;">    "inner": {
</span><span style="color:#323232;">      "impl": {
</span><span style="color:#323232;">        "is_unsafe": false,
</span><span style="color:#323232;">        "generics": {
</span><span style="color:#323232;">          "params": [],
</span><span style="color:#323232;">          "where_predicates": []
</span><span style="color:#323232;">        },
</span><span style="color:#323232;">        "provided_trait_methods": [],
</span><span style="color:#323232;">        "trait": {
</span><span style="color:#323232;">          "name": "UnwindSafe",
</span><span style="color:#323232;">          "id": "1:8659:4267",
</span><span style="color:#323232;">          "args": {
</span><span style="color:#323232;">            "angle_bracketed": {
</span><span style="color:#323232;">              "args": [],
</span><span style="color:#323232;">              "bindings": []
</span><span style="color:#323232;">            }
</span><span style="color:#323232;">          }
</span><span style="color:#323232;">        },
</span><span style="color:#323232;">        "for": {
</span><span style="color:#323232;">          "resolved_path": {
</span><span style="color:#323232;">            "name": "BacktraceFrame",
</span><span style="color:#323232;">            "id": "0:638:4291",
</span><span style="color:#323232;">            "args": {
</span><span style="color:#323232;">              "angle_bracketed": {
</span><span style="color:#323232;">                "args": [],
</span><span style="color:#323232;">                "bindings": []
</span><span style="color:#323232;">              }
</span><span style="color:#323232;">            }
</span><span style="color:#323232;">          }
</span><span style="color:#323232;">        },
</span><span style="color:#323232;">        "items": [],
</span><span style="color:#323232;">        "negative": false,
</span><span style="color:#323232;">        "synthetic": true,
</span><span style="color:#323232;">        "blanket_impl": null
</span><span style="color:#323232;">      }
</span><span style="color:#323232;">    }
</span><span style="color:#323232;">  },
</span><span style="color:#323232;">
</span>

This is the first object in the list.

The ‘meat’ of an object is the ‘inner’ field. Inner can be one of:


<span style="color:#323232;">zcat /usr/share/doc/rust/json/std.json.gz | jq '.. | objects | .inner // empty | keys[]' | sort | uniq 
</span><span style="color:#323232;">
</span><span style="color:#323232;">=>
</span><span style="color:#323232;">
</span><span style="color:#323232;">"assoc_const"
</span><span style="color:#323232;">"assoc_type"
</span><span style="color:#323232;">"constant"
</span><span style="color:#323232;">"enum"
</span><span style="color:#323232;">"extern_crate"
</span><span style="color:#323232;">"function"
</span><span style="color:#323232;">"impl"
</span><span style="color:#323232;">"import"
</span><span style="color:#323232;">"macro"
</span><span style="color:#323232;">"module"
</span><span style="color:#323232;">"primitive"
</span><span style="color:#323232;">"struct"
</span><span style="color:#323232;">"struct_field"
</span><span style="color:#323232;">"trait"
</span><span style="color:#323232;">"type_alias"
</span><span style="color:#323232;">"variant"
</span>

I have parsers for most of these, but not all .And the parsers are incomplete.

These all have common fields. The most important field is the type. Another one is generics field. These two occur a lot.

I wanna turn this into perhaps, a larger project. I made a ChatGPT model to teach me PostScript. I wanna write a documentation language, similar to POD, and I wanna write several targets for it. Then, the Rust Manpaes could use this language.


I know that there MIGHT be some people who may not be aware of what UNIX manpages are, maybe they use Window, dunno. So I wanna explain manpages, and why I am adamant to convert Rust documentation to them.

Basically, the story is:

MacIlroy, Thompson and Ritchie decided that, instead of sucking the dicks of higher-ups at Bell labs to buy them a shiny PDP-11 to expand their shiny new OS, UNIX, with, they could promise them some sort of ‘clerical use’ for it. Using computers for clerical use was not very common back then. In fact, it was only a few years after ASCII was introduced. Story goes, 20-25 years prior, Von Neumann himself slaughtered an undergrad student who had dared to write what is today’s equivalent of a ‘charset encoding’ for one of them giant compooters. This was modern times and people were slowly realizing that computers have other uses than launching rockets at the Vietnamese rice field workers. But even a mini-computer was an investment.

So they conceived ROFF, a documentation system which was adapted by the patent office gals. These gals would get their asses slapped, their boobies touched (as was the custom of the time) and write patents on their terminals with ROFF.

Source of this story:


<span style="color:#323232;">man 7 roff
</span>

The same documentation system was used when Bell Labs decided to sell UNIX to people. And today, we have GNU Roff to take its place. There’s also the Hoodlum Toolchest or whatever it’s called, and BSD’s Roff (which happens to be identical to Bedlam or whatever toolchest).

Groff has a man macro package which makes it extremely easy to write manpages with.

Manpages have ‘sections’, which are numbered. They could also have letters in them. On Linux, the section for utilities like ls and sh and man itself is 1, then syscalls are 2, library is 3 etc:

These two are equivalent:


<span style="color:#323232;">man ls
</span><span style="color:#323232;">man 1 ls
</span>

But these two are not:


<span style="color:#323232;">man getopt
</span><span style="color:#323232;">man 3 getopt
</span>

Most languages have manpages.


<span style="color:#323232;">man 3o List # Ocaml List manpage
</span><span style="color:#323232;">man 3perl Pod::Usage # Perl Pod::Usage manpage
</span>

In both these instances, you can omit ‘3o’ and ‘3perl’. On Linux, when man gets a conflict, it looks uses the default order ,which the user may set.

Man pages are saved at /usr/share/man and /usr/local/share/man.

You can use apropos to search man pages:


<span style="color:#323232;">apropos pid
</span>

You can view all the pages in a section with:


<span style="color:#323232;">apropos -s [section] -k .
</span><span style="color:#323232;"># line
</span><span style="color:#323232;">apropos -s 3o -k .
</span>

Why do I want Rust Manpages?

Simply put, manpages are simpler to navigate, at least for me, than a webpge. Convenience is key here.

Some people like to launch Firefox or Chrome or whatever, and search their shit on google. I don’t like that. I consider myself an intermediate practicioner of programming. The last time I used Stack Overflow was several months ago. I don’t need to see how a function is used to know how to use it. I can just look at the documentation. So I think that is why I find manpages necessary.

I may make them for Go too. And Nim! Python needs them too. Although Python is like 10 years older than Go and Rust (12 yo Rust, 14 yo Go) so there might be manpages for Python.

Tell me what you think? Do you like this? Has someone already done this?

Thanks.

crispy_kilt, (edited )

Nice. Now reimplement it in Rust

ChubakPDP11,

You guys do realize that, Rust, a compiled, statically-typed systems language is not a good suit for scripting right? I understand, when I was a beginner years ago I used Rust for scripting. That was because I was clueless. Right now I am using Rust for what it’s suited for, systems programs. This is a scripting task. I really ask you to learn about the difference between scripting and programming.

leean00,
@leean00@discuss.systems avatar

@ChubakPDP11 @crispy_kilt hmm sounds like a place I worked where they were writing applications in c, in win32 with no version control because...I dunno they were sadists!!!!

crispy_kilt,

That must be why man is written in a scripting language instead of C.

ChubakPDP11,

‘man’ is not a single program. Manpages, as I said, are written in ROFF. These are then processed and then paged. I use Most to page them. You can use less or more or any other pager to page them. I am not going to write a pager, I am going to write a script that translates the JSONs of manuals to ROFF.

expr,

Briefly glancing through your code there’s a typo on line 37:

outlives_parsed = parse_trail_outlives(bouds.fetch(‘outlives’, nil))

Of course this wouldn’t be an issue had you actually implemented it in Rust since such a thing wouldn’t compile. Not really a good reason to be using ruby for this.

ChubakPDP11,

Ever heard of an ‘static analyzer’?

Lmaydev,

You clearly haven’t lol

Turun,

What about cargo doc? With lynx if you demand terminal exclusive usage.

radiant_bloom,

Great idea ! I don’t personally use Rust, but man pages are so much better than searching the web 😭

kdwarn,

Rust documentation online is pretty great (docs.rs/std), and you can also generate it locally by running rustup doc --std.

owsei,

The point, I think, is not about fetching the page, but how to navigate it.

I adore using man pages with vim and i would rather have that than a web browser

ChubakPDP11,

Exactly! I still remember crawling through manpages back in the day. It’s very nice.

taladar,

1- An interpreted language; 2- A dynamically typed language

Why? In fact, why would you want to write tooling for Rust in anything other than Rust?

nous,

Yeah, I really hate having to install a different language interpreter when working another one. Basically makes me very unlikely to bother with the tool in the first place.

taladar,

And not only that, technically everyone who wants to install your code from source would have to install that and installing a specific version of a dynamic language interpreter on an arbitrary platform can be a real pain.

  • All
  • Subscribed
  • Moderated
  • Favorites
  • rust@programming.dev
  • PowerRangers
  • DreamBathrooms
  • tacticalgear
  • magazineikmin
  • vwfavf
  • Youngstown
  • ngwrru68w68
  • ethstaker
  • slotface
  • rosin
  • mdbf
  • thenastyranch
  • kavyap
  • modclub
  • provamag3
  • Durango
  • cubers
  • osvaldo12
  • GTA5RPClips
  • everett
  • khanakhh
  • InstantRegret
  • Leos
  • tester
  • normalnudes
  • cisconetworking
  • anitta
  • megavids
  • All magazines