Skip to content
Merged
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
17 changes: 13 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,17 +38,25 @@ Import external code files in your Obsidian notes using `@import` syntax (compat

### Parameters

| Parameter | Description | Example |
|-----------|-------------|---------|
| `line_begin` | Start line (0-based index) | `line_begin=4` starts from 5th line |
| `line_end` | End line (exclusive, supports negative) | `line_end=14` or `line_end=-1` |
| Parameter | Description (0-based) | Description (1-based) |
|-----------|----------------------|----------------------|
| `line_begin` | Start line, 0-based index | Start line, 1-based index |
| `line_end` | End line, exclusive (supports negative) | End line, inclusive (supports negative) |

### Line Index Examples

**0-based mode** (default, Foam-compatible):

- `{line_begin=0 line_end=10}` → Lines 1-10 (indices 0-9)
- `{line_begin=5}` → From line 6 to end
- `{line_end=-2}` → From start, excluding last 2 lines

**1-based mode:**

- `{line_begin=1 line_end=10}` → Lines 1-10
- `{line_begin=5}` → From line 5 to end
- `{line_end=-2}` → From start, excluding last 2 lines

## Installation

### From Community Plugins
Expand Down Expand Up @@ -85,6 +93,7 @@ In your markdown file:
|---------|-------------|---------|
| Show file name | Display filename header above code block | On |
| Wrap code | Wrap long lines instead of horizontal scrolling | Off |
| Line number base | 0-based (Foam-compatible) or 1-based indexing for `line_begin`/`line_end` | 0-based |

## License

Expand Down
1 change: 1 addition & 0 deletions src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ export default class CodeImportPlugin extends Plugin {
{
showFileName: this.settings.showFileName,
wrapCode: this.settings.wrapCode,
lineNumberBase: this.settings.lineNumberBase,
},
this
);
Expand Down
30 changes: 25 additions & 5 deletions src/renderer.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import { MarkdownRenderer, App, Component } from 'obsidian';
import { ImportDirective, extractLines, getFileExtension, extensionToLanguage } from './parser';
import type { LineNumberBase } from './settings';

export interface RenderOptions {
showFileName: boolean;
wrapCode: boolean;
lineNumberBase: LineNumberBase;
}

/**
Expand Down Expand Up @@ -56,8 +58,21 @@ export async function renderCodeBlock(
const ext = getFileExtension(directive.filePath);
const language = extensionToLanguage(ext);

// Convert 1-based line numbers to 0-based for extractLines
let internalBegin = directive.lineBegin;
let internalEnd = directive.lineEnd;

if (options.lineNumberBase === '1') {
// Convert 1-based begin to 0-based: line 1 → index 0
if (internalBegin !== undefined) {
internalBegin = internalBegin - 1;
}
// 1-based inclusive end N == 0-based exclusive end N, so no adjustment needed
// Negative values remain unchanged (they count from the end)
}

// Extract lines if specified
const extractedContent = extractLines(content, directive.lineBegin, directive.lineEnd);
const extractedContent = extractLines(content, internalBegin, internalEnd);

// Create wrapper for visual styling
const wrapper = document.createElement('div');
Expand All @@ -73,19 +88,24 @@ export async function renderCodeBlock(

header.appendChild(fileName);

// Add line range info if specified (display as 1-based for readability)
// Add line range info if specified
if (directive.lineBegin !== undefined || directive.lineEnd !== undefined) {
const lineInfo = document.createElement('span');
lineInfo.className = 'code-import-line-info';

const parts: string[] = [];
if (directive.lineBegin !== undefined) {
// Convert 0-based to 1-based for display
parts.push(`L${directive.lineBegin + 1}`);
if (options.lineNumberBase === '1') {
// Already 1-based, display as-is
parts.push(`L${directive.lineBegin}`);
} else {
// Convert 0-based to 1-based for display
parts.push(`L${directive.lineBegin + 1}`);
}
}
if (directive.lineEnd !== undefined) {
// Negative values show as-is (e.g., -1 means "exclude last")
// Positive values: exclusive end in 0-based equals last line number in 1-based
// Positive values: display as-is for both modes (0-based exclusive end == 1-based inclusive end)
parts.push(`L${directive.lineEnd}`);
}
lineInfo.textContent = parts.join('-');
Expand Down
18 changes: 18 additions & 0 deletions src/settings.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
import { App, PluginSettingTab, Setting } from 'obsidian';
import type CodeImportPlugin from './main';

export type LineNumberBase = '0' | '1';

export interface CodeImportSettings {
showFileName: boolean;
wrapCode: boolean;
lineNumberBase: LineNumberBase;
}

export const DEFAULT_SETTINGS: CodeImportSettings = {
showFileName: true,
wrapCode: false,
lineNumberBase: '0',
};

export class CodeImportSettingTab extends PluginSettingTab {
Expand Down Expand Up @@ -47,5 +51,19 @@ export class CodeImportSettingTab extends PluginSettingTab {
await this.plugin.saveSettings();
})
);

new Setting(containerEl)
.setName('Line number base')
.setDesc('Whether line_begin and line_end use 0-based or 1-based indexing')
.addDropdown((dropdown) =>
dropdown
.addOption('0', '0-based (default)')
.addOption('1', '1-based')
.setValue(this.plugin.settings.lineNumberBase)
.onChange(async (value) => {
this.plugin.settings.lineNumberBase = value as LineNumberBase;
await this.plugin.saveSettings();
})
);
}
}
Loading