Why does Scribble give this duplicate information warning with `defmodulelang`, and how do I avoid it?

There's a gist of code available (replace scribblings-* with scribblings/*, since gists apparently can't have directories). If you get that setup properly and do raco pkg install, you'll see output like in scribble defmodulelang duplicate tag · GitHub.

I wanted to create a multi-page document for a large tool (it has 2 languages and a CLI, and the languages re-export chunks of a library). However, even just stubbing out some basic pages and adding defmodule and defmodulelang (actually defmodulelang* in the full-version, but there was no difference) gives the warnings in the log.

  • Why?
  • How do I avoid it?

I have read 4.2.2 Documenting Modules which says

Besides generating text, unless #:no-declare appears as an option, this form expands to a use of declare-exporting with module-paths; the #:use-sources clause, if provided, is propagated to declare-exporting. Consequently, defmodule should be used at most once in a section without #:no-declare, though it can be shadowed with defmodules in sub-sections. Use #:no-declare form when you want to provide a more specific list of modules (e.g., to name both a specific module and one that combines several modules) via your own declare-exporting declaration

But the second defmodulelang is in a document inserted via include-section so it should be in a sub-section, no? Or have I misunderstood something?

Somewhat relatedly, which I or a mod can split off to a new topic if desired: since the lang re-exports things original presented from the library, how can I reasonably document the bindings in both places? One option is to say "lang re-exports all of X, Y, Z" and conversely "these bindings are provided by lib X and lang." But I saw #:use-sources and

Use #:use-sources sparingly, but it is needed when

  • bindings are documented as originating from a module M, but the bindings are actually re-exported from some module P; and
  • other documented modules also re-export the bindings from P, but they are documented as re-exporting from M.

and this is just confusing enough for me that I haven't tried to draw the ideas yet to figure out if I need it or how to use it.


Shooting in the dark, haven't even read your message carefully, but is there any way this could be related to

which is a change that will be a part of the 8.4 release?

Again, haven't done my homework on this, probably unrelated, just a thought.

EDIT: pretty sure I'm on the wrong track here, my apologies.

1 Like

It looks like your "info.rkt" specifies two documents: "dupe-tag-doc.scrbl" and "dupe-tag-lang.scrbl". At the same time, "dupe-tag-doc.scrbl" includes "dupe-tag-lang.scrbl" via @include-section{dupe-tag-lang.scrbl}, which means that the redered form has a copy of "dupe-tag-lang.scrbl". So, anything defined in "dupe-tag-lang.scrbl" will be defined twice.

The intended approach to this kind of documentation is that "dupe-tag-lang.scrbl" would define some bindings and "dupe-tag-doc.scrbl" would just link to the "dupe-tag-lang.scrbl" documentation, instead of having its own copy. For example, it module X reexports everything from module Y, a typical approach is to write something like "The @racketmodname[X] module reprovides all bindings of @racketmodname[Y], in addition to the bindings documented here."

1 Like

Hm, it seems I didn't understand the typical patterns for Scribble, then.

I was hoping to have a multi-page "main documentation" for an overview plus a series of related documented interfaces to the same core ideas (this includes, basically, a language and a library). But I was hoping that the language and API documents could also be separate, so that the local installation's documentation page would have "Foo" (the multi-page tutorial + other docs), and "Foo lang", "Foo API" in the relevant sections.

It seems that's not a supported (or at least intended use), so I will re-think this idea.