1
0
mirror of https://github.com/sharkdp/bat.git synced 2025-10-16 08:43:50 +01:00

Merge pull request #3435 from MuntasirSZN/fix/markdown-typescript

feat: add typescript codeblock highlight patches for markdown
This commit is contained in:
Keith Hall
2025-10-14 22:22:33 +03:00
committed by GitHub
4 changed files with 132 additions and 2 deletions

View File

@@ -7,6 +7,7 @@
- Support negative relative line ranges, e.g. `bat -r :-10` / `bat -r='-10:'`, see #3068 (@ajesipow)
- Support context in line ranges, e.g. `bat -r 30::5` / `bat -r 30:40:5`, see #3345 (@cavanaug)
- Add built-in 'minus' pager, e.g. `bat --pager=builtin` see PR #3402 (@academician)
- Syntax highlighting for typescript code blocks within Markdown files, see #3435 (@MuntasirSZN)
## Bugfixes

View File

@@ -166,7 +166,7 @@ index 19dc685d..3a45ea05 100644
- match: ^\s*$\n?
scope: invalid.illegal.non-terminated.bold-italic.markdown
pop: true
@@ -1073,6 +1031,21 @@ contexts:
@@ -1073,6 +1031,36 @@ contexts:
escape: '{{code_fence_escape}}'
escape_captures:
0: meta.code-fence.definition.end.python.markdown-gfm
@@ -185,10 +185,25 @@ index 19dc685d..3a45ea05 100644
+ escape: '{{code_fence_escape}}'
+ escape_captures:
+ 0: meta.code-fence.definition.end.puppet.markdown-gfm
+ 1: punctuation.definition.raw.code-fence.end.markdown
+ - match: |-
+ (?x)
+ {{fenced_code_block_start}}
+ ((?i:typescript|ts))
+ {{fenced_code_block_trailing_infostring_characters}}
+ captures:
+ 0: meta.code-fence.definition.begin.typescript.markdown-gfm
+ 2: punctuation.definition.raw.code-fence.begin.markdown
+ 5: constant.other.language-name.markdown
+ embed: scope:source.ts
+ embed_scope: markup.raw.code-fence.typescript.markdown-gfm
+ escape: '{{code_fence_escape}}'
+ escape_captures:
+ 0: meta.code-fence.definition.end.typescript.markdown-gfm
1: punctuation.definition.raw.code-fence.end.markdown
- match: |-
(?x)
@@ -1152,7 +1125,7 @@ contexts:
@@ -1152,7 +1155,7 @@ contexts:
- match: |-
(?x)
{{fenced_code_block_start}}

View File

@@ -0,0 +1,57 @@
# Typescript test
```typescript
enum Status {
 Pending,
 InProgress,
 Completed,
}
interface Task {
 id: number;
 title: string;
 status: Status;
 assignee?: string;
}
class TaskManager<T extends Task> {
 private tasks: T[] = [];
 addTask(task: T): void {
 this.tasks.push(task);
 }
 getTasksByStatus(status: Status): T[] {
 return this.tasks.filter(task => task.status === status);
 }
 async fetchTasks(): Promise<T[]> {
 // Simulate async fetch
 return new Promise(resolve => setTimeout(() => resolve(this.tasks), 500));
 }
}
// Type guard
function isTask(obj: any): obj is Task {
 return typeof obj.id === 'number' && typeof obj.title === 'string';
}
// Usage
const manager = new TaskManager<Task>();
manager.addTask({ id: 1, title: "Write docs", status: Status.Pending });
manager.addTask({ id: 2, title: "Review PR", status: Status.InProgress, assignee: "Alice" });
(async () => {
 const allTasks = await manager.fetchTasks();
 allTasks.forEach(task => {
 if (isTask(task)) {
 console.log(`Task #${task.id}: ${task.title} [${Status[task.status]}]`);
 }
 });
})();
// Type assertion
const unknownValue: unknown = { id: 3, title: "Test", status: Status.Completed };
const assertedTask = unknownValue as Task;
console.log(assertedTask.title);
```

View File

@@ -0,0 +1,57 @@
# Typescript test
```typescript
enum Status {
Pending,
InProgress,
Completed,
}
interface Task {
id: number;
title: string;
status: Status;
assignee?: string;
}
class TaskManager<T extends Task> {
private tasks: T[] = [];
addTask(task: T): void {
this.tasks.push(task);
}
getTasksByStatus(status: Status): T[] {
return this.tasks.filter(task => task.status === status);
}
async fetchTasks(): Promise<T[]> {
// Simulate async fetch
return new Promise(resolve => setTimeout(() => resolve(this.tasks), 500));
}
}
// Type guard
function isTask(obj: any): obj is Task {
return typeof obj.id === 'number' && typeof obj.title === 'string';
}
// Usage
const manager = new TaskManager<Task>();
manager.addTask({ id: 1, title: "Write docs", status: Status.Pending });
manager.addTask({ id: 2, title: "Review PR", status: Status.InProgress, assignee: "Alice" });
(async () => {
const allTasks = await manager.fetchTasks();
allTasks.forEach(task => {
if (isTask(task)) {
console.log(`Task #${task.id}: ${task.title} [${Status[task.status]}]`);
}
});
})();
// Type assertion
const unknownValue: unknown = { id: 3, title: "Test", status: Status.Completed };
const assertedTask = unknownValue as Task;
console.log(assertedTask.title);
```