mirror of
https://github.com/jzillmann/pdf-to-markdown.git
synced 2025-02-18 10:50:47 +01:00
Show page labels + default mapping to 1
This commit is contained in:
parent
98972d67a8
commit
71ef84153c
@ -2,7 +2,7 @@
|
|||||||
* Holds the information which (zero based) page index maps to a page number.
|
* Holds the information which (zero based) page index maps to a page number.
|
||||||
*/
|
*/
|
||||||
export default class PageMapping {
|
export default class PageMapping {
|
||||||
constructor(public pageFactor: number, public detectedOnPage: boolean) {}
|
constructor(public pageFactor: number = 1, public detectedOnPage: boolean = false) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Translates a given page index to a page number label as printed on the page. E.g [0,1,2,3,4] could become [I, II, 1, 2].
|
* Translates a given page index to a page number label as printed on the page. E.g [0,1,2,3,4] could become [I, II, 1, 2].
|
||||||
@ -10,10 +10,14 @@ export default class PageMapping {
|
|||||||
*/
|
*/
|
||||||
pageLabel(pageIndex: number) {
|
pageLabel(pageIndex: number) {
|
||||||
const pageNumber = pageIndex + this.pageFactor;
|
const pageNumber = pageIndex + this.pageFactor;
|
||||||
if (pageNumber < 0) {
|
if (pageNumber < 1) {
|
||||||
return romanize(pageNumber - this.pageFactor + 1);
|
return romanize(Math.abs(pageNumber - this.pageFactor) + 1);
|
||||||
}
|
}
|
||||||
return `${pageNumber + 1}`;
|
return `${pageNumber}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
shifted(): boolean {
|
||||||
|
return this.pageFactor != 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,7 +73,6 @@ export default class CalculateStatistics extends ItemTransformer {
|
|||||||
|
|
||||||
const groupedByPage = groupByPage(items);
|
const groupedByPage = groupByPage(items);
|
||||||
const pageMapping = parsePageMapping(groupedByPage, minX, maxX, minY, maxY);
|
const pageMapping = parsePageMapping(groupedByPage, minX, maxX, minY, maxY);
|
||||||
console.log(pageMapping);
|
|
||||||
|
|
||||||
// Parse line distances
|
// Parse line distances
|
||||||
const distanceToOccurrence = {};
|
const distanceToOccurrence = {};
|
||||||
@ -165,7 +164,7 @@ function parsePageMapping(
|
|||||||
}),
|
}),
|
||||||
{ sampleCount: 20, minFulfillment: 0.8 },
|
{ sampleCount: 20, minFulfillment: 0.8 },
|
||||||
);
|
);
|
||||||
return typeof pageFactor === 'undefined' ? new PageMapping(0, false) : new PageMapping(pageFactor, true);
|
return typeof pageFactor === 'undefined' ? new PageMapping() : new PageMapping(pageFactor, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getMostUsedKey(keyToOccurrence): any {
|
function getMostUsedKey(keyToOccurrence): any {
|
||||||
|
@ -25,6 +25,10 @@ export default class Globals {
|
|||||||
return element;
|
return element;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getOptional<T>(definition: GlobalDefinition<T>): T | undefined {
|
||||||
|
return this.map.get(definition.key) as T;
|
||||||
|
}
|
||||||
|
|
||||||
set<T>(definition: GlobalDefinition<T>, value: T) {
|
set<T>(definition: GlobalDefinition<T>, value: T) {
|
||||||
assertNot(this.isDefined(definition), `Global with key '${definition.key}' already registered.`);
|
assertNot(this.isDefined(definition), `Global with key '${definition.key}' already registered.`);
|
||||||
this.map.set(definition.key, value);
|
this.map.set(definition.key, value);
|
||||||
|
@ -1,12 +1,17 @@
|
|||||||
import PageMapping from 'src/PageMapping';
|
import PageMapping from 'src/PageMapping';
|
||||||
|
|
||||||
test('1-to-1', async () => {
|
test('1-to-1', async () => {
|
||||||
const mapping = new PageMapping(0, false);
|
const mapping = new PageMapping(1, false);
|
||||||
expect(mapping.pageFactor).toEqual(0);
|
expect(mapping.pageFactor).toEqual(1);
|
||||||
expect([...Array(3).keys()].map((i) => mapping.pageLabel(i))).toEqual(['1', '2', '3']);
|
expect([...Array(3).keys()].map((i) => mapping.pageLabel(i))).toEqual(['1', '2', '3']);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('lame start', async () => {
|
test('one starter page', async () => {
|
||||||
const mapping = new PageMapping(-3, true);
|
const mapping = new PageMapping(0, true);
|
||||||
|
expect([...Array(5).keys()].map((i) => mapping.pageLabel(i))).toEqual(['I', '1', '2', '3', '4']);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('three starter pages', async () => {
|
||||||
|
const mapping = new PageMapping(-2, true);
|
||||||
expect([...Array(5).keys()].map((i) => mapping.pageLabel(i))).toEqual(['I', 'II', 'III', '1', '2']);
|
expect([...Array(5).keys()].map((i) => mapping.pageLabel(i))).toEqual(['I', 'II', 'III', '1', '2']);
|
||||||
});
|
});
|
||||||
|
@ -8,6 +8,7 @@ test('not set', async () => {
|
|||||||
const globals = new Globals();
|
const globals = new Globals();
|
||||||
globals.set(MyGlobalString, '23');
|
globals.set(MyGlobalString, '23');
|
||||||
expect(globals.isDefined(MyGlobalNumber)).toBeFalsy();
|
expect(globals.isDefined(MyGlobalNumber)).toBeFalsy();
|
||||||
|
expect(globals.getOptional(MyGlobalNumber)).toBeUndefined();
|
||||||
expect(() => globals.get(MyGlobalNumber)).toThrow(
|
expect(() => globals.get(MyGlobalNumber)).toThrow(
|
||||||
`No global with key '${MyGlobalNumber.key}' registered. Only [${MyGlobalString.key}]`,
|
`No global with key '${MyGlobalNumber.key}' registered. Only [${MyGlobalString.key}]`,
|
||||||
);
|
);
|
||||||
@ -19,6 +20,7 @@ test('set', async () => {
|
|||||||
|
|
||||||
expect(globals.isDefined(MyGlobalNumber)).toBeTruthy();
|
expect(globals.isDefined(MyGlobalNumber)).toBeTruthy();
|
||||||
expect(globals.get(MyGlobalNumber)).toEqual(24);
|
expect(globals.get(MyGlobalNumber)).toEqual(24);
|
||||||
|
expect(globals.getOptional(MyGlobalNumber)).toEqual(24);
|
||||||
expect(globals.keys()).toEqual([MyGlobalNumber.key]);
|
expect(globals.keys()).toEqual([MyGlobalNumber.key]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -33,7 +33,7 @@
|
|||||||
"minY": 36.1763,
|
"minY": 36.1763,
|
||||||
"maxY": 811.1348,
|
"maxY": 811.1348,
|
||||||
"pageMapping": {
|
"pageMapping": {
|
||||||
"pageFactor": 0,
|
"pageFactor": 1,
|
||||||
"detectedOnPage": false
|
"detectedOnPage": false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -37,7 +37,7 @@
|
|||||||
"minY": 36.1763,
|
"minY": 36.1763,
|
||||||
"maxY": 811.1348,
|
"maxY": 811.1348,
|
||||||
"pageMapping": {
|
"pageMapping": {
|
||||||
"pageFactor": 0,
|
"pageFactor": 1,
|
||||||
"detectedOnPage": false
|
"detectedOnPage": false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -36,7 +36,7 @@
|
|||||||
"minY": 36.1763,
|
"minY": 36.1763,
|
||||||
"maxY": 811.1348,
|
"maxY": 811.1348,
|
||||||
"pageMapping": {
|
"pageMapping": {
|
||||||
"pageFactor": 0,
|
"pageFactor": 1,
|
||||||
"detectedOnPage": false
|
"detectedOnPage": false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -36,7 +36,7 @@
|
|||||||
"minY": 36.1763,
|
"minY": 36.1763,
|
||||||
"maxY": 811.1348,
|
"maxY": 811.1348,
|
||||||
"pageMapping": {
|
"pageMapping": {
|
||||||
"pageFactor": 0,
|
"pageFactor": 1,
|
||||||
"detectedOnPage": false
|
"detectedOnPage": false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -33,7 +33,7 @@
|
|||||||
"minY": 75.60000000000002,
|
"minY": 75.60000000000002,
|
||||||
"maxY": 712.8,
|
"maxY": 712.8,
|
||||||
"pageMapping": {
|
"pageMapping": {
|
||||||
"pageFactor": 0,
|
"pageFactor": 1,
|
||||||
"detectedOnPage": false
|
"detectedOnPage": false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -37,7 +37,7 @@
|
|||||||
"minY": 75.60000000000002,
|
"minY": 75.60000000000002,
|
||||||
"maxY": 712.8,
|
"maxY": 712.8,
|
||||||
"pageMapping": {
|
"pageMapping": {
|
||||||
"pageFactor": 0,
|
"pageFactor": 1,
|
||||||
"detectedOnPage": false
|
"detectedOnPage": false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -36,7 +36,7 @@
|
|||||||
"minY": 75.60000000000002,
|
"minY": 75.60000000000002,
|
||||||
"maxY": 712.8,
|
"maxY": 712.8,
|
||||||
"pageMapping": {
|
"pageMapping": {
|
||||||
"pageFactor": 0,
|
"pageFactor": 1,
|
||||||
"detectedOnPage": false
|
"detectedOnPage": false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -36,7 +36,7 @@
|
|||||||
"minY": 75.60000000000002,
|
"minY": 75.60000000000002,
|
||||||
"maxY": 712.8,
|
"maxY": 712.8,
|
||||||
"pageMapping": {
|
"pageMapping": {
|
||||||
"pageFactor": 0,
|
"pageFactor": 1,
|
||||||
"detectedOnPage": false
|
"detectedOnPage": false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -33,7 +33,7 @@
|
|||||||
"minY": 75.025,
|
"minY": 75.025,
|
||||||
"maxY": 747.22,
|
"maxY": 747.22,
|
||||||
"pageMapping": {
|
"pageMapping": {
|
||||||
"pageFactor": 0,
|
"pageFactor": 1,
|
||||||
"detectedOnPage": false
|
"detectedOnPage": false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -37,7 +37,7 @@
|
|||||||
"minY": 75.025,
|
"minY": 75.025,
|
||||||
"maxY": 747.22,
|
"maxY": 747.22,
|
||||||
"pageMapping": {
|
"pageMapping": {
|
||||||
"pageFactor": 0,
|
"pageFactor": 1,
|
||||||
"detectedOnPage": false
|
"detectedOnPage": false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -36,7 +36,7 @@
|
|||||||
"minY": 75.025,
|
"minY": 75.025,
|
||||||
"maxY": 747.22,
|
"maxY": 747.22,
|
||||||
"pageMapping": {
|
"pageMapping": {
|
||||||
"pageFactor": 0,
|
"pageFactor": 1,
|
||||||
"detectedOnPage": false
|
"detectedOnPage": false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -36,7 +36,7 @@
|
|||||||
"minY": 75.025,
|
"minY": 75.025,
|
||||||
"maxY": 747.22,
|
"maxY": 747.22,
|
||||||
"pageMapping": {
|
"pageMapping": {
|
||||||
"pageFactor": 0,
|
"pageFactor": 1,
|
||||||
"detectedOnPage": false
|
"detectedOnPage": false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -36,7 +36,7 @@
|
|||||||
"minY": 68.44329999999982,
|
"minY": 68.44329999999982,
|
||||||
"maxY": 713.7734000000003,
|
"maxY": 713.7734000000003,
|
||||||
"pageMapping": {
|
"pageMapping": {
|
||||||
"pageFactor": 0,
|
"pageFactor": 1,
|
||||||
"detectedOnPage": false
|
"detectedOnPage": false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
export let pageControl: PageControl;
|
export let pageControl: PageControl;
|
||||||
export let pageIndex: number;
|
export let pageIndex: number;
|
||||||
|
|
||||||
let { pagePinned, canPrev, canNext } = pageControl;
|
let { pagePinned, canPrev, canNext, pageMapping } = pageControl;
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="flex items-center space-x-1">
|
<div class="flex items-center space-x-1">
|
||||||
@ -20,7 +20,13 @@
|
|||||||
<Icon class="text-xs hover:text-select hover:opacity-25 cursor-pointer opacity-75" icon={pin} />
|
<Icon class="text-xs hover:text-select hover:opacity-25 cursor-pointer opacity-75" icon={pin} />
|
||||||
</span>
|
</span>
|
||||||
{/if}
|
{/if}
|
||||||
<div>Page {pageIndex + 1} {$pagePinned ? '' : ' / ' + pageControl.totalPages}</div>
|
<div>
|
||||||
|
Page
|
||||||
|
{$pageMapping.pageLabel(pageIndex)}
|
||||||
|
{#if $pageMapping.shifted()}
|
||||||
|
<span class="font-light"> ({pageIndex + 1}/{pageControl.totalPages}) </span>
|
||||||
|
{:else}/ {pageControl.totalPages + $pageMapping.pageFactor - 1}{/if}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{#if $pagePinned}
|
{#if $pagePinned}
|
||||||
<div class="absolute flex ml-4 space-x-2">
|
<div class="absolute flex ml-4 space-x-2">
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
import { flip } from 'svelte/animate';
|
import { flip } from 'svelte/animate';
|
||||||
|
|
||||||
import type Debugger from '@core/Debugger';
|
import type Debugger from '@core/Debugger';
|
||||||
|
import { PAGE_MAPPING } from '../../../core/src/transformer/CacluclateStatistics';
|
||||||
|
|
||||||
import { debugStage } from '../config';
|
import { debugStage } from '../config';
|
||||||
import ControlBar from './ControlBar.svelte';
|
import ControlBar from './ControlBar.svelte';
|
||||||
@ -19,6 +20,7 @@
|
|||||||
let onlyRelevantItems = true;
|
let onlyRelevantItems = true;
|
||||||
|
|
||||||
$: stageResult = debug.stageResult($debugStage);
|
$: stageResult = debug.stageResult($debugStage);
|
||||||
|
$: pageControl.updateMapping(stageResult.globals.getOptional(PAGE_MAPPING));
|
||||||
$: supportsGrouping = !!stageResult.descriptor?.debug?.itemMerger;
|
$: supportsGrouping = !!stageResult.descriptor?.debug?.itemMerger;
|
||||||
$: supportsRelevanceFiltering = !stageResult.descriptor?.debug?.showAll;
|
$: supportsRelevanceFiltering = !stageResult.descriptor?.debug?.showAll;
|
||||||
$: visiblePages = pageControl.selectPages(stageResult, onlyRelevantItems, groupingEnabled, $pinnedPageIndex);
|
$: visiblePages = pageControl.selectPages(stageResult, onlyRelevantItems, groupingEnabled, $pinnedPageIndex);
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import Page from '@core/debug/Page';
|
|
||||||
import StageResult from '@core/debug/StageResult';
|
import StageResult from '@core/debug/StageResult';
|
||||||
|
import PageMapping from '../../../core/src/PageMapping';
|
||||||
import { Writable, writable, get, Readable, derived } from 'svelte/store';
|
import { Writable, writable, get, Readable, derived } from 'svelte/store';
|
||||||
|
|
||||||
export default class PageControl {
|
export default class PageControl {
|
||||||
@ -8,6 +8,7 @@ export default class PageControl {
|
|||||||
canPrev: Readable<boolean>;
|
canPrev: Readable<boolean>;
|
||||||
canNext: Readable<boolean>;
|
canNext: Readable<boolean>;
|
||||||
pagesWithItems: Set<number> = new Set();
|
pagesWithItems: Set<number> = new Set();
|
||||||
|
pageMapping: Writable<PageMapping> = writable(new PageMapping());
|
||||||
|
|
||||||
constructor(public totalPages: number) {
|
constructor(public totalPages: number) {
|
||||||
this.pinnedPageIndex = writable(undefined);
|
this.pinnedPageIndex = writable(undefined);
|
||||||
@ -22,6 +23,12 @@ export default class PageControl {
|
|||||||
this.unpinPage.bind(this);
|
this.unpinPage.bind(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
updateMapping(pageMapping: PageMapping | undefined) {
|
||||||
|
if (pageMapping) {
|
||||||
|
this.pageMapping.set(pageMapping);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
selectPages(stageResult: StageResult, relevantChangesOnly: boolean, groupItems: boolean, pinnedPage?: number) {
|
selectPages(stageResult: StageResult, relevantChangesOnly: boolean, groupItems: boolean, pinnedPage?: number) {
|
||||||
const allRelevantPages = stageResult.selectPages(relevantChangesOnly, groupItems);
|
const allRelevantPages = stageResult.selectPages(relevantChangesOnly, groupItems);
|
||||||
this.pagesWithItems = new Set(
|
this.pagesWithItems = new Set(
|
||||||
|
@ -8,7 +8,8 @@
|
|||||||
|
|
||||||
export let pageControl: PageControl;
|
export let pageControl: PageControl;
|
||||||
|
|
||||||
let { pinnedPageIndex, pagePinned } = pageControl;
|
let { pinnedPageIndex, pagePinned, pageMapping } = pageControl;
|
||||||
|
let showIndex = false;
|
||||||
|
|
||||||
const popupOpened: Writable<boolean> = getContext('popupOpened');
|
const popupOpened: Writable<boolean> = getContext('popupOpened');
|
||||||
|
|
||||||
@ -34,7 +35,7 @@
|
|||||||
<div
|
<div
|
||||||
on:click={() => pageControl.pageHasItems(idx) && pinPage(idx)}
|
on:click={() => pageControl.pageHasItems(idx) && pinPage(idx)}
|
||||||
class="px-2 border border-gray-300 rounded-full text-center {pageControl.pageHasItems(idx) ? ($pinnedPageIndex === idx ? 'bg-select' : 'hover:text-select hover:border-select cursor-pointer') : 'opacity-50'}">
|
class="px-2 border border-gray-300 rounded-full text-center {pageControl.pageHasItems(idx) ? ($pinnedPageIndex === idx ? 'bg-select' : 'hover:text-select hover:border-select cursor-pointer') : 'opacity-50'}">
|
||||||
{idx + 1}
|
{#if showIndex}{idx}{:else}{$pageMapping.pageLabel(idx)}{/if}
|
||||||
</div>
|
</div>
|
||||||
{/each}
|
{/each}
|
||||||
</div>
|
</div>
|
||||||
|
Loading…
Reference in New Issue
Block a user