JakobOvrum / bootDoc

Theme for the DDoc documentation generator
Other
36 stars 7 forks source link

Add `XREF` macro support #27

Closed denis-sh closed 11 years ago

denis-sh commented 11 years ago

XREF is very usable and should be added IMHO.

denis-sh commented 11 years ago

And do we need CXREF and ECXREF? If yes, we should fix them, if not - delete.

JakobOvrum commented 11 years ago

Problem is that XREF assumes that only one package is relevant. What about subpackages? What about documentation covering multiple top level packages? That's why CXREF exists, because Phobos has two relevant top level packages, but hardly any subpackages are used.

Also, #17 is related.

edit:

The diff wasn't updating, missed XREF2 and XREF3. But what about when multiple top level packages are relevant? What should the macros for the other packages be called? Should there be an easy way for users to define them if we can't neatly cover this functionality with the default macros?

denis-sh commented 11 years ago

I decided to remove CXREF, ECXREF, and some other dlang.org's macros. Do not forget to update your Phobos's settings.ddoc if this will be merged.

denis-sh commented 11 years ago

As an exampel of huge library we probably can consider .Net Framework which has at most 5 package levels. So if we will support 6-7 levels it will be enough.

But what about when multiple top level packages are relevant?

Yes, it should be supported.

denis-sh commented 11 years ago

Will think a bit and redesign this pull...

JakobOvrum commented 11 years ago

I agree that it's easy to support sufficient package depth, the problem is if the user needs to define a flurry of custom depth macros to support the same thing for a different top level package. It doesn't smell right.

I'd merge this now but if there's a better solution waiting to be discovered, I don't want people to have to change all their uses of XREF if the better solution requires a different syntax. And that's why #17 has been untouched since forever.

Maybe Phobos' solution of XREF and CXREF is indicative that a better solution doesn't really exist. In that case, it should at least be as easy as possible to define new relevant top level packages.

edit:

Using JavaScript is an option we can't forget, but it would be nasty if there was no decent fallback code. I guess simply turning cross-reference links into regular text for disabled JavaScript is an acceptable fallback?

denis-sh commented 11 years ago

No, wait a bit!

denis-sh commented 11 years ago

As I wrote, I'm redesigning it and will inform you when it will be finished. Thanks.

JakobOvrum commented 11 years ago

Yeah, just throwing out ideas :)

denis-sh commented 11 years ago

OK, I'll push here my fixes and generate.d updates for full cross-reference support today.

denis-sh commented 11 years ago

Here we are.

denis-sh commented 11 years ago

About bootdoc.ddoc changes: I also tried to use joining with special macro, but it looks even worse:

__JOIN2 = $2$1$3
__JOIN3 = $(__JOIN2 $1, $2$1$3, $4)
__JOIN4 = $(__JOIN3 $1, $2$1$3, $4, $5)

__SYMBOLREF = <a href="$1.html#$3">$(D $2.$3)</a>

UNPACKAGEDREF     = $(__SYMBOLREF $1, $1, $2)

CROSSPACKAGEREF   = $(__SYMBOLREF $(__JOIN2 $(PACKAGESEP), $1, $2), $(__JOIN2 ., $1, $2), $3)
CROSSPACKAGEREF2  = $(__SYMBOLREF $(__JOIN3 $(PACKAGESEP), $1, $2, $3), $(__JOIN3 ., $1, $2, $3), $4)
CROSSPACKAGEREF3  = $(__SYMBOLREF $(__JOIN4 $(PACKAGESEP), $1, $2, $3, $4), $(__JOIN4 ., $1, $2, $3, $4), $5)

than my current solution:

__SYMBOLREF0 = <a href="$1.html#$3">$(D $2.$3)</a>
__SYMBOLREF1 = $(__SYMBOLREF0 $1$(PACKAGESEP)$3, $2.$3, $4)
__SYMBOLREF2 = $(__SYMBOLREF1 $1$(PACKAGESEP)$3, $2.$3, $4, $5)
__SYMBOLREF3 = $(__SYMBOLREF2 $1$(PACKAGESEP)$3, $2.$3, $4, $5, $6, $7)

UNPACKAGEDREF     = $(__SYMBOLREF0 $1, $1, $2)

CROSSPACKAGEREF   = $(__SYMBOLREF1 $1, $1, $2, $3)
CROSSPACKAGEREF2  = $(__SYMBOLREF2 $1, $1, $2, $3, $4)
CROSSPACKAGEREF3  = $(__SYMBOLREF3 $1, $1, $2, $3, $4, $5)
denis-sh commented 11 years ago

And yes, I'm of course not sure about names.

JakobOvrum commented 11 years ago

Think you could post usage examples for the various different kinds of references?

JakobOvrum commented 11 years ago

New generator tool uses in string a lot, did you mean in char[]?

If you did mean in string (guess you prefer the tail part to be const), we should use it consistently throughout the module instead of the mix it is now.

denis-sh commented 11 years ago

By the way, why are we discussing an outdated diff according to github?

JakobOvrum commented 11 years ago

The discussion we had became outdated when you pushed the fixes for the issues discussed.

denis-sh commented 11 years ago

Here https://github.com/JakobOvrum/bootDoc/wiki/settings.ddoc you write this:

As with all .ddoc files, remember to put a newline at the end of the file.

But what about the beginning (it ignores the first macro otherwise, see comment in my code) and is it documented somewhere?

denis-sh commented 11 years ago

Think you could post usage examples for the various different kinds of references?

Are you talking about Wiki updates or about proofing to you that it is usable?

JakobOvrum commented 11 years ago

But what about the beginning (it ignores the first macro otherwise, see comment in my code) and is it documented somewhere?

I think it's a bug.

I don't remember too clearly, but I think it will only "ignore" (actually, it's worse...) the first macro if the previously passed DDoc file didn't have a trailing newline. The reason being that it seems like DDoc just strings all DDoc files into one, or otherwise somehow preserves the state from the previous file.

I haven't looked at the DMD source code for this, it's just a guess.

JakobOvrum commented 11 years ago

Are you talking about Wiki updates or about proofing to you that it is usable?

To make sure I understand it correctly.

denis-sh commented 11 years ago

New generator tool uses in string a lot, did you mean in char[]?

If you did mean in string (guess you prefer the tail part to be const), we should use it consistently throughout the module instead of the mix it is now.

Replaced with in char[] (as it's more usable) where possible and make parseModuleFile's argument in string as it's passed to File.__ctor. Also fixed my ;; typo.

Squashed commits together into 8c5db56d59db1d32e38acb283fb516e33dfc4011.

denis-sh commented 11 years ago

To make sure I understand it correctly.

mainpackage
    module1
        /**
        Same as $(LREF a1) but fully qualifies:
        $(CROSSPACKAGEREF mainpackage, module1, a1)

        The only way to refer `additionalpackage`:
        $(CROSSPACKAGEREF additionalpackage, module3, a3)
        $(CROSSPACKAGEREF2 additionalpackage, subpackage1, module11, a11)
        */
        int a1; /// It's a1.
    module2
        /**
        $(DEFAULTPACKAGEREF module1, a1)
        $(INPACKAGEREF      module1, a1)
        $(INROOTPACKAGEREF  module1, a1)
        */

additionalpackage
    module3
        int a3; /// It's a3.
    module4
        /**
        $(DEFAULTPACKAGEREF module1, a)
        $(INPACKAGEREF      module3, a3)
        $(INROOTPACKAGEREF  module3, a3)
        */
    subpackage1
        module11
            int a11; /// It's aa.
        module12
            /**
            $(DEFAULTPACKAGEREF module1, a)
            $(INPACKAGEREF      module11, a11)
            $(INROOTPACKAGEREF  module3, a3)
            $(INROOTPACKAGEREF2  subpackage1, module11, a11)
            */
JakobOvrum commented 11 years ago

So, INROOTPACKAGEREF and INPACKAGEREF will only work if the documentation is generated with the generator tool. I guess a workaround the user could use for that is to use the Macros DDoc section to introduce THISPACKAGE and THISROOTPACKAGE per-module.

For naming, I think it's important to be succinct here, lest we make proper documentation even more of a chore (it seems some people really don't like writing docs). Maybe we should take LREF and build on that. For example, INPACKAGEREF could be REF, and CROSSPACKAGEREF could be XREF. What do you think?

I'm not so sure about INROOTPACKAGEREF and DEFAULTPACKAGEREF. Maybe ROOTREF for the former? As for the latter, it seems to me that the convenience of INPACKAGEREF largely supersedes it. Maybe we could just drop it? That would also drop the assumption that a project has a single "most important package".

Overall, I think I'm happy with this solution. While using JavaScript could make the syntax nicer and more robust, it would help the documenting experience at the cost of harming the viewing experience (reliance on JavaScript). The balance has to be in favour of the viewer.

I'd like to hear your thoughts on it.

denis-sh commented 11 years ago

So, INROOTPACKAGEREF and INPACKAGEREF will only work if the documentation is generated with the generator tool. I guess a workaround the user could use for that is to use the Macros DDoc section to introduce THISPACKAGE and THISROOTPACKAGE per-module.

Yes, and once this will be accepted, bootDoc docs should mention this. And the second workaround is to add similar functionality to theirs build scripts.

For naming, I think it's important to be succinct here, lest we make proper documentation even more of a chore (it seems some people really don't like writing docs).

Of course, as succinct as possible.

Maybe we should take LREF and build on that. For example, INPACKAGEREF could be REF, and CROSSPACKAGEREF could be XREF. What do you think?

I'd like to use unambiguous one-letter prefixes (the prefix defines a root for a reference):

  1. In this symbols: SREF TODO
    • this symbol members
  2. It this module: MREF (was LREF)
    • deprecate LREF (but rest for backward compatibility) as local is ambiguous as it doesn't tell its root (symbol, module, or package?)
  3. In this package: PREF (was INPACKAGEREF)
    • let's not use REF here for the same reason as for LREF
  4. In other package: RREF (Root reference) (was CROSSPACKAGEREF)
    • also possibly GREF (Global reference), but it looks more like internet link
    • XREF looks confusing as it is unobvious cross what is it? And it's alredy used in Phobos in different meaning (as PREF)

Also this variations could be useful (two-letter prefixes):

  1. In default package: DPREF (was DEFAULTPACKAGEREF)
  2. In this root package: RPREF (was INROOTPACKAGEREF)
  3. For package-less modules: UPREF (was UNPACKAGEDREF)

I'm not so sure about INROOTPACKAGEREF and DEFAULTPACKAGEREF. Maybe ROOTREF for the former? As for the latter, it seems to me that the convenience of INPACKAGEREF largely supersedes it. Maybe we could just drop it? That would also drop the assumption that a project has a single "most important package".

But "most important package" is a common situation. DPREF can be used without per-package DDoc files and looks like a preferred way to link symbols in DEFAULTPACKAGE as it allows to copy-paste links to other packages.


So, what do you think about these my thoughts?

JakobOvrum commented 11 years ago

So, what do you think about these my thoughts?

Sounds good!

denis-sh commented 11 years ago

Will rebase this pull soon to see how it looks...

denis-sh commented 11 years ago

I decided to add a renaming commit instead of rebasing as original names are good for history. )

JakobOvrum commented 11 years ago

Awesome. Thanks!

JakobOvrum commented 11 years ago

BTW, what about some macros to link to modules without referencing a symbol? In Phobos, these are linked with raw HTML, but since we have a customizable package separator we must do better. Would you mind if I added PMODULE, DPMODULE etc (and do you have any objections to the names)?

denis-sh commented 11 years ago

Good idea. Looks like *MODULE is reasonable long name (as it isn't referenced as often as *REF) and *MOD will confuse people.

denis-sh commented 11 years ago

And per-module DDoc creation will simplify and make more consistent generate.d.

JakobOvrum commented 11 years ago

Added: 9509831f2194b47bcbd66c4865cdab684fb7b588