42 | {{/exceptions}}
43 | {{/hasExceptions}}
--------------------------------------------------------------------------------
/ContentTemplate/partials/dotnet/moniker.tmpl.partial:
--------------------------------------------------------------------------------
1 | {{! this partial template contains h2 tags with static id, so please only use it once in one page.}}
2 | {{#monikers.0}}
3 |
11 | {{/xamlMemberSyntax}}
--------------------------------------------------------------------------------
/ContentTemplate/partials/dotnet/typeContent.tmpl.partial:
--------------------------------------------------------------------------------
1 | {{! this partial template contains h2 tags with static id, so please only use it once in one page.}}
2 | {{#examples}}
3 |
9 | {{{.}}}
10 | {{/remarks}}
--------------------------------------------------------------------------------
/ContentTemplate/partials/dotnet/typeFooter.tmpl.partial:
--------------------------------------------------------------------------------
1 | {{! this partial template contains h2 tags with static id, so please only use it once in one page.}}
2 | {{#threadSafety}}
3 |
`
42 |
43 | Custom tags
44 | -------
45 | ### inheritdoc
46 | `docfx` supports a subset of the [inheritdoc functionality available in Sandcastle](https://ewsoftware.github.io/XMLCommentsGuide/html/86453FFB-B978-4A2A-9EB5-70E118CA8073.htm). Specifically, it implements most of the "Top-Level Inheritance Rules". It does not implement:
47 | * Support for the `select` attribute.
48 | * Automatic inheritance of documentation for explicit interface implementations.
49 | * Support for inline `inheritdoc` tags (i.e., an `inheritdoc` tag inside of an `example` tag).
50 |
51 |
--------------------------------------------------------------------------------
/samples/toc.yml:
--------------------------------------------------------------------------------
1 | - name: Tutorials
2 | href: tutorial/
3 | - name: Specifications
4 | href: spec/
5 | homepage: spec/metadata_format_spec.md
6 | - name: API Documentation
7 | href: obj/temp/docfxapi/
8 |
--------------------------------------------------------------------------------
/samples/tutorial/advanced_support_hyperlink.md:
--------------------------------------------------------------------------------
1 | 🔧 Advanced: Support Hyperlink
2 | ===============================
3 |
4 | In this topic, we will support hyperlinking in rtf files.
5 |
6 | Create a hyperlink in the rtf file:
7 | 1. Open `foo.rtf` by `Word`.
8 | 2. Add a hyperlink in content
9 | 3. Set the link target to an existing `bar.rtf`
10 | 4. Save the document.
11 |
12 | About link
13 | ----------
14 | An author can write any valid hyperlink in the document, and then needs to run `DocFX build` to update file links.
15 |
16 | ### What is file link:
17 | 1. The hyperlink must be a relative path and not rooted.
18 | * valid: `foo\bar.rtf`, `../foobar.rtf`
19 | * invalid: `/foo.rtf`, `c:\foo\bar.rtf`, `http://foo.bar/`, `mailto:foo@bar.foobar`
20 | 2. The file must exist.
21 |
22 | ### Why update file link:
23 |
24 | The story is:
25 | 1. In `foo.rtf`, it has a file link to `bar.rtf`.
26 | 2. In document build, `bar.rtf` generates a file with the name `bar.html`.
27 | 3. But in `foo.rtf`, the link target is still `bar.rtf`, thus in the output folder we cannot find this file and we will get a broken link.
28 | 4. To resolve the broken link, we need to update the link target from `bar.rtf` to `bar.html`.
29 |
30 | File link is a relative path, but we cannot track the relative path easily.
31 | So we track the *normalized file path* instead.
32 |
33 | ### What is a *normalized file path*:
34 | 1. It always starts from the working folder (the folder that contains `docfx.json`), and we write it as `~/`.
35 | 2. No `../` or `./` or `//`
36 | 3. Replace `\` with `/`.
37 | 4. No url encoding. The path must be same as it in the file system.
38 | 5. No anchor.
39 |
40 | Finally, a valid *normalized file path* looks like: `~/foo/bar.rtf`.
41 |
42 | * Pros
43 | * Same form in different documents when the target is the same file.
44 |
45 | When file structure is:
46 | ```
47 | z:\a\b\foo.rtf
48 | z:\a\b\c\bar.rtf
49 | z:\a\b\c\foobar.rtf
50 | ```
51 | Link target `c/foobar.rtf` in `foo.rtf` and link target `foobar.rtf` in `bar.rtf` is the same file.
52 | When the working folder is `z:\a\`, the link target is always `~/b/c/foobar.rtf`.
53 |
54 | * Avoids differences in style when referring to the same file.
55 |
56 | For example, the following hyperlinks target the same file: `a/foo.rtf`, `./a/foo.rtf`, `a/b/../foo.rtf`, `a//foo.rtf`, `a\foo.rtf`
57 |
58 | * Cons
59 | * A folder with the name `~` is not supported.
60 |
61 | Prepare
62 | -------
63 | 1. Open the rtf plug-in library project in `Visual Studio`.
64 |
65 | 2. Add nuget packages:
66 | for plug-in: `Microsoft.DocAsCode.Utility`
67 |
68 | 3. Add framework assembly reference:
69 | `System.Core`, `System.Web`, `System.Xml.Linq`
70 |
71 | Update rtf document processor
72 | -----------------------------
73 | 1. Following the rules for hyperlink, add a `FixLink` help method:
74 | [!Code-csharp[FixLink](../codesnippet/Rtf/Hyperlink/RtfDocumentProcessor.cs?name=FixLink)]
75 |
76 | `RelativePath` helps us generate the links correctly.
77 |
78 | 2. Then add `CollectLinksAndFixDocument` method:
79 | [!Code-csharp[CollectLinksAndFixDocument](../codesnippet/Rtf/Hyperlink/RtfDocumentProcessor.cs?name=CollectLinksAndFixDocument)]
80 |
81 | 3. Modify `Save` method with report links:
82 | [!Code-csharp[Save](../codesnippet/Rtf/Hyperlink/RtfDocumentProcessor.cs?name=Save)]
83 |
84 |
85 |
86 | View final [RtfDocumentProcessor.cs](../codesnippet/Rtf/Hyperlink/RtfDocumentProcessor.cs)
87 |
88 |
89 | Test and verify
90 | ---------------
91 | 1. Build project.
92 | 2. Copy dll to `Plugins` folder.
93 | 3. Modify rtf file, create hyperlink, link to another rtf file, and save.
94 | 4. Build with command `DocFX build`.
95 | 5. Verify output html file.
--------------------------------------------------------------------------------
/samples/tutorial/artifacts/docfx.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/docascode/template/dc97fc1eb4cd42e85c861e8d2925f32f914e4c94/samples/tutorial/artifacts/docfx.zip
--------------------------------------------------------------------------------
/samples/tutorial/getting-started.md:
--------------------------------------------------------------------------------
1 | # Getting Started
2 |
3 | This tutorial shows how to build a documentation website.
4 |
5 | You'll learn how to:
6 |
7 | - Create the documentation project.
8 | - Add a homepage.
9 | - Add a markdown document.
10 |
11 | ## Installation
12 |
13 | The easiest way to install docfx is to use [.NET Tools](https://docs.microsoft.com/en-us/dotnet/core/tools/global-tools). Install the latest version of [.NET SDK](https://dotnet.microsoft.com/en-us/download/visual-studio-sdks) and run:
14 |
15 | ```
16 | dotnet tool install -g docfx
17 | ```
18 |
19 | Or you can download from [GitHub Releases](https://github.com/dotnet/docfx/releases).
20 |
21 | ## Create a documentation project
22 |
23 | Open a command shell, and enter the following command:
24 |
25 | ```
26 | docfx new conceptual -o mydocs
27 | ```
28 |
29 | The preceding command creates a new documentation project. The `-o mydocs` parameter creates a directory named `mydocs` with the project files inside.
30 |
31 | ## Run the website locally
32 |
33 | Run the following command:
34 |
35 | ```
36 | docfx build mydocs
37 | docfx serve mydocs --watch
38 | ```
39 |
40 | After the command shell indicates that the website has started, browse to https://localhost:5001.
41 |
42 |
43 | [!code[name](toc.yml?highlight=1,2-2,4-)]
--------------------------------------------------------------------------------
/samples/tutorial/howto_add_a_customized_post_processor.md:
--------------------------------------------------------------------------------
1 | How-to: Add a customized post-processor
2 | ====================================
3 |
4 | We provide the ability to process output files by adding a customized post-processor.
5 | In DocFX, the index file for full-text-search is generated by one post-processor named `ExtractSearchIndex`.
6 | In this topic, we will show how to add a customized post-processor.
7 |
8 | ## Step0: Preparation
9 |
10 | * Create a new C# class library project in `Visual Studio`.
11 | * Add nuget packages:
12 | * [`System.Collections.Immutable`](https://www.nuget.org/packages/System.Collections.Immutable/1.3.1) with version 1.3.1
13 | * [`Microsoft.Composition`](https://www.nuget.org/packages/Microsoft.Composition/1.0.31) with version 1.0.31
14 | * Add `Microsoft.DocAsCode.Plugins`
15 | If you are building DocFX from source code, add this reference to the project,
16 | otherwise add the nuget package `Microsoft.DocAsCode.Plugins` with the same version as DocFX.
17 |
18 | ## Step1: Create a new class (MyProcessor.cs) with the following code:
19 |
20 | ```csharp
21 | [Export(nameof(MyProcessor), typeof(IPostProcessor))]
22 | public class MyProcessor : IPostProcessor
23 | {
24 | // TODO: implements IPostProcessor
25 | }
26 | ```
27 |
28 | ## Step2: Update global metadata
29 |
30 | ```csharp
31 | public ImmutableDictionary PrepareMetadata(ImmutableDictionary metadata)
32 | {
33 | // TODO: add/remove/update property from global metadata
34 | return metadata;
35 | }
36 | ```
37 |
38 | In this method, we can update the global metadata before building all the files declared in `docfx.json`. Otherwise, you can just return the metadata from parameters if you don't need to change global metadata.
39 |
40 | Using `ExtractSearchIndex` for example, we add `"_enableSearch": true` in global metadata. The default template would then know it should load a search box in the navbar.
41 |
42 | ## Step3: Process all the files generated by DocFX
43 |
44 | ```csharp
45 | public Manifest Process(Manifest manifest, string outputFolder)
46 | {
47 | // TODO: add/remove/update all the files included in manifest
48 | return manifest;
49 | }
50 | ```
51 |
52 | Input for the method `manifest` contains a list of all files to process, and `outputFolder` specifies the output folder where our static website will be placed. We can implement customized operations here to process all files generated by DocFX.
53 |
54 | > [!Note]
55 | > Post-processor aims to process the output files, so the `FileModel` can't be accessed in this phase. If some metadata is needed here, an option is to save it in `FileModel.ManifestProperties` in build phase, then access it through `ManifestItem.Metadata`. Another option is to save it somewhere in output files, like HTML's `` Tag.
56 |
57 | Using `ExtractSearchIndex` for example again, we traverse all HTML files, extract key words from these HTML files and save a file named `index.json` under the `outputFolder`. Finally we return the manifest which is not modified.
58 |
59 | ## Step4: Build your project and copy the output dll files to:
60 |
61 | * Global: the folder with name `Plugins` under DocFX.exe
62 | * Non-global: the folder with name `Plugins` under a template folder, then run `DocFX build` command with parameter `-t {template}`.
63 |
64 | *Hint*: DocFX can merge templates, so we can specify multiple template folders as `DocFX build -t {templateForRender},{templateForPlugins}`. Each of the template folders should have a subfolder named `Plugins` with exported assemblies.
65 |
66 | ## Step5: Add your post processor in `docfx.json`
67 |
68 | In this step, we need to enable the processor by adding its name in `docfx.json`. Here is an example:
69 |
70 | ```json
71 | {
72 | "build": {
73 | ...
74 | "postProcessors": ["OutputPDF", "BeautifyHTML", "OutputPDF"]
75 | }
76 | }
77 | ```
78 |
79 | As you can see, the `postProcessors` is an array, which means it could have multiple processors.
80 | It needs to be pointed out that the order of `postProcessors` written in `docfx.json` is also the order to process output files.
81 | In the above example, DocFX will run `OutputPDF` first, then `BeautifyHTML`, and then `OutputPDF` again.
82 |
83 | If you want to enable the post processors without changing `docfx.json`, you can use the build command option like `docfx build --postProcessors=OutputPDF,BeautifyHTML,OutputPDF`.
84 |
85 | One more thing need to be noted: the build command option `postProcessors` would override the corresponding configuration in `docfx.json`.
86 |
--------------------------------------------------------------------------------
/samples/tutorial/howto_create_custom_template.md:
--------------------------------------------------------------------------------
1 | How-to: Create A Custom Template
2 | ===============================
3 |
4 | Templates are organized as a zip package or a folder. The file path (without the `.zip` extension) of the zip package or the path of the folder is considered to be the template name.
5 |
6 | Quickstart
7 | ---------------
8 | Let's create a template to transform Markdown files into a simple html file.
9 |
10 | ### Step 1. Create a template folder
11 | Create a folder for the template, for example, `c:/docfx_howto/simple_template`.
12 |
13 | ### Step 2. Add *Renderer* file
14 | Create a file `conceptual.html.primary.tmpl` under the template folder with the following content:
15 |
16 | ```mustache
17 | {{{conceptual}}}
18 | ```
19 |
20 | Now a simple custom template is created.
21 |
22 | You may notice that DocFX reports a warning message saying that: *Warning: [Build Document.Apply Templates]There is no template processing document type(s): Toc*. It is because our custom template only specifies how to handle document with type `conceptual`.
23 |
24 | To test the output of the template, create a simple documentation project following [Walkthrough Part I](walkthrough/walkthrough_create_a_docfx_project.md) or download the [zipped documentation project](walkthrough/artifacts/walkthrough1.zip) directly.
25 |
26 | In the documentation project, run `docfx build docfx.json -t c:/docfx_howto/simple_template --serve`. The `-t` command option specifies the template name(s) used by the current build.
27 |
28 | Open http://localhost:8080 and you can see a simple web page as follows:
29 |
30 | 
31 |
32 | Add *Preprocessor* file
33 | -----------------------
34 | ### Step 3. Add *Preprocessor* file
35 | Sometimes the input data model is not exactly what *Renderer* wants, you may want to add some properties to the data model, or modify the data model a little bit before applying the *Renderer* file. This can be done by creating a *Preprocessor* file.
36 |
37 | Create a file `conceptual.html.primary.js` under the template folder with the following content:
38 |
39 | ```javascript
40 | exports.transform = function (model) {
41 | model._extra_property = "Hello world";
42 | return model;
43 | }
44 | ```
45 |
46 | Update the file `conceptual.html.primary.tmpl` with the following content:
47 |
48 | ```mustache
49 |
{{_extra_property}}
50 | {{{conceptual}}}
51 | ```
52 |
53 | In the documentation project, run `docfx build docfx.json -t c:/docfx_howto/simple_template --serve`.
54 |
55 | Open http://localhost:8080 and you can see `_extra_property` is added to the web page.
56 |
57 | 
58 |
59 | Merge template with `default` template
60 | ------------------------------------------
61 | DocFX contains some embedded template resources that you can refer to directly. You can use `docfx template list` to list available templates provided by DocFX.
62 |
63 | Take `default` template as an example.
64 |
65 | Run `docfx template export default`. It exports what's inside `default` template into the folder `_exported_templates`. You can see that there are sets of *Preprocessor* and *Renderer* files to deal with different types of documents.
66 |
67 | DocFX supports specifying multiple templates for a documentation project. That allows you to leverage the `default` template for handling other types of documents, together with your custom template.
68 |
69 | When dealing with multiple templates, DocFX merges the files inside these templates.
70 |
71 | The principle for merging is: if a file name collides then the file in the latter template overwrites the one in the former template.
72 |
73 | For example, you can merge `default` template and your custom template by calling `docfx build docfx.json -t default,c:/docfx_howto/simple_template`. Multiple templates are split by a comma `,` in the command line. Or you can define it in `docfx.json` by:
74 | ```
75 | "build": {
76 | "template": [
77 | "default",
78 | "c:/docfx_howto/simple_template"
79 | ]
80 | }
81 | ```
82 |
83 | In the documentation project, run `docfx build docfx.json -t default,c:/docfx_howto/simple_template --serve`.
84 |
85 | Now the warning message *There is no template processing document type(s): Toc* disappears because the default template contains *Renderer* to handle TOC files.
86 |
87 | Open http://localhost:8080/toc.html and you can see a toc web page.
88 | 
89 |
90 | > [!Tip]
91 | > Run `docfx template export default` to view what's inside the default template.
92 | >
93 | > [!Note]
94 | > It is possible that DocFX updates its embedded templates when a new version is released.
95 | > So please make sure to re-export the template if you overwrite or are dependent on it in your custom template.
96 |
97 | Extension for *Preprocessor* file
98 | ----------------------------------
99 | If you want to modify some properties based on DocFX `default` template's *Preprocessor*, you can use *Preprocessor* extension file to achieve this.
100 |
101 | For example, if you want to add a property to the managed reference's data model after `default` template's *Preprocessor*, you can update the file `ManagedReference.extension.js` in your custom template with the following content:
102 | ```
103 | /**
104 | * This method will be called at the start of exports.transform in ManagedReference.html.primary.js
105 | */
106 | exports.preTransform = function (model) {
107 | return model;
108 | }
109 |
110 | /**
111 | * This method will be called at the end of exports.transform in ManagedReference.html.primary.js
112 | */
113 | exports.postTransform = function (model) {
114 | model._extra_property = "Hello world";
115 | return model;
116 | }
117 | ```
118 | Compared with modifying `ManagedReference.html.primary.js` directly, you needn't worry about merging your custom templates with DocFX's embedded templates when DocFX updates.
119 |
--------------------------------------------------------------------------------
/samples/tutorial/images/simple_web_page.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/docascode/template/dc97fc1eb4cd42e85c861e8d2925f32f914e4c94/samples/tutorial/images/simple_web_page.png
--------------------------------------------------------------------------------
/samples/tutorial/images/toc_web_page.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/docascode/template/dc97fc1eb4cd42e85c861e8d2925f32f914e4c94/samples/tutorial/images/toc_web_page.png
--------------------------------------------------------------------------------
/samples/tutorial/images/web_page_with_extra_property.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/docascode/template/dc97fc1eb4cd42e85c861e8d2925f32f914e4c94/samples/tutorial/images/web_page_with_extra_property.png
--------------------------------------------------------------------------------
/samples/tutorial/incrementalbuild/advanced_cache_file_structure.md:
--------------------------------------------------------------------------------
1 | 🔧 Advanced: Cache File Structure
2 | =====================================
3 |
4 | DocFX incremental build cache files are centralized and put in a folder specified with option `--intermediateFolder` or `obj/.cache/build/` relative to your `docfx.json` by default.
5 |
6 | In the root folder of the cache files, there is a `build.info`, it is kind of index page, which is the entry point of the cache files. Below table lists the major information inside.
7 |
8 | ### BuildInfo model
9 |
10 | Property | Type | Description
11 | --------------------- | --------------------- | -----------------------------------------------------------
12 | DirectoryName | string | Base directory of the cache files of last successful build
13 | DocfxVersion | string | DocFX version
14 | PluginHash | string | The hash of plugins plugged in DocFX
15 | TemplateHash | string | The hash of specified Templates
16 | Versions | List<[BuildVersionInfo](#buildversioninfo-model)> | entry point of the cache files per version
17 | PostProcessInfo | [PostProcessInfo](#postprocessinfo-model) | The entry point of the cache files for postprocessor
18 |
19 | ### BuildVersionInfo model
20 |
21 | Property | Type | Description
22 | --------------------- | --------------------- | -----------------------------------------------------------
23 | VersionName | string | Version name
24 | ConfigHash | string | The hash of configs for the version
25 | DependencyFile | string | The file link for dependency
26 | AttributesFile | string | The file link for file attributes
27 | OutputFile | string | The file link for build outputs
28 | ManifestFile | string | The file link for the manifest file
29 | XRefSpecMapFile | string | The file link for the XRefMap file
30 | ExternalXRefSpecFile | string | The file link for the ExternalXRefSpec file
31 | FileMapFile | string | The file link for the FileMap file
32 | BuildMessageFile | string | The file link for build message file
33 | TocRestructionsFile | string | The file link for TocRestructions file
34 | Processors | List<[ProcessorInfo](#processorinfo-model)> | The entry point of the cache files per processor
35 |
36 | ### ProcessorInfo model
37 |
38 | Property | Type | Description
39 | --------------------- | --------------------- | -----------------------------------------------------------
40 | Name | string | The name of the processor
41 | IncrementalContextHash | string | The context hash of the processor
42 | IntermediateModelManifestFile | string | The file link for the BuildModel manifest file
43 | Steps | List<[ProcessorStepInfo](#processorstepinfo-model)> | The entry point of cache files per step for the processor
44 |
45 | ### ProcessorStepInfo model
46 |
47 | Property | Type | Description
48 | --------------------- | --------------------- | -----------------------------------------------------------
49 | Name | string | The name of the step
50 | IncrementalContextHash | string | The context hash of the step
51 | ContextInfoFile | string | The file link for the context info for the step
52 |
53 | ### PostProcessInfo model
54 |
55 | Property | Type | Description
56 | --------------------- | --------------------- | ---------------------
57 | MessageInfoFile | string | The file link for the log message file, to restore the warning message
58 | ManifestItemsFile | string | The file link for the manifest items file, to restore the manifest items
59 | PostProcessOutputsFile | string | The file link for post processing outputs
60 | PostProcessorInfos | List<[PostProcessorInfo](#postprocessorinfo-model)> | The information of post processors
61 |
62 | ### PostProcessorInfo model
63 |
64 | | Property | Type | Description |
65 | |------------------------|--------|------------------------------------|
66 | | Name | string | The name of the step |
67 | | IncrementalContextHash | string | The context hash of the step |
68 | | ContextInfoFile | string | The file link for the context info |
69 |
70 |
--------------------------------------------------------------------------------
/samples/tutorial/incrementalbuild/customize_a_post_processor_to_be_incremental.md:
--------------------------------------------------------------------------------
1 | # Walkthrough: Customize a post processor to be incremental
2 |
3 | In this tutorial, we'll walk through how to enable a post processor to be incremental.
4 |
5 | ## Implement @Microsoft.DocAsCode.Plugins.ISupportIncrementalPostProcessor for the post processor
6 |
7 | ```csharp
8 | public class AppendIntegerPostProcessor : ISupportIncrementalPostProcessor
9 | {
10 | // to-do: implements IPostProcessor
11 |
12 | public IPostProcessorHost PostProcessorHost { get; set; }
13 |
14 | public string GetIncrementalContextHash()
15 | {
16 | // to-do: incremental context hash. If it changes, incremental post processing isn't triggered.
17 | }
18 | }
19 | ```
20 |
21 | ## Optional: Load and save customized context information from cache
22 |
23 | @Microsoft.DocAsCode.Plugins.IPostProcessorHost is the host to provide incremental post processing information as following.
24 |
25 | Property | Type | Description
26 | --------------------- | --------------------- | ---------------------
27 | SourceFileInfos | List of @Microsoft.DocAsCode.Plugins.SourceFileInfo | Information of source files
28 | ShouldTraceIncrementalInfo | bool | Whether the post processor should trace incremental information
29 | IsIncremental | bool | Whether the post processor can be incremental
30 |
31 | @Microsoft.DocAsCode.Plugins.IPostProcessorHost can also load and save customized context information per post processor in incremental cache.
32 |
33 | Method | Return Type | Description
34 | --------------------- | --------------- | ---------------------
35 | LoadContextInfo() | Stream | Load context information from last post processing
36 | SaveContextInfo() | Stream | Save context information to current post processing
37 |
38 | Here's the sample:
39 | ```csharp
40 | public class AppendIntegerPostProcessor : ISupportIncrementalPostProcessor
41 | {
42 | public IPostProcessorHost PostProcessorHost { get; set; }
43 |
44 | public string GetIncrementalContextHash() { return string.Empty; }
45 |
46 | public Manifest Process(Manifest manifest, string outputFolder)
47 | {
48 | string contextInfo = string.Empty;
49 | var stream = PostProcessorHost.LoadContextInfo();
50 | if (stream != null)
51 | {
52 | using (var sr = new StreamReader(stream))
53 | {
54 | contextInfo = sr.ReadToEnd();
55 | }
56 | }
57 |
58 | using (var saveStream = PostProcessorHost.SaveContextInfo())
59 | using (var sw = new StreamWriter(saveStream))
60 | {
61 | sw.Write(contextInfo + "-updated");
62 | }
63 |
64 | return manifest;
65 | }
66 | }
67 | ```
--------------------------------------------------------------------------------
/samples/tutorial/incrementalbuild/customize_a_processor_to_support_incremental.md:
--------------------------------------------------------------------------------
1 | Walkthrough: Customize a processor to support incremental build
2 | ================================================================
3 |
4 | During this tutorial, we'll walk through the steps to enable a processor to be incremental.
5 |
6 | Step1. Implement @Microsoft.DocAsCode.Plugins.ISupportIncrementalDocumentProcessor interface for the processor
7 | ------------------------------------------------------------------------------------
8 |
9 | ```csharp
10 | public class RtfDocumentProcessor : ISupportIncrementalDocumentProcessor
11 | {
12 | // to-do: implements IDocumentProcessor
13 |
14 | public virtual string GetIncrementalContextHash()
15 | {
16 | // to-do: context related hash. if it changes, incremental build isn't triggered.
17 | }
18 |
19 | public virtual void SaveIntermediateModel(FileModel model, Stream stream)
20 | {
21 | // to-do: the logic to store filemodel
22 | }
23 |
24 | public virtual FileModel LoadIntermediateModel(Stream stream)
25 | {
26 | // to-do: the logic to load filemodel
27 | }
28 | }
29 | ```
30 |
31 | Step2. Implement @Microsoft.DocAsCode.Plugins.ISupportIncrementalBuildStep interface for all the plugins plugged in the processor
32 | ------------------------------------------------------------------------------------------------------
33 | Plugins are flexible to register customized dependency types by implementing the interface's method @Microsoft.DocAsCode.Plugins.ISupportIncrementalBuildStep.GetDependencyTypesToRegister.
34 |
35 | Plugins are also flexible to report dependencies by invoking the methods provided by @Microsoft.DocAsCode.Plugins.IHostService.
36 |
37 | ```csharp
38 | public class RtfBuildStep : ISupportIncrementalBuildStep
39 | {
40 | // to-do: implements IDocumentBuildStep
41 |
42 | public bool CanIncrementalBuild(FileAndType fileAndType) => true;
43 |
44 | public string GetIncrementalContextHash() => null;
45 |
46 | public IEnumerable GetDependencyTypesToRegister() => new[]
47 | {
48 | new DependencyType()
49 | {
50 | Name = "ref",
51 | Phase = BuildPhase.Link,
52 | Transitivity = DependencyTransitivity.None,
53 | }
54 | };
55 |
56 | public override void Build(FileModel model, IHostService host)
57 | {
58 | //.....
59 | host.ReportDependencyTo(model, "uid", DependencyItemSourceType.Uid, "ref");
60 | }
61 | }
62 | ```
63 |
64 | The above sample registered a dependency type named `ref`, this type of dependency applies during `Link` phase and it isn't transitive. `DocFX` has some reserved dependency types, you can refer to [Reserved Dependency Types](advanced_report_dependency.md#reserved-dependency-types) for more details.
65 |
66 | In `Build` step, this plugin reports dependencies of type `ref` by invoking @Microsoft.DocAsCode.Plugins.IHostService 's `ReportDependencyTo` method. @Microsoft.DocAsCode.Plugins.IHostService also provides `ReportDependencyFrom` method you can report reverse dependency.
67 |
68 | For more details about how to register your own dependency types and report , you can refer to [Advanced: register and report dependency](advanced_report_dependency.md).
69 |
70 |
71 | Step3. [Optional]Implement @Microsoft.DocAsCode.Plugins.ICanTraceContextInfoBuildStep interface for plugins that need to access context info
72 | -----------------------------------------------------------------------------------------------------------------------
73 | When building articles, some plugins might need the info of unloaded articles. Incremental Build Framework provides the interface @Microsoft.DocAsCode.Plugins.ICanTraceContextInfoBuildStep, which is the superset of @Microsoft.DocAsCode.Plugins.ISupportIncrementalBuildStep and also contains methods to save/load context info.
74 |
75 | ```csharp
76 | public class RtfBuildStep : ICanTraceContextInfoBuildStep
77 | {
78 | // to-do: implements ISupportIncrementalBuildStep
79 |
80 | public void LoadContext(Stream stream)
81 | {
82 | // to-do: the logic to load last context info
83 | }
84 |
85 | public void SaveContext(Stream stream)
86 | {
87 | // to-do: the logic to save current context info
88 | }
89 | }
90 | ```
91 |
92 |
93 | Now you're done! Your processor can run incrementally!
--------------------------------------------------------------------------------
/samples/tutorial/incrementalbuild/images/incrementalbuildframework.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/docascode/template/dc97fc1eb4cd42e85c861e8d2925f32f914e4c94/samples/tutorial/incrementalbuild/images/incrementalbuildframework.png
--------------------------------------------------------------------------------
/samples/tutorial/incrementalbuild/images/incrementalpostprocessingframework.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/docascode/template/dc97fc1eb4cd42e85c861e8d2925f32f914e4c94/samples/tutorial/incrementalbuild/images/incrementalpostprocessingframework.png
--------------------------------------------------------------------------------
/samples/tutorial/incrementalbuild/intro_incremental_post_processing.md:
--------------------------------------------------------------------------------
1 | # Introduction to *DocFX Incremental Post Processing*
2 |
3 | ## Workflow
4 |
5 | 
6 |
7 | Overall, the output of all post processors would be cached in following:
8 | 1. Manifest items: to restore incremental manifest items.
9 | 2. Log message info: to replay the log message.
10 | 3. Output files: to restore the post processing outputs.
11 |
12 | Based on incremental build result, `IsIncremental` flag of the manifest item could hint whether the item is incremental or not.
13 | 1. If the post processing meets [Incremental Condition](#incremental-condition):
14 | 1. For the incremental manifest items, restore from cache.
15 | 2. For the non-incremental manifest items, they will be handled by post processors, and save the information into cache at the same time.
16 | 2. If the post processing doesn't meet [Incremental Condition](#incremental-condition), set `IsIncremental` flag to false to all manifest items, then they will be handled by post processors.
17 |
18 | ## Incremental Condition
19 |
20 | The post processing could be incremental only if it meets all of the following conditions:
21 | 1. Both last cache file [`build.info`](advanced_cache_file_structure.md) and its [`PostProcessInfo`](advanced_cache_file_structure.md#postprocessinfo-model) exist, which is essential to restore the last incremental post processing info.
22 | 2. Not set option `forcePostProcess` and `force` of build command or `docfx.json` config, to enable incremental post processing.
23 | 3. Post processor requirement:
24 | 1. Each of the post processor implements @Microsoft.DocAsCode.Plugins.ISupportIncrementalPostProcessor. Currently, @Microsoft.DocAsCode.Build.Engine.HtmlPostProcessor implements the interface while @Microsoft.DocAsCode.Build.Engine.ExtractSearchIndex does not. Refer to [Customize a post processor to be incremental](customize_a_post_processor_to_be_incremental.md) for more details.
25 | 2. Post processor number isn't changed.
26 | 3. Each post processor's `IncrementalContextHash` isn't changed
27 |
28 |
--------------------------------------------------------------------------------
/samples/tutorial/incrementalbuild/toc.yml:
--------------------------------------------------------------------------------
1 | - name: Introduction to DocFX incremental build
2 | href: intro_incremental_build.md
3 | - name: Customize a processor to support incremental build
4 | href: customize_a_processor_to_support_incremental.md
5 | - name: 'Advanced: Report Dependency'
6 | href: advanced_report_dependency.md
7 | - name: 'Advanced: Cache File Structure'
8 | href: advanced_cache_file_structure.md
9 | - name: Incremental post processing
10 | items:
11 | - name: Introduction to incremental post processing
12 | href: intro_incremental_post_processing.md
13 | - name: Customize a post processor to be incremental
14 | href: customize_a_post_processor_to_be_incremental.md
--------------------------------------------------------------------------------
/samples/tutorial/intro_default_template.md:
--------------------------------------------------------------------------------
1 | 🔧 Default Template Introduction
2 | ===============================================
3 |
4 | ## Search Library -- [`lunr.js`](https://lunrjs.com/)
5 |
6 | ## Customize full-text search in your website
7 |
8 | ### Search enable
9 |
10 | ### Disable full-text for specific pages
--------------------------------------------------------------------------------
/samples/tutorial/toc.yml:
--------------------------------------------------------------------------------
1 | - name: Getting Started
2 | items:
3 | - name: Quickstart
4 | href: getting-started.md
5 | - name: DocFX User Manual
6 | href: docfx.exe_user_manual.md
7 | - name: "HowTo: Filter Out Unwanted APIs"
8 | href: howto_filter_out_unwanted_apis_attributes.md
9 | - name: Walkthrough Topics
10 | href: walkthrough/toc.md
11 | homepage: walkthrough/walkthrough_overview.md
12 | - name: Content
13 | items:
14 | - name: TOC
15 | href: intro_toc.md
16 | - name: REST API
17 | href: intro_rest_api_documentation.md
18 | - name: Overwrite Files
19 | href: intro_overwrite_files.md
20 | - name: Links and Cross References
21 | href: links_and_cross_references.md
22 | - name: Template
23 | items:
24 | - name: Template System
25 | href: intro_template.md
26 | - name: "HowTo: Create Custom Template"
27 | href: howto_create_custom_template.md
28 | - name: Incremental Build
29 | href: incrementalbuild/toc.yml
30 | - name: Extensibility
31 | items:
32 | - name: How to build your own type of documentation with custom plug-in
33 | href: howto_build_your_own_type_of_documentation_with_custom_plug-in.md
34 | items:
35 | - name: "Advanced: Support Hyperlink"
36 | href: advanced_support_hyperlink.md
37 | - name: How to add a customized post processor
38 | href: howto_add_a_customized_post_processor.md
39 | - name: Validate your markdown files
40 | href: validate_your_markdown_files.md
41 | - name: Intro markdown lite
42 | href: intro_markdown_lite.md
43 | - name: How to customize DocFX Flavored Markdown
44 | href: howto_customize_docfx_flavored_markdown.md
45 | - name: "Multiple Programming Languages Support"
46 | href: universalreference/toc.yml
47 |
--------------------------------------------------------------------------------
/samples/tutorial/universalreference/gen_doc_for_js.md:
--------------------------------------------------------------------------------
1 | # Generate API Documentation for JavaScript
2 |
3 | ## 1. Prerequisite
4 |
5 | * [DocFX](https://dotnet.github.io/docfx/tutorial/docfx_getting_started.html#2-use-docfx-as-a-command-line-tool)
6 | * [Node.js](https://nodejs.org/en/download/) (includes npm)
7 |
8 | ## 2. Steps
9 |
10 | ### 2.1 Prepare Source Code
11 | Prepare the JavaScript source code for generating document. In this tutorial, we take [azure-batch](https://www.npmjs.com/package/azure-batch) as an example
12 | ```
13 | npm install azure-batch
14 | ```
15 |
16 | ### 2.2 Generate Metadata
17 | We use [Node2DocFX](https://www.npmjs.com/package/node2docfx) tool to generate YAML files.
18 | ```
19 | npm install node2docfx
20 | ```
21 |
22 | Create the `node2docfx.json` for the tool configuration:
23 | ```json
24 | {
25 | "source": {
26 | "include": ["node_modules/azure-batch/lib"]
27 | },
28 | "destination": "yml"
29 | }
30 | ```
31 | With this config, the tool will read source code under `node_modules/azure-batch/lib`, and extract metadata to YAML files under `yml` folder:
32 | ```
33 | node node_modules/node2docfx/node2docfx.js node2docfx.json
34 | ```
35 |
36 | ### 2.3 Build Document
37 | Create the configuration `docfx.json` for DocFX:
38 | ```json
39 | {
40 | "build": {
41 | "content": [
42 | {
43 | "files": ["**/*.yml"],
44 | "src": "yml",
45 | "dest": "api"
46 | }
47 | ],
48 | "dest": "_site"
49 | }
50 | }
51 | ```
52 |
53 | More information about `docfx.json` can be found in [user manual](https://dotnet.github.io/docfx/tutorial/docfx.exe_user_manual.html). Run:
54 | ```
55 | docfx docfx.json --serve
56 | ```
57 | Now you can see your generated pages: http://localhost:8080/api/Account.html
--------------------------------------------------------------------------------
/samples/tutorial/universalreference/gen_doc_for_ts.md:
--------------------------------------------------------------------------------
1 | # Generate API Documentation for TypeScript
2 |
3 | ## 1. Prerequisite
4 |
5 | * [DocFX](https://dotnet.github.io/docfx/tutorial/docfx_getting_started.html#2-use-docfx-as-a-command-line-tool)
6 | * [Node.js](https://nodejs.org/en/download/) (includes npm)
7 | * [Git](https://git-scm.com/)
8 |
9 | ## 2. Steps
10 |
11 | ### 2.1 Prepare Source Code
12 | Prepare the TypeScript source code for generating document. In this tutorial, we take [azure-iot-device](https://github.com/Azure/azure-iot-sdk-node/tree/master/device/core) as an example.
13 | ```
14 | git clone https://github.com/Azure/azure-iot-sdk-node.git
15 | ```
16 |
17 |
18 | ### 2.2 Generate Metadata for a package
19 | We use [typedoc](http://typedoc.org/) tool and [type2docfx](https://www.npmjs.com/package/type2docfx) to generate YAML files.
20 |
21 | First, let's install the tools globally.
22 | ```
23 | npm install -g typedoc type2docfx
24 | ```
25 |
26 | #### 2.2.1 TypeDoc to parse source code into a JSON format output
27 | Go to the folder where package.json file locate.
28 | Run
29 | ```
30 | typedoc --json api.json azure-iot-sdk-node/device/core/src --module commonjs --includeDeclarations --ignoreCompilerErrors --excludeExternals
31 | ```
32 |
33 | The parameter may differ for your needs. You can use `typedoc -h` to explore more options.
34 |
35 |
36 | #### 2.2.2 Type2docfx to extract the JSON format output into YAML files
37 | Find the output `api.json` file and run:
38 | ```
39 | type2docfx api.json yml
40 | ```
41 | The `yml` stands for the output folder, you can specify the folder as the content publishing folder in Section 2.3. And you can explore more option by `type2docfx -h`. With `--sourceUrl, --sourceBranch, and --basePath` parameters, you can generate yaml files referencing to the source code in Github, which will help developer to find the corresponding source code easily.
42 |
43 | > [!NOTE]
44 | >
45 | > All sources under `node_modules` path will be automatically ignored.
46 |
47 | ### 2.3 Build Document
48 | Create the configuration `docfx.json` for DocFX:
49 | ```json
50 | {
51 | "build": {
52 | "content": [
53 | {
54 | "files": ["**/*.yml"],
55 | "src": "yml",
56 | "dest": "api"
57 | }
58 | ],
59 | "dest": "_site"
60 | }
61 | }
62 | ```
63 |
64 | More information about `docfx.json` can be found in [user manual](https://dotnet.github.io/docfx/tutorial/docfx.exe_user_manual.html). Run:
65 | ```
66 | docfx docfx.json --serve
67 | ```
68 | Now you can see your generated pages: http://localhost:8080/api/azure-iot-device/Client.html#azure_iot_device_Client
69 |
70 | ## 3. Know issues
71 | 1. Some types can't link to the property correctly now. They displays in plain text and prefixed with `@`.
72 |
--------------------------------------------------------------------------------
/samples/tutorial/universalreference/intro_multiple_langs_support.md:
--------------------------------------------------------------------------------
1 | # Introduction to Multiple Languages Support
2 |
3 | ## 1. Introduction
4 |
5 | DocFX supports generating API documentation for C# and VB natively. However, it's not limited to these. DocFX is designed to support any language. When generating documents for a language, two steps are required: generating metadata and building documents from the metadata.
6 |
7 | ## 2. Workflow
8 |
9 | ### 2.1 Generate Metadata
10 |
11 | As different programming language has different tool written with different language to generate API documentation, this step is not included in DocFX core. We call the tool used as **Metadata Tool**.
12 |
13 | As [UniversalReferenceDocumentProcessor](https://github.com/dotnet/docfx/tree/dev/src/Microsoft.DocAsCode.Build.UniversalReference) is used to process these metadata files, the metadata tool should generate files according the processor's input schema. The files should:
14 | 1. be in YAML format and end with `.yml` or `.yaml`
15 | 2. have YamlMime `### YamlMime:UniversalReference` as the first line
16 | 3. conform to the [data model defined for UniversalReference](https://github.com/dotnet/docfx/tree/dev/src/Microsoft.DocAsCode.DataContracts.UniversalReference)
17 |
18 | Usually, a TOC should be generated along with YAML files for easy navigation among files.
19 |
20 | ### 2.2 Build Document
21 |
22 | The YAML files generated are used as input to DocFX. DocFX will build these YAML files into HTML pages.
23 |
24 | ## 3. Supported Languages
25 | * [JavaScript](gen_doc_for_js.md)
26 | * TypeScript (coming soon ...)
27 | * Python (coming soon ...)
28 |
--------------------------------------------------------------------------------
/samples/tutorial/universalreference/toc.yml:
--------------------------------------------------------------------------------
1 | - name: Introduction
2 | href: intro_multiple_langs_support.md
3 | - name: JavaScript
4 | href: gen_doc_for_js.md
5 | - name: TypeScript
6 | href: gen_doc_for_ts.md
--------------------------------------------------------------------------------
/samples/tutorial/walkthrough/TOC.md:
--------------------------------------------------------------------------------
1 | # [Part I: Generate a Simple Documentation Website](walkthrough_create_a_docfx_project.md)
2 | # [Part II: Add API Documentation to the Website](walkthrough_create_a_docfx_project_2.md)
3 | # [Part III: Generate PDF Documentation](walkthrough_generate_pdf.md)
4 | # [Advanced: Customize Your Website](advanced_walkthrough.md)
--------------------------------------------------------------------------------
/samples/tutorial/walkthrough/advanced_walkthrough.md:
--------------------------------------------------------------------------------
1 | Walkthrough Advanced: Customize Your Website
2 | ===================================
3 |
4 | ## Apply your own styles to the website or PDF
5 |
6 | ### Export the default template
7 |
8 | To export the default HTML template, open the command line at the root of the directory and run `docfx template export default`.
9 |
10 | A folder called `_exported_templates` is added at root with a directory inside called `default`. This is the DocFX default HTML template.
11 |
12 | To export the default PDF template, run `docfx template export pdf.default`.
13 |
14 | ### Create a new template
15 |
16 | Create a new directory at root to hold your custom templates - name it something like `templates`. Inside that folder, create a new folder and name it whatever you want to name your custom template. In this folder you'll replicate files from `_exported_templates/default` or `_exported_templates/pdf.default` (and only those files) you want to overwrite.
17 |
18 | ### Apply the template
19 |
20 | To apply your custom HTML template permanently, add the following to `docfx.json` at the root of the project inside `"build": {`:
21 |
22 | ```
23 | "template": [
24 | "default",
25 | "templates/"
26 | ],
27 | ```
28 |
29 | To apply your custom PDF template permanently, add the following at the same level as `"content"` under `"pdf"`:
30 |
31 | ```
32 | "template": [
33 | "pdf.default",
34 | "templates/pdf"
35 | ],
36 | ```
37 |
38 | To apply a template manually, append a `-t` with the template filepath to the build command:
39 |
40 | ```docfx build docfx.json -t C:\\templates\ --serve```
41 |
42 | ### Customize your template
43 |
44 | Inside the `_exported_templates/default` or `exported_templates/pdf.default` folder, copy any file you want to overwrite with your custom template. Paste it in your custom template folder, replicating the directory structure.
45 |
46 | For example, to change the copyright in the footer of the HTML template:
47 |
48 | - Copy `_exported_templates/default/partials/footer.tmpl.partial`.
49 | - Paste it in `templates//partials`.
50 | - Edit `templates//partials`.
51 |
52 | To change the CSS of the HTML or PDF template:
53 |
54 | - Copy `_exported_templates/default/styles/main.css` or `_exported_templates/pdf.default/styles/main.css`.
55 | - Paste it in `templates//styles`.
56 | - Edit `templates//partials`.
57 |
58 | Example of changing heading styles in `main.css` for an HTML template:
59 |
60 | ```
61 | article h1 {
62 | font-size: 40px;
63 | font-weight: 300;
64 | margin-top: 40px;
65 | margin-bottom: 20px;
66 | color: #000000;
67 | }
68 | ```
69 |
70 | Example of preventing words from breaking across lines for an HTML template:
71 |
72 | ```
73 | article h1, h2, h3, h4, h5, h6 {
74 | word-break: keep-all;
75 | }
76 | ```
77 |
78 | Example of changing heading styles for a PDF template:
79 |
80 | ```
81 | h1 {
82 | font-weight: 200;
83 | color: #007bb8;
84 | }
85 | ```
86 |
87 | To change the look of the table of contents in the PDF template, use this file: `_exported_templates/default/toc.html.tmpl`
88 |
89 | ## See a list of all your templates
90 |
91 | ```docfx template list```
92 |
93 | ## See template commands
94 |
95 | ```docfx help template```
96 |
--------------------------------------------------------------------------------
/samples/tutorial/walkthrough/artifacts/walkthrough1.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/docascode/template/dc97fc1eb4cd42e85c861e8d2925f32f914e4c94/samples/tutorial/walkthrough/artifacts/walkthrough1.zip
--------------------------------------------------------------------------------
/samples/tutorial/walkthrough/artifacts/walkthrough2.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/docascode/template/dc97fc1eb4cd42e85c861e8d2925f32f914e4c94/samples/tutorial/walkthrough/artifacts/walkthrough2.zip
--------------------------------------------------------------------------------
/samples/tutorial/walkthrough/artifacts/walkthrough3.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/docascode/template/dc97fc1eb4cd42e85c861e8d2925f32f914e4c94/samples/tutorial/walkthrough/artifacts/walkthrough3.zip
--------------------------------------------------------------------------------
/samples/tutorial/walkthrough/images/uid.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/docascode/template/dc97fc1eb4cd42e85c861e8d2925f32f914e4c94/samples/tutorial/walkthrough/images/uid.png
--------------------------------------------------------------------------------
/samples/tutorial/walkthrough/images/walkthrough2_step3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/docascode/template/dc97fc1eb4cd42e85c861e8d2925f32f914e4c94/samples/tutorial/walkthrough/images/walkthrough2_step3.png
--------------------------------------------------------------------------------
/samples/tutorial/walkthrough/images/walkthrough2_step4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/docascode/template/dc97fc1eb4cd42e85c861e8d2925f32f914e4c94/samples/tutorial/walkthrough/images/walkthrough2_step4.png
--------------------------------------------------------------------------------
/samples/tutorial/walkthrough/images/walkthrough2_step5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/docascode/template/dc97fc1eb4cd42e85c861e8d2925f32f914e4c94/samples/tutorial/walkthrough/images/walkthrough2_step5.png
--------------------------------------------------------------------------------
/samples/tutorial/walkthrough/images/walkthrough3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/docascode/template/dc97fc1eb4cd42e85c861e8d2925f32f914e4c94/samples/tutorial/walkthrough/images/walkthrough3.png
--------------------------------------------------------------------------------
/samples/tutorial/walkthrough/images/walkthrough_api.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/docascode/template/dc97fc1eb4cd42e85c861e8d2925f32f914e4c94/samples/tutorial/walkthrough/images/walkthrough_api.png
--------------------------------------------------------------------------------
/samples/tutorial/walkthrough/images/walkthrough_homepage.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/docascode/template/dc97fc1eb4cd42e85c861e8d2925f32f914e4c94/samples/tutorial/walkthrough/images/walkthrough_homepage.png
--------------------------------------------------------------------------------
/samples/tutorial/walkthrough/images/walkthrough_simple_homepage.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/docascode/template/dc97fc1eb4cd42e85c861e8d2925f32f914e4c94/samples/tutorial/walkthrough/images/walkthrough_simple_homepage.png
--------------------------------------------------------------------------------
/samples/tutorial/walkthrough/images/walkthrough_step5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/docascode/template/dc97fc1eb4cd42e85c861e8d2925f32f914e4c94/samples/tutorial/walkthrough/images/walkthrough_step5.png
--------------------------------------------------------------------------------
/samples/tutorial/walkthrough/walkthrough_create_a_docfx_project.md:
--------------------------------------------------------------------------------
1 | Walkthrough Part I: Generate a Simple Documentation Website
2 | ===================================
3 |
4 | By completing this walkthrough, you'll become familiar with the workflow of `docfx` and the general principle of organizing documents inside `docfx`. You will finish this walkthrough with a static website that can be published to any host service. Download the files used in this walkthrough [here](artifacts/walkthrough1.zip).
5 |
6 | Step1. Setup DocFX
7 | ------------------------
8 | Download *docfx* from http://dotnet.github.io/docfx/. [Getting Started with docfx](http://dotnet.github.io/docfx/tutorial/docfx_getting_started.html#2-use-docfx-exe-directly) describes three ways to install *docfx*. This walkthrough uses the first one: Use *docfx.exe* directly.
9 |
10 | 1. Download *docfx.zip* and unzip it to `D:\docfx\`
11 | 2. Add `D:\docfx\` to `PATH` so that the command `docfx` can be directly called from everywhere for convenience. (For example, for Windows, `set PATH=%PATH%;D:\docfx\`.)
12 |
13 | Step2. Init a DocFX project
14 | ---------------------------
15 | 1. Create a new folder `D:\docfx_walkthrough`
16 | 2. Start Command Line under `D:\docfx_walkthrough`
17 | 3. Call `docfx init -q`. This command generates a `docfx_project` folder with the default `docfx.json` file under it. `docfx.json` is the configuration file `docfx` uses to generate documentation. `-q` option means generating the project quietly using default values, you can also try `docfx init` and follow the instructions to provide your own settings.
18 |
19 | Step3. Build our website
20 | -----------------------
21 | Run command `docfx docfx_project/docfx.json`. Note that a new subfolder `_site` is generated under that folder. This is where the static website is generated.
22 |
23 | Step4. Preview our website
24 | -------------------------
25 | The generated static website can be published to GitHub pages, Azure websites, or your own hosting services without any further changes. You can also run command `docfx serve docfx_project/_site` to preview the website locally.
26 |
27 | If port `8080` is not in use, `docfx` will host `_site` under `http://localhost:8080`. If `8080` is in use, you can use `docfx serve _site -p ` to change the port to be used by `docfx`.
28 |
29 | Congrats! You can now see a simple website similar to:
30 | 
31 |
32 | ----------------------
33 |
34 | Step5. Add a set of articles to the website
35 | -------------------------
36 | 1. Place more `.md` files into `articles`, e.g., `details1.md`, `details2.md`, `details3.md`. If the files reference any resources, put those resources into the `images` folder.
37 | 2. In order to organize these articles, we add these files into `toc.yml` under `articles` subfolder. The content of `toc.yml` is as below:
38 |
39 | ```yml
40 | - name: Introduction
41 | href: intro.md
42 | - name: Details 1
43 | href: details1.md
44 | - name: Details 2
45 | href: details2.md
46 | - name: Details 3
47 | href: details3.md
48 | ```
49 |
50 | So now our folder layout is:
51 | ```
52 | |- index.md
53 | |- toc.yml
54 | |- articles
55 | | |- intro.md
56 | | |- details1.md
57 | | |- details2.md
58 | | |- details3.md
59 | | |- toc.yml
60 | |- images
61 | |- details1_image.png
62 | ```
63 | 4. Run **Step3** and **Step4** again, and the website is now:
64 | .
65 |
66 | Notice that more items are added to the sidebar for *Articles* nav page. The title inside the sidebar is exactly what we set in the `toc.yml` inside `articles` subfolder.
67 |
68 | Conclusion
69 | ---------
70 | In this walkthrough, we built a website from a set of `.md` files. We call these `.md` files **Conceptual Documentation**. In walkthrough part 2, we will learn to add **API Documentation** to our website. The **API Documentation** is extracted directly from .NET source code. In a series of advanced walkthroughs, we will learn advanced concepts in `docfx`, such as *cross reference* between articles, *external reference* to other documentation sets, etc. We will also learn to customize our websites, from theme to layout to metadata extraction.
71 |
72 | Read more
73 | ---------
74 | * [Walkthrough Part II: Adding API Documentation to the Website](walkthrough_create_a_docfx_project_2.md)
75 |
76 | * [Walkthrough Advanced: Customize Your Website](advanced_walkthrough.md)
77 |
--------------------------------------------------------------------------------
/samples/tutorial/walkthrough/walkthrough_generate_pdf.md:
--------------------------------------------------------------------------------
1 | Walkthrough Part III: Generate PDF Documentation
2 | ==========================
3 |
4 | After completing [Walkthrough Part II: Add API Documentation to the Website](walkthrough_create_a_docfx_project_2.md), we successfully create a website containing both Conceptual and API documentation. In this section, we will generate PDF files for these articles.
5 |
6 | After completing walkthrough part II, our `D:\docfx_walkthrough\docfx_project` folder is in the following structure(Download the artifacts [*HERE*](artifacts/walkthrough3.zip)):
7 |
8 | ```
9 | |- articles
10 | |- images
11 | |- src
12 | |- src2
13 | |- index.md
14 | |- toc.yml
15 | |- docfx.json
16 | ```
17 |
18 | Step0. Install prerequisite
19 | ---------------------------
20 | We leverage [wkhtmltopdf](https://wkhtmltopdf.org/) to generate PDF. [Download wkhtmltopdf](https://wkhtmltopdf.org/downloads.html) to some folder, e.g. `E:\Program Files\wkhtmltopdf\`, and save the executable folder path to **%PATH%** by: `set PATH=%PATH%;E:\Program Files\wkhtmltopdf\bin`.
21 |
22 | > [!NOTE]
23 | > Alternativeley you can install wkhtmltopdf via [chocolatey](https://chocolatey.org/) with `choco install wkhtmltopdf`. This will also add the executable folder to **%PATH%** during installation.
24 |
25 | Step1. Add a toc.yml specific for PDF
26 | ---------------------------
27 | Current design is that each TOC file generates a corresponding PDF file, TOC is also used as the table of contents page of the PDF, so we create a `toc.yml` file specific for PDF under a new folder `pdf`, using [TOC Include](http://dotnet.github.io/docfx/tutorial/intro_toc.html?q=toc%20inclu#link-to-another-toc-file) to include content from other TOC files.
28 | ```yml
29 | - name: Articles
30 | href: ../articles/toc.yml
31 | - name: Api Documentation
32 | href: ../api/toc.yml
33 | - name: Another Api Documentation
34 | href: ../api-vb/toc.yml
35 | ```
36 |
37 | Step2. Add *pdf* section into docfx.json
38 | ----------------------------------------------------
39 | Parameters are similar to `build` section, definitely it is using a different template (the builtin template is `pdf.default`), with another output destination. We also exclude TOC files as each TOC file generates a PDF file:
40 | ```json
41 | ...
42 | "pdf": {
43 | "content": [
44 | {
45 | "files": [
46 | "api/**.yml",
47 | "api-vb/**.yml"
48 | ],
49 | "exclude": [
50 | "**/toc.yml",
51 | "**/toc.md"
52 | ]
53 | },
54 | {
55 | "files": [
56 | "articles/**.md",
57 | "articles/**/toc.yml",
58 | "toc.yml",
59 | "*.md",
60 | "pdf/*"
61 | ],
62 | "exclude": [
63 | "**/bin/**",
64 | "**/obj/**",
65 | "_site_pdf/**",
66 | "**/toc.yml",
67 | "**/toc.md"
68 | ]
69 | },
70 | {
71 | "files": "pdf/toc.yml"
72 | }
73 | ],
74 | "resource": [
75 | {
76 | "files": [
77 | "images/**"
78 | ],
79 | "exclude": [
80 | "**/bin/**",
81 | "**/obj/**",
82 | "_site_pdf/**"
83 | ]
84 | }
85 | ],
86 | "overwrite": [
87 | {
88 | "files": [
89 | "apidoc/**.md"
90 | ],
91 | "exclude": [
92 | "**/bin/**",
93 | "**/obj/**",
94 | "_site_pdf/**"
95 | ]
96 | }
97 | ],
98 | "wkhtmltopdf": {
99 | "additionalArguments": "--enable-local-file-access"
100 | },
101 | "dest": "_site_pdf"
102 | }
103 | ```
104 |
105 | Now, let's run `docfx`, and you can find pdf file walkthrough3_pdf.pdf generated under `_site_pdf` folder:
106 | 
107 |
108 | *Optional* Step3. Enable plugins
109 | ----------------------------------------------------
110 | If you wish to use plugins with pdf as well, you need to add a `template` node to the pdf section. It needs to start with the `pdf.template` followed by the path to the plugins you want to use:
111 |
112 | ```json
113 | "template": [
114 | "pdf.default",
115 | "pluginPackages/rest.tagpage.2.31.0/content"
116 | ],
117 | ```
118 |
119 | Conclusion
120 | ---------
121 | In this walkthrough, we build a PDF file according to the TOC file under `pdf` folder. Note that TOC plays an important role in PDF generation, it not only determines the files included in the PDF, but also the table of contents page for this PDF file. One TOC file generates one PDF file, so don't forget to exclude TOC files you don't want from docfx.json.
122 |
123 | Read more
124 | ---------
125 | * [Walkthrough Part I: Generate a Simple Documentation Website](walkthrough_create_a_docfx_project.md)
126 |
127 | * [Walkthrough Part II: Adding API Documentation to the Website](walkthrough_create_a_docfx_project_2.md)
128 |
129 | * [Walkthrough Advanced: Customize Your Website](advanced_walkthrough.md)
130 |
--------------------------------------------------------------------------------
/samples/tutorial/walkthrough/walkthrough_overview.md:
--------------------------------------------------------------------------------
1 | Walkthrough Overview
2 | ===================================
3 |
4 | By completing these walkthroughs, you'll create a static website, containing both **Conceptual Documentation** which comes from `.md` files and **API Documentation** which comes from .NET source code. You'll also be able to customize your website with your own styles and templates!
5 |
6 | List of Articles
7 | ---------
8 | 1. [Walkthrough Part I: Generate a Simple Documentation Website](walkthrough_create_a_docfx_project.md)
9 |
10 | 2. [Walkthrough Part II: Adding API Documentation to the Website](walkthrough_create_a_docfx_project_2.md)
11 |
12 | 3. [Walkthrough Advanced: Customize Your Website](advanced_walkthrough.md)
13 |
--------------------------------------------------------------------------------
/src/docfx.scss:
--------------------------------------------------------------------------------
1 | // Copyright (c) Microsoft. All rights reserved.
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | :root {
5 | --navbar-bg-color: #164268;
6 | }
7 |
8 | $primary: #2d74b2 !default;
9 | $link-decoration: none !default;
10 | $link-hover-decoration: underline !default;
11 | $container-max-widths: (
12 | xxl: 1768px
13 | ) !default;
14 |
15 | @import '../node_modules/bootstrap/scss/bootstrap.scss';
16 | @import '../node_modules/highlight.js/styles/stackoverflow-light.css';
17 | @import './styles/layout.scss';
18 | @import './styles/article.scss';
19 | @import './styles/markdown.scss';
20 | @import './styles/home.scss';
21 | @import './styles/nav.scss';
22 | @import './styles/toc.scss';
23 | @import './styles/dotnet.scss';
24 |
25 | .container.page-type-home {
26 | padding: 0;
27 | }
28 |
29 |
--------------------------------------------------------------------------------
/src/docfx.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) Microsoft. All rights reserved.
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | import 'bootstrap'
5 | import { enableAnchor } from './scripts/anchor'
6 | import { highlight } from './scripts/highlight'
7 | import { renderAlerts, renderLinks, renderTables, renderTabs } from './scripts/markdown'
8 | import { renderAside, renderNavbar } from './scripts/nav'
9 | import { enableSwitchTheme } from './scripts/theme'
10 | import { renderToc } from './scripts/toc'
11 |
12 | document.addEventListener('DOMContentLoaded', onContentLoad)
13 |
14 | function onContentLoad() {
15 | enableAnchor()
16 | enableSwitchTheme()
17 | highlight()
18 |
19 | renderTables()
20 | renderAlerts()
21 | renderLinks()
22 |
23 | renderNavbar()
24 | renderToc()
25 |
26 | renderAside()
27 | renderTabs()
28 | }
--------------------------------------------------------------------------------
/src/scripts/anchor.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) Microsoft. All rights reserved.
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | import AnchorJs from 'anchor-js';
5 |
6 | export function enableAnchor() {
7 | const anchors = new AnchorJs()
8 | anchors.options = {
9 | placement: 'right',
10 | visible: 'hover'
11 | };
12 | anchors.add('article h2,h3');
13 | }
14 |
--------------------------------------------------------------------------------
/src/scripts/highlight.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) Microsoft. All rights reserved.
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | import hljs from 'highlight.js';
5 |
6 | export function highlight() {
7 | document.querySelectorAll('pre code').forEach(block => {
8 | hljs.highlightElement(block as HTMLElement)
9 | })
10 |
11 | document.querySelectorAll('pre code[highlight-lines]').forEach(block => {
12 | if (block.innerHTML === "") return
13 | var lines = block.innerHTML.split('\n')
14 |
15 | var queryString = block.getAttribute('highlight-lines')
16 | if (!queryString) return
17 |
18 | var ranges = queryString.split(',')
19 | for (var j = 0, range; range = ranges[j++];) {
20 | var found = range.match(/^(\d+)\-(\d+)?$/)
21 | if (found) {
22 | // consider region as `{startlinenumber}-{endlinenumber}`, in which {endlinenumber} is optional
23 | var start = +found[1]
24 | var end = +found[2]
25 | if (isNaN(end) || end > lines.length) {
26 | end = lines.length
27 | }
28 | } else {
29 | // consider region as a sigine line number
30 | if (isNaN(range)) continue
31 | var start = +range
32 | var end = start
33 | }
34 | if (start <= 0 || end <= 0 || start > end || start > lines.length) {
35 | // skip current region if invalid
36 | continue;
37 | }
38 | lines[start - 1] = '' + lines[start - 1]
39 | lines[end - 1] = lines[end - 1] + ''
40 | }
41 |
42 | block.innerHTML = lines.join('\n')
43 | })
44 | }
--------------------------------------------------------------------------------
/src/scripts/nav.tsx:
--------------------------------------------------------------------------------
1 | // Copyright (c) Microsoft. All rights reserved.
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | import React from 'jsx-dom'
5 | import { getAbsolutePath, getDirectory, isRelativePath, isVisible, meta } from './utility';
6 |
7 | export interface NavItem {
8 | name: string
9 | href?: string
10 | }
11 |
12 | export async function renderNavbar() {
13 | const navbarElement = document.getElementById('navbar')
14 | const navbarPath = meta('menu_path')?.replace(/\\/g, '/')
15 | if (!navbarPath || !navbarElement) {
16 | return
17 | }
18 |
19 | const data = await (await fetch(navbarPath)).json()
20 |
21 | let activeItem: NavItem
22 | let maxItemPathLength = 1
23 | const navrel = getDirectory(navbarPath)
24 | const windowPath = getAbsolutePath(window.location.pathname).toLowerCase()
25 |
26 | const items = data.items.map(item => {
27 | const href = isRelativePath(item.href) ? navrel + '/' + item.href : item.href;
28 | const result = { href: href, name: item.name }
29 | if (href) {
30 | const itemPath = getAbsolutePath(href).toLowerCase();
31 | const itemLength = commonPathPrefixLength(windowPath, itemPath);
32 | if (itemLength > maxItemPathLength) {
33 | maxItemPathLength = itemLength
34 | activeItem = result
35 | }
36 | }
37 | return result
38 | })
39 |
40 | navbarElement.appendChild(
41 |