|
| 1 | +# Documentation for Tutorial Authors |
| 2 | + |
| 3 | +# General |
| 4 | + |
| 5 | +The setup of this project allows maintaining *one* tutorial text that covers both JavaScript and TypeScript with minimal overhead and without duplication of content. |
| 6 | + |
| 7 | +Readers of the tutorial can freely switch the programming language of code snippets or the entire page, once deployed on GitHub Pages. For tutorial authors, an integrated dev server allows previewing the result with the same functionality locally and instantly. |
| 8 | + |
| 9 | +Main features of the two-language support are: |
| 10 | +1. Content meant only for *one* of the programming languages can be hidden in the other by enclosing it in a specific block. |
| 11 | +2. Two adjacent code sections in different languages are automatically converted to a tab container which allows switching between languages. |
| 12 | +3. File extensions writen as `.?s` appear automatically as `.js` or `.ts` depending on the current language. |
| 13 | + |
| 14 | +## Limitations |
| 15 | + |
| 16 | +The feature 3. above does not work inside code blocks (yet). |
| 17 | + |
| 18 | + |
| 19 | +## Running the preview/dev server |
| 20 | + |
| 21 | +To immediately preview the markdown document you are writing *including* the two-language magic, simply run |
| 22 | + |
| 23 | +```sh |
| 24 | +npm i |
| 25 | +``` |
| 26 | + |
| 27 | +in the root folder of this project once for the setup, then to actually run the server, run |
| 28 | + |
| 29 | +```sh |
| 30 | +npm start |
| 31 | +``` |
| 32 | + |
| 33 | +Then, open http://localhost:1337/README.md in your browser. |
| 34 | + |
| 35 | +Alternatively, and even easier, run |
| 36 | + |
| 37 | +```sh |
| 38 | +npm run watch |
| 39 | +``` |
| 40 | + |
| 41 | +And the browser will automatically open (on port 3000) and automatically reload on every saved change. |
| 42 | + |
| 43 | + |
| 44 | +## Writing *one* document which covers both JavaScript and TypeScript without duplication |
| 45 | + |
| 46 | +The following features help providing language-specific content without duplication of other content. |
| 47 | + |
| 48 | +### 1. Language-specific Blocks of Content |
| 49 | + |
| 50 | +When a certain part of the tutorial content (can be explanation and/or code) is only relevant for *one* of the languages (JavaScript *or* TypeScript), then enclose it within the following tags. The CSS class decides for which language it is meant! |
| 51 | + |
| 52 | +TypeScript-only: |
| 53 | + |
| 54 | +```html |
| 55 | +<details class="ts-only" markdown="1"><summary>This section is relevant for TypeScript only</summary> |
| 56 | +...here comes the TS-only text... |
| 57 | +</details> |
| 58 | +``` |
| 59 | + |
| 60 | +JavaScript-only: |
| 61 | + |
| 62 | +```html |
| 63 | +<details class="js-only" markdown="1"><summary>This section is relevant for JavaScript only</summary> |
| 64 | +...here comes the JS-only text... |
| 65 | +</details> |
| 66 | +``` |
| 67 | + |
| 68 | +The `markdown="1"` part is required for markdown parsing within HTML and the `<summary>` is helpful for readers of the raw markdown view, so please use the tag structure as-is, with your actual content in between. |
| 69 | + |
| 70 | +#### Resulting Appearance<span class="hidden"> in markdown view (not in the final page)</span> |
| 71 | + |
| 72 | +<details class="ts-only" markdown="1"><summary>This section is relevant for TypeScript only</summary> |
| 73 | +...here comes the TS-only text... |
| 74 | +</details> |
| 75 | + |
| 76 | +<details class="js-only" markdown="1"><summary>This section is relevant for JavaScript only</summary> |
| 77 | +...here comes the JS-only text... |
| 78 | +</details> |
| 79 | + |
| 80 | + |
| 81 | +### 2. Switchable code blocks in both languages |
| 82 | + |
| 83 | +When a piece of code should be displayed in either JS or TS, whatever is current, then simply create two adjacent markdown-fenced code blocks. They are automatically recognized as language-specific alternatives. |
| 84 | + |
| 85 | +Example: |
| 86 | +```md |
| 87 | + |
| 88 | + ```js |
| 89 | + const i = 0; |
| 90 | + ``` |
| 91 | + |
| 92 | + ```ts |
| 93 | + const i: number = 0; |
| 94 | + ``` |
| 95 | +``` |
| 96 | +> Do not indent, this was only done to make the backticks within the code block visible. |
| 97 | +
|
| 98 | +> Some places where this occurs may not be properly recognized, so make sure to test it. |
| 99 | +
|
| 100 | +#### Resulting Appearance<span class="hidden"> in markdown view (here in markdown you still see BOTH and no tab container; the magic only happens in the dev server and in GitHub Pages)</span> |
| 101 | + |
| 102 | +```js |
| 103 | +const i = 0; |
| 104 | +``` |
| 105 | + |
| 106 | +```ts |
| 107 | +const i: number = 0; |
| 108 | +``` |
| 109 | + |
| 110 | +### 3. File Extensions (`.js/.ts`) |
| 111 | + |
| 112 | +When the text or a section heading mentions the name of a file that will be JavaScript or TypeScript, depending on the language, then use the file extension `.\?s`. It will automatically be switched to the current language. |
| 113 | + |
| 114 | +Example: |
| 115 | +```md |
| 116 | +In this step you create the file `Example.controller.\?s`. |
| 117 | +``` |
| 118 | + |
| 119 | +#### Resulting Appearance<span class="hidden"> in markdown view (here the extension is not replaced, the replacement only happens in the dev server and in GitHub Pages)</span> |
| 120 | + |
| 121 | +In this step you create the file `Example.controller.?s`. |
| 122 | + |
| 123 | +## Converting the JS Code to TypeScript |
| 124 | + |
| 125 | +TODO: tool support for this functionality does not exist yet. It can, however, already be done manually. |
| 126 | + |
| 127 | +General approach: develop the tutorial in TS and use the debug version of the transpilation result as JS code. |
| 128 | + |
| 129 | +To clean up the transpilation result, search for and remove content containing the following in the transpiled JS code: |
| 130 | + |
| 131 | +### `_interopRequireDefault` |
| 132 | + |
| 133 | +Looks like this: |
| 134 | + |
| 135 | +```js |
| 136 | +sap.ui.define(["./BaseController"], function (__BaseController) { |
| 137 | + |
| 138 | + function _interopRequireDefault(obj) { |
| 139 | + return obj && obj.__esModule && typeof obj.default !== "undefined" ? obj.default : obj; |
| 140 | + } |
| 141 | + const BaseController = _interopRequireDefault(__BaseController); |
| 142 | +``` |
| 143 | +
|
| 144 | +Remove the function definition and the line calling the function. Rename the dependency in the `sap.ui.define` call from `__BaseController` to `BaseController`. |
| 145 | +
|
| 146 | +
|
| 147 | +### TODO: Some more similar things, unless we do it in the transpiler |
0 commit comments