diff --git a/src/applications/diviner/controller/DivinerAtomController.php b/src/applications/diviner/controller/DivinerAtomController.php index 028800f28d..54d5f4c5dd 100644 --- a/src/applications/diviner/controller/DivinerAtomController.php +++ b/src/applications/diviner/controller/DivinerAtomController.php @@ -100,11 +100,7 @@ final class DivinerAtomController extends DivinerController { $group_name = null; } - $properties->addProperty( - pht('Defined'), - $atom->getFile().':'.$atom->getLine()); - - + $this->buildDefined($properties, $symbol); $this->buildExtendsAndImplements($properties, $symbol); $warnings = $atom->getWarnings(); @@ -281,4 +277,32 @@ final class DivinerAtomController extends DivinerController { return $implements; } + private function buildDefined( + PhabricatorPropertyListView $view, + DivinerLiveSymbol $symbol) { + + $atom = $symbol->getAtom(); + $defined = $atom->getFile().':'.$atom->getLine(); + + $link = $symbol->getBook()->getConfig('uri.source'); + if ($link) { + $link = strtr( + $link, + array( + '%%' => '%', + '%f' => phutil_escape_uri($atom->getFile()), + '%l' => phutil_escape_uri($atom->getLine()), + )); + $defined = phutil_tag( + 'a', + array( + 'href' => $link, + 'target' => '_blank', + ), + $defined); + } + + $view->addProperty(pht('Defined'), $defined); + } + } diff --git a/src/docs/book/phabricator.book b/src/docs/book/phabricator.book index 6974b01453..ecac4a6ba0 100644 --- a/src/docs/book/phabricator.book +++ b/src/docs/book/phabricator.book @@ -3,6 +3,8 @@ "title" : "Phabricator Technical Documentation", "short" : "Phabricator Tech Docs", "root" : "../../../", + "uri.source" : + "https://secure.phabricator.com/diffusion/P/browse/master/%f$%l", "rules" : { "(\\.php$)" : "DivinerPHPAtomizer" }, diff --git a/src/docs/book/user.book b/src/docs/book/user.book index f8f69df87c..35fb7fed15 100644 --- a/src/docs/book/user.book +++ b/src/docs/book/user.book @@ -3,6 +3,8 @@ "title" : "Phabricator User Documentation", "short" : "Phabricator User Docs", "root" : "../../../", + "uri.source" : + "https://secure.phabricator.com/diffusion/P/browse/master/%f$%l", "rules" : { "(\\.diviner$)" : "DivinerArticleAtomizer" }, diff --git a/src/docs/userguide/diviner.diviner b/src/docs/userguide/diviner.diviner new file mode 100644 index 0000000000..e392a606d5 --- /dev/null +++ b/src/docs/userguide/diviner.diviner @@ -0,0 +1,84 @@ +@title Diviner User Guide +@group userguide + +Using Diviner, a documentation generator. + += Overview = + +NOTE: Diviner is new and not yet generally useful. + += Generating Documentation = + +To generate documentation, run: + + phabricator/ $ ./bin/diviner generate --book + += .book Files = + +Diviner documentation books are configured using JSON `.book` files, which +look like this: + + name=example.book + { + "name" : "example", + "title" : "Example Documentation", + "short" : "Example Docs", + "root" : ".", + "uri.source" : "http://example.com/diffusion/X/browse/master/%f$%l", + "rules" : { + "(\\.diviner$)" : "DivinerArticleAtomizer" + }, + "exclude" : [ + "(^externals/)", + "(^scripts/)", + "(^support/)" + ], + "groups" : { + "forward" : { + "name" : "Doing Stuff" + }, + "reverse" : { + "name" : "Undoing Stuff" + } + } + } + +The properties in this file are: + + - `name`: Required. Short, unique name to identify the documentation book. This + will be used in URIs, so it should not have special characters. Good names + are things like `"example"` or `"libcabin"`. + - `root`: Required. The root directory (relative to the `.book` file) which + documentation should be generated from. Often this will be a value like + `"../../"`, to specify the project root (for example, if the `.book` file + is in `project/src/docs/example.book`, the value `"../../"` would generate + documentation from the `project/` directory. + - `title`: Optional. Full human-readable title of the documentation book. This + is used when there's plenty of display space and should completely describe + the book. Good titles are things like `"Example Documentation"`, or + `"libcabin Developer Documentation"`. + - `short`: Optional. Shorter version of the title for use when display space + is limited (for example, in navigation breadcrumbs). If omitted, the full + title is used. Good short titles are things like `"Example Docs"` or + `"libcabin Dev Docs"`. + - `uri.source`: Optional. Diviner can link from the documentation to a + repository browser so that you can quickly jump to the definition of a class + or function. To do this, it uses a URI pattern which you specify here. + Normally, this URI should point at a repository browser like Diffusion. + For example, `"http://repobrowser.yourcompany.com/%f#%l"`. You can use these + conversions in the URI, which will be replaced at runtime: + - `%f`: Replaced with the name of the file. + - `%l`: Replaced with the line number. + - `%%`: Replaced with a literal `%` symbol. + - `rules`: Optional. A map of regular expressions to Atomizer classes which + controls which documentation generator runs on each file. If omitted, + Diviner will use its default ruleset. For example, adding the key + `"(\\.diviner$)"` to the map with value `"DivinerArticleAtomizer"` tells + Diviner to analyze any file with a name ending in `.diviner` using the + "article" atomizer. + - `exclude`: Optional. A list of regular expressions matching paths which + will be excluded from documentation generation for this book. For example, + adding a pattern like `"(^externals/)"` or `"(^vendor/)"` will make Diviner + ignore those directories. + - `groups`: Optional. Describes top level organizational groups which atoms + should be placed into.