Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/lighthouse-report.yml
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ jobs:
- name: Add Lighthouse stats as comment
id: comment_to_pr
if: github.event.pull_request.head.repo.full_name == github.repository
uses: marocchino/sticky-pull-request-comment@5770ad5eb8f42dd2c4f34da00c94c5381e49af88 # 3.0.5
with:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/lint-autofix.yml
Original file line number Diff line number Diff line change
Expand Up @@ -55,5 +55,6 @@ jobs:
run: git diff

- uses: stefanzweifel/git-auto-commit-action@4a55954c782fc1ea30b9056cd3e7a2b40ca8887d # v7.2.0
if: github.event.pull_request.head.repo.full_name == github.repository
with:
commit_message: 'refactor: apply lint autofix'
5 changes: 5 additions & 0 deletions packages/docusaurus-bundler/src/minifyHtml.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,11 @@ async function getSwcMinifier(): Promise<HtmlMinifier> {
// See https://github.com/swc-project/swc/issues/10994
tagOmission: 'keep-head-and-body',

// Keep attribute quotes. WhatsApp and some RDFa parsers ignore
// og:image when the minifier emits property=og:image without quotes.
// See https://github.com/facebook/docusaurus/issues/12368
quotes: true,

// Sorting these attributes (class) can lead to React hydration errors
sortSpaceSeparatedAttributeValues: false,
sortAttributes: false,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"theme.IdealImageMessage.404error": "404. Təsvir tapılmadı",
"theme.IdealImageMessage.error": "Xəta. Yeniləmək üçün klik edin.",
"theme.IdealImageMessage.load": "Yükləmək üçün klik edin{sizeMessage}",
"theme.IdealImageMessage.loading": "Yüklənir...",
"theme.IdealImageMessage.offline": "Brauzer oflayndır. Təsvir yüklənmədi"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"theme.PwaReloadPopup.closeButtonAriaLabel": "Bağla",
"theme.PwaReloadPopup.info": "Yeni versiya mövcuddur",
"theme.PwaReloadPopup.refreshButtonText": "Yenilə"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
{
"theme.AnnouncementBar.closeButtonAriaLabel": "Bağla",
"theme.BackToTopButton.buttonAriaLabel": "Səhifənin başına qayıt",
"theme.CodeBlock.copied": "Kopyalandı",
"theme.CodeBlock.copy": "Kopyala",
"theme.CodeBlock.copyButtonAriaLabel": "Kodu kopyala",
"theme.CodeBlock.wordWrapToggle": "Söz sürüşdürməni aç/bağla",
"theme.DocSidebarItem.collapseCategoryAriaLabel": "'{label}' yan panel kateqoriyasını yığ",
"theme.DocSidebarItem.expandCategoryAriaLabel": "'{label}' yan panel kateqoriyasını aç",
"theme.ErrorPageContent.title": "Bu səhifə çökdü.",
"theme.ErrorPageContent.tryAgain": "Yenidən cəhd edin",
"theme.IconExternalLink.ariaLabel": "(yeni tab-da açılır)",
"theme.NavBar.navAriaLabel": "Əsas",
"theme.NotFound.p1": "Axtardığınızı tapa bilmədik.",
"theme.NotFound.p2": "Zəhmət olmasa, sizi bu ünvana yönləndirən saytın sahibi ilə əlaqə saxlayın və linkin işləmədiyini bildirin.",
"theme.NotFound.title": "Səhifə tapılmadı",
"theme.TOCCollapsible.toggleButtonLabel": "Bu səhifədə",
"theme.admonition.caution": "diqqət",
"theme.admonition.danger": "təhlükə",
"theme.admonition.info": "məlumat",
"theme.admonition.note": "qeyd",
"theme.admonition.tip": "məsləhət",
"theme.admonition.warning": "xəbərdarlıq",
"theme.blog.archive.description": "Arxiv",
"theme.blog.archive.title": "Arxiv",
"theme.blog.author.noPosts": "Bu müəllif hələ heç bir yazı yazmayıb.",
"theme.blog.author.pageTitle": "{authorName} - {nPosts}",
"theme.blog.authorsList.pageTitle": "Müəlliflər",
"theme.blog.authorsList.viewAll": "Bütün müəlliflərə bax",
"theme.blog.paginator.navAriaLabel": "Bloq siyahısı səhifə naviqasiyası",
"theme.blog.paginator.newerEntries": "Daha yeni yazılar",
"theme.blog.paginator.olderEntries": "Daha köhnə yazılar",
"theme.blog.post.paginator.navAriaLabel": "Bloq yazısı səhifə naviqasiyası",
"theme.blog.post.paginator.newerPost": "Daha yeni yazı",
"theme.blog.post.paginator.olderPost": "Daha köhnə yazı",
"theme.blog.post.plurals": "Bir yazı|{count} yazı",
"theme.blog.post.readMore": "Ətraflı oxu",
"theme.blog.post.readMoreLabel": "{title} haqqında ətraflı oxu",
"theme.blog.post.readingTime.plurals": "Bir dəqiqəlik oxu|{readingTime} dəqiqəlik oxu",
"theme.blog.sidebar.navAriaLabel": "Bloqun son yazıları üzrə naviqasiya",
"theme.blog.tagTitle": "\"{tagName}\" etiketi ilə {nPosts}",
"theme.colorToggle.ariaLabel": "Tünd və işıqlı rejim arasında keçid et (hazırda {mode})",
"theme.colorToggle.ariaLabel.mode.dark": "tünd rejim",
"theme.colorToggle.ariaLabel.mode.light": "işıqlı rejim",
"theme.colorToggle.ariaLabel.mode.system": "sistem rejimi",
"theme.common.editThisPage": "Səhifəni redaktə et",
"theme.common.headingLinkTitle": "{heading} başlığına birbaşa keçid",
"theme.common.skipToMainContent": "Əsas məzmuna keç",
"theme.contentVisibility.draftBanner.message": "Bu səhifə qaralamadır. O, yalnız dev rejimində görünəcək və istismar mühitinə daxil edilməyəcək.",
"theme.contentVisibility.draftBanner.title": "Qaralama səhifə",
"theme.contentVisibility.unlistedBanner.message": "Bu səhifə siyahıya alınmayıb. Axtarış sistemləri onu indeksləməyəcək və ona yalnız birbaşa linki olan istifadəçilər daxil ola biləcək.",
"theme.contentVisibility.unlistedBanner.title": "Siyahıya alınmamış səhifə",
"theme.docs.DocCard.categoryDescription.plurals": "1 element|{count} element",
"theme.docs.breadcrumbs.home": "Ana səhifə",
"theme.docs.breadcrumbs.navAriaLabel": "Naviqasiya yolu",
"theme.docs.paginator.navAriaLabel": "Sənəd səhifələri",
"theme.docs.paginator.next": "Növbəti",
"theme.docs.paginator.previous": "Əvvəlki",
"theme.docs.sidebar.closeSidebarButtonAriaLabel": "Naviqasiya panelini bağla",
"theme.docs.sidebar.collapseButtonAriaLabel": "Yan paneli yığ",
"theme.docs.sidebar.collapseButtonTitle": "Yan paneli yığ",
"theme.docs.sidebar.expandButtonAriaLabel": "Yan paneli aç",
"theme.docs.sidebar.expandButtonTitle": "Yan paneli aç",
"theme.docs.sidebar.navAriaLabel": "Sənədlər yan paneli",
"theme.docs.sidebar.toggleSidebarButtonAriaLabel": "Yan paneli aç/bağla",
"theme.docs.tagDocListPageTitle": "\"{tagName}\" etiketi ilə {nDocsTagged}",
"theme.docs.tagDocListPageTitle.nDocsTagged": "Bir sənəd etiketlənib|{count} sənəd etiketlənib",
"theme.docs.versionBadge.label": "Versiya: {versionLabel}",
"theme.docs.versions.latestVersionLinkLabel": "Ən son versiya",
"theme.docs.versions.latestVersionSuggestionLabel": "Ən son sənədlər üçün {latestVersionLink} ({versionLabel}) səhifəsinə baxın.",
"theme.docs.versions.unmaintainedVersionLabel": "Bu, {siteTitle} {versionLabel} üçün sənədlərdir və artıq aktiv şəkildə dəstəklənmir.",
"theme.docs.versions.unreleasedVersionLabel": "Bu, {siteTitle} {versionLabel} versiyası üçün hələ buraxılmamış sənədlərdir",
"theme.lastUpdated.atDate": " {date} tarixində",
"theme.lastUpdated.byUser": " {user} tərəfindən",
"theme.lastUpdated.lastUpdatedAtBy": "Son yenilənmə{atDate}{byUser}",
"theme.navbar.mobileDropdown.collapseButton.collapseAriaLabel": "Siyahını yığ",
"theme.navbar.mobileDropdown.collapseButton.expandAriaLabel": "Siyahını genişləndir",
"theme.navbar.mobileLanguageDropdown.label": "Dillər",
"theme.navbar.mobileSidebarSecondaryMenu.backButtonLabel": "← Əsas menyuya qayıt",
"theme.navbar.mobileVersionsDropdown.label": "Versiyalar",
"theme.tags.tagsListLabel": "Etiketlər:",
"theme.tags.tagsPageLink": "Bütün etiketlərə bax",
"theme.tags.tagsPageTitle": "Etiketlər"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"theme.Playground.buttons.reset": "Sıfırla",
"theme.Playground.liveEditor": "Canlı redaktor",
"theme.Playground.result": "Nəticə"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
{
"theme.SearchBar.label": "Axtar",
"theme.SearchBar.seeAll": "{count} nəticənin hamısına bax",
"theme.SearchModal.askAiScreen.afterToolCallText": "Axtarıldı:",
"theme.SearchModal.askAiScreen.copyButtonCopiedText": "Kopyalandı!",
"theme.SearchModal.askAiScreen.copyButtonText": "Kopyala",
"theme.SearchModal.askAiScreen.copyButtonTitle": "Kopyala",
"theme.SearchModal.askAiScreen.disclaimerText": "Cavablar süni intellekt tərəfindən yaradılır və səhv ola bilər. Cavabları yoxlayın.",
"theme.SearchModal.askAiScreen.dislikeButtonTitle": "Bəyənmədim",
"theme.SearchModal.askAiScreen.duringToolCallText": "Axtarılır: ",
"theme.SearchModal.askAiScreen.likeButtonTitle": "Bəyəndim",
"theme.SearchModal.askAiScreen.preToolCallText": "Axtarılır...",
"theme.SearchModal.askAiScreen.relatedSourcesText": "Əlaqəli mənbələr",
"theme.SearchModal.askAiScreen.thanksForFeedbackText": "Rəyiniz üçün təşəkkür edirik!",
"theme.SearchModal.askAiScreen.thinkingText": "Düşünür...",
"theme.SearchModal.errorScreen.helpText": "İnternet bağlantınızı yoxlamağınız faydalı ola bilər.",
"theme.SearchModal.errorScreen.titleText": "Nəticələri əldə etmək mümkün olmadı",
"theme.SearchModal.footer.backToSearchText": "Axtarışa qayıt",
"theme.SearchModal.footer.closeKeyAriaLabel": "Escape düyməsi",
"theme.SearchModal.footer.closeText": "Bağla",
"theme.SearchModal.footer.navigateDownKeyAriaLabel": "Aşağı ox",
"theme.SearchModal.footer.navigateText": "Naviqasiya",
"theme.SearchModal.footer.navigateUpKeyAriaLabel": "Yuxarı ox",
"theme.SearchModal.footer.searchByText": "Dəstəkləyir: ",
"theme.SearchModal.footer.selectKeyAriaLabel": "Enter düyməsi",
"theme.SearchModal.footer.selectText": "Seç",
"theme.SearchModal.footer.submitQuestionText": "Sualı göndər",
"theme.SearchModal.noResultsScreen.noResultsText": "Nəticə tapılmadı:",
"theme.SearchModal.noResultsScreen.reportMissingResultsLinkText": "Bizə bildirin.",
"theme.SearchModal.noResultsScreen.reportMissingResultsText": "Bu sorğunun nəticə qaytarmalı olduğunu düşünürsünüz?",
"theme.SearchModal.noResultsScreen.suggestedQueryText": "Bunu axtarmağa cəhd edin:",
"theme.SearchModal.placeholder": "Sənədlərdə axtar",
"theme.SearchModal.resultsScreen.askAiPlaceholder": "Süni intellektdən soruş: ",
"theme.SearchModal.searchBox.backToKeywordSearchButtonAriaLabel": "Açar söz axtarışına qayıt",
"theme.SearchModal.searchBox.backToKeywordSearchButtonText": "Açar söz axtarışına qayıt",
"theme.SearchModal.searchBox.cancelButtonText": "Ləğv et",
"theme.SearchModal.searchBox.enterKeyHint": "axtar",
"theme.SearchModal.searchBox.enterKeyHintAskAi": "enter",
"theme.SearchModal.searchBox.placeholderText": "Sənədlərdə axtar",
"theme.SearchModal.searchBox.placeholderTextAskAi": "Başqa sual verin...",
"theme.SearchModal.searchBox.placeholderTextAskAiStreaming": "Cavablandırılır...",
"theme.SearchModal.searchBox.resetButtonTitle": "Sorğunu təmizlə",
"theme.SearchModal.searchBox.searchInputLabel": "Axtar",
"theme.SearchModal.startScreen.favoriteSearchesTitle": "Seçilmiş",
"theme.SearchModal.startScreen.noRecentSearchesText": "Son axtarış yoxdur",
"theme.SearchModal.startScreen.recentConversationsTitle": "Son söhbətlər",
"theme.SearchModal.startScreen.recentSearchesTitle": "Son",
"theme.SearchModal.startScreen.removeFavoriteSearchButtonTitle": "Bu axtarışı seçilmişlərdən sil",
"theme.SearchModal.startScreen.removeRecentConversationButtonTitle": "Bu söhbəti tarixçədən sil",
"theme.SearchModal.startScreen.removeRecentSearchButtonTitle": "Bu axtarışı tarixçədən sil",
"theme.SearchModal.startScreen.saveRecentSearchButtonTitle": "Axtarışı yadda saxla",
"theme.SearchPage.algoliaLabel": "Powered by Algolia",
"theme.SearchPage.documentsFound.plurals": "Bir sənəd tapıldı|{count} sənəd tapıldı",
"theme.SearchPage.emptyResultsTitle": "Sənədlərdə axtar",
"theme.SearchPage.existingResultsTitle": "\"{query}\" üçün axtarış nəticələri",
"theme.SearchPage.fetchingNewResults": "Yeni nəticələr yüklənir...",
"theme.SearchPage.inputLabel": "Axtar",
"theme.SearchPage.inputPlaceholder": "Axtarış məntini buraya yazın",
"theme.SearchPage.noResultsText": "Heç bir nəticə tapılmadı"
}
112 changes: 99 additions & 13 deletions packages/docusaurus-utils/src/__tests__/markdownUtils.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,47 @@ describe('createExcerpt', () => {
);
});

it('creates excerpt for h1 heading containing hash in text (e.g. C#)', () => {
expect(
createExcerpt(dedent`

# C# Programming Guide

This paragraph should become the description.
`),
).toBe('This paragraph should become the description.');
});

it('creates excerpt for h1 heading containing hash in text (e.g. F#)', () => {
expect(
createExcerpt(dedent`

# F# Programming Guide

This paragraph should become the description.
`),
).toBe('This paragraph should become the description.');
});

it('creates excerpt for h1 heading containing hash with trailing ATX closing marker', () => {
expect(
createExcerpt(dedent`

# C# Programming Guide #

This paragraph should become the description.
`),
).toBe('This paragraph should become the description.');
});

it('creates excerpt for h2 heading containing hash in text (e.g. C#)', () => {
expect(
createExcerpt(dedent`
## C# Setup Guide
`),
).toBe('C# Setup Guide');
});

it('creates excerpt for regular content with alternate title', () => {
expect(
createExcerpt(dedent`
Expand Down Expand Up @@ -572,6 +613,26 @@ Lorem Ipsum
});
});

it('parses markdown h1 title placed after export declarations', () => {
const markdown = dedent`
export function Author() {
return (
<a href="mailto:author@example.com">Author</a>
);
}

# Markdown Title

Lorem Ipsum

`;

expect(parseMarkdownContentTitle(markdown)).toEqual({
content: markdown,
contentTitle: 'Markdown Title',
});
});

it('parses markdown h1 title placed after multiple import declarations', () => {
const markdown = dedent`
import Component1 from '@site/src/components/Component1';
Expand Down Expand Up @@ -602,23 +663,21 @@ Lorem Ipsum
});
});

it('parses markdown h1 title placed after multiple import declarations and remove it', () => {
it('parses markdown h1 title placed after multiple import/export declarations and remove it', () => {
const markdown = dedent`
import Component1 from '@site/src/components/Component1';
import Component2 from '@site/src/components/Component2';
import Component3 from '@site/src/components/Component3';
import Component4 from '@site/src/components/Component4';
export function Component3() {
return <span>Component3</span>
}

export function Component4() {
return <span>Component4</span>
}
import Component5 from '@site/src/components/Component5';
import Component6 from '@site/src/components/Component6';
import Component7 from '@site/src/components/Component7';
import Component8 from '@site/src/components/Component8';
import Component9 from '@site/src/components/Component9';
import Component10 from '@site/src/components/Component10';
import Component11 from '@site/src/components/Component11';
import Component12 from '@site/src/components/Component12';
import Component13 from '@site/src/components/Component13';
import Component14 from '@site/src/components/Component14';
import Component15 from '@site/src/components/Component15';
export function Component6() {
return <span>Component6</span>
}

# Markdown Title

Expand All @@ -633,6 +692,33 @@ Lorem Ipsum
contentTitle: 'Markdown Title',
});
});

it('parses markdown h1 title placed after multiple import/export declarations', () => {
const markdown = dedent`
import Component1 from '@site/src/components/Component1';
import Component2 from '@site/src/components/Component2';
export function Component3() {
return <span>Component3</span>
}

export function Component4() {
return <span>Component4</span>
}
import Component5 from '@site/src/components/Component5';
export function Component6() {
return <span>Component6</span>
}

# Markdown Title

Lorem Ipsum
`;

expect(parseMarkdownContentTitle(markdown)).toEqual({
content: markdown,
contentTitle: 'Markdown Title',
});
});
});

describe('parseFileContentFrontMatter', () => {
Expand Down
16 changes: 8 additions & 8 deletions packages/docusaurus-utils/src/markdownUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ export function createExcerpt(fileString: string): string | undefined {
// Remove HTML tags.
.replace(/<[^>]*>/g, '')
// Remove Title headers
.replace(/^#[^#]+#?/gm, '')
.replace(/^#(?!#).*/gm, '')
// Remove Markdown + ATX-style headers
.replace(/^#{1,6}\s*(?<text>[^#]*?)\s*#{0,6}/gm, '$1')
// Remove emphasis.
Expand Down Expand Up @@ -255,18 +255,18 @@ export function parseMarkdownContentTitle(
const removeContentTitleOption = options?.removeContentTitle ?? false;

const content = contentUntrimmed.trim();
// We only need to detect import statements that will be parsed by MDX as
// `import` nodes, as broken syntax can't render anyways. That means any block
// that has `import` at the very beginning and surrounded by empty lines.
const contentWithoutImport = content
.replace(/^(?:import\s(?:.|\r?\n(?!\r?\n))*(?:\r?\n){2,})*/, '')
// We only need to detect import/export statements that will be parsed by MDX as
// `import` or `export` nodes, as broken syntax can't render anyways. That means any block
// that has `import` or `export` at the very beginning and surrounded by empty lines.
const contentWithoutImportExport = content
.replace(/^(?:(?:import|export)\s(?:.|\r?\n(?!\r?\n))*(?:\r?\n){2,})*/, '')
.trim();

const regularTitleMatch = /^#[ \t]+(?<title>[^ \t].*)(?:\r?\n|$)/.exec(
contentWithoutImport,
contentWithoutImportExport,
);
const alternateTitleMatch = /^(?<title>.*)\r?\n=+(?:\r?\n|$)/.exec(
contentWithoutImport,
contentWithoutImportExport,
);

const titleMatch = regularTitleMatch ?? alternateTitleMatch;
Expand Down
Loading
Loading