Skip to content

Commit

Permalink
[docs] Keep the same header between locales (#21041)
Browse files Browse the repository at this point in the history
  • Loading branch information
Jairon Alves Lima committed May 16, 2020
1 parent dcc7ff5 commit 49ea748
Show file tree
Hide file tree
Showing 2 changed files with 229 additions and 15 deletions.
60 changes: 45 additions & 15 deletions docs/src/modules/utils/parseMarkdown.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ const titleRegExp = /# (.*)[\r\n]/;
const descriptionRegExp = /<p class="description">(.*)<\/p>[\r\n]/;
const headerKeyValueRegExp = /(.*): (.*)/g;
const emptyRegExp = /^\s*$/;
const notEnglishMarkdownRegExp = /-([a-z]{2})\.md$/;

/**
* Extract information from the top of the markdown.
Expand Down Expand Up @@ -130,19 +131,32 @@ export function prepareMarkdown(config) {

const demos = {};
const docs = {};
const headingHashes = {};

// Process the English markdown before the other locales.
let filenames = [];
requireRaw.keys().forEach((filename) => {
if (filename.match(notEnglishMarkdownRegExp)) {
filenames.push(filename);
} else {
filenames = [filename].concat(filenames);
}
});

filenames.forEach((filename) => {
if (filename.indexOf('.md') !== -1) {
const match = filename.match(/-([a-z]{2})\.md$/);
const matchNotEnglishMarkdown = filename.match(notEnglishMarkdownRegExp);

const userLanguage =
match && LANGUAGES_IN_PROGRESS.indexOf(match[1]) !== -1 ? match[1] : 'en';
matchNotEnglishMarkdown && LANGUAGES_IN_PROGRESS.indexOf(matchNotEnglishMarkdown[1]) !== -1
? matchNotEnglishMarkdown[1]
: 'en';

const markdown = requireRaw(filename);
const contents = getContents(markdown);
const headers = getHeaders(markdown);

const title = headers.title || getTitle(markdown);
const description = headers.description || getDescription(markdown);
const contents = getContents(markdown);

if (headers.components.length > 0) {
contents.push(`
Expand All @@ -157,8 +171,10 @@ ${headers.components
`);
}

const headingHashes = {};
const toc = [];
const headingHashesFallbackTranslated = {};
let headingIndex = -1;

const rendered = contents.map((content) => {
if (demos && demoRegexp.test(content)) {
try {
Expand Down Expand Up @@ -186,17 +202,28 @@ ${headers.components
) // remove emojis
.replace(/<\/?[^>]+(>|$)/g, '') // remove HTML
.trim();
const hash = textToHash(headingText, headingHashes);

// Standardizes the hash from the default location (en) to different locations
// Need english.md file parsed first
let hash;
if (userLanguage === 'en') {
hash = textToHash(headingText, headingHashes);
} else {
headingIndex += 1;
hash = Object.keys(headingHashes)[headingIndex];
if (!hash) {
hash = textToHash(headingText, headingHashesFallbackTranslated);
}
}

// enable splitting of long words from function name + first arg name
// Closing parens are less interesting since this would only allow breaking one character earlier.
// Applying the same mechanism would also allow breaking of non-function signatures like "Community help (free)".
// To detect that we enabled breaking of open/closing parens we'd need a context-sensitive parser.
const displayText = headingText.replace(/([^\s]\()/g, '$1&#8203;');
/**
* create a nested structure with 2 levels starting with level 2 e.g.
* [{...level2, children: [level3, level3, level3]}, level2]
*/

// create a nested structure with 2 levels starting with level 2 e.g.
// [{...level2, children: [level3, level3, level3]}, level2]
if (level === 2) {
toc.push({
text: displayText,
Expand Down Expand Up @@ -247,18 +274,21 @@ ${headers.components
},
});
});

// fragment link symbol
rendered.unshift(`<svg style="display: none;" xmlns="http://www.w3.org/2000/svg">
<symbol id="anchor-link-icon" viewBox="0 0 16 16">
<path d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z" />
</symbol>
</svg>`);

const location = headers.filename || `/docs/src/pages/${pageFilename}/${filename}`;

const localized = { description, location, rendered, toc, title };

docs[userLanguage] = localized;
docs[userLanguage] = {
description,
location: headers.filename || `/docs/src/pages/${pageFilename}/${filename}`,
rendered,
toc,
title,
};
} else if (filename.indexOf('.tsx') !== -1) {
const demoName = `pages/${pageFilename}/${filename
.replace(/\.\//g, '')
Expand Down
184 changes: 184 additions & 0 deletions docs/src/modules/utils/parseMarkdown.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -104,5 +104,189 @@ describe('parseMarkdown', () => {
},
]);
});

it('use english hash for different locales', () => {
const markdownEn = `
# Localization
## Locales
### Example
### Use same hash
`;

const markdownPt = `
# Localização
## Idiomas
### Exemplo
### Usar o mesmo hash
`;

const markdownZh = `
# 所在位置
## 语言环境
### 例
### 使用相同的哈希
`;
// mock require.context
function requireRaw(filename) {
switch (filename) {
case 'localization-pt.md':
return markdownPt;
case 'localization-zh.md':
return markdownZh;
default:
return markdownEn;
}
}
requireRaw.keys = () => ['localization-pt.md', 'localization.md', 'localization-zh.md'];

const {
docs: {
en: { toc: tocEn },
pt: { toc: tocPt },
zh: { toc: tocZh },
},
} = prepareMarkdown({
pageFilename: 'same-hash-test',
requireRaw,
});

expect(tocZh).to.have.deep.ordered.members([
{
children: [
{
hash: 'example',
level: 3,
text: '例',
},
{
hash: 'use-same-hash',
level: 3,
text: '使用相同的哈希',
},
],
hash: 'locales',
level: 2,
text: '语言环境',
},
]);

expect(tocPt).to.have.deep.ordered.members([
{
children: [
{
hash: 'example',
level: 3,
text: 'Exemplo',
},
{
hash: 'use-same-hash',
level: 3,
text: 'Usar o mesmo hash',
},
],
hash: 'locales',
level: 2,
text: 'Idiomas',
},
]);

expect(tocEn).to.have.deep.ordered.members([
{
children: [
{
hash: 'example',
level: 3,
text: 'Example',
},
{
hash: 'use-same-hash',
level: 3,
text: 'Use same hash',
},
],
hash: 'locales',
level: 2,
text: 'Locales',
},
]);
});

it('use translated hash for translations are not synced', () => {
const markdownEn = `
# Localization
## Locales
### Example
### Use same hash
`;

const markdownPt = `
# Localização
## Idiomas
### Exemplo
### Usar o mesmo hash
### Usar traduzido
`;

// mock require.context
function requireRaw(filename) {
return filename === 'localization-pt.md' ? markdownPt : markdownEn;
}
requireRaw.keys = () => ['localization-pt.md', 'localization.md'];

const {
docs: {
en: { toc: tocEn },
pt: { toc: tocPt },
},
} = prepareMarkdown({
pageFilename: 'same-hash-test',
requireRaw,
});

expect(tocPt).to.have.deep.ordered.members([
{
children: [
{
hash: 'example',
level: 3,
text: 'Exemplo',
},
{
hash: 'use-same-hash',
level: 3,
text: 'Usar o mesmo hash',
},
{
hash: 'usar-traduzido',
level: 3,
text: 'Usar traduzido',
},
],
hash: 'locales',
level: 2,
text: 'Idiomas',
},
]);

expect(tocEn).to.have.deep.ordered.members([
{
children: [
{
hash: 'example',
level: 3,
text: 'Example',
},
{
hash: 'use-same-hash',
level: 3,
text: 'Use same hash',
},
],
hash: 'locales',
level: 2,
text: 'Locales',
},
]);
});
});
});

0 comments on commit 49ea748

Please sign in to comment.