Skip to content
Draft
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
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
*~

# Core
core/node_modules
viewer.js.map

# Byte-compiled / optimized / DLL files
__pycache__/
*.py[codz]
Expand Down
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,11 @@ Open [http://localhost:8080/](http://localhost:8080/) and click **Load demo**.
| **Open file** | Select a `.dclx` archive, or a standalone `.dclg` / `.xml` markup file. |
| **Drag and drop** | Drop any supported file onto the page. |

Supported types: `.dclx`, `.dclg`, `.xml`. The demo URL is configured in [`demo-data.js`](demo-data.js).
Supported types: `.dclx`, `.dclg`, `.xml`. The demo/example URL is configured via the `example` attribute on the `<doclang-viewer>` element in [`index.html`](index.html).

## Files

- `demo-data.js` — demo archive URL
- `index.html` — shell UI
- `viewer.js` — parsing, page alignment, bbox overlay
- `viewer.css` — layout and theme
- `index.html` — shell page; loads `viewer.js`
- `viewer.js` — standalone ESM bundle (lit inlined); tracked in git for CDN / script-tag use
- `core/dist/` — npm library build (lit external, tree-shakeable); gitignored
- `core/` — TypeScript source; run `npm run build` inside to rebuild
Binary file added assets/icon-1024.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/icon-192.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/icon-512.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 2 additions & 0 deletions core/.prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
dist/
node_modules/
11 changes: 11 additions & 0 deletions core/.prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"arrowParens": "avoid",
"bracketSpacing": true,
"printWidth": 88,
"quoteProps": "as-needed",
"semi": true,
"singleQuote": true,
"tabWidth": 2,
"trailingComma": "es5",
"useTabs": false
}
20 changes: 20 additions & 0 deletions core/eslint.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// @ts-check

import eslint from '@eslint/js';
import globals from 'globals';
import tseslint from 'typescript-eslint';

export default tseslint.config(
{
ignores: ['dist', 'node_modules'],
},
eslint.configs.recommended,
...tseslint.configs.recommended,
{
languageOptions: {
globals: {
...globals.browser,
},
},
}
);
28 changes: 28 additions & 0 deletions core/examples/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# DocLang Viewer — component examples

Isolated examples for the larger content-rendering components. Each page loads the demo archive via the `src` attribute — no build step required.

## Individual panes

| Example | Component | Description |
|---------|-----------|-------------|
| [markup-pane.html](markup-pane.html) | `<doclang-markup-pane>` | Formatted DocLang XML source view, page-by-page |
| [reading-pane.html](reading-pane.html) | `<doclang-reading-pane>` | Rendered reading view with layers toggle |
| [page-img-pane.html](page-img-pane.html) | `<doclang-page-img-pane>` | Original page image with bounding-box overlay (requires a `.dclx` archive with images) |

## Composed

| Example | Description |
|---------|-------------|
| [all-panes.html](all-panes.html) | All three panes side-by-side, with page navigation and element selection cross-linked via vanilla JS |

## Running locally

These pages fetch the demo archive over HTTP, so they need to be served rather than opened as `file://`:

```bash
# from the repo root
python3 -m http.server 8080
```

Then open <http://localhost:8080/core/examples/>.
102 changes: 102 additions & 0 deletions core/examples/all-panes.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>DocLang — three panes in sync</title>
<link rel="stylesheet" href="example.css">
<script type="module" src="../../viewer.js"></script>
<style>
.page-controls {
display: flex;
align-items: center;
gap: 0.5rem;
padding: 0.4rem 1rem;
background: #f7f8fa;
border-bottom: 1px solid #e5e7eb;
flex-shrink: 0;
font-size: 0.85rem;
}
.page-controls button {
padding: 0.2rem 0.6rem;
border: 1px solid #d0d7de;
border-radius: 4px;
background: #fff;
cursor: pointer;
font-size: 0.85rem;
}
.page-controls button:disabled { opacity: 0.4; cursor: default; }
#page-label { color: #57606a; min-width: 6rem; }

.pane-row {
flex: 1;
min-height: 0;
display: grid;
grid-template-columns: 1fr 1fr 1fr;
}
.pane-row > * { min-width: 0; border-right: 1px solid #e5e7eb; }
.pane-row > *:last-child { border-right: none; }
</style>
</head>
<body>
<header>
<a href="README.md">← examples</a>
<span>All three panes in sync — click an element in any pane to cross-highlight</span>
</header>

<div class="page-controls">
<button id="btn-prev" disabled>← Prev</button>
<button id="btn-next">Next →</button>
<span id="page-label">Page 1</span>
</div>

<div class="pane-row">
<doclang-page-img-pane id="pv" src="../../assets/2501.17887.dclx" page="1"></doclang-page-img-pane>
<doclang-markup-pane id="mp" src="../../assets/2501.17887.dclx" page="1"></doclang-markup-pane>
<doclang-reading-pane id="rp" src="../../assets/2501.17887.dclx" page="1"></doclang-reading-pane>
</div>

<script type="module">
const pv = document.getElementById('pv');
const mp = document.getElementById('mp');
const rp = document.getElementById('rp');
const btnPrev = document.getElementById('btn-prev');
const btnNext = document.getElementById('btn-next');
const pageLabel = document.getElementById('page-label');

let page = 1;
let pageCount = 1;

// Sync page and selection across all three panes.
function setPage(n) {
page = Math.min(Math.max(1, n), pageCount);
[pv, mp, rp].forEach(el => { el.page = page; });
btnPrev.disabled = page <= 1;
btnNext.disabled = page >= pageCount;
pageLabel.textContent = `Page ${page} of ${pageCount}`;
}

function setSelected(id) {
[pv, mp, rp].forEach(el => { el.selected = id; });
}

// Once the page-view pane renders its first overlay it emits
// doclang-layout-refresh — use that moment to read pageCount.
pv.addEventListener('doclang-layout-refresh', () => {
pageCount = pv.document?.pageCount ?? 1;
setPage(page);
}, { once: true });

// Element selection events bubble up from any pane.
document.addEventListener('doclang-element-select', e => setSelected(e.detail.id));
document.addEventListener('doclang-clear-selection', () => setSelected(null));

// Page navigation.
btnPrev.addEventListener('click', () => setPage(page - 1));
btnNext.addEventListener('click', () => setPage(page + 1));

// view-page events emitted by page-nav inside each pane (if any).
document.addEventListener('view-page', e => setPage(e.detail.page));
</script>
</body>
</html>
23 changes: 23 additions & 0 deletions core/examples/example.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
* { box-sizing: border-box; }

body {
margin: 0;
display: flex;
flex-direction: column;
height: 100dvh;
font-family: system-ui, sans-serif;
}

header {
padding: 0.5rem 1rem;
background: #f7f8fa;
border-bottom: 1px solid #e5e7eb;
font-size: 0.85rem;
color: #57606a;
display: flex;
align-items: center;
gap: 1rem;
flex-shrink: 0;
}
header a { color: #3b82d4; text-decoration: none; }
header code { background: #e5e7eb; padding: 0.1em 0.35em; border-radius: 3px; }
34 changes: 34 additions & 0 deletions core/examples/markup-pane.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>doclang-markup-pane — example</title>
<link rel="stylesheet" href="example.css">
<style>
doclang-markup-pane { flex: 1; min-height: 0; }
</style>
<script type="module" src="../../viewer.js"></script>
</head>
<body>
<header>
<a href="README.md">← examples</a>
<span><code>&lt;doclang-markup-pane&gt;</code> — loaded via <code>src</code> attribute from the demo archive</span>
</header>

<!--
src — URL of a .dclx archive or a plain .dclg / .xml markup file.
page — initial page number (default: 1).
selected — element-id to pre-select (optional).

The component fetches and parses the file automatically.
Serve this directory over HTTP so the fetch can resolve:
python3 -m http.server 8080 (from the repo root)
then open: http://localhost:8080/core/examples/markup-pane.html
-->
<doclang-markup-pane
src="../../assets/2501.17887.dclx"
page="1"
></doclang-markup-pane>
</body>
</html>
33 changes: 33 additions & 0 deletions core/examples/page-img-pane.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>doclang-page-img-pane — example</title>
<link rel="stylesheet" href="example.css">
<style>
doclang-page-img-pane { flex: 1; min-height: 0; }
</style>
<script type="module" src="../../viewer.js"></script>
</head>
<body>
<header>
<a href="README.md">← examples</a>
<span><code>&lt;doclang-page-img-pane&gt;</code> — original page image with bounding-box overlay</span>
</header>

<!--
src — must be a .dclx archive that includes page images; a plain markup
file has no images so the page-view pane will show nothing.
page — initial page number (default: 1).

Serve this directory over HTTP so the fetch can resolve:
python3 -m http.server 8080 (from the repo root)
then open: http://localhost:8080/core/examples/page-img-pane.html
-->
<doclang-page-img-pane
src="../../assets/2501.17887.dclx"
page="1"
></doclang-page-img-pane>
</body>
</html>
33 changes: 33 additions & 0 deletions core/examples/reading-pane.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>doclang-reading-pane — example</title>
<link rel="stylesheet" href="example.css">
<style>
doclang-reading-pane { flex: 1; min-height: 0; }
</style>
<script type="module" src="../../viewer.js"></script>
</head>
<body>
<header>
<a href="README.md">← examples</a>
<span><code>&lt;doclang-reading-pane&gt;</code> — loaded via <code>src</code> attribute from the demo archive</span>
</header>

<!--
src — URL of a .dclx archive or a plain .dclg / .xml markup file.
page — initial page number (default: 1).
selected — element-id to pre-select (optional).

Serve this directory over HTTP so the fetch can resolve:
python3 -m http.server 8080 (from the repo root)
then open: http://localhost:8080/core/examples/reading-pane.html
-->
<doclang-reading-pane
src="../../assets/2501.17887.dclx"
page="1"
></doclang-reading-pane>
</body>
</html>
Loading