Skip to content

Commit

Permalink
Ported preview feature from rst-vscode.
Browse files Browse the repository at this point in the history
  • Loading branch information
lextm committed Mar 26, 2016
1 parent 6fe6d00 commit 3cf4b41
Show file tree
Hide file tree
Showing 16 changed files with 1,090 additions and 8 deletions.
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ that VS Code provides.
- Code snippets
- `code` Code block
- `image` Image
- `figure` Figure
- `link` Link
- `attention` Attention
- `note` Note
Expand All @@ -27,6 +28,13 @@ that VS Code provides.
- `doc` Doc reference

To trigger snippets, please refer to [Visual Studio Code shortcuts](https://code.visualstudio.com/docs/customization/keybindings).

- Preview (ported from rst-vscode extension)

The shortcuts are

- `ctrl+shift+r` Preview
- `ctrl+k r` Preview to Side

## How to Install from Gallery

Expand Down
8 changes: 7 additions & 1 deletion Third Party Notices.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,10 @@ restructuredtext.tmbundle

The license terms can be found at

https://github.com/textmate/restructuredtext.tmbundle
https://github.com/textmate/restructuredtext.tmbundle

ReStructured Text Previewer

The license terms can be found at

https://github.com/tht13/RST-vscode/blob/master/LICENSE
11 changes: 8 additions & 3 deletions docs/development.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
# Working with the reStructuredText extension code

1. Clone the repo to a local path such as `~/vscode-restructuredtext`.
2. Navigate to this folder.
3. Run VS Code from this folder.
4. In this editing VS Code instance, press F5 to start a debugging instance.
1. Navigate to this folder.
1. Resolve NPM dependencies via `npm install`.
1. Build via `npm run compile`.
1. Install Python and DocUtils via `pip install docutils`.
1. Run VS Code from this folder via `code .`.
1. In this editing VS Code instance, press F5 to start a debugging instance.
```
cd ~
git clone https://github.com/lextm/vscode-restructuredtext.git
cd ~/vscode-restructuredtext
npm install
npm run compile
code .
```

Expand Down
50 changes: 46 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@
"name": "restructuredtext",
"displayName": "reStructuredText",
"description": "Develop reStructuredText in Visual Studio Code!",
"version": "0.0.5",
"version": "0.0.6",
"publisher": "lextudio",
"engines": {
"vscode": "0.10.*"
"vscode": "^0.10.8"
},
"license":"SEE LICENSE IN LICENSE.txt",
"homepage": "https://github.com/lextm/vscode-restructuredtext/blob/master/README.md",
Expand All @@ -21,6 +21,12 @@
"type": "git",
"url": "https://github.com/lextm/vscode-restructuredtext.git"
},
"bugs": "https://github.com/lextm/vscode-restructuredtext/issues",
"main": "./out/src/extension",
"activationEvents": [
"onCommand:restructuredtext.preview",
"onCommand:restructuredtext.previewToSide"
],
"contributes": {
"languages": [{
"id": "restructuredtext",
Expand All @@ -37,6 +43,42 @@
"language": "restructuredtext",
"path": "./snippets/snippets.json"
}
]
}
],
"keybindings": [
{
"command": "restructuredtext.preview",
"key": "ctrl+shift+r",
"when": "editorTextFocus"
},
{
"command": "restructuredtext.previewToSide",
"key": "ctrl+k r",
"when": "editorTextFocus"
}
],
"commands": [
{
"command": "restructuredtext.preview",
"title": "Toggle Preview",
"category": "reStructuredText"
},
{
"command": "restructuredtext.previewToSide",
"title": "Open Preview to the Side",
"category": "reStructuredText"
}
]
},
"scripts": {
"vscode:prepublish": "node ./node_modules/vscode/bin/compile",
"compile": "node ./node_modules/vscode/bin/compile -watch -p ./",
"postinstall": "node ./node_modules/vscode/bin/install"
},
"dependencies": {
"file-url": "^1.0.1"
},
"devDependencies": {
"typescript": "^1.7.5",
"vscode": "^0.11.x"
}
}
6 changes: 6 additions & 0 deletions snippets/snippets.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,12 @@
"description": "Image",
"scope": "text.restructuredtext"
},
"figure": {
"prefix": "figure",
"body": ".. figure:: ${1:path}\n\n $0",
"description": "Figure",
"scope": "text.restructuredtext"
},
"link": {
"prefix": "link",
"body": "`${1:Title} <${2:http://link}>`_ ",
Expand Down
176 changes: 176 additions & 0 deletions src/extension.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
"use strict";
import { workspace, window, ExtensionContext, commands,
TextEditor, TextDocumentContentProvider, EventEmitter,
Event, Uri, TextDocumentChangeEvent, ViewColumn,
TextEditorSelectionChangeEvent,
TextDocument, Disposable } from "vscode";
import { exec } from "child_process";
import * as fs from "fs";
import * as path from "path";
let fileUrl = require("file-url");

export function activate(context: ExtensionContext) {

let previewUri: Uri;

let provider: RstDocumentContentProvider;
let registration: Disposable;

workspace.onDidChangeTextDocument((e: TextDocumentChangeEvent) => {
if (e.document === window.activeTextEditor.document) {
provider.update(previewUri);
}
});

workspace.onDidSaveTextDocument((e: TextDocument) => {
if (e === window.activeTextEditor.document) {
provider.update(previewUri);
}
});

function sendHTMLCommand(displayColumn: ViewColumn): PromiseLike<void> {
let previewTitle = `Preview: '${path.basename(window.activeTextEditor.document.fileName)}'`;
provider = new RstDocumentContentProvider();
registration = workspace.registerTextDocumentContentProvider("restructuredtext-preview", provider);
previewUri = Uri.parse(`restructuredtext-preview://preview/${previewTitle}`);
return commands.executeCommand("vscode.previewHtml", previewUri, displayColumn).then((success) => {
}, (reason) => {
console.warn(reason);
window.showErrorMessage(reason);
});
}

let previewToSide = commands.registerCommand("restructuredtext.previewToSide", () => {
let displayColumn: ViewColumn;
switch (window.activeTextEditor.viewColumn) {
case ViewColumn.One:
displayColumn = ViewColumn.Two;
break;
case ViewColumn.Two:
case ViewColumn.Three:
displayColumn = ViewColumn.Three;
break;
}
return sendHTMLCommand(displayColumn);
});

let preview = commands.registerCommand("restructuredtext.preview", () => {
return sendHTMLCommand(window.activeTextEditor.viewColumn);
});

context.subscriptions.push(previewToSide, preview, registration);
}

// this method is called when your extension is deactivated
export function deactivate() {
}

class RstDocumentContentProvider implements TextDocumentContentProvider {
private _onDidChange = new EventEmitter<Uri>();
private resultText = "";

public provideTextDocumentContent(uri: Uri): string | Thenable<string> {
return this.createRstSnippet();
}

get onDidChange(): Event<Uri> {
return this._onDidChange.event;
}

public update(uri: Uri) {
this._onDidChange.fire(uri);
}

private createRstSnippet(): string | Thenable<string> {
let editor = window.activeTextEditor;
if (!(editor.document.languageId === "restructuredtext")) {
return this.errorSnippet("Active editor doesn't show a reStructuredText document - no properties to preview.");
}
return this.preview(editor);
}

private errorSnippet(error: string): string {
return `
<body>
${error}
</body>`;
}

private buildPage(document: string, headerArgs: string[]): string {
return `
<html lang="en">
<head>
${headerArgs.join("\n")}
</head>
<body>
${document}
</body>
</html>`;
}

private createStylesheet(file: string) {
let href = fileUrl(
path.join(
__dirname,
"..",
"..",
"src",
"static",
file
)
);
return `<link href="${href}" rel="stylesheet" />`;
}

private fixLinks(document: string, documentPath: string): string {
return document.replace(
new RegExp("((?:src|href)=[\'\"])(.*?)([\'\"])", "gmi"), (subString: string, p1: string, p2: string, p3: string): string => {
return [
p1,
fileUrl(path.join(
path.dirname(documentPath),
p2
)),
p3
].join("");
}
);
}

public preview(editor: TextEditor): Thenable<string> {
let doc = editor.document;
return new Promise<string>((resolve, reject) => {
let cmd = [
"python",
path.join(
__dirname,
"..",
"..",
"src",
"preview.py"
),
doc.fileName
].join(" ");
exec(cmd, (error: Error, stdout: Buffer, stderr: Buffer) => {
if (error) {
let errorMessage = [
error.name,
error.message,
error.stack,
"",
stderr.toString()
].join("\n");
console.error(errorMessage);
reject(errorMessage);
} else {
let result = this.fixLinks(stdout.toString(), editor.document.fileName);
let headerArgs = [
this.createStylesheet("basic.css"),
this.createStylesheet("default.css")
];
resolve(this.buildPage(result, headerArgs));
}
});
});
}
}
19 changes: 19 additions & 0 deletions src/preview.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import sys
from docutils import core
filepath = sys.argv[1]

page_string = open(filepath, 'r').read()

# page_string = page_string.encode('utf-8', errors="ignore")

overrides = {'initial_header_level': 1,
'halt_level': 5}

parts = core.publish_parts(
source=page_string, source_path=filepath, writer_name='html', settings_overrides=overrides)

html_document = parts['html_body']
#remove bom
html_document = html_document.replace('\ufeff', '')

print(html_document)
Loading

0 comments on commit 3cf4b41

Please sign in to comment.