From 9e8c7fd0d2f4fadd58750acdfe030271147c1587 Mon Sep 17 00:00:00 2001 From: Jeremy LaCivita Date: Thu, 26 Oct 2023 16:23:29 -0400 Subject: [PATCH] fix: Extra newline for really long words --- requirements/glossary.md | 35 +++--- requirements/governance.md | 66 +++++----- .../specifications/lifecycle/index.md | 115 +++++++++--------- .../specifications/lifecycle/presentation.md | 11 +- requirements/style-guide-and-template.md | 37 +++--- src/js/github.io/markdown.mjs | 45 +++++-- 6 files changed, 162 insertions(+), 147 deletions(-) diff --git a/requirements/glossary.md b/requirements/glossary.md index d64bf031d..d7f7c227f 100644 --- a/requirements/glossary.md +++ b/requirements/glossary.md @@ -8,8 +8,7 @@ Document Status: Working Draft ## 1. Overview This document describes various terms used as part of Firebolt APIs, e.g. -method names or parameters, and how they are used by Firebolt, for -consistency. +method names or parameters, and how they are used by Firebolt, for consistency. The terms are this document are commonly used across multiple modules. However, new APIs should be deferential to all existing APIs, not just words listed @@ -58,14 +57,14 @@ grant](#313-user-grant). Available capabilities are, by definition, noun. - Used in the context of [content](#36-content) to denote that the content *could* be consumed if either the device has an -[entitlement](#37-entitlement) to the content, or the content does not -require any entitlement. +[entitlement](#37-entitlement) to the content, or the content does not require +any entitlement. ### 3.4. capability noun. - A discrete unit of functionality that a Firebolt device might be able -to perform. It is granular enough to enable appropriate access controls -across all Firebolt Apps, but useful enough to be a meaningful functional -unit that an App might care about. +to perform. It is granular enough to enable appropriate access controls across +all Firebolt Apps, but useful enough to be a meaningful functional unit that an +App might care about. ### 3.5. closed captions noun. - Closed Captions are text tracks rendered over or near @@ -77,21 +76,21 @@ noun. - Content consumed on Firebolt platforms, e.g. video, games, music, etc. ### 3.7. entitlement noun. - Used in the context of [content](#36-content) to denote that the device -or user has acquired the *right* to consume the content. Content may also -have [availability](#33-availability) requirements for consumption, e.g. a -user may have pre-orded a piece of content, and therefor have an entitlement -to it, that becomes available in the future. +or user has acquired the *right* to consume the content. Content may also have +[availability](#33-availability) requirements for consumption, e.g. a user may +have pre-orded a piece of content, and therefor have an entitlement to it, that +becomes available in the future. ### 3.8. granted adj. - Used in the context of a [capability](#34-capability) to denote that the -capability has been granted to an app by the user. Capabilities that are -gated by [user grant](#313-user-grant) cannot be leveraged by any app w/out -being granted. +capability has been granted to an app by the user. Capabilities that are gated +by [user grant](#313-user-grant) cannot be leveraged by any app w/out being +granted. ### 3.9. lifecycle noun. - Used to describe the life, from being loaded to unloaded, of a Firebolt -[app](#31-app). The app lifecycle has many states that inform the app how it -is being percieved and how it should behave. +[app](#31-app). The app lifecycle has many states that inform the app how it is +being percieved and how it should behave. ### 3.10. media noun. - [Content](#36-content) that that plays back over time without requiring @@ -115,5 +114,5 @@ adj. - Used in the context of a [capability](#34-capability) to denote that the capability *could* be leveraged at some point on this device, because the distributor offers it as part of this device's feature set. Leveraging a capability also requires that it is [available](#32-available), -[permitted](#311-permitted), and either [granted](#38-granted) or is not -gated by a [user grant](#313-user-grant). +[permitted](#311-permitted), and either [granted](#38-granted) or is not gated +by a [user grant](#313-user-grant). diff --git a/requirements/governance.md b/requirements/governance.md index da7d64978..7869b937d 100644 --- a/requirements/governance.md +++ b/requirements/governance.md @@ -39,8 +39,8 @@ Requirements Specifications and Architectural Decision Records. The goal of the Firebolt Open-Source Project is to provide a Distributor-configurable set of integration APIs and functional requirements -for those APIs so that Apps can integrate with the APIs once and run their -app on every Firebolt platform (regardless of distributor) consistently. +for those APIs so that Apps can integrate with the APIs once and run their app +on every Firebolt platform (regardless of distributor) consistently. Specifically, Firebolt provides: - Write Apps once, run on all Firebolt distributors @@ -63,13 +63,13 @@ While enabling Distributors to: ## 4. Governance The Firebolt Open-Source Project is governed by an Advisory Board. The purpose -of the Advisory Board is to ensure that each major, minor, and patch version -of the Firebolt Requirements is aligned with the goals of the Firebolt -Open-Source Project. +of the Advisory Board is to ensure that each major, minor, and patch version of +the Firebolt Requirements is aligned with the goals of the Firebolt Open-Source +Project. The Firebolt Requirements are the collection of all Requirements Specifications -and all Architectural Decision Records that are ratified by the Advisory -Board (and contained in this repository). +and all Architectural Decision Records that are ratified by the Advisory Board +(and contained in this repository). ### 4.1. Scope This document describes the governance model for the following components: @@ -80,10 +80,9 @@ This document describes the governance model for the following components: ### 4.2. Firebolt Version A Firebolt Version is a snapshot of the Firebolt Requirements that has been -ratified as an official release of the requirements. Note that the -requirements are decoupled from any implementation of those requirements, and -iterations to the requirements will occur with input from any teams -implementing them. +ratified as an official release of the requirements. Note that the requirements +are decoupled from any implementation of those requirements, and iterations to +the requirements will occur with input from any teams implementing them. Firebolt Versions **MUST** follow Semantic Versioning. ### 4.3. Advisory Board @@ -118,8 +117,8 @@ spanning technical and product experts. Further recommendations on working group composition are left to the Advisory Board. As new features are prioritized, Working Groups should be formed to gather and -document requirements for those features. Working groups may be self-forming -or selected by the Advisory Board, but all working groups must have their +document requirements for those features. Working groups may be self-forming or +selected by the Advisory Board, but all working groups must have their membership reviewed and approved by the board to ensure that they are well balanced. @@ -132,16 +131,16 @@ to the Advisory Board A Requirements Specification includes all details necessary for multiple, disassociated teams to build a consistent implementation of a feature, -including API signatures, validation, and functionality, as well as -functional and behavioral requirements of the feature that are not directly -exposed by an API. +including API signatures, validation, and functionality, as well as functional +and behavioral requirements of the feature that are not directly exposed by an +API. Requirements and APIs may be targeted towards traditional 3rd party apps, as well as more foundational 1st party apps. The level of detail in an acceptable Requirements Specification should be such -that any App should run consistently on any implementation of the feature -that is based on the Specification. +that any App should run consistently on any implementation of the feature that +is based on the Specification. Requirements Specifications are written using the [IETF Best Common Practice 14](https://www.rfc-editor.org/rfc/rfc2119.txt) and should include the @@ -155,23 +154,22 @@ interpreted as described in [BCP only when, they appear in all capitals, as shown here. Requirements Specification move through several [stages](#48-approval-stages) -from being a draft, to being an official versioned requirements -specification. +from being a draft, to being an official versioned requirements specification. ### 4.7. Architectural Decision Record An Architectural Decision Record includes all details necessary to ensure that -Firebolt Requirements are fulfilled with an architecturally sound design. -This is often used in cases where listing out explicit requirements, e.g. +Firebolt Requirements are fulfilled with an architecturally sound design. This +is often used in cases where listing out explicit requirements, e.g. performance or operational requirements, is not possible or realistic, e.g. Requiring use of a well-known open source component to fulfill some aspect of the platform, or requiring adherence to a high level modular breakdown of concerns to keep platform maintenance manageable. Since ADRs included in the Firebolt Requirements **MUST** be adhered to, not -every architectural decision made in order to fulfill the Firebolt -Requirements needs to have a formal ADR in the Firebolt Requirements -repository. It is up to the Advisory Board which ADRs warrent a formal -inclusion in the Firebolt Requirements. +every architectural decision made in order to fulfill the Firebolt Requirements +needs to have a formal ADR in the Firebolt Requirements repository. It is up to +the Advisory Board which ADRs warrent a formal inclusion in the Firebolt +Requirements. ADRs move through the same [stages](#48-approval-stages) as Requirements Specifications. @@ -193,8 +191,8 @@ Artifacts: Note that a Draft **MUST** not be committed to any public location, e.g. the Requirements Repository, because it has not yet been reviewed by the Working -Group and could mistakenly contain sensative, private information related to -a specific Firebolt distributor. +Group and could mistakenly contain sensative, private information related to a +specific Firebolt distributor. #### 4.8.2. Working Draft A version of the requirements specification that is approved by the Working @@ -212,8 +210,8 @@ Artifacts: A version of the requirements specification that is approved by the Working Group for proof-of-concept implementations and peer-review by the larger -Community. Candidate Specifications have been through significant review by -the Working Group and are ready for feedback from the larger community. +Community. Candidate Specifications have been through significant review by the +Working Group and are ready for feedback from the larger community. Once this is published to the peer group for review, they’ll have two weeks to add their comments, make amendments requests, etc. @@ -250,8 +248,8 @@ Artifacts: #### 4.8.6. Specification An official versioned stage of the requirements specification that is done and -will not change until a future version is created. This version may be used -for official production implementations. +will not change until a future version is created. This version may be used for +official production implementations. Artifacts: - Markdown specification merged into the #main branch of the Requirements Repository @@ -303,8 +301,8 @@ The organization requesting the fork **MUST** be willing to migrate to the approved APIs, which may be different than the API in the fork. The Advisory Board, and selected Working Group, **SHOULD** be willing to avoid -unnecessary changes to make migration as easy as possible, without -sacrificing the integrity of the Firebolt Open-Source Project’s goals. +unnecessary changes to make migration as easy as possible, without sacrificing +the integrity of the Firebolt Open-Source Project’s goals. ### 4.12. Release Versions diff --git a/requirements/specifications/lifecycle/index.md b/requirements/specifications/lifecycle/index.md index dd66c9742..091cbe377 100644 --- a/requirements/specifications/lifecycle/index.md +++ b/requirements/specifications/lifecycle/index.md @@ -20,10 +20,9 @@ See [Firebolt Requirements Governance](../../governance.md) for more info. ## 1. Overview This document describes the requirements that Firebolt platforms and Firebolt -applications must fulfill when managing App Lifecycles. *App Lifecycle* -refers to the lifecycle of an individual app from the time it is -launched/loaded to the time it is destroyed and all runtime resources are -discarded. +applications must fulfill when managing App Lifecycles. *App Lifecycle* refers +to the lifecycle of an individual app from the time it is launched/loaded to +the time it is destroyed and all runtime resources are discarded. *Initializing* an app refers to fetching the initial resources, e.g. the app-manifest and index.html, and loading them into a container capable of @@ -96,8 +95,8 @@ A Firebolt app, once running, **MUST** be in one of several states and **MUST NOT** be in more than one state at a time. As an app changes states the platform will invoke specific app-provided -transition methods, see [Transitions](#4-lifecycle-state-transitions), for -more on this. +transition methods, see [Transitions](#4-lifecycle-state-transitions), for more +on this. ![Lifecycle States](../../images/specifications/lifecycle/lifecycle-states.png) @@ -129,8 +128,8 @@ This is the initial state an app exists from the moment it starts receiving CPU cycles. When an app starts running it **MUST** initialize the Firebolt SDK as quickly -as possible and then wait for the `Application.create()` interface to be -called before doing further setup. +as possible and then wait for the `Application.create()` interface to be called +before doing further setup. Apps in this state **MUST NOT** have a graphics surface allocated yet. @@ -150,8 +149,7 @@ This state allows an app to be running and ready to go, but not actively part of the user-perceptible experience. Running apps can execute code, but are not [Presented](./presentation.md) to -the user, do not receive any input from RCUs, and cannot use the video -decoder. +the user, do not receive any input from RCUs, and cannot use the video decoder. Apps in this state **MUST** have access to the graphics surface. @@ -202,8 +200,7 @@ When an app transitions to this state, the platform **MUST** dispatch the This state allows an app to remain in memory and consume fewer resources. Suspended apps can execute code, but are not [Presented](./presentation.md) to -the user, do not receive any input from RCUs, and cannot use the video -decoder. +the user, do not receive any input from RCUs, and cannot use the video decoder. Apps in this state **MUST NOT** have a graphics surface allocated any longer. It **MUST** have been deallocated in the `suspend()` transition. @@ -228,9 +225,9 @@ memory, and resume in the same state. *If* a platform does not support the `xrn:firebolt:capability:lifecycle:sleepable` capability, then the following -requirements **MUST NOT** be fulfilled, even partially. A platform **MUST -NOT** use the APIs documented here to implement an alternate, non-compliant -version of the app sleeping feature. +requirements **MUST NOT** be fulfilled, even partially. A platform **MUST NOT** +use the APIs documented here to implement an alternate, non-compliant version +of the app sleeping feature. *If* a platform supports the `xrn:firebolt:capability:lifecycle:sleepable` capability, then the following requirements **MUST** be fulfilled. @@ -252,8 +249,8 @@ current lifecycle state of the app. If an app is in a transtition from one state to another, then it **MUST** be considered in the state *before* the transition until such time as the app's -implementation of the [transition](#4-lifecycle-state-transitions) has -returned and the platfrom has finshed the transition. +implementation of the [transition](#4-lifecycle-state-transitions) has returned +and the platfrom has finshed the transition. The `state` API **MUST** have a corresponding `onStateChanged` notification. @@ -325,9 +322,9 @@ This includes: By providing an implementation of the -`xrn:firebolt:capability:lifecycle:application` interface, an app can -influence how resources are managed during these state transitions. See -[Application Interface](#71-application-interface) for more info. +`xrn:firebolt:capability:lifecycle:application` interface, an app can influence +how resources are managed during these state transitions. See [Application +Interface](#71-application-interface) for more info. User-facing apps **MUST** implement the `Activity` interface, `xrn:firebolt:capability:lifecycle:activatible`. @@ -338,9 +335,9 @@ This includes: By providing an implementation of the -`xrn:firebolt:capability:lifecycle:activatible` interface, an app can -influence how resources are managed during these state transitions. See -[Activity Interface](#82-activity-interface) for more info. +`xrn:firebolt:capability:lifecycle:activatible` interface, an app can influence +how resources are managed during these state transitions. See [Activity +Interface](#82-activity-interface) for more info. ### 4.1. Initializing an app Once an app is loaded it **MUST** be initialized immediately. @@ -352,8 +349,8 @@ Initializing consists of three parts: If an app does not provide the `xrn:firebolt:capability:lifecycle:application` -capability within `initializeTimeout` milliseconds, then the platform -**MUST** terminate the app. +capability within `initializeTimeout` milliseconds, then the platform **MUST** +terminate the app. Otherwise, the platform **MUST** call the app's implementation of `Application.create()`: @@ -371,8 +368,8 @@ Otherwise, the platform **MUST** call the app's implementation of Apps **SHOULD** set up any Firebolt event listeners either before calling `Lifecycle.provide` or during `create()`, since the platform will wait until -the app is ready before dispatching many critical events such as Lifecycle -and Presentation events. +the app is ready before dispatching many critical events such as Lifecycle and +Presentation events. Apps **SHOULD** acquire any important authentication needed for the app to function during initialization. @@ -414,9 +411,8 @@ To activate an app, platforms **MUST** use the following process. If the app is already in the `ACTIVE` state, then it is already activated and there is no need to do anything else. The platform **MUST NOT** dispatch any -*additional* lifecycle notifications when attempting to activate an app that -is already in the active state and the remainder of this section does not -apply. +*additional* lifecycle notifications when attempting to activate an app that is +already in the active state and the remainder of this section does not apply. If the app is not loaded, then the platform **MUST** [load](undefined) it first. @@ -467,9 +463,9 @@ activation which may include: The platform will display a loading screen for the entire duration of the -`activate()` callback, and apps **SHOULD** do whatever is necessary to -present the user with content that fulfills the `intent` without additional -loading screens in the app's UX. +`activate()` callback, and apps **SHOULD** do whatever is necessary to present +the user with content that fulfills the `intent` without additional loading +screens in the app's UX. **TODO**: Discuss ^^ ### 4.3. Deactivating an app @@ -491,9 +487,9 @@ To close an app, platforms **MUST** use the following process. If an app is already in the `RUNNING`, `SUSPENDED`, or `SLEEPING` state, then it is already closed and there is no need to do anything else. The platform -**MUST NOT** dispatch any *additional* lifecycle notifications when -attempting to close an app that is already in the `RUNNING` state and the -remainder of this section does not apply. +**MUST NOT** dispatch any *additional* lifecycle notifications when attempting +to close an app that is already in the `RUNNING` state and the remainder of +this section does not apply. **TODO**: list out all possible transition "interuptions" and make sure they are described in this doc. @@ -501,8 +497,8 @@ are described in this doc. If an app is in the `initializing` state, then it is not If an app is already performing a `deactivate()` transition, the platform -**MUST** ignore the new attempt to close the app, allow the pending closure -to complete, and the remainder of this section does not apply. +**MUST** ignore the new attempt to close the app, allow the pending closure to +complete, and the remainder of this section does not apply. If an app is already performing an `activate()` transition, the platform **MUST** wait for the activate call to succeed or fail and then skip the @@ -542,12 +538,12 @@ The platform **MAY** begin to transition the app out of view as soon as Suspending an app transitions it to the `SUSPENDED` state, where it is no -longer allowed to use graphics composition, and is expected to consume less -CPU and RAM. +longer allowed to use graphics composition, and is expected to consume less CPU +and RAM. The platform may suspend apps in order to free up memory, or for any number of -reasons that are out of scope for this document. However, it is the -platform's decision to suspend an app, not the app itself. +reasons that are out of scope for this document. However, it is the platform's +decision to suspend an app, not the app itself. To suspend an app, platforms **MUST** use the following process. @@ -556,14 +552,14 @@ If an app is in the `ACTIVE` state then it cannot yet be suspended, and If an app is in the `SLEEPING` state then it cannot be suspended and there is no need to do anything else. The platform **MUST NOT** dispatch any -*additional* lifecycle notifications when attempting to suspend an app that -is already in the `SLEEPING` state and the remainder of this section does not +*additional* lifecycle notifications when attempting to suspend an app that is +already in the `SLEEPING` state and the remainder of this section does not apply. If an app is already in the `SUSPENDED` state, then it is already suspended and there is no need to do anything else. The platform **MUST NOT** dispatch any -*additional* lifecycle notifications when attempting to suspend an app that -is already in the suspended state and the remainder of this section does not +*additional* lifecycle notifications when attempting to suspend an app that is +already in the suspended state and the remainder of this section does not apply. If the app is not loaded, or is not in the `RUNNING` state, then it cannot be @@ -604,8 +600,7 @@ To resume an app, platforms **MUST** use the following process. If an app is not in the `SUSPENDED` state, then it cannot be resumed and there is no need to do anything else. The platform **MUST NOT** dispatch any *additional* lifecycle notifications when attempting to resume an app that is -not in the `SUSPENDED` state and the remainder of this section does not -apply. +not in the `SUSPENDED` state and the remainder of this section does not apply. At this point, the app **MUST** be in the `SUSPENDED` state. @@ -657,9 +652,9 @@ To destroy an app, platforms **MUST** use the following process. If an app is not in the `RUNNING` state, then it cannot be destroyed and there is no need to do anything else. The platform **MUST NOT** dispatch any -*additional* lifecycle notifications when attempting to destroy an app that -is not in the `RUNNING` state and the remainder of this section does not need -to happen. +*additional* lifecycle notifications when attempting to destroy an app that is +not in the `RUNNING` state and the remainder of this section does not need to +happen. At this point, the app **MUST** be in the `RUNNING` state. @@ -818,14 +813,14 @@ Lifecycle.provide([ class. See the [Firebolt API -Documentation](https://developer.comcast.com/firebolt/core/sdk/latest/api/) -for details around syntax, etc. +Documentation](https://developer.comcast.com/firebolt/core/sdk/latest/api/) for +details around syntax, etc. ### 7.5. Ready The Lifecycle.ready() API allows an app to notify the platform that it is -initialized and ready to be displayed to the end user. This method **MUST -NOT** be called more than once. +initialized and ready to be displayed to the end user. This method **MUST NOT** +be called more than once. ### 7.6. Close @@ -842,17 +837,17 @@ is requesting to be closed: Platforms generally **SHOULD** respect this call and move the app to the -running state, but there may be edge cases where this is not possible, e.g. -the app is considered to be the default experience for the device, and -closing it would leave no other UX present. +running state, but there may be edge cases where this is not possible, e.g. the +app is considered to be the default experience for the device, and closing it +would leave no other UX present. When the request to close is not respected, the Lifecycle.close() method **MUST** return an error. Platforms **MAY** prioritize apps to be destroyed based on the reason provided. For example, apps closed due to the RCU are less likely to be destroyed since -it may be an accidental RCU press, whereas an explicit user exit is more -likely to be intentional. +it may be an accidental RCU press, whereas an explicit user exit is more likely +to be intentional. ### 7.7. State diff --git a/requirements/specifications/lifecycle/presentation.md b/requirements/specifications/lifecycle/presentation.md index 7ba84f5ce..70b754e5d 100644 --- a/requirements/specifications/lifecycle/presentation.md +++ b/requirements/specifications/lifecycle/presentation.md @@ -117,14 +117,13 @@ the active media pipeline. ## 7. Navigation Typically navigation is handled either when the app is activated, via the -`intent` parameter of the [`activate` -method](./index.md#42-activating-an-app), or by internal input within the -app. +`intent` parameter of the [`activate` method](./index.md#42-activating-an-app), +or by internal input within the app. There are other times when the platform needs to inform an app of a user's -intent to navigate when the app is already `ACTIVE`, e.g. when a voice -command is executed or an RCU sends a reserved key to the platform that would -result in the app taking some action, e.g. going to its home screen. +intent to navigate when the app is already `ACTIVE`, e.g. when a voice command +is executed or an RCU sends a reserved key to the platform that would result in +the app taking some action, e.g. going to its home screen. If the app provides the `xrn:firebolt:capability:presentation:navigation` capability then the platform **MUST** call the `Navigation.navigateTo` method diff --git a/requirements/style-guide-and-template.md b/requirements/style-guide-and-template.md index 78665a6a6..09180e575 100644 --- a/requirements/style-guide-and-template.md +++ b/requirements/style-guide-and-template.md @@ -15,10 +15,10 @@ This document is both a style guide *and* a template for Firebolt Requirements Specifications. The Overview section is a non-normative or informative introduction to the -contents and subject matter of the document. This is included to introduce -the reader to the overall problem, solution, and scope. No formal -requirements will be included here, as it will often be skipped by readers -that are already familiar with the document. +contents and subject matter of the document. This is included to introduce the +reader to the overall problem, solution, and scope. No formal requirements will +be included here, as it will often be skipped by readers that are already +familiar with the document. Overviews can be as long or short as appropriate for the subject matter, and should have a target audience ranging from technical product managers to @@ -51,16 +51,15 @@ only when, they appear in all capitals, as shown here. **NOTE**: This is a simple table of contents. It should include links to all headers in the document, except for the top-level header (i.e. `# Title`). It is recommended to use a Markdown plugin to generate this based on headers -ranging from level two to level six. Delete this note from your actual spec -:) +ranging from level two to level six. Delete this note from your actual spec :) ## 3. Specification Style Requirements Firebolt uses method templates in order to code-generate consistent APIs. For example, methods with the `"property"` tag only need to have the `getter` -editorially defined. The Firebolt OpenRPC tools will auto-generate the -`setter` and `subscriber` as OpenRPC methods with matching types. -Additionally, the Firebolt OpenRPC tools wil then code-generate the getter, -setter, and subscriber as APIs in various languages using templates. +editorially defined. The Firebolt OpenRPC tools will auto-generate the `setter` +and `subscriber` as OpenRPC methods with matching types. Additionally, the +Firebolt OpenRPC tools wil then code-generate the getter, setter, and +subscriber as APIs in various languages using templates. This enables both consistent APIs (all properties have a recongnizable pattern) and consistent SDK implementation, which reduces the code that needs to be @@ -73,8 +72,8 @@ separated with '.' Module and method names, as well as constants **MUST** be in monospace font, e.g. the `Foo` module **MUST** have a `bar` method that returns `true`. Specs should use JavaScript notation for any code examples if the spec is not -targeting another specific language binding, e.g. a spec about Event -listeners in C++ would use C++ syntax. +targeting another specific language binding, e.g. a spec about Event listeners +in C++ would use C++ syntax. String constants and values **MUST** be wrapped in quotes for clarity, e.g. `"Hello World"`. @@ -122,23 +121,23 @@ to have a level of consistency across APIs. If a Firebolt method is specified such that it requires a non-existant template, then a new Requirements Specification **MUST** be written and -referenced by the specification that inspired it. Method templates **MUST** -be designed with re-use in mind. +referenced by the specification that inspired it. Method templates **MUST** be +designed with re-use in mind. ## 4. Example Section A section describes group of closely related features. Many specifications have only one section, however, more complicated specifications may have many. The -first paragraph of a section is typically a non-normative introduction to -that section, and therefor does not contain any formal requirements. +first paragraph of a section is typically a non-normative introduction to that +section, and therefor does not contain any formal requirements. ### 4.1. Example Feature Each feature under a section will have it's own heading. Non-normative introductions to features are not typically needed, as the reader is ready to get into requirements at this point. It is recommended that all Feature headings under each Section contain only sentences or short paragraphs with -formal requirements, e.g. **MUST**, **SHOULD**, **MAY**, **MUST** NOT, -**SHOULD NOT**, etc. These sentences should be separated by blank lines for -readability, e.g.: +formal requirements, e.g. **MUST**, **SHOULD**, **MAY**, **MUST** NOT, **SHOULD +NOT**, etc. These sentences should be separated by blank lines for readability, +e.g.: This requirement **MUST** be satisifed. diff --git a/src/js/github.io/markdown.mjs b/src/js/github.io/markdown.mjs index 4e1da98b9..a7641d3e5 100644 --- a/src/js/github.io/markdown.mjs +++ b/src/js/github.io/markdown.mjs @@ -35,9 +35,19 @@ const processFiles = (docs) => { docs[ref] = data } }) + + // do external links after all local links are fixed + Object.keys(docs).forEach(ref => { + if (ref.endsWith('.md')) { + docs[ref] = fixBrokenExternalLinks(docs[ref], ref, docs) + } + }) } -function fixBrokenLinks(data, ref, files) { +function fixBrokenExternalLinks(data, ref, files) { + return fixBrokenLinks(data, ref, files, true) +} +function fixBrokenLinks(data, ref, files, external=false) { const getSlugs = (data) => { // find all headers @@ -59,13 +69,16 @@ function fixBrokenLinks(data, ref, files) { links && links.map(l => l.slice(2, -1)).forEach(link => { if (!slugs.find(s => s === link)) { - const best = slugs.find(s => s.match(new RegExp(link.replace(/^\#[0-9]+/, '#[0-9]+')))) || slugs.find(s => s.startsWith(link.split('-')[0] + '-')) - if (best) { - console.log('Fixing broken link: (' + link + ') -> (' + best + ')') - data = data.replace('](' + link + ')', '](' + best + ')') + // fix local links + if (!external) { + const best = slugs.find(s => s.match(new RegExp(link.replace(/^\#[0-9]+/, '#[0-9]+')))) || slugs.find(s => s.startsWith(link.split('-')[0] + '-')) + if (best) { + console.log('Fixing broken link: (' + link + ') -> (' + best + ')') + data = data.replace('](' + link + ')', '](' + best + ')') + } } - // TODO: fix bad slugs in links to other files - else if (link.match(/[^\)]+?\#[^\)]*?/gms)) { + // fix bad slugs in links to other files + else if (external && link.match(/[^\)]+?\#[^\)]*?/gms)) { // external const [file, slug] = link.split('#') const fileRef = path.join(path.dirname(ref), file) @@ -127,21 +140,33 @@ function wrapText(data) { } } - line.split(/\s+/).forEach(word => { + let first = true + line.split(/\s+/).filter(word => word).forEach((word, i, words) => { if (word.match(block_regex)) { throw "Found > in line: " + line } + + if (i === 0) { + console.error(`First word of line: ${word}`) + } + if (word && !word.match(/^\s+$/)) { let len = word.length + 1 // .replace(/\(.*?\)/g, '') - if (width + len > maximum) { + if (len > maximum && width === (quote ? 2 : 0)) { + buffer += (quote ? '> ' : '') + word + ' ' + width = len + (quote ? 2 : 0) + } + else if (width + len > maximum) { buffer += '\n' + (quote ? '> ' : '') + word + ' ' - width = len + 2 + width = len + (quote ? 2 : 0) +// !first && (first = true) } else { buffer += word + ' ' width += len } } + first = false }) } })