Readable Source Code Documentation
for 25 Programming Languages
![]() | Natural Docs lets you document code written in any of 25 programming languages, plus it can be easily extended for more so whatever you use, it can too. And if your project uses multiple languages, no problem! It will all be included in the same set of documentation. |
Natural Docs also speaks your other language... English! Its comments are designed to be very natural and readable so they're just as usable in the source code as they are in the generated documentation. No weird syntax or tags scattered everywhere. | ![]() |
![]() | Natural Docs' generated documentation is pretty and powerful, with three independently scrolling panels, dynamic menus, search, and pop-up summaries when you hover over links. All its features work wherever you put it, be it a web server, a network share, or just opened from your hard drive. |
If you're new to Natural Docs be sure to read our Getting Started guide and we'll have you up and running in no time. If you've been using Natural Docs 1.5, check out our tour of What's New in 2.0! |
New update time. Let's see what I've been up to. Repository Links You can now add links to web-based repository sites like GitHub to your documentation. After you do, whenever you hover over a prototype a tab will pop up with a link to its source code: ![]() It works for class prototypes too: ![]() But what if more than one file defines something, like how C++ has header and source files? I got you: ![]() You can see it working live on Natural Docs' own documentation. To add this to your project, edit Project.txt and add "[Site Name] Repository: [Project URL]" under the Source Folder heading. If you have multiple Source Folder lines they would each need their own: Source Folder: C:\My Project\src If you're using GitHub, Codeberg, or Gitea that's all you need. If you're using GitLab or you want links to go to a specific branch, add the line "Branch: [Branch Name]" underneath it. (GitLab doesn't have a way to link to the trunk without knowing its name, so you have to specify whether it's "master" or "main".) If you use a different site you have to tell Natural Docs how to link to source files. Add a "Link Template: [URL]" line underneath with {File} and {LineNumber} used to represent where the file path and line number should go. For example: Source Folder: C:\My Project\src The repository name and project link aren't otherwise used yet, but they'll probably be added to the menu somewhere in a later release. Are there any other major repository sites you use? Building in support would mean people wouldn't have to define the link template manually. I know there are others like Azure Repos but I couldn't find public projects to test them out. E-mail me if you use one; there's only three or four questions I would need answered and they're pretty straightforward. Speeeed! So... I may have undersold the speed increase of moving to native binaries when I announced development release 1. I only tested macOS, and the source and output folders were on network shares which muted the results. I ran them again with everything local and, well, Natural Docs 2.4 DR1 actually cuts 73% off the run time when doing a full rebuild. Yes, running a native binary on Apple silicon without Mono and Rosetta removes almost three quarters of the run time. It's faster on Windows too! Running a native x64 binary cuts 41% off the run time versus running it through the .NET Framework. Things were tweaked a bit further for development release 2. I moved from .NET 8 to .NET 10, which has new compiler optimizations, and I made a customized build of SQLite that cut out a bunch of things I don't use. The results are a tiny additional speed bump over DR1, most pronounced on Windows. ![]() The only tradeoff is that Natural Docs now requires macOS 12 Monterey. Development release 1 supported back to macOS 10.15 Catalina, but the move from .NET 8 to .NET 10 bumped up the requirements. So yeah, if you aren't already using the development releases I would highly recommend doing so! Quick Documentation As I mentioned last time, I was thinking about requiring Javadoc or XML comment symbols for quick documentation, since that would prevent it from being triggered accidentally. It's only one extra character, and it more clearly shows that the comment is intended to be documentation. It's been implemented, so now you use it like this: /* Enum: Colors Note that this is only for the comment symbols, meaning you have to use /// or /** and */. It does not mean you have to format the comment contents in Javadoc or XML, so you can still use Natural Docs formatting like *bold* and <links>. Language Improvements
Odds and Ends
It's time for a new development release. What's been going on behind the scenes? Native Binaries I've migrated Natural Docs from the .NET Framework to precompiled .NET 8 binaries. What does that mean for you? The biggest benefit is that Apple-silicon Macs and Windows Snapdragon PCs will be faster and more efficient. They're ARM64 chips, and now we have ARM64 binaries! My testing showed the "resolving links" stage on an M1 Mac takes 30% less time this way. The parsing and building stages won't see as big an improvement but that's because they're more I/O-bound. Up until now I've relied on Mono to run Natural Docs on Macs, but Mono only emits x64 instructions (at least the version on mono-project.com anyway.) That means it must then also be run through translation layers like Apple's Rosetta. Having a native ARM64 version allows it to skip all that and run at full speed. Also, Apple will be discontinuing Rosetta in a couple of years so this had to happen eventually. So now you can just download and run the new macOS and Linux binaries without installing anything else. You don't need Mono anymore. You don't need to install anything for .NET either, all the components it needs are compiled into Natural Docs itself. But wait, isn't bundling .NET going to bloat Natural Docs? I was worried about that, not wanting it to turn into a 100MB download or become heavy like Electron apps, but I was pleasantly surprised. The libraries get stripped down to only the parts you actually use, and Natural Docs has a very light footprint, so the downloads are all less than 5MB in size. The web site will automatically detect your system and select the correct download for you. However, only Chrome and Edge allow it to detect the processor type so you may need to double check it if you're using Safari or Firefox. All downloads are available by clicking "Other Platforms and Options". I didn't make any 32-bit builds because I assume no one needs them, but you can let me know if I'm wrong. An Experiment with Quick Documentation So I alluded to a potential new feature in the last update, and it's something that's currently only implemented for enums in C#, but it has the potential to expand beyond that. Suppose you're documenting enum values. You have to duplicate them in the comment: /* Enum: Colors What if you could just document them with a quick comment inline? /* Enum: Colors This is already implemented and working for C# enums. You can just put a regular comment after any value on the same line and it will be pulled into the documentation. It doesn't need a keyword or any other kind of header. You can extend the comment to multiple lines if it needs to be longer, and you can choose to only document some values if the others are self-explanatory. It doesn't seem like that big a deal above, but when lists get to be a dozen or more values the duplication is more of an issue. Also, when this idea was first suggested to me it was for documenting simple structs where there would be more space and effort savings. You could replace this: /* Struct: Point with this: /* Struct: Point So C# enums were a proof-of-concept, with other potential applications being simple structs like above, module ports in SystemVerilog, and maybe even function parameters. However, getting something that works predictably is a bit tricky. Ideally I'd like both of the struct comment styles above to Just Work™ without needing any special syntax to distinguish between the two approaches. That might be doable, but the second method is potentially fragile when you try to do it with basic language support. For example, it wouldn't work once you add a function to the struct, if the parent isn't documented, or if it's longer than a certain length. If a feature doesn't behave predictably and in ways that are obvious (it doesn't matter if I document the conditions somewhere, people aren't going to memorize them) then it's potentially unreliable, which makes it a bad feature. It's more robust with full language support but that limits its reach. So I'm left between "leave it as a niche feature for enums but don't expand it to areas where it can be flaky" and "don't scrap a feature that could be nice in certain conditions just because it wouldn't work in all of them." There's also the issue of it being triggered unintentionally, but I think I'm going to change it to require Javadoc-style comment symbols (/// or /**) to prevent that. It's only one extra character and it more clearly says "this is supposed to be documentation." Another issue is it's not easy to integrate this idea into the rest of the code so it's a bit of a time suck when I could be working on features that are more broadly beneficial, like finally adding more languages to basic language support and adding source links to repositories like GitHub. I think I'm leaning towards expanding it slowly over time with full language support where it's more robust, but not putting a high priority on it. Maybe it can be added to basic language support in a few places where I feel it can be reliable. What are your thoughts? Would you ever use it for, say, documenting function parameters? Language Improvements
Odds and Ends
|