diff --git a/content/code-security/security-overview/index.md b/content/code-security/security-overview/index.md index 8bb6d7a54910..713872786c36 100644 --- a/content/code-security/security-overview/index.md +++ b/content/code-security/security-overview/index.md @@ -1,8 +1,8 @@ --- -title: Viewing security alerts for repositories in your organization +title: Viewing security information for your organization or enterprise shortTitle: Security overview allowTitleToDifferFromFilename: true -intro: 'View, sort, and filter the security alerts from across your organization in one place.' +intro: 'View, sort, and filter security alerts and coverage information from across your organization or enterprise, and enable security features for their repositories.' product: '{% data reusables.gated-features.security-overview %}' versions: fpt: '*' diff --git a/src/content-render/liquid/data.js b/src/content-render/liquid/data.js index 0cd501dd67d6..dd2140652472 100644 --- a/src/content-render/liquid/data.js +++ b/src/content-render/liquid/data.js @@ -13,10 +13,11 @@ export default { } this.path = tagToken.args + this.tagToken = tagToken }, async render(scope) { - const text = getDataByLanguage(this.path, scope.environments.currentLanguage) + let text = getDataByLanguage(this.path, scope.environments.currentLanguage) if (text === undefined) { if (scope.environments.currentLanguage === 'en') { const message = `Can't find the key 'data ${this.path}' in the scope.` @@ -28,6 +29,21 @@ export default { return } - return this.liquid.parseAndRender(text.trim(), scope.environments) + if (text.trim().split('\n\n').length === 1 && text.split('\n').length > 0) { + const { input, begin } = this.tagToken + let i = 1 + while (input.charAt(begin - i) === ' ') { + i++ // this goes one character "to the left" + } + const goBack = input.slice(begin - i, begin) + if (goBack.charAt(0) === '\n' && goBack.length > 1) { + const numSpaces = goBack.length - 1 + text = text.trim().replace(/^/gm, ' '.repeat(numSpaces)).trim() + } + } else { + text = text.trim() + } + + return this.liquid.parseAndRender(text, scope.environments) }, } diff --git a/tests/fixtures/content/get-started/liquid/data.md b/tests/fixtures/content/get-started/liquid/data.md new file mode 100644 index 000000000000..6d11bc3ec8ee --- /dev/null +++ b/tests/fixtures/content/get-started/liquid/data.md @@ -0,0 +1,66 @@ +--- +title: Data Liquid tag +intro: The `data` Liquid tag can understand where it was used +versions: + fpt: '*' + ghes: '*' + ghae: '*' + ghec: '*' +type: how_to +--- + +## Introduction + +What this fixture accomplishes is that it uses the `\{\% data %}` Liquid +tag to inject itself after some left-side whitespace. That same amount +of left-side whitespace is then "replicated" to all lines of the string +that gets injected. + +In this example, the + +1. Bullet point + + {% data reusables.injectables.multiple_numbers %} + +1. Another bullet point + + After 3 spaces, here's the "body" of the second bullet point. + +## Injected insode a code block + +1. Here's some Yaml code. + + ```yaml copy + {% data reusables.injectables.multiple_numbers %} + + {% data reusables.injectables.one_line_numbers %} + + name: Move assigned card + on: + issues: + types: + - assigned + ``` + +## Injected without any leading whitespace + +On its own line: + +{% data reusables.injectables.multiple_numbers %} + +Directly after this: {% data reusables.injectables.multiple_numbers %} + +And now for a table on its own starting line + +{% data reusables.injectables.some_table %} + +## Insert the same table inside a bullet point + +1. Point 1 + +1. Point 2 + + What's important here is that in CommonMark when a Markdown table + is injected and indented into a bullet point, that it works at all. + + {% data reusables.injectables.some_table %} diff --git a/tests/fixtures/content/get-started/liquid/index.md b/tests/fixtures/content/get-started/liquid/index.md index aef559efb1fc..09e704f0a338 100644 --- a/tests/fixtures/content/get-started/liquid/index.md +++ b/tests/fixtures/content/get-started/liquid/index.md @@ -18,4 +18,5 @@ children: - /ifversion - /links-with-liquid - /tool-specific + - /data --- diff --git a/tests/fixtures/data/reusables/injectables/multiple_numbers.md b/tests/fixtures/data/reusables/injectables/multiple_numbers.md new file mode 100644 index 000000000000..4a6216023c04 --- /dev/null +++ b/tests/fixtures/data/reusables/injectables/multiple_numbers.md @@ -0,0 +1,4 @@ +One +Two +Three +Four diff --git a/tests/fixtures/data/reusables/injectables/one_line_numbers.md b/tests/fixtures/data/reusables/injectables/one_line_numbers.md new file mode 100644 index 000000000000..792b36432800 --- /dev/null +++ b/tests/fixtures/data/reusables/injectables/one_line_numbers.md @@ -0,0 +1 @@ +One Two Three Four diff --git a/tests/fixtures/data/reusables/injectables/some_table.md b/tests/fixtures/data/reusables/injectables/some_table.md new file mode 100644 index 000000000000..517d9cb95ace --- /dev/null +++ b/tests/fixtures/data/reusables/injectables/some_table.md @@ -0,0 +1,9 @@ +| Port | Service | Description | +|------|---------|------------------------------------------------------------| +| 22 | SSH | Git over SSH access. | +| 25 | SMTP | SMTP with encryption (STARTTLS) support. | +| 80 | HTTP | Web application access. | +| 122 | SSH | Instance shell access. | +| 161 | SNMP | Required for network monitoring protocol operation. | +| 443 | HTTPS | Web application and Git over HTTPS access. | +| 1194 | VPN | Secure replication network tunnel in high availability configuration. | diff --git a/tests/rendering-fixtures/liquid.js b/tests/rendering-fixtures/liquid.js index 6802e161c8e2..566e7a5afec8 100644 --- a/tests/rendering-fixtures/liquid.js +++ b/tests/rendering-fixtures/liquid.js @@ -233,3 +233,50 @@ describe('misc Liquid', () => { expect(texts[1]).toBe('Pricing') }) }) + +describe('data tag', () => { + test('injects data reusables with the right whitespace', async () => { + const $ = await getDOM('/get-started/liquid/data') + + // This proves that the two injected reusables tables work. + // CommonMark is finicky if the indentation isn't perfect, so + // if you don't get exactly 2 tables, something is wrong, and if it's + // wrong it's most likely because of the leading whitespaces. + expect($('#article-contents table').length).toBe(2) + + // To truly understand this test, you have to see + // http://localhost:4000/en/get-started/liquid/data to understand it. + // The page uses `{% data ... %}` within the bodies of bullet points. + // If the whitespace isn't correct and working, the bullet points + // would get confused and think the bullet point "body" is a new + // bullet point on its own. + expect($('#article-contents ol').length).toBe(3) + expect($('#article-contents ol li').length).toBe(2 + 1 + 2) + + // In the very first bullet point we inject something that multiple + // linebreaks in it. The source looks like this: + // + // 1. Bullet point + // + // {% data reusables.injectables.multiple_numbers %} + // + // (The code comment itself here has 3 spaces of manual indentation) + // What's important is that all the expected lines of that reusables + // stick inside this `ul li` block. + const liText = $('#article-contents ol li').first().text() + expect(liText).toMatch(/Bullet point\nOne\nTwo\nThree\nFour/) + + // The code block uses `{% data ... %}` and it should be indented + // so that it aligns perfectly with the code block itself. + // One of the injected data reusables contains multiple lines. + // It's important that each line from that starts at the far + // left. No more or less whitespace. + const codeBlock = $('#article-contents li pre').text() + expect(codeBlock).toMatch(/^One\n/) + expect(codeBlock).toMatch(/^One\nTwo\n/) + expect(codeBlock).toMatch(/^One\nTwo\nThree\n/) + + // The code block also a reusables that is just one line. + expect(codeBlock).toMatch(/One Two Three Four\n/) + }) +})