mirror of
https://github.com/iaremarkus/wol-reference-viewer.git
synced 2026-07-22 06:14:20 +00:00
styles + types
This commit is contained in:
parent
34893b4211
commit
a5ffc8ac44
6 changed files with 319 additions and 124 deletions
4
css.d.ts
vendored
Normal file
4
css.d.ts
vendored
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
declare module '*.css' {
|
||||
const content: string;
|
||||
export default content;
|
||||
}
|
||||
|
|
@ -14,6 +14,7 @@ async function runBuild() {
|
|||
format: 'cjs',
|
||||
target: 'es2018',
|
||||
external: ['obsidian', '@codemirror/view', '@codemirror/state'],
|
||||
loader: { '.css': 'text' },
|
||||
outdir: '.',
|
||||
};
|
||||
|
||||
|
|
|
|||
10
package.json
10
package.json
|
|
@ -1,15 +1,15 @@
|
|||
{
|
||||
"name": "obsidian-verse-plugin",
|
||||
"name": "obsidian-wol-reference-viewer",
|
||||
"version": "1.0.0",
|
||||
"description": "An Obsidian plugin that fetches and displays Bible verses from IAM Research Suite API",
|
||||
"description": "An Obsidian plugin that looks up Bible verses and WOL research articles inline in your notes using !!reference!! syntax.",
|
||||
"main": "main.js",
|
||||
"scripts": {
|
||||
"dev": "node esbuild.config.mjs",
|
||||
"build": "tsc -noEmit -skipLibCheck && node esbuild.config.mjs production",
|
||||
"version": "node version-bump.mjs && git add manifest.json versions.json"
|
||||
},
|
||||
"keywords": ["obsidian", "bible", "verses", "research"],
|
||||
"author": "Your Name",
|
||||
"keywords": ["obsidian", "bible", "verses", "wol", "jw"],
|
||||
"author": "@iaremarkus",
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"@types/node": "^16.11.6",
|
||||
|
|
@ -21,4 +21,4 @@
|
|||
"tslib": "2.4.0",
|
||||
"typescript": "^5.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
66
reference-stylist.ts
Normal file
66
reference-stylist.ts
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
// reference-stylist.ts
|
||||
|
||||
/**
|
||||
* Parses verse numbers from a user-provided reference string.
|
||||
* Examples: "John 3:16" -> [16], "Romans 13:8-10" -> [8, 9, 10], "Ps 119:24,25" -> [24, 25]
|
||||
*/
|
||||
function parseReferenceNumbers(ref: string): number[] {
|
||||
const refNumbers: number[] = [];
|
||||
|
||||
const refPartMatch = ref.match(/:(.+)$/);
|
||||
const refPart = refPartMatch ? refPartMatch[1] : ref;
|
||||
|
||||
for (const segment of refPart.split(',')) {
|
||||
const parts = segment.trim().match(/^(\d+)(?:-(\d+))?$/);
|
||||
if (parts) {
|
||||
const start = parseInt(parts[1], 10);
|
||||
refNumbers.push(start);
|
||||
if (parts[2]) {
|
||||
const end = parseInt(parts[2], 10);
|
||||
for (let i = start + 1; i <= end; i++) {
|
||||
refNumbers.push(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return refNumbers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders reference text into a container element, wrapping inline verse numbers
|
||||
* (e.g. the leading "16" in "16 For God loved the world…") with styled spans.
|
||||
*
|
||||
* IMPORTANT: pass the original user-provided reference (e.g. "Romans 13:8-10"),
|
||||
* NOT the `reference` field from the API response (which is the WOL page title).
|
||||
*/
|
||||
export function renderReferenceText(container: HTMLElement, text: string, ref: string): void {
|
||||
const numbers = parseReferenceNumbers(ref);
|
||||
|
||||
if (numbers.length === 0) {
|
||||
container.appendText(text);
|
||||
return;
|
||||
}
|
||||
|
||||
// Sort descending so "10" is matched before "1"
|
||||
numbers.sort((a, b) => b - a);
|
||||
|
||||
// Use digit lookahead/lookbehind instead of \b for reliable boundary matching
|
||||
const pattern = numbers.map(n => `(?<!\\d)${n}(?!\\d)`).join('|');
|
||||
const regex = new RegExp(pattern, 'g');
|
||||
|
||||
let lastIndex = 0;
|
||||
let match: RegExpExecArray | null;
|
||||
|
||||
while ((match = regex.exec(text)) !== null) {
|
||||
if (match.index > lastIndex) {
|
||||
container.appendText(text.slice(lastIndex, match.index));
|
||||
}
|
||||
container.createSpan({ cls: 'ref-number', text: match[0] });
|
||||
lastIndex = match.index + match[0].length;
|
||||
}
|
||||
|
||||
if (lastIndex < text.length) {
|
||||
container.appendText(text.slice(lastIndex));
|
||||
}
|
||||
}
|
||||
346
styles.css
346
styles.css
|
|
@ -1,173 +1,305 @@
|
|||
.verse-reference {
|
||||
text-decoration: underline;
|
||||
cursor: pointer;
|
||||
color: #e6db74;
|
||||
border-bottom: none;
|
||||
.wol-ref-link {
|
||||
color: var(--color-accent);
|
||||
cursor: pointer;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.verse-reference:hover {
|
||||
opacity: 0.8;
|
||||
.wol-ref-link::before {
|
||||
content: " 📖 ";
|
||||
}
|
||||
|
||||
.wol-ref-link:hover {
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
/* New style for custom verlink class */
|
||||
.verlink {
|
||||
color: var(--text-accent); /* Use Obsidian's accent color */
|
||||
text-decoration: none;
|
||||
font-weight: bold;
|
||||
color: var(--text-accent);
|
||||
text-decoration: none;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.verlink:hover {
|
||||
text-decoration: underline;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
|
||||
.verse-modal .modal-content {
|
||||
padding: 20px;
|
||||
font-family: var(--font-family);
|
||||
.ref-modal .modal-content {
|
||||
padding: 20px;
|
||||
font-family: var(--font-family);
|
||||
}
|
||||
|
||||
.verse-modal p {
|
||||
margin-bottom: 10px;
|
||||
line-height: 1.8; /* Changed from 1.6 to 1.8 */
|
||||
.ref-modal p {
|
||||
margin-bottom: 10px;
|
||||
line-height: 1.8;
|
||||
}
|
||||
|
||||
.verse-modal p:last-child {
|
||||
margin-bottom: 0;
|
||||
.ref-modal p:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.verse-modal-reference {
|
||||
font-size: 0.9em;
|
||||
color: var(--text-muted);
|
||||
font-style: italic;
|
||||
margin-top: 15px;
|
||||
text-align: right;
|
||||
.ref-modal-reference {
|
||||
font-size: 0.9em;
|
||||
color: var(--text-muted);
|
||||
font-style: italic;
|
||||
margin-top: 15px;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.verse-modal-wol-link {
|
||||
display: block;
|
||||
margin-top: 10px;
|
||||
text-align: right;
|
||||
color: var(--text-accent);
|
||||
text-decoration: none;
|
||||
.ref-modal-wol-link,
|
||||
.ref-popover-wol-link,
|
||||
.ref-sidebar-wol-link {
|
||||
text-decoration: none;
|
||||
font-size: 80%;
|
||||
font-weight: 500;
|
||||
color: var(--color-accent);
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.verse-modal-wol-link:hover {
|
||||
text-decoration: underline;
|
||||
.ref-modal-wol-link:hover,
|
||||
.ref-popover-wol-link:hover,
|
||||
.ref-sidebar-wol-link:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.ref-modal-button-container button {
|
||||
font-size: 80%;
|
||||
font-weight: 600 !important;
|
||||
}
|
||||
|
||||
.ref-modal-result > li {
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
.ref-modal-result ol > li::marker,
|
||||
.ref-modal-result ul > li::marker {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.resultItems {
|
||||
margin: 0 !important;
|
||||
padding: 0 !important;
|
||||
}
|
||||
|
||||
.resultItems ::marker {
|
||||
display: none !important;
|
||||
opacity: 0 !important;
|
||||
color: transparent;
|
||||
}
|
||||
|
||||
.mod-cta {
|
||||
padding: 8px 10px 10px !important;
|
||||
line-height: 1 !important;
|
||||
height: auto !important;
|
||||
}
|
||||
|
||||
/* Live Preview editor decoration */
|
||||
.cm-verse-reference {
|
||||
font-weight: bold;
|
||||
color: var(--text-accent);
|
||||
.cm-wol-ref {
|
||||
color: var(--color-accent);
|
||||
opacity: 0.8;
|
||||
font-weight: 500;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.cm-wol-ref::before {
|
||||
content: " ";
|
||||
}
|
||||
|
||||
.cm-wol-ref:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
/* Inline reference result widget rendered in the editor for !!ref!!> */
|
||||
.cm-ref-inline-result,
|
||||
.ref-callout {
|
||||
background-color: transparent;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.cm-ref-inline-body,
|
||||
.ref-callout .callout-content {
|
||||
background: rgba(0, 0, 0, 0.1);
|
||||
border: 1px solid var(--background-modifier-border);
|
||||
padding: 15px;
|
||||
border-radius: 10px;
|
||||
font-size: 90%;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.cm-ref-inline-label,
|
||||
.ref-callout .callout-title {
|
||||
font-size: 90%;
|
||||
font-weight: 500;
|
||||
color: var(--text-normal) !important;
|
||||
margin-left: 3%;
|
||||
width: 94%;
|
||||
background-color: rgba(0, 0, 0, 0.2);
|
||||
padding: 5px 10px;
|
||||
border-radius: 10px 10px 0 0;
|
||||
box-shadow: none;
|
||||
line-height: inherit;
|
||||
}
|
||||
|
||||
.ref-callout .callout-title-inner {
|
||||
font-weight: inherit;
|
||||
}
|
||||
|
||||
.cm-ref-inline-item,
|
||||
.ref-callout-result {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 5px;
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
|
||||
.cm-ref-inline-item:last-child,
|
||||
.ref-callout-result:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.cm-ref-inline-item a,
|
||||
.ref-callout-result a {
|
||||
color: var(--text-accent);
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.cm-ref-inline-item a:hover,
|
||||
.ref-callout-result a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.cm-ref-inline-body p,
|
||||
.ref-callout .callout-content p {
|
||||
margin: 0 !important;
|
||||
}
|
||||
|
||||
/* Add style for popover paragraph text */
|
||||
.verse-popover p {
|
||||
line-height: 1.8;
|
||||
.ref-popover p {
|
||||
line-height: 1.8;
|
||||
}
|
||||
|
||||
.verse-number {
|
||||
font-weight: 700;
|
||||
color: var(--text-accent);
|
||||
font-size: 0.85em;
|
||||
.ref-number,
|
||||
span.v .vl {
|
||||
font-size: 70%;
|
||||
font-weight: 600;
|
||||
opacity: 0.5;
|
||||
padding: 1px 2px;
|
||||
position: relative;
|
||||
top: -1px;
|
||||
margin: 0 3px;
|
||||
line-height: 1;
|
||||
background: rgba(0, 0, 0, 0.3);
|
||||
border-radius: 3px;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
span.v .b {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* Sidebar */
|
||||
.verse-sidebar {
|
||||
padding: 12px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0;
|
||||
.ref-sidebar {
|
||||
padding: 12px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 20px;
|
||||
}
|
||||
|
||||
.verse-sidebar-empty {
|
||||
color: var(--text-muted);
|
||||
font-style: italic;
|
||||
font-size: var(--font-ui-small);
|
||||
text-align: center;
|
||||
margin-top: 24px;
|
||||
.ref-sidebar-empty {
|
||||
color: var(--text-muted);
|
||||
font-style: italic;
|
||||
font-size: var(--font-ui-small);
|
||||
text-align: center;
|
||||
margin-top: 24px;
|
||||
}
|
||||
|
||||
.verse-sidebar-item {
|
||||
padding: 12px 0;
|
||||
border-bottom: 1px solid var(--background-modifier-border);
|
||||
.ref-sidebar-item {
|
||||
padding: 12px 0;
|
||||
}
|
||||
|
||||
.verse-sidebar-item:last-child {
|
||||
border-bottom: none;
|
||||
.ref-sidebar .ref-sidebar-item:not(:last-of-type) {
|
||||
border-bottom: 1px dotted rgba(255, 255, 255, 0.2);
|
||||
padding-bottom: 20px;
|
||||
}
|
||||
|
||||
.verse-sidebar-header {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 6px;
|
||||
.ref-sidebar-header {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
width: 100%;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
|
||||
.verse-sidebar-ref {
|
||||
font-size: var(--font-ui-small);
|
||||
font-weight: 600;
|
||||
color: var(--text-accent);
|
||||
.ref-sidebar-ref {
|
||||
font-size: 90%;
|
||||
font-weight: 500;
|
||||
color: var(--color-accent);
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.verse-sidebar-wol-icon {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
color: var(--text-muted);
|
||||
line-height: 1;
|
||||
.ref-sidebar-wol-icon {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
color: var(--text-muted);
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.verse-sidebar-wol-icon:hover {
|
||||
color: var(--text-accent);
|
||||
.ref-sidebar-wol-icon:hover {
|
||||
color: var(--text-accent);
|
||||
}
|
||||
|
||||
.verse-sidebar-wol-icon svg {
|
||||
width: 13px;
|
||||
height: 13px;
|
||||
.ref-sidebar-wol-icon svg {
|
||||
width: 13px;
|
||||
height: 13px;
|
||||
}
|
||||
|
||||
.verse-sidebar-body p {
|
||||
font-size: var(--font-ui-small);
|
||||
line-height: 1.7;
|
||||
color: var(--text-normal);
|
||||
margin: 0 0 6px 0;
|
||||
.ref-sidebar-body p {
|
||||
font-size: var(--font-ui-small);
|
||||
line-height: 1.7;
|
||||
color: var(--text-normal);
|
||||
margin: 0 0 6px 0;
|
||||
}
|
||||
|
||||
.verse-sidebar-loading {
|
||||
color: var(--text-muted);
|
||||
font-style: italic;
|
||||
.ref-sidebar-loading {
|
||||
color: var(--text-muted);
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.verse-sidebar-error {
|
||||
color: var(--text-error);
|
||||
font-size: var(--font-ui-smaller);
|
||||
.ref-sidebar-error {
|
||||
color: var(--text-error);
|
||||
font-size: var(--font-ui-smaller);
|
||||
}
|
||||
|
||||
/* WOL search result cards */
|
||||
.verse-sidebar-wol-result {
|
||||
font-size: var(--font-ui-small);
|
||||
line-height: 1.6;
|
||||
color: var(--text-normal);
|
||||
padding: 6px 0;
|
||||
border-top: 1px solid var(--background-modifier-border);
|
||||
.ref-sidebar-wol-result {
|
||||
font-size: var(--font-ui-small);
|
||||
line-height: 1.6;
|
||||
color: var(--text-normal);
|
||||
padding: 6px 0;
|
||||
border-top: 1px solid var(--background-modifier-border);
|
||||
}
|
||||
|
||||
.verse-sidebar-wol-result:first-child {
|
||||
border-top: none;
|
||||
padding-top: 0;
|
||||
.ref-sidebar-wol-result:first-child {
|
||||
border-top: none;
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
.verse-sidebar-wol-result img {
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
.ref-sidebar-wol-result img {
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.verse-sidebar-wol-result a {
|
||||
color: var(--text-accent);
|
||||
text-decoration: none;
|
||||
.ref-sidebar-wol-result a {
|
||||
color: var(--text-accent);
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.verse-sidebar-wol-result a:hover {
|
||||
text-decoration: underline;
|
||||
.ref-sidebar-wol-result a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
/* Inline callout */
|
||||
.ref-callout-loading {
|
||||
color: var(--text-muted);
|
||||
font-style: italic;
|
||||
}
|
||||
|
|
|
|||
16
types.ts
16
types.ts
|
|
@ -1,13 +1,5 @@
|
|||
export interface VerseData {
|
||||
type: 'verse';
|
||||
text: string;
|
||||
reference: string;
|
||||
translation?: string;
|
||||
export interface ReferenceData {
|
||||
type: 'reference';
|
||||
ref: string; // the original query string
|
||||
results: string[]; // HTML strings from each result
|
||||
}
|
||||
|
||||
export interface WolData {
|
||||
type: 'wol';
|
||||
results: string[]; // outerHTML of each article.scalableui element
|
||||
}
|
||||
|
||||
export type ReferenceData = VerseData | WolData;
|
||||
|
|
|
|||
Loading…
Reference in a new issue