Export subtree PDFs in batches of 20 with previous/next navigation

This commit is contained in:
Peter White
2026-10-06 16:02:05 +02:00
parent 3ed448fed7
commit 8d238f76d4
46 changed files with 543 additions and 214 deletions
@@ -3,6 +3,13 @@ import { describe, expect, it } from 'bun:test';
import { RevisionPageType } from '@gitbook/api';
import { createPDFLinker } from './linker';
import { selectPages } from './selectPages';
import {
PDF_DEFAULT_LIMIT,
PDF_SUBTREE_DEFAULT_LIMIT,
getPDFSearchParams,
getPDFURLSearchParams,
} from './urls';
import { createLinker, linkerWithAbsoluteURLs } from '@/lib/links';
import { getLinkerForSiteSpace } from '@/lib/sites';
@@ -15,6 +22,10 @@ function createDocumentPage(id: string, path: string) {
} as any;
}
function createDocumentPageWithChildren(id: string, children: any[]) {
return { ...createDocumentPage(id, id), pages: children };
}
function createGroupPage(id: string, path: string) {
return {
id,
@@ -208,3 +219,183 @@ describe('createPDFLinker', () => {
).toBe('https://open-2v.gitbook.com/~space/HJ1ltuWFvsArFWtevnRn~gitbook/pdf/respond');
});
});
describe('createPDFLinker with batches', () => {
const baseLinker = createLinker({
host: 'open-2v.gitbook.com',
siteBasePath: '/~space/HJ1ltuWFvsArFWtevnRn',
spaceBasePath: '/~space/HJ1ltuWFvsArFWtevnRn',
});
const getBatchURL = (page: { id: string }) =>
page.id === 'other-batch'
? 'https://open-2v.gitbook.com/~gitbook/pdf?offset=20'
: undefined;
it('prefers the published URL for documents exported in another batch', () => {
const linker = createPDFLinker(
baseLinker,
[{ page: createDocumentPage('included', '') }],
createPublishedLinker(),
{ getBatchURL }
);
expect(
linker.toPathForPage({
pages: [
createDocumentPage('included', ''),
createDocumentPage('other-batch', 'respond'),
],
page: createDocumentPage('other-batch', 'respond'),
})
).toBe('https://docs.vectra.ai/deployment/respond');
});
it('links to the batch containing a page when there is no published URL', () => {
const linker = createPDFLinker(
baseLinker,
[{ page: createDocumentPage('included', '') }],
undefined,
{ getBatchURL }
);
expect(
linker.toPathForPage({
pages: [createDocumentPage('other-batch', 'respond')],
page: createDocumentPage('other-batch', 'respond'),
anchor: 'faq',
})
).toBe('https://open-2v.gitbook.com/~gitbook/pdf?offset=20#page-other-batch-faq');
});
it('links group pages to the batch containing them', () => {
const linker = createPDFLinker(
baseLinker,
[{ page: createDocumentPage('included', '') }],
createPublishedLinker(),
{ getBatchURL }
);
expect(
linker.toPathForPage({
pages: [createGroupPage('other-batch', 'group')],
page: createGroupPage('other-batch', 'group'),
})
).toBe('https://open-2v.gitbook.com/~gitbook/pdf?offset=20#page-other-batch');
});
});
describe('getPDFSearchParams', () => {
it('defaults to a small batch for subtree exports', () => {
expect(getPDFSearchParams(new URLSearchParams('page=abc&only=yes'))).toEqual({
page: 'abc',
only: true,
limit: PDF_SUBTREE_DEFAULT_LIMIT,
offset: 0,
});
expect(PDF_SUBTREE_DEFAULT_LIMIT).toBe(20);
});
it('keeps the larger default for whole-space and single-page exports', () => {
expect(getPDFSearchParams(new URLSearchParams('')).limit).toBe(PDF_DEFAULT_LIMIT);
expect(getPDFSearchParams(new URLSearchParams('page=abc')).limit).toBe(PDF_DEFAULT_LIMIT);
expect(PDF_DEFAULT_LIMIT).toBe(100);
});
it('parses an explicit limit and offset', () => {
const params = getPDFSearchParams(
new URLSearchParams('page=abc&only=yes&limit=5&offset=10')
);
expect(params.limit).toBe(5);
expect(params.offset).toBe(10);
});
it('ignores invalid limit and offset values', () => {
const params = getPDFSearchParams(
new URLSearchParams('page=abc&only=yes&limit=nope&offset=-3')
);
expect(params.limit).toBe(PDF_SUBTREE_DEFAULT_LIMIT);
expect(params.offset).toBe(0);
expect(getPDFSearchParams(new URLSearchParams('limit=0&offset=1.5'))).toMatchObject({
limit: PDF_DEFAULT_LIMIT,
offset: 0,
});
});
it('round-trips through getPDFURLSearchParams', () => {
const params = { page: 'abc', only: true, limit: 20, offset: 40, back: 'false' };
expect(getPDFSearchParams(getPDFURLSearchParams(params))).toEqual(params);
});
it('omits offset and limit when not set', () => {
expect(getPDFURLSearchParams({ page: 'abc', only: true }).toString()).toBe(
'page=abc&only=yes'
);
});
});
describe('selectPages', () => {
const children = Array.from({ length: 45 }, (_, index) =>
createDocumentPage(`child-${index}`, `child-${index}`)
);
const rootPages = [createDocumentPageWithChildren('root', children)];
const ids = (pages: { page: { id: string } }[] | undefined) =>
(pages ?? []).map(({ page }) => page.id);
const childIds = (from: number, to: number) => children.slice(from, to).map((page) => page.id);
it('renders the first batch of a subtree by default', () => {
const selection = selectPages(
rootPages,
getPDFSearchParams(new URLSearchParams('page=root&only=yes'))
);
expect(selection?.total).toBe(46);
expect(selection?.offset).toBe(0);
expect(ids(selection?.pages)).toEqual(['root', ...childIds(0, 19)]);
expect(selection?.allPages).toHaveLength(46);
});
it('slices the batch from offset to offset + limit', () => {
const selection = selectPages(rootPages, {
page: 'root',
only: true,
limit: 20,
offset: 20,
});
expect(selection?.offset).toBe(20);
expect(ids(selection?.pages)).toEqual(childIds(19, 39));
});
it('returns a shorter last batch', () => {
const selection = selectPages(rootPages, {
page: 'root',
only: true,
limit: 20,
offset: 40,
});
expect(ids(selection?.pages)).toEqual(childIds(39, 45));
});
it('falls back to the last batch when offset is past the end', () => {
const selection = selectPages(rootPages, {
page: 'root',
only: true,
limit: 20,
offset: 100,
});
expect(selection?.offset).toBe(26);
expect(selection?.pages).toHaveLength(20);
});
it('only selects the page itself without only', () => {
const selection = selectPages(rootPages, { page: 'root', limit: 100, offset: 0 });
expect(ids(selection?.pages)).toEqual(['root']);
expect(selection?.total).toBe(1);
});
it('returns null for an unknown page', () => {
expect(selectPages(rootPages, { page: 'missing', limit: 100, offset: 0 })).toBeNull();
});
});
+30 -73
View File
@@ -3,7 +3,6 @@ import { notFound } from 'next/navigation';
import * as React from 'react';
import {
type Revision,
type RevisionPageDocument,
type RevisionPageGroup,
type SiteCustomizationSettings,
@@ -16,7 +15,8 @@ import { ImagesLoadingStatus } from './ImagesLoadingStatus';
import { createPDFLinker, getPagePDFContainerId } from './linker';
import { PageControlButtons } from './PageControlButtons';
import { PDFPrintControls } from './PDFPrintControls';
import { type PDFSearchParams, getPDFSearchParams } from './urls';
import { selectPages } from './selectPages';
import { getPDFSearchParams, getPDFURLSearchParams } from './urls';
import { DocumentView } from '@/components/DocumentView';
import { Trademark } from '@/components/TableOfContents/Trademark';
import type { PolymorphicComponentProp } from '@/components/utils/types';
@@ -27,13 +27,10 @@ import type { GitBookSiteContext, GitBookSpaceContext } from '@/lib/context';
import { getPageDocument } from '@/lib/data';
import { type GitBookLinker, createLinker, linkerWithAbsoluteURLs } from '@/lib/links';
import './pdf.css';
import { resolvePageId } from '@/lib/pages';
import { getLinkerForSiteSpace } from '@/lib/sites';
import { tcls } from '@/lib/tailwind';
import { defaultCustomization } from '@/lib/utils';
const DEFAULT_LIMIT = 100;
/**
* Generate the metadata for the PDF page.
*/
@@ -62,13 +59,37 @@ export async function PDFPage(props: {
const language = await getSpaceLanguage(baseContext);
// Compute the pages to render
const { pages, total } = selectPages(baseContext.revision.pages, pdfParams);
const selection = selectPages(baseContext.revision.pages, pdfParams);
if (!selection) {
notFound();
}
const { pages, allPages, offset, total } = selection;
const batchParams = { ...pdfParams, offset };
const pageIds = pages.map(
({ page }) => [page.id, getPagePDFContainerId(page)] as [string, string]
);
// Build a linker that create anchor links for the pages rendered in the PDF page.
const linker = createPDFLinker(baseContext.linker, pages, getPublishedLinker(baseContext));
const pageIndexes = new Map(allPages.map(({ page }, index) => [page.id, index]));
const linker = createPDFLinker(baseContext.linker, pages, getPublishedLinker(baseContext), {
getBatchURL: (page) => {
const index = pageIndexes.get(page.id);
if (index === undefined) {
return undefined;
}
// Align on the current batch so these links match the previous/next controls.
const batchOffset = Math.max(
0,
offset + Math.floor((index - offset) / pdfParams.limit) * pdfParams.limit
);
return baseContext.linker.toAbsoluteURL(
baseContext.linker.toPathInSpace(
`~gitbook/pdf?${getPDFURLSearchParams({ ...pdfParams, offset: batchOffset }).toString()}`
)
);
},
});
const context: GitBookSpaceContext = {
...baseContext,
@@ -113,7 +134,7 @@ export async function PDFPage(props: {
</div>
<PageControlButtons
params={pdfParams}
params={batchParams}
pageIds={pageIds}
total={total}
trademark={
@@ -126,7 +147,7 @@ export async function PDFPage(props: {
}
/>
{pdfParams.only ? null : (
{pdfParams.only || offset > 0 ? null : (
<PDFSpaceIntro space={context.space} customization={customization} />
)}
{pages.map(({ page }) =>
@@ -273,67 +294,3 @@ function PrintPage(
</div>
);
}
type FlatPageEntry = { page: RevisionPageDocument | RevisionPageGroup; depth: number };
/**
* Compute the ordered flat set of pages to render.
*/
function selectPages(
rootPages: Revision['pages'],
params: PDFSearchParams
): { pages: FlatPageEntry[]; total: number } {
const flattenPage = (
page: RevisionPageDocument | RevisionPageGroup,
depth: number
): FlatPageEntry[] => {
return [
{ page, depth },
...page.pages.flatMap((child) => {
if (child.type !== 'document') {
return [];
}
if (child.hidden) {
return [];
}
return flattenPage(child, depth + 1);
}),
];
};
const limitTo = (entries: FlatPageEntry[]) => {
return {
// Apply a soft-limit, the limit can be controlled by the URL to allow testing
pages: entries.slice(0, params.limit ?? DEFAULT_LIMIT),
total: entries.length,
};
};
if (params.page) {
const found = resolvePageId(rootPages, params.page);
if (!found) {
notFound();
}
if (!params.only) {
return limitTo([{ page: found.page, depth: 0 }]);
}
return limitTo(flattenPage(found.page, 0));
}
const allPages = rootPages.flatMap((page) => {
if (page.type !== 'document' && page.type !== 'group') {
return [];
}
if (page.hidden) {
return [];
}
return flattenPage(page, 0);
});
return limitTo(allPages);
}
@@ -10,8 +10,6 @@ import { Button } from '@/components/primitives';
import { t, tString, useLanguage } from '@/intl/client';
import { tcls } from '@/lib/tailwind';
const limitExtend = 50;
/**
* Dynamic controls to show active page and to let the user select between modes.
*/
@@ -19,7 +17,7 @@ export function PageControlButtons(props: {
params: PDFSearchParams;
/** Array of the [pageId, divId] */
pageIds: [string, string][];
/** Total number of pages targetted by the generation */
/** Total number of pages targetted by the generation, across all batches */
total: number;
/** Trademark to display */
trademark?: React.ReactNode;
@@ -38,6 +36,10 @@ export function PageControlButtons(props: {
const activeIndex = (activeDivId ? divIds.indexOf(activeDivId) : 0) + 1;
const activePageId = pageIds[activeIndex - 1]?.[0];
const batchEnd = params.offset + pageIds.length;
const previousCount = Math.min(params.limit, params.offset);
const nextCount = Math.min(params.limit, total - batchEnd);
return (
<>
<div
@@ -58,6 +60,8 @@ export function PageControlButtons(props: {
...params,
page: activePageId,
only: true,
limit: undefined,
offset: undefined,
}).toString()}`}
variant="secondary"
label={tString(language, 'pdf_mode_only_page')}
@@ -68,6 +72,8 @@ export function PageControlButtons(props: {
...params,
page: undefined,
only: false,
limit: undefined,
offset: undefined,
}).toString()}`}
variant="secondary"
label={tString(language, 'pdf_mode_all')}
@@ -89,7 +95,7 @@ export function PageControlButtons(props: {
'z-50'
)}
>
{total !== pageIds.length ? (
{previousCount > 0 || nextCount > 0 ? (
<div
role="banner"
className={tcls(
@@ -112,19 +118,32 @@ export function PageControlButtons(props: {
className={tcls('size-6', 'mr-3', 'mt-1')}
/>{' '}
<div>
<div>{t(language, 'pdf_limit_reached', total, pageIds.length)}</div>
<div>
<a
href={`?${getPDFURLSearchParams({
...params,
page: undefined,
only: false,
limit: params.limit + limitExtend,
}).toString()}`}
className={tcls('underline')}
>
{t(language, 'pdf_limit_reached_continue', limitExtend)}
</a>
{t(language, 'pdf_batch_range', params.offset + 1, batchEnd, total)}
</div>
<div className={tcls('flex', 'flex-row', 'flex-wrap', 'gap-x-3')}>
{previousCount > 0 ? (
<a
href={`?${getPDFURLSearchParams({
...params,
offset: params.offset - previousCount,
}).toString()}`}
className={tcls('underline')}
>
{t(language, 'pdf_batch_previous', previousCount)}
</a>
) : null}
{nextCount > 0 ? (
<a
href={`?${getPDFURLSearchParams({
...params,
offset: batchEnd,
}).toString()}`}
className={tcls('underline')}
>
{t(language, 'pdf_batch_next', nextCount)}
</a>
) : null}
</div>
</div>
</div>
@@ -146,7 +165,7 @@ export function PageControlButtons(props: {
'border'
)}
>
{t(language, 'pdf_page_of', activeIndex, pageIds.length)}
{t(language, 'pdf_page_of', params.offset + activeIndex, total)}
</div>
</div>
</>
+21 -18
View File
@@ -20,36 +20,39 @@ export function getPagePDFContainerId(
/**
* Create a custom linker for PDF exports.
*
* This linker generates in-document anchor links for pages that are included
* in the current PDF export, using `getPagePDFContainerId` to build the
* target element ID. For pages that are not part of the exported PDF, it
* falls back to URLs pointing to the published site if `publishedLinker` is
* provided, preserving navigability for external content. Otherwise, it uses
* absolute URLs from the base linker.
*
* @param baseLinker - The base GitBook linker used to resolve standard paths and URLs.
* @param pages - The list of pages that are included in the current PDF export.
* @param publishedLinker - Optional linker for the published space for external page links.
* @returns A `GitBookLinker` configured to generate PDF-friendly links.
* Pages rendered in the current batch get in-document anchors. Other pages link to the
* published site when possible; pages exported in another batch otherwise link to that batch.
*/
export function createPDFLinker(
baseLinker: GitBookLinker,
pages: { page: Revision['pages'][number] }[],
publishedLinker?: GitBookLinker
publishedLinker?: GitBookLinker,
options: {
/** URL of the export batch rendering a page, for pages outside the current batch. */
getBatchURL?: (page: RevisionPageDocument | RevisionPageGroup) => string | undefined;
} = {}
): GitBookLinker {
const pageIds = new Set(pages.map((p) => p.page.id));
return {
...baseLinker,
toPathForPage(input) {
if (pages.some((p) => p.page.id === input.page.id)) {
if (pageIds.has(input.page.id)) {
return `#${getPagePDFContainerId(input.page, input.anchor)}`;
}
if (input.page.type === RevisionPageType.Group) {
return '#';
// A published page outlives the export URL, so prefer it for documents.
if (input.page.type !== RevisionPageType.Group && publishedLinker) {
return publishedLinker.toPathForPage(input);
}
// For pages that are not embedded in this PDF export, keep links on the published site.
if (publishedLinker) {
return publishedLinker.toPathForPage(input);
const batchURL = options.getBatchURL?.(input.page);
if (batchURL) {
return `${batchURL}#${getPagePDFContainerId(input.page, input.anchor)}`;
}
if (input.page.type === RevisionPageType.Group) {
return '#';
}
return baseLinker.toAbsoluteURL(baseLinker.toPathForPage(input));
@@ -0,0 +1,92 @@
import type { Revision, RevisionPageDocument, RevisionPageGroup } from '@gitbook/api';
import type { PDFSearchParams } from './urls';
import { resolvePageId } from '@/lib/pages';
export type FlatPageEntry = { page: RevisionPageDocument | RevisionPageGroup; depth: number };
export interface PDFPageSelection {
/** Pages rendered in the current batch */
pages: FlatPageEntry[];
/** Every page targeted by the export, across all batches */
allPages: FlatPageEntry[];
/** Index in `allPages` of the first page of the batch */
offset: number;
/** Total number of pages targeted by the export */
total: number;
}
/**
* Compute the ordered flat set of pages targeted by the export, and the batch to render.
* Returns `null` if the requested page doesn't exist.
*/
export function selectPages(
rootPages: Revision['pages'],
params: Pick<PDFSearchParams, 'page' | 'only' | 'limit' | 'offset'>
): PDFPageSelection | null {
const allPages = selectAllPages(rootPages, params);
if (!allPages) {
return null;
}
const total = allPages.length;
// Fall back to the last batch rather than rendering an empty one.
const offset = params.offset < total ? params.offset : Math.max(0, total - params.limit);
return {
pages: allPages.slice(offset, offset + params.limit),
allPages,
offset,
total,
};
}
function selectAllPages(
rootPages: Revision['pages'],
params: Pick<PDFSearchParams, 'page' | 'only'>
): FlatPageEntry[] | null {
if (params.page) {
const found = resolvePageId(rootPages, params.page);
if (!found) {
return null;
}
if (!params.only) {
return [{ page: found.page, depth: 0 }];
}
return flattenPage(found.page, 0);
}
return rootPages.flatMap((page) => {
if (page.type !== 'document' && page.type !== 'group') {
return [];
}
if (page.hidden) {
return [];
}
return flattenPage(page, 0);
});
}
function flattenPage(
page: RevisionPageDocument | RevisionPageGroup,
depth: number
): FlatPageEntry[] {
return [
{ page, depth },
...page.pages.flatMap((child) => {
if (child.type !== 'document') {
return [];
}
if (child.hidden) {
return [];
}
return flattenPage(child, depth + 1);
}),
];
}
+56 -12
View File
@@ -1,33 +1,61 @@
const DEFAULT_LIMIT = 100;
/** Default number of pages rendered per request when exporting the whole space. */
export const PDF_DEFAULT_LIMIT = 100;
/**
* Default number of pages rendered per request when exporting a page and its subtree.
* Subtrees are often OpenAPI references, which are much heavier to render than prose
* and get the request killed for CPU/memory at higher limits.
*/
export const PDF_SUBTREE_DEFAULT_LIMIT = 20;
export interface PDFSearchParams {
/** Page to export. If none is passed, all pages are exported. */
page?: string;
/** If true, only the `page` is exported, and not its descendant */
/** If true, the `page` is exported with its descendants */
only?: boolean;
/** Limit the number of pages */
/** Maximum number of pages to render in this batch */
limit: number;
/** Index of the first page to render in this batch */
offset: number;
/** URL to redirect back to */
back?: string;
}
/**
* Params accepted when building a PDF export URL. `limit` and `offset` fall back to the defaults.
*/
export type PDFURLParams = Omit<PDFSearchParams, 'limit' | 'offset'> & {
limit?: number;
offset?: number;
};
/**
* Default batch size for a given PDF export.
*/
export function getDefaultPDFLimit(params: Pick<PDFSearchParams, 'page' | 'only'>): number {
return params.page && params.only ? PDF_SUBTREE_DEFAULT_LIMIT : PDF_DEFAULT_LIMIT;
}
/**
* Get the PDF export params from the URL serch params.
*/
export function getPDFSearchParams(searchParams: URLSearchParams): PDFSearchParams {
const page = searchParams.has('page') ? (searchParams.get('page') ?? '') : undefined;
const only = searchParams.has('only') ? true : undefined;
const params: PDFSearchParams = {
limit: DEFAULT_LIMIT,
limit:
parseInteger(searchParams.get('limit'), { min: 1 }) ??
getDefaultPDFLimit({ page, only }),
offset: parseInteger(searchParams.get('offset'), { min: 0 }) ?? 0,
};
if (searchParams.has('page')) {
params.page = searchParams.get('page') ?? '';
if (page !== undefined) {
params.page = page;
}
if (searchParams.has('only')) {
if (only) {
params.only = true;
}
if (searchParams.has('limit')) {
params.limit = Number(searchParams.get('limit'));
}
if (searchParams.has('back')) {
params.back = searchParams.get('back') ?? '';
}
@@ -39,7 +67,7 @@ export function getPDFSearchParams(searchParams: URLSearchParams): PDFSearchPara
* Get the URL search params to use for a PDF export.
*/
export function getPDFURLSearchParams(
params: PDFSearchParams,
params: PDFURLParams,
searchParams = new URLSearchParams({})
): URLSearchParams {
if (params?.page) {
@@ -53,9 +81,16 @@ export function getPDFURLSearchParams(
searchParams.delete('only');
}
// Persist limit and back
// Persist limit, offset and back
if (params?.limit) {
searchParams.set('limit', String(params.limit));
} else {
searchParams.delete('limit');
}
if (params?.offset) {
searchParams.set('offset', String(params.offset));
} else {
searchParams.delete('offset');
}
if (params?.back) {
searchParams.set('back', String(params.back));
@@ -63,3 +98,12 @@ export function getPDFURLSearchParams(
return searchParams;
}
function parseInteger(value: string | null, options: { min: number }): number | undefined {
if (value === null || value.trim() === '') {
return undefined;
}
const parsed = Number(value);
return Number.isInteger(parsed) && parsed >= options.min ? parsed : undefined;
}
@@ -533,7 +533,6 @@ function getPageActionsURLs({
`~gitbook/pdf?${getPDFURLSearchParams({
page: page.id,
only: true,
limit: 100,
}).toString()}`
)
: undefined,
+3 -2
View File
@@ -96,8 +96,9 @@ export const ar: TranslationLanguage = {
pdf_page_of: '${1} من ${2}',
pdf_mode_only_page: 'هذه الصفحة فقط',
pdf_mode_all: 'كل الصفحات',
pdf_limit_reached: 'تعذر إنشاء ملف PDF لـ ${1} صفحات، وتوقف الإنشاء عند ${2}.',
pdf_limit_reached_continue: 'التوسيع بإضافة ${1} صفحات أخرى.',
pdf_batch_range: 'عرض الصفحات ${1}–${2} من ${3}.',
pdf_batch_previous: 'الصفحات الـ ${1} السابقة',
pdf_batch_next: 'الصفحات الـ ${1} التالية',
more: 'المزيد',
link_tooltip_external_link: 'رابط خارجي إلى',
link_tooltip_email: 'إرسال بريد إلكتروني إلى',
+3 -3
View File
@@ -99,9 +99,9 @@ export const bg: TranslationLanguage = {
pdf_page_of: '${1} от ${2}',
pdf_mode_only_page: 'Само тази страница',
pdf_mode_all: 'Всички страници',
pdf_limit_reached:
'PDF файлът за ${1} страници не можа да бъде генериран, генерирането спря на ${2}.',
pdf_limit_reached_continue: 'Разширяване с още ${1} страници.',
pdf_batch_range: 'Показани са страници ${1}–${2} от ${3}.',
pdf_batch_previous: 'Предишни ${1} страници',
pdf_batch_next: 'Следващи ${1} страници',
more: 'Още',
link_tooltip_external_link: 'Външна връзка към',
link_tooltip_email: 'Изпращане на имейл до',
+3 -3
View File
@@ -97,9 +97,9 @@ export const cs: TranslationLanguage = {
pdf_page_of: '${1} z ${2}',
pdf_mode_only_page: 'Pouze tato stránka',
pdf_mode_all: 'Všechny stránky',
pdf_limit_reached:
'Nepodařilo se vygenerovat PDF pro ${1} stránek, generování se zastavilo na ${2}.',
pdf_limit_reached_continue: 'Rozšířit o dalších ${1} stránek.',
pdf_batch_range: 'Zobrazeny stránky ${1}–${2} z ${3}.',
pdf_batch_previous: 'Předchozích ${1} stránek',
pdf_batch_next: 'Dalších ${1} stránek',
more: 'Více',
link_tooltip_external_link: 'Externí odkaz na',
link_tooltip_email: 'Odeslat e-mail na',
+3 -2
View File
@@ -97,8 +97,9 @@ export const da: TranslationLanguage = {
pdf_page_of: '${1} af ${2}',
pdf_mode_only_page: 'Kun denne side',
pdf_mode_all: 'Alle sider',
pdf_limit_reached: 'Kunne ikke generere PDF for ${1} sider, genereringen stoppede ved ${2}.',
pdf_limit_reached_continue: 'Udvid med ${1} flere sider.',
pdf_batch_range: 'Viser sider ${1}–${2} af ${3}.',
pdf_batch_previous: 'Forrige ${1} sider',
pdf_batch_next: 'Næste ${1} sider',
more: 'Mere',
link_tooltip_external_link: 'Eksternt link til',
link_tooltip_email: 'Send e-mail til',
+3 -3
View File
@@ -102,9 +102,9 @@ export const de: TranslationLanguage = {
pdf_page_of: '${1} von ${2}',
pdf_mode_only_page: 'Nur diese Seite',
pdf_mode_all: 'Alle Seiten',
pdf_limit_reached:
'Das PDF konnte für ${1} Seiten nicht generiert werden, Generierung wurde bei ${2} gestoppt.',
pdf_limit_reached_continue: 'Mit ${1} weiteren Seiten erweitern.',
pdf_batch_range: 'Seiten ${1}–${2} von ${3}.',
pdf_batch_previous: 'Vorherige ${1} Seiten',
pdf_batch_next: 'Nächste ${1} Seiten',
more: 'Mehr',
link_tooltip_external_link: 'Externer Link zu',
link_tooltip_email: 'E-Mail senden an',
+3 -3
View File
@@ -100,9 +100,9 @@ export const el: TranslationLanguage = {
pdf_page_of: '${1} από ${2}',
pdf_mode_only_page: 'Μόνο αυτή η σελίδα',
pdf_mode_all: 'Όλες οι σελίδες',
pdf_limit_reached:
'Δεν ήταν δυνατή η δημιουργία PDF για ${1} σελίδες, η δημιουργία σταμάτησε στο ${2}.',
pdf_limit_reached_continue: 'Επέκταση με ${1} ακόμη σελίδες.',
pdf_batch_range: 'Εμφάνιση σελίδων ${1}–${2} από ${3}.',
pdf_batch_previous: 'Προηγούμενες ${1} σελίδες',
pdf_batch_next: 'Επόμενες ${1} σελίδες',
more: 'Περισσότερα',
link_tooltip_external_link: 'Εξωτερικός σύνδεσμος προς',
link_tooltip_email: 'Αποστολή email σε',
+3 -2
View File
@@ -95,8 +95,9 @@ export const en = {
pdf_page_of: '${1} of ${2}',
pdf_mode_only_page: 'Only this page',
pdf_mode_all: 'All pages',
pdf_limit_reached: "Couldn't generate the PDF for ${1} pages, generation stopped at ${2}.",
pdf_limit_reached_continue: 'Extend with ${1} more pages.',
pdf_batch_range: 'Showing pages ${1}–${2} of ${3}.',
pdf_batch_previous: 'Previous ${1} pages',
pdf_batch_next: 'Next ${1} pages',
more: 'More',
link_tooltip_external_link: 'External link to',
link_tooltip_email: 'Send an email to',
+3 -3
View File
@@ -101,9 +101,9 @@ export const es: TranslationLanguage = {
pdf_page_of: '${1} de ${2}',
pdf_mode_only_page: 'Solo esta página',
pdf_mode_all: 'Todas las páginas',
pdf_limit_reached:
'No se pudo generar el PDF para ${1} páginas, la generación se detuvo en ${2}.',
pdf_limit_reached_continue: 'Extender con ${1} páginas más.',
pdf_batch_range: 'Mostrando las páginas ${1}–${2} de ${3}.',
pdf_batch_previous: '${1} páginas anteriores',
pdf_batch_next: '${1} páginas siguientes',
more: 'Más',
link_tooltip_external_link: 'Enlace externo a',
link_tooltip_email: 'Enviar un correo electrónico a',
+3 -2
View File
@@ -97,8 +97,9 @@ export const et: TranslationLanguage = {
pdf_page_of: '${1}/${2}',
pdf_mode_only_page: 'Ainult see leht',
pdf_mode_all: 'Kõik lehed',
pdf_limit_reached: 'PDF-i ei saanud luua ${1} lehe jaoks, loomine peatus kohas ${2}.',
pdf_limit_reached_continue: 'Laienda veel ${1} lehe võrra.',
pdf_batch_range: 'Kuvatakse lehti ${1}–${2}/${3}.',
pdf_batch_previous: 'Eelmised ${1} lehte',
pdf_batch_next: 'Järgmised ${1} lehte',
more: 'Rohkem',
link_tooltip_external_link: 'Väline link aadressile',
link_tooltip_email: 'Saada e-kiri aadressile',
+3 -2
View File
@@ -99,8 +99,9 @@ export const fi: TranslationLanguage = {
pdf_page_of: '${1}/${2}',
pdf_mode_only_page: 'Vain tämä sivu',
pdf_mode_all: 'Kaikki sivut',
pdf_limit_reached: 'PDF-tiedostoa ei voitu luoda ${1} sivulle, luonti pysähtyi kohtaan ${2}.',
pdf_limit_reached_continue: 'Laajenna ${1} sivulla.',
pdf_batch_range: 'Näytetään sivut ${1}–${2}/${3}.',
pdf_batch_previous: 'Edelliset ${1} sivua',
pdf_batch_next: 'Seuraavat ${1} sivua',
more: 'Lisää',
link_tooltip_external_link: 'Ulkoinen linkki kohteeseen',
link_tooltip_email: 'Lähetä sähköpostia osoitteeseen',
+3 -2
View File
@@ -98,8 +98,9 @@ export const fr: TranslationLanguage = {
pdf_page_of: '${1} sur ${2}',
pdf_mode_only_page: 'Cette page uniquement',
pdf_mode_all: 'Toutes les pages',
pdf_limit_reached: 'Impossible de générer le PDF pour ${1} pages, arrêté à ${2}.',
pdf_limit_reached_continue: 'Ajouter ${1} pages supplémentaires',
pdf_batch_range: 'Pages ${1} à ${2} sur ${3}.',
pdf_batch_previous: '${1} pages précédentes',
pdf_batch_next: '${1} pages suivantes',
more: 'Plus',
link_tooltip_external_link: 'Lien externe vers',
link_tooltip_email: 'Envoyer un e-mail à',
+3 -2
View File
@@ -96,8 +96,9 @@ export const he: TranslationLanguage = {
pdf_page_of: '${1} מתוך ${2}',
pdf_mode_only_page: 'רק הדף הזה',
pdf_mode_all: 'כל הדפים',
pdf_limit_reached: 'לא ניתן ליצור PDF עבור ${1} דפים, היצירה נעצרה ב-${2}.',
pdf_limit_reached_continue: 'הרחבה עם עוד ${1} דפים.',
pdf_batch_range: 'מוצגים דפים ${1}–${2} מתוך ${3}.',
pdf_batch_previous: '${1} הדפים הקודמים',
pdf_batch_next: '${1} הדפים הבאים',
more: 'עוד',
link_tooltip_external_link: 'קישור חיצוני אל',
link_tooltip_email: 'שליחת אימייל אל',
+3 -2
View File
@@ -96,8 +96,9 @@ export const hi: TranslationLanguage = {
pdf_page_of: '${1} में से ${2}',
pdf_mode_only_page: 'केवल यह पृष्ठ',
pdf_mode_all: 'सभी पृष्ठ',
pdf_limit_reached: '${1} पृष्ठों के लिए PDF नहीं बन सका, जनरेशन ${2} पर रुक गया।',
pdf_limit_reached_continue: '${1} और पृष्ठों के साथ बढ़ाएं।',
pdf_batch_range: '${3} में से पृष्ठ ${1}–${2} दिखाए जा रहे हैं।',
pdf_batch_previous: 'पिछले ${1} पृष्ठ',
pdf_batch_next: 'अगले ${1} पृष्ठ',
more: 'अधिक',
link_tooltip_external_link: 'बाहरी लिंक',
link_tooltip_email: 'ईमेल भेजें',
+3 -3
View File
@@ -97,9 +97,9 @@ export const hr: TranslationLanguage = {
pdf_page_of: '${1} od ${2}',
pdf_mode_only_page: 'Samo ova stranica',
pdf_mode_all: 'Sve stranice',
pdf_limit_reached:
'Nije moguće generirati PDF za ${1} stranica, generiranje je zaustavljeno na ${2}.',
pdf_limit_reached_continue: 'Proširi za još ${1} stranica.',
pdf_batch_range: 'Prikazane stranice ${1}–${2} od ${3}.',
pdf_batch_previous: 'Prethodnih ${1} stranica',
pdf_batch_next: 'Sljedećih ${1} stranica',
more: 'Više',
link_tooltip_external_link: 'Vanjska poveznica na',
link_tooltip_email: 'Pošalji e-poštu na',
+3 -3
View File
@@ -97,9 +97,9 @@ export const hu: TranslationLanguage = {
pdf_page_of: '${1} / ${2}',
pdf_mode_only_page: 'Csak ez az oldal',
pdf_mode_all: 'Minden oldal',
pdf_limit_reached:
'Nem sikerült PDF-et létrehozni ${1} oldalhoz, a létrehozás itt megállt: ${2}.',
pdf_limit_reached_continue: 'Bővítés további ${1} oldallal.',
pdf_batch_range: '${1}–${2}. oldal, összesen ${3}.',
pdf_batch_previous: 'Előző ${1} oldal',
pdf_batch_next: 'Következő ${1} oldal',
more: 'Továbbiak',
link_tooltip_external_link: 'Külső hivatkozás ide:',
link_tooltip_email: 'E-mail küldése ide:',
+3 -2
View File
@@ -97,8 +97,9 @@ export const id: TranslationLanguage = {
pdf_page_of: '${1} dari ${2}',
pdf_mode_only_page: 'Hanya halaman ini',
pdf_mode_all: 'Semua halaman',
pdf_limit_reached: 'Tidak dapat membuat PDF untuk ${1} halaman, pembuatan berhenti di ${2}.',
pdf_limit_reached_continue: 'Perluas dengan ${1} halaman lagi.',
pdf_batch_range: 'Menampilkan halaman ${1}–${2} dari ${3}.',
pdf_batch_previous: '${1} halaman sebelumnya',
pdf_batch_next: '${1} halaman berikutnya',
more: 'Lainnya',
link_tooltip_external_link: 'Tautan eksternal ke',
link_tooltip_email: 'Kirim email ke',
+3 -3
View File
@@ -100,9 +100,9 @@ export const it: TranslationLanguage = {
pdf_page_of: '${1} di ${2}',
pdf_mode_only_page: 'Solo questa pagina',
pdf_mode_all: 'Tutte le pagine',
pdf_limit_reached:
'Impossibile generare il PDF per ${1} pagine, la generazione si è fermata a ${2}.',
pdf_limit_reached_continue: 'Estendi con altre ${1} pagine.',
pdf_batch_range: 'Pagine ${1}–${2} di ${3}.',
pdf_batch_previous: '${1} pagine precedenti',
pdf_batch_next: '${1} pagine successive',
more: 'Altro',
link_tooltip_external_link: 'Link esterno a',
link_tooltip_email: "Invia un'email a",
+3 -2
View File
@@ -98,8 +98,9 @@ export const ja: TranslationLanguage = {
pdf_page_of: '${1} / ${2}',
pdf_mode_only_page: 'このページのみ',
pdf_mode_all: '全てのページ',
pdf_limit_reached: '${1}ページのPDFを生成できませんでした、${2}で生成が停止しました。',
pdf_limit_reached_continue: 'さらに${1}ページで拡張',
pdf_batch_range: '${3}ページ中 ${1}–${2}ページを表示しています。',
pdf_batch_previous: '前の${1}ページ',
pdf_batch_next: '次の${1}ページ',
more: 'もっと見る',
link_tooltip_external_link: '外部リンクへ',
link_tooltip_email: 'メールを送信',
+3 -2
View File
@@ -97,8 +97,9 @@ export const ko: TranslationLanguage = {
pdf_page_of: '${1} / ${2}',
pdf_mode_only_page: '이 페이지만',
pdf_mode_all: '모든 페이지',
pdf_limit_reached: '${1}페이지에 대한 PDF를 생성할 수 없어 ${2}에서 생성이 중지되었습니다.',
pdf_limit_reached_continue: '${1}페이지 더 확장하기.',
pdf_batch_range: '전체 ${3}페이지 중 ${1}–${2}페이지를 표시하고 있습니다.',
pdf_batch_previous: '이전 ${1}페이지',
pdf_batch_next: '다음 ${1}페이지',
more: '더 보기',
link_tooltip_external_link: '외부 링크',
link_tooltip_email: '이메일 보내기',
+3 -2
View File
@@ -98,8 +98,9 @@ export const lt: TranslationLanguage = {
pdf_page_of: '${1} iš ${2}',
pdf_mode_only_page: 'Tik šis puslapis',
pdf_mode_all: 'Visi puslapiai',
pdf_limit_reached: 'Nepavyko sugeneruoti PDF ${1} puslapiams, generavimas sustojo ties ${2}.',
pdf_limit_reached_continue: 'Išplėsti dar ${1} puslapiais.',
pdf_batch_range: 'Rodomi puslapiai ${1}–${2} iš ${3}.',
pdf_batch_previous: 'Ankstesni ${1} puslapiai',
pdf_batch_next: 'Kiti ${1} puslapiai',
more: 'Daugiau',
link_tooltip_external_link: 'Išorinė nuoroda į',
link_tooltip_email: 'Siųsti el. laišką į',
+3 -2
View File
@@ -96,8 +96,9 @@ export const lv: TranslationLanguage = {
pdf_page_of: '${1} no ${2}',
pdf_mode_only_page: 'Tikai šī lapa',
pdf_mode_all: 'Visas lapas',
pdf_limit_reached: 'Neizdevās ģenerēt PDF ${1} lapām, ģenerēšana apstājās pie ${2}.',
pdf_limit_reached_continue: 'Paplašināt ar vēl ${1} lapām.',
pdf_batch_range: 'Rāda lapas ${1}–${2} no ${3}.',
pdf_batch_previous: 'Iepriekšējās ${1} lapas',
pdf_batch_next: 'Nākamās ${1} lapas',
more: 'Vairāk',
link_tooltip_external_link: 'Ārēja saite uz',
link_tooltip_email: 'Sūtīt e-pastu uz',
+3 -2
View File
@@ -97,8 +97,9 @@ export const ms: TranslationLanguage = {
pdf_page_of: '${1} daripada ${2}',
pdf_mode_only_page: 'Halaman ini sahaja',
pdf_mode_all: 'Semua halaman',
pdf_limit_reached: 'Tidak dapat menjana PDF untuk ${1} halaman, penjanaan berhenti pada ${2}.',
pdf_limit_reached_continue: 'Lanjutkan dengan ${1} halaman lagi.',
pdf_batch_range: 'Memaparkan halaman ${1}–${2} daripada ${3}.',
pdf_batch_previous: '${1} halaman sebelumnya',
pdf_batch_next: '${1} halaman seterusnya',
more: 'Lagi',
link_tooltip_external_link: 'Pautan luaran ke',
link_tooltip_email: 'Hantar e-mel kepada',
+3 -2
View File
@@ -100,8 +100,9 @@ export const nl: TranslationLanguage = {
pdf_page_of: '${1} van ${2}',
pdf_mode_only_page: 'Alleen deze pagina',
pdf_mode_all: "Alle pagina's",
pdf_limit_reached: "Kon de PDF niet genereren voor ${1} pagina's, generatie gestopt bij ${2}.",
pdf_limit_reached_continue: "Verleng met ${1} extra pagina's.",
pdf_batch_range: "Pagina's ${1}–${2} van ${3}.",
pdf_batch_previous: "Vorige ${1} pagina's",
pdf_batch_next: "Volgende ${1} pagina's",
more: 'Meer',
link_tooltip_external_link: 'Externe link naar',
link_tooltip_email: 'E-mail versturen naar',
+3 -2
View File
@@ -99,8 +99,9 @@ export const no: TranslationLanguage = {
pdf_page_of: '${1} av ${2}',
pdf_mode_only_page: 'Kun denne siden',
pdf_mode_all: 'Alle sider',
pdf_limit_reached: 'Kunne ikke generere PDF for ${1} sider, generering stoppet ved ${2}.',
pdf_limit_reached_continue: 'Utvid med ${1} flere sider.',
pdf_batch_range: 'Viser sider ${1}–${2} av ${3}.',
pdf_batch_previous: 'Forrige ${1} sider',
pdf_batch_next: 'Neste ${1} sider',
more: 'Mer',
link_tooltip_external_link: 'Ekstern lenke til',
link_tooltip_email: 'Send e-post til',
+3 -3
View File
@@ -97,9 +97,9 @@ export const pl: TranslationLanguage = {
pdf_page_of: '${1} z ${2}',
pdf_mode_only_page: 'Tylko ta strona',
pdf_mode_all: 'Wszystkie strony',
pdf_limit_reached:
'Nie udało się wygenerować PDF dla ${1} stron, generowanie zatrzymało się na ${2}.',
pdf_limit_reached_continue: 'Rozszerz o kolejne ${1} stron.',
pdf_batch_range: 'Strony ${1}–${2} z ${3}.',
pdf_batch_previous: 'Poprzednie ${1} stron',
pdf_batch_next: 'Następne ${1} stron',
more: 'Więcej',
link_tooltip_external_link: 'Link zewnętrzny do',
link_tooltip_email: 'Wyślij e-mail do',
@@ -101,9 +101,9 @@ export const pt_br: TranslationLanguage = {
pdf_page_of: '${1} de ${2}',
pdf_mode_only_page: 'Somente esta página',
pdf_mode_all: 'Todas as páginas',
pdf_limit_reached:
'Não foi possível gerar o PDF para ${1} páginas, a geração foi interrompida em ${2}.',
pdf_limit_reached_continue: 'Estender com mais ${1} páginas.',
pdf_batch_range: 'Mostrando as páginas ${1}–${2} de ${3}.',
pdf_batch_previous: '${1} páginas anteriores',
pdf_batch_next: 'Próximas ${1} páginas',
more: 'Mais',
link_tooltip_external_link: 'Link externo para',
link_tooltip_email: 'Enviar e-mail para',
+3 -2
View File
@@ -99,8 +99,9 @@ export const pt: TranslationLanguage = {
pdf_page_of: '${1} de ${2}',
pdf_mode_only_page: 'Apenas esta página',
pdf_mode_all: 'Todas as páginas',
pdf_limit_reached: 'Não foi possível gerar o PDF para ${1} páginas; a geração parou em ${2}.',
pdf_limit_reached_continue: 'Expandir com mais ${1} páginas.',
pdf_batch_range: 'A mostrar as páginas ${1}–${2} de ${3}.',
pdf_batch_previous: '${1} páginas anteriores',
pdf_batch_next: '${1} páginas seguintes',
more: 'Mais',
link_tooltip_external_link: 'Ligação externa para',
link_tooltip_email: 'Enviar e-mail para',
+3 -3
View File
@@ -100,9 +100,9 @@ export const ro: TranslationLanguage = {
pdf_page_of: '${1} din ${2}',
pdf_mode_only_page: 'Doar această pagină',
pdf_mode_all: 'Toate paginile',
pdf_limit_reached:
'Nu s-a putut genera PDF-ul pentru ${1} pagini, generarea s-a oprit la ${2}.',
pdf_limit_reached_continue: 'Extinde cu încă ${1} pagini.',
pdf_batch_range: 'Se afișează paginile ${1}–${2} din ${3}.',
pdf_batch_previous: '${1} pagini anterioare',
pdf_batch_next: 'Următoarele ${1} pagini',
more: 'Mai multe',
link_tooltip_external_link: 'Link extern către',
link_tooltip_email: 'Trimite e-mail către',
+3 -3
View File
@@ -100,9 +100,9 @@ export const ru: TranslationLanguage = {
pdf_page_of: '${1} из ${2}',
pdf_mode_only_page: 'Только эта страница',
pdf_mode_all: 'Все страницы',
pdf_limit_reached:
'Не удалось создать PDF-файл для ${1} страниц, генерация остановлена на ${2}.',
pdf_limit_reached_continue: 'Расширьте ещё на ${1} страниц.',
pdf_batch_range: 'Страницы ${1}–${2} из ${3}.',
pdf_batch_previous: 'Предыдущие ${1} страниц',
pdf_batch_next: 'Следующие ${1} страниц',
more: 'Ещё',
link_tooltip_external_link: 'Внешняя ссылка на',
link_tooltip_email: 'Отправить письмо на',
+3 -3
View File
@@ -99,9 +99,9 @@ export const sk: TranslationLanguage = {
pdf_page_of: '${1} z ${2}',
pdf_mode_only_page: 'Iba táto stránka',
pdf_mode_all: 'Všetky stránky',
pdf_limit_reached:
'Nepodarilo sa vygenerovať PDF pre ${1} stránok, generovanie sa zastavilo na ${2}.',
pdf_limit_reached_continue: 'Rozšíriť o ďalších ${1} stránok.',
pdf_batch_range: 'Zobrazené stránky ${1}–${2} z ${3}.',
pdf_batch_previous: 'Predchádzajúcich ${1} stránok',
pdf_batch_next: 'Ďalších ${1} stránok',
more: 'Viac',
link_tooltip_external_link: 'Externý odkaz na',
link_tooltip_email: 'Odoslať e-mail na',
+3 -3
View File
@@ -97,9 +97,9 @@ export const sl: TranslationLanguage = {
pdf_page_of: '${1} od ${2}',
pdf_mode_only_page: 'Samo ta stran',
pdf_mode_all: 'Vse strani',
pdf_limit_reached:
'PDF-ja ni bilo mogoče ustvariti za ${1} strani, ustvarjanje se je ustavilo pri ${2}.',
pdf_limit_reached_continue: 'Razširi še za ${1} strani.',
pdf_batch_range: 'Prikazane strani ${1}–${2} od ${3}.',
pdf_batch_previous: 'Prejšnjih ${1} strani',
pdf_batch_next: 'Naslednjih ${1} strani',
more: 'Več',
link_tooltip_external_link: 'Zunanja povezava do',
link_tooltip_email: 'Pošlji e-pošto na',
+3 -3
View File
@@ -97,9 +97,9 @@ export const sv: TranslationLanguage = {
pdf_page_of: '${1} av ${2}',
pdf_mode_only_page: 'Endast denna sida',
pdf_mode_all: 'Alla sidor',
pdf_limit_reached:
'Det gick inte att generera PDF för ${1} sidor, genereringen stoppades vid ${2}.',
pdf_limit_reached_continue: 'Utöka med ytterligare ${1} sidor.',
pdf_batch_range: 'Visar sidorna ${1}–${2} av ${3}.',
pdf_batch_previous: 'Föregående ${1} sidor',
pdf_batch_next: 'Nästa ${1} sidor',
more: 'Mer',
link_tooltip_external_link: 'Extern länk till',
link_tooltip_email: 'Skicka e-post till',
+3 -2
View File
@@ -95,8 +95,9 @@ export const th: TranslationLanguage = {
pdf_page_of: '${1} จาก ${2}',
pdf_mode_only_page: 'เฉพาะหน้านี้',
pdf_mode_all: 'ทุกหน้า',
pdf_limit_reached: 'ไม่สามารถสร้าง PDF สำหรับ ${1} หน้าได้ การสร้างหยุดที่ ${2}',
pdf_limit_reached_continue: 'ขยายอีก ${1} หน้า',
pdf_batch_range: 'แสดงหน้า ${1}–${2} จาก ${3}',
pdf_batch_previous: '${1} หน้าก่อนหน้า',
pdf_batch_next: '${1} หน้าถัดไป',
more: 'เพิ่มเติม',
link_tooltip_external_link: 'ลิงก์ภายนอกไปยัง',
link_tooltip_email: 'ส่งอีเมลไปยัง',
+3 -2
View File
@@ -96,8 +96,9 @@ export const tr: TranslationLanguage = {
pdf_page_of: '${1} / ${2}',
pdf_mode_only_page: 'Yalnızca bu sayfa',
pdf_mode_all: 'Tüm sayfalar',
pdf_limit_reached: '${1} sayfa için PDF oluşturulamadı, oluşturma ${2} konumunda durdu.',
pdf_limit_reached_continue: '${1} sayfa daha ekleyerek genişlet.',
pdf_batch_range: '${3} sayfadan ${1}–${2} arası gösteriliyor.',
pdf_batch_previous: 'Önceki ${1} sayfa',
pdf_batch_next: 'Sonraki ${1} sayfa',
more: 'Daha fazla',
link_tooltip_external_link: 'Harici bağlantı',
link_tooltip_email: 'E-posta gönder',
+3 -2
View File
@@ -96,8 +96,9 @@ export const uk: TranslationLanguage = {
pdf_page_of: '${1} з ${2}',
pdf_mode_only_page: 'Лише ця сторінка',
pdf_mode_all: 'Усі сторінки',
pdf_limit_reached: 'Не вдалося створити PDF для ${1} сторінок, створення зупинилося на ${2}.',
pdf_limit_reached_continue: 'Розширити ще на ${1} сторінок.',
pdf_batch_range: 'Сторінки ${1}–${2} з ${3}.',
pdf_batch_previous: 'Попередні ${1} сторінок',
pdf_batch_next: 'Наступні ${1} сторінок',
more: 'Більше',
link_tooltip_external_link: 'Зовнішнє посилання на',
link_tooltip_email: 'Надіслати електронний лист на',
+3 -2
View File
@@ -96,8 +96,9 @@ export const vi: TranslationLanguage = {
pdf_page_of: '${1} trên ${2}',
pdf_mode_only_page: 'Chỉ trang này',
pdf_mode_all: 'Tất cả trang',
pdf_limit_reached: 'Không thể tạo PDF cho ${1} trang, quá trình tạo đã dừng tại ${2}.',
pdf_limit_reached_continue: 'Mở rộng thêm ${1} trang.',
pdf_batch_range: 'Đang hiển thị trang ${1}–${2} trên ${3}.',
pdf_batch_previous: '${1} trang trước',
pdf_batch_next: '${1} trang tiếp theo',
more: 'Thêm',
link_tooltip_external_link: 'Liên kết ngoài tới',
link_tooltip_email: 'Gửi email tới',
@@ -94,8 +94,9 @@ export const yue: TranslationLanguage = {
pdf_page_of: '${1} / ${2}',
pdf_mode_only_page: '只限呢頁',
pdf_mode_all: '所有頁面',
pdf_limit_reached: '無法為 ${1} 頁產生 PDF,已喺 ${2} 停止。',
pdf_limit_reached_continue: '再加 ${1} 頁。',
pdf_batch_range: '而家顯示緊第 ${1}–${2} 頁,總共 ${3} 頁。',
pdf_batch_previous: '上 ${1} 頁',
pdf_batch_next: '下 ${1} 頁',
more: '更多',
link_tooltip_external_link: '外部連結到',
link_tooltip_email: '傳送電郵到',
@@ -94,8 +94,9 @@ export const zh_tw: TranslationLanguage = {
pdf_page_of: '${1} / ${2}',
pdf_mode_only_page: '僅此頁面',
pdf_mode_all: '所有頁面',
pdf_limit_reached: '無法為 ${1} 頁產生 PDF,已在 ${2} 停止產生。',
pdf_limit_reached_continue: '再擴展 ${1} 頁。',
pdf_batch_range: '正在顯示第 ${1}–${2} 頁,共 ${3} 頁。',
pdf_batch_previous: '上 ${1} 頁',
pdf_batch_next: '下 ${1} 頁',
more: '更多',
link_tooltip_external_link: '外部連結至',
link_tooltip_email: '傳送電子郵件至',
+3 -2
View File
@@ -95,8 +95,9 @@ export const zh: TranslationLanguage = {
pdf_page_of: '${1} / ${2}',
pdf_mode_only_page: '仅本页',
pdf_mode_all: '所有页面',
pdf_limit_reached: '无法为 ${1} 页生成 PDF,生成在 ${2} 页时停止。',
pdf_limit_reached_continue: '再扩展 ${1} 页。',
pdf_batch_range: '正在显示第 ${1}–${2} 页,共 ${3} 页。',
pdf_batch_previous: '上 ${1} 页',
pdf_batch_next: '下 ${1} 页',
more: '更多',
link_tooltip_external_link: '外部链接到',
link_tooltip_email: '发送邮件到',