From b2cf2f134e6df03017d57078227ab8a18925cd93 Mon Sep 17 00:00:00 2001 From: Erik Michelson Date: Mon, 4 Jan 2021 13:01:34 +0100 Subject: [PATCH] Add ability to use yaml-array for tags (#874) --- CHANGELOG.md | 3 ++ cypress/integration/metadata.spec.ts | 37 +++++++++++++++++++ public/locales/en.json | 4 +- .../yaml-metadata/yaml-metadata.test.ts | 35 +++++++++++++++++- .../editor/yaml-metadata/yaml-metadata.ts | 14 ++++++- .../full-markdown-renderer.tsx | 17 ++++++++- .../sequence-diagram/deprecation-warning.tsx | 2 +- src/redux/document-content/reducers.ts | 4 +- 8 files changed, 107 insertions(+), 9 deletions(-) create mode 100644 cypress/integration/metadata.spec.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index 05be45d92..9a7f7d1ba 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,7 @@ SPDX-License-Identifier: CC-BY-SA-4.0 - `{%slideshare user/my-awesome-presentation %}` -> Embedding removed - `{%speakerdeck foobar %}` -> Embedding removed - The use of `sequence` as code block language ([Why?](https://hedgedoc.org/faq/)) +- Comma-separated definition of tags in the yaml-metadata ### Removed @@ -33,6 +34,7 @@ SPDX-License-Identifier: CC-BY-SA-4.0 - Import content from a url - F9 shortcut to sort lines - Highlight.JS language support for `1c` was removed. +- Support for tag definitions in headings ### Added @@ -73,6 +75,7 @@ SPDX-License-Identifier: CC-BY-SA-4.0 - The dark-mode is also applied to the read-only-view and can be toggled from there. - Access tokens for the CLI and 3rd-party-clients can be managed in the user profile. - Change editor font to "Fira Code" +- Note tags can be set as yaml-array in frontmatter --- diff --git a/cypress/integration/metadata.spec.ts b/cypress/integration/metadata.spec.ts new file mode 100644 index 000000000..1863eace6 --- /dev/null +++ b/cypress/integration/metadata.spec.ts @@ -0,0 +1,37 @@ +/* + * SPDX-FileCopyrightText: 2020 The HedgeDoc developers (see AUTHORS file) + * + * SPDX-License-Identifier: AGPL-3.0-only + */ + +describe('yaml-metadata: tags', () => { + beforeEach(() => { + cy.visit('/n/features') + cy.get('.CodeMirror textarea') + .type('{ctrl}a', { force: true }) + .type('{backspace}') + }) + + it('show deprecation notice on old syntax', () => { + cy.get('.CodeMirror textarea') + .type('---\ntags: a, b, c\n---') + cy.get('.splitter.right .w-100.h-100 .alert.alert-warning') + .should('be.visible') + }) + + it('show no deprecation notice on yaml-array (1)', () => { + cy.get('.CodeMirror textarea') + .type('---\ntags: [\'a\', \'b\', \'c\']\n---') + cy.get('.splitter.right .w-100.h-100 .alert.alert-warning') + .should('not.exist') + }) + + it('show no deprecation notice on yaml-array (2)', () => { + cy.get('.CodeMirror textarea') + .type('---\ntags:\n - a\nb\nc\n') + .type('{backspace}{backspace}{backspace}{backspace}') + .type('---') + cy.get('.splitter.right .w-100.h-100 .alert.alert-warning') + .should('not.exist') + }) +}) diff --git a/public/locales/en.json b/public/locales/en.json index 5c56f47b0..b81b22681 100644 --- a/public/locales/en.json +++ b/public/locales/en.json @@ -185,6 +185,7 @@ "untitledNote": "Untitled", "placeholder": "← Start by entering a title here\n===\nVisit the features page if you don't know what to do.\nHappy hacking :)", "invalidYaml": "The yaml-header is invalid. See <0> for more information.", + "deprecatedTags": "The comma-separated definition of tags in the yaml-metadata is deprecated. Use a yaml-array instead.", "infoToc": "Structure your note with headings to see a table-of-contents here.", "help": { "shortcuts": { @@ -453,7 +454,8 @@ "why": "Why?", "successfullyCopied": "Copied!", "copyError": "Error while copying!", - "errorOccurred": "An error occurred" + "errorOccurred": "An error occurred", + "readForMoreInfo": "Read here for more information" }, "login": { "chooseMethod": "Choose method", diff --git a/src/components/editor/yaml-metadata/yaml-metadata.test.ts b/src/components/editor/yaml-metadata/yaml-metadata.test.ts index 9e6605bef..19ed69cfa 100644 --- a/src/components/editor/yaml-metadata/yaml-metadata.test.ts +++ b/src/components/editor/yaml-metadata/yaml-metadata.test.ts @@ -69,7 +69,7 @@ describe('yaml tests', () => { }) }) - it('tags only', () => { + it('tags only (old syntax)', () => { testMetadata(`--- tags: test123, abc ___ @@ -78,10 +78,41 @@ describe('yaml tests', () => { tags: 'test123, abc' }, { - tags: ['test123', 'abc'] + tags: ['test123', 'abc'], + deprecatedTagsSyntax: true }) }) + it('tags only', () => { + testMetadata(`--- + tags: + - test123 + - abc + ___ + `, + { + tags: ['test123', 'abc'] + }, + { + tags: ['test123', 'abc'], + deprecatedTagsSyntax: false + }) + }) + + it('tags only (alternative syntax)', () => { + testMetadata(`--- + tags: ['test123', 'abc'] + ___ + `, + { + tags: ['test123', 'abc'] + }, + { + tags: ['test123', 'abc'], + deprecatedTagsSyntax: false + }) + }) + it('breaks only', () => { testMetadata(`--- breaks: false diff --git a/src/components/editor/yaml-metadata/yaml-metadata.ts b/src/components/editor/yaml-metadata/yaml-metadata.ts index 7b9a19a5c..29ad2965c 100644 --- a/src/components/editor/yaml-metadata/yaml-metadata.ts +++ b/src/components/editor/yaml-metadata/yaml-metadata.ts @@ -11,7 +11,7 @@ type iso6391 = 'aa' | 'ab' | 'af' | 'am' | 'ar' | 'ar-ae' | 'ar-bh' | 'ar-dz' | export interface RawYAMLMetadata { title: string | undefined description: string | undefined - tags: string | undefined + tags: string | string[] | undefined robots: string | undefined lang: string | undefined dir: string | undefined @@ -27,6 +27,7 @@ export class YAMLMetaData { title: string description: string tags: string[] + deprecatedTagsSyntax: boolean robots: string lang: iso6391 dir: 'ltr' | 'rtl' @@ -53,7 +54,16 @@ export class YAMLMetaData { transition: 'none', theme: 'white' } */ - this.tags = rawData?.tags?.split(',').map(entry => entry.trim()) ?? [] + if (typeof rawData?.tags === 'string') { + this.tags = rawData?.tags?.split(',').map(entry => entry.trim()) ?? [] + this.deprecatedTagsSyntax = true + } else if (typeof rawData?.tags === 'object') { + this.tags = rawData?.tags?.filter(tag => tag !== null) ?? [] + this.deprecatedTagsSyntax = false + } else { + this.tags = [] + this.deprecatedTagsSyntax = false + } this.opengraph = rawData?.opengraph ? new Map(Object.entries(rawData.opengraph)) : new Map() } } diff --git a/src/components/markdown-renderer/full-markdown-renderer.tsx b/src/components/markdown-renderer/full-markdown-renderer.tsx index 411160cdc..e1fd28001 100644 --- a/src/components/markdown-renderer/full-markdown-renderer.tsx +++ b/src/components/markdown-renderer/full-markdown-renderer.tsx @@ -6,9 +6,13 @@ SPDX-License-Identifier: AGPL-3.0-only import React, { useCallback, useMemo, useRef, useState } from 'react' import { Alert } from 'react-bootstrap' -import { Trans } from 'react-i18next' +import { Trans, useTranslation } from 'react-i18next' import { TocAst } from 'markdown-it-toc-done-right' +import { useSelector } from 'react-redux' +import { ApplicationState } from '../../redux' import { InternalLink } from '../common/links/internal-link' +import links from '../../links.json' +import { TranslatedExternalLink } from '../common/links/translated-external-link' import { ShowIf } from '../common/show-if/show-if' import { RawYAMLMetadata, YAMLMetaData } from '../editor/yaml-metadata/yaml-metadata' import { BasicMarkdownRenderer } from './basic-markdown-renderer' @@ -40,8 +44,10 @@ export const FullMarkdownRenderer: React.FC { const allReplacers = useReplacerInstanceListCreator(onTaskCheckedChange) + useTranslation() const [yamlError, setYamlError] = useState(false) + const yamlDeprecatedTags = useSelector((state: ApplicationState) => state.documentContent.metadata.deprecatedTagsSyntax) const rawMetaRef = useRef() const firstHeadingRef = useRef() @@ -79,10 +85,17 @@ export const FullMarkdownRenderer: React.FC - + + + + +
+ +
+
diff --git a/src/components/markdown-renderer/replace-components/sequence-diagram/deprecation-warning.tsx b/src/components/markdown-renderer/replace-components/sequence-diagram/deprecation-warning.tsx index 52593b7e1..ba7169f00 100644 --- a/src/components/markdown-renderer/replace-components/sequence-diagram/deprecation-warning.tsx +++ b/src/components/markdown-renderer/replace-components/sequence-diagram/deprecation-warning.tsx @@ -17,7 +17,7 @@ export const DeprecationWarning: React.FC = () => {   - + ) } diff --git a/src/redux/document-content/reducers.ts b/src/redux/document-content/reducers.ts index d27027b6f..bb23a989a 100644 --- a/src/redux/document-content/reducers.ts +++ b/src/redux/document-content/reducers.ts @@ -9,7 +9,8 @@ import { DocumentContent, DocumentContentAction, DocumentContentActionType, - SetDocumentContentAction, SetDocumentMetadataAction, + SetDocumentContentAction, + SetDocumentMetadataAction, SetNoteIdAction } from './types' @@ -20,6 +21,7 @@ export const initialState: DocumentContent = { title: '', description: '', tags: [], + deprecatedTagsSyntax: false, robots: '', lang: 'en', dir: 'ltr',