texlite 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +661 -0
- package/README.md +403 -0
- package/README.zh-CN.md +391 -0
- package/dist/client/assets/GitDialog-BHHxSBn3.js +3 -0
- package/dist/client/assets/HistoryDialog-Dlv57tYf.js +5 -0
- package/dist/client/assets/LatexEditor-B-0VRUPv.js +55 -0
- package/dist/client/assets/PdfPreview-617TWFJN.js +1 -0
- package/dist/client/assets/ProjectNavigationDialogs-Cpt2LVEt.js +1 -0
- package/dist/client/assets/SystemMetricsDialog-fkFHVVzJ.js +1 -0
- package/dist/client/assets/editor-JxT6uSYX.js +14 -0
- package/dist/client/assets/index-Bc5CmFMl.js +15 -0
- package/dist/client/assets/index-CMqYAbDx.css +1 -0
- package/dist/client/assets/pdf-DPnwNQHb.js +55 -0
- package/dist/client/assets/pdf.worker.min-CHFwMXne.mjs +29 -0
- package/dist/client/assets/plus-DzbLkp6l.js +1 -0
- package/dist/client/assets/react-CsO_xvbl.js +49 -0
- package/dist/client/assets/spellCheck-R6fUM9oA.js +49783 -0
- package/dist/client/index.html +20 -0
- package/dist/client/logo.svg +4 -0
- package/dist/server/anchors.js +95 -0
- package/dist/server/app.js +1624 -0
- package/dist/server/archive.js +26 -0
- package/dist/server/auth.js +42 -0
- package/dist/server/cli.js +318 -0
- package/dist/server/collaboration.js +635 -0
- package/dist/server/compileArtifacts.js +86 -0
- package/dist/server/compileDiagnostics.js +227 -0
- package/dist/server/compiler.js +514 -0
- package/dist/server/config.js +336 -0
- package/dist/server/db.js +280 -0
- package/dist/server/environment.js +57 -0
- package/dist/server/files.js +121 -0
- package/dist/server/git.js +414 -0
- package/dist/server/history.js +379 -0
- package/dist/server/http.js +7 -0
- package/dist/server/index.js +75 -0
- package/dist/server/latexCompletion.js +296 -0
- package/dist/server/metrics.js +34 -0
- package/dist/server/pm2.js +234 -0
- package/dist/server/projectOutline.js +101 -0
- package/dist/server/projectSearch.js +112 -0
- package/dist/server/projects.js +29 -0
- package/dist/server/routes/compile.js +343 -0
- package/dist/server/runtimePaths.js +42 -0
- package/dist/server/security.js +29 -0
- package/dist/server/spellCheck.js +195 -0
- package/dist/server/synctex.js +56 -0
- package/dist/server/zip.js +185 -0
- package/package.json +110 -0
- package/preview.png +0 -0
- package/texlite.config.example.json +33 -0
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="zh-CN">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
|
+
<meta name="color-scheme" content="light" />
|
|
7
|
+
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
|
8
|
+
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
|
9
|
+
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Fira+Code:wght@400;500;600&family=IBM+Plex+Mono:wght@400;500;600&family=Inter:wght@400;500;600;700;800&family=JetBrains+Mono:wght@400;500;600&family=Source+Code+Pro:wght@400;500;600&display=swap" />
|
|
10
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/fontsource/fonts/iosevka@latest/latin-400-normal.css" />
|
|
11
|
+
<link rel="icon" type="image/svg+xml" href="/logo.svg" />
|
|
12
|
+
<title>TexLite</title>
|
|
13
|
+
<script type="module" crossorigin src="/assets/index-Bc5CmFMl.js"></script>
|
|
14
|
+
<link rel="modulepreload" crossorigin href="/assets/react-CsO_xvbl.js">
|
|
15
|
+
<link rel="stylesheet" crossorigin href="/assets/index-CMqYAbDx.css">
|
|
16
|
+
</head>
|
|
17
|
+
<body>
|
|
18
|
+
<div id="root"></div>
|
|
19
|
+
</body>
|
|
20
|
+
</html>
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 1024 1024">
|
|
2
|
+
<path d="M0 0h1024v1024H0z" fill="none" />
|
|
3
|
+
<path fill="#2196f3" d="M80 192L64 320h32c16-80 16-96 63.242-96H176c8.837 0 16 7.163 16 16v352c0 8.837 0 16-32 16h-32v32h192v-32h-32c-32 0-32-7.163-32-16V240c0-8.837 7.163-16 16-16h16c48 0 48 16 64 96h32l-16-128zm560 0v32c16 0 45.713 0 52.57 16L776 434.666L708.57 592c-6.857 16-52.57 16-68.57 16v32h128v-32s-34.285 0-27.428-16L792 472l51.428 120c3.103 7.24-1.52 16-11.428 16v32h128v-32c-16 0-45.713 0-52.57-16L824 397.334L891.43 240c6.857-16 52.57-16 68.57-16v-32H832v32s34.285 0 27.428 16L808 360l-51.428-120c-3.103-7.24 1.52-16 11.428-16v-32zM320 384v32h32c32 0 32 7.163 32 16v352c0 8.837 0 16-32 16h-32v32h304l16-128h-32c-16 80-16 96-64 96h-64c-32 0-32-7.163-32-16V624h80c8.837 0 16 0 16 32v16h32V544h-32v16c0 32-7.163 32-16 32h-80V432c0-8.837 0-16 32-16h64c48 0 48 16 64 96h32l-16-128z" />
|
|
4
|
+
</svg>
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import diff_match_patch from "diff-match-patch";
|
|
2
|
+
const CONTEXT_SIZE = 48;
|
|
3
|
+
export function createSourceAnchor(source, startInput, endInput) {
|
|
4
|
+
const startOffset = clamp(Math.min(startInput, endInput), 0, source.length);
|
|
5
|
+
const endOffset = clamp(Math.max(startInput, endInput), startOffset, source.length);
|
|
6
|
+
return anchorAt(source, startOffset, endOffset, false);
|
|
7
|
+
}
|
|
8
|
+
export function reanchorFileComments(db, projectId, filePath, oldSource, newSource) {
|
|
9
|
+
if (oldSource === newSource)
|
|
10
|
+
return;
|
|
11
|
+
const dmp = new diff_match_patch();
|
|
12
|
+
const diffs = dmp.diff_main(oldSource, newSource, true);
|
|
13
|
+
dmp.diff_cleanupSemantic(diffs);
|
|
14
|
+
const comments = db.prepare(`SELECT id, selected_text, start_offset, end_offset, context_before, context_after
|
|
15
|
+
FROM comments WHERE project_id = ? AND file_path = ?`).all(projectId, filePath);
|
|
16
|
+
const update = db.prepare(`UPDATE comments SET selected_text = ?, start_offset = ?, end_offset = ?,
|
|
17
|
+
context_before = ?, context_after = ?, orphaned = ?, updated_at = ? WHERE id = ?`);
|
|
18
|
+
for (const comment of comments) {
|
|
19
|
+
const oldStart = clamp(comment.start_offset, 0, oldSource.length);
|
|
20
|
+
const oldEnd = clamp(comment.end_offset, oldStart, oldSource.length);
|
|
21
|
+
let start = clamp(dmp.diff_xIndex(diffs, oldStart), 0, newSource.length);
|
|
22
|
+
let end = clamp(dmp.diff_xIndex(diffs, oldEnd), start, newSource.length);
|
|
23
|
+
let orphaned = false;
|
|
24
|
+
if (oldEnd > oldStart && end === start) {
|
|
25
|
+
const relocated = nearestContextualMatch(newSource, comment.selected_text, start, comment.context_before, comment.context_after);
|
|
26
|
+
if (relocated === null) {
|
|
27
|
+
orphaned = true;
|
|
28
|
+
}
|
|
29
|
+
else {
|
|
30
|
+
start = relocated;
|
|
31
|
+
end = relocated + comment.selected_text.length;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
const anchor = anchorAt(newSource, start, end, orphaned);
|
|
35
|
+
update.run(orphaned ? comment.selected_text : anchor.selectedText, anchor.startOffset, anchor.endOffset, anchor.contextBefore, anchor.contextAfter, Number(anchor.orphaned), new Date().toISOString(), comment.id);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
export function offsetToLine(source, offsetInput) {
|
|
39
|
+
const offset = clamp(offsetInput, 0, source.length);
|
|
40
|
+
let line = 1;
|
|
41
|
+
for (let index = 0; index < offset; index += 1)
|
|
42
|
+
if (source.charCodeAt(index) === 10)
|
|
43
|
+
line += 1;
|
|
44
|
+
return line;
|
|
45
|
+
}
|
|
46
|
+
function anchorAt(source, startOffset, endOffset, orphaned) {
|
|
47
|
+
return {
|
|
48
|
+
startOffset,
|
|
49
|
+
endOffset,
|
|
50
|
+
selectedText: source.slice(startOffset, endOffset),
|
|
51
|
+
contextBefore: source.slice(Math.max(0, startOffset - CONTEXT_SIZE), startOffset),
|
|
52
|
+
contextAfter: source.slice(endOffset, Math.min(source.length, endOffset + CONTEXT_SIZE)),
|
|
53
|
+
orphaned
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
function nearestContextualMatch(source, selected, expected, contextBefore, contextAfter) {
|
|
57
|
+
if (!selected)
|
|
58
|
+
return null;
|
|
59
|
+
let best = null;
|
|
60
|
+
let bestRank = Number.NEGATIVE_INFINITY;
|
|
61
|
+
let cursor = 0;
|
|
62
|
+
while (cursor <= source.length) {
|
|
63
|
+
const found = source.indexOf(selected, cursor);
|
|
64
|
+
if (found < 0)
|
|
65
|
+
break;
|
|
66
|
+
const distance = Math.abs(found - expected);
|
|
67
|
+
const before = source.slice(Math.max(0, found - contextBefore.length), found);
|
|
68
|
+
const after = source.slice(found + selected.length, found + selected.length + contextAfter.length);
|
|
69
|
+
const contextScore = commonSuffixLength(before, contextBefore) + commonPrefixLength(after, contextAfter);
|
|
70
|
+
const rank = contextScore * 1000 - distance;
|
|
71
|
+
if (rank > bestRank) {
|
|
72
|
+
best = found;
|
|
73
|
+
bestRank = rank;
|
|
74
|
+
}
|
|
75
|
+
cursor = found + Math.max(1, selected.length);
|
|
76
|
+
}
|
|
77
|
+
return best;
|
|
78
|
+
}
|
|
79
|
+
function commonPrefixLength(left, right) {
|
|
80
|
+
const limit = Math.min(left.length, right.length);
|
|
81
|
+
let index = 0;
|
|
82
|
+
while (index < limit && left[index] === right[index])
|
|
83
|
+
index += 1;
|
|
84
|
+
return index;
|
|
85
|
+
}
|
|
86
|
+
function commonSuffixLength(left, right) {
|
|
87
|
+
const limit = Math.min(left.length, right.length);
|
|
88
|
+
let count = 0;
|
|
89
|
+
while (count < limit && left[left.length - 1 - count] === right[right.length - 1 - count])
|
|
90
|
+
count += 1;
|
|
91
|
+
return count;
|
|
92
|
+
}
|
|
93
|
+
function clamp(value, min, max) {
|
|
94
|
+
return Math.max(min, Math.min(max, Number.isFinite(value) ? Math.floor(value) : min));
|
|
95
|
+
}
|