Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 | 4x 4x 32x 32x 32x 4x 28x 8x 3x 3x 4x 4x 4x | // Maps a source file to the Prism language id Obsidian's bundled highlighter
// understands, so code source previews render as highlighted code instead of
// plain text. Extensions absent here (markdown, plain text) render as-is.
const EXTENSION_LANGUAGE: Record<string, string> = {
py: "python",
pyi: "python",
ts: "typescript",
tsx: "tsx",
js: "javascript",
jsx: "jsx",
mjs: "javascript",
cjs: "javascript",
rs: "rust",
go: "go",
java: "java",
kt: "kotlin",
scala: "scala",
c: "c",
h: "c",
cpp: "cpp",
cc: "cpp",
cxx: "cpp",
hpp: "cpp",
cs: "csharp",
rb: "ruby",
php: "php",
swift: "swift",
sh: "bash",
bash: "bash",
zsh: "bash",
yaml: "yaml",
yml: "yaml",
toml: "toml",
json: "json",
jsonc: "json",
xml: "xml",
sql: "sql",
lua: "lua",
dart: "dart",
ex: "elixir",
exs: "elixir",
hs: "haskell",
};
// Extensionless filenames that are still code.
const FILENAME_LANGUAGE: Record<string, string> = {
dockerfile: "docker",
makefile: "makefile",
};
/** Prism language id for a source path, or null when it should render as-is. */
export function languageForSource(source: string): string | null {
const name = source.replace(/^.*[\\/]/, "").toLowerCase();
const dot = name.lastIndexOf(".");
if (dot <= 0) {
return FILENAME_LANGUAGE[name] ?? null;
}
return EXTENSION_LANGUAGE[name.slice(dot + 1)] ?? null;
}
/** Pixels to scroll a rendered code block so the cited line sits near the top
* with a couple of lines of lead-in — the code equivalent of the PDF preview's
* jump to the cited page. Returns 0 when there is nothing to scroll to. */
export function citedLineScrollTop(scrollHeight: number, totalLines: number, line: number | null): number {
if (line === null || line <= 1 || totalLines <= 0 || scrollHeight <= 0) return 0;
const lineHeight = scrollHeight / totalLines;
return Math.max(0, (line - 1) * lineHeight - lineHeight * 2);
}
/** Wrap content in a fenced code block whose fence outlives any backtick run
* inside it, so embedded backticks can't close the block early. */
export function toCodeFence(content: string, lang: string): string {
const longestRun = (content.match(/`+/g) ?? []).reduce((n, run) => Math.max(n, run.length), 0);
const fence = "`".repeat(Math.max(3, longestRun + 1));
return `${fence}${lang}\n${content}\n${fence}`;
}
|