Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix document to document xrefs in preview when the documents are included #872

Merged
merged 2 commits into from
Oct 11, 2024
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
47 changes: 30 additions & 17 deletions src/asciidocEngine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,21 +23,12 @@ export type AsciidoctorBuiltInBackends = 'html5' | 'docbook5'
const previewConfigurationManager = new AsciidocPreviewConfigurationManager()

export class AsciidocEngine {
private stylesdir: string

constructor (
readonly contributionProvider: AsciidocContributionProvider,
readonly asciidoctorConfigProvider: AsciidoctorConfigProvider,
readonly asciidoctorExtensionsProvider: AsciidoctorExtensionsProvider,
readonly asciidoctorDiagnosticProvider: AsciidoctorDiagnosticProvider
) {
// Asciidoctor.js in the browser environment works with URIs however for desktop clients
// the "stylesdir" attribute is expected to look like a file system path (especially on Windows)
if ('browser' in process && (process as any).browser === true) {
this.stylesdir = vscode.Uri.joinPath(contributionProvider.extensionUri, 'media').toString()
} else {
this.stylesdir = vscode.Uri.joinPath(contributionProvider.extensionUri, 'media').fsPath
}
}

// Export
Expand All @@ -58,7 +49,7 @@ export class AsciidocEngine {
await this.asciidoctorConfigProvider.activate(registry, textDocumentUri)
asciidoctorProcessor.restoreBuiltInSyntaxHighlighter()

const baseDir = AsciidocTextDocument.fromTextDocument(textDocument).getBaseDir()
const baseDir = AsciidocTextDocument.fromTextDocument(textDocument).baseDir
const options: { [key: string]: any } = {
attributes: {
'env-vscode': '',
Expand Down Expand Up @@ -91,10 +82,16 @@ export class AsciidocEngine {
context: vscode.ExtensionContext,
editor: WebviewResourceProvider,
line?: number
): Promise<{html: string, document?: Asciidoctor.Document}> {
): Promise<{ html: string, document?: Asciidoctor.Document }> {
const textDocument = await vscode.workspace.openTextDocument(documentUri)
const { html, document } = await this.convertFromTextDocument(textDocument, context, editor, line)
return { html, document }
const {
html,
document,
} = await this.convertFromTextDocument(textDocument, context, editor, line)
return {
html,
document,
}
}

public async convertFromTextDocument (
Expand All @@ -111,7 +108,10 @@ export class AsciidocEngine {
// load the Asciidoc header only to get kroki-server-url attribute
const text = textDocument.getText()
const attributes = AsciidoctorAttributesConfig.getPreviewAttributes()
const document = processor.load(text, { attributes, header_only: true })
const document = processor.load(text, {
attributes,
header_only: true,
})
const isRougeSourceHighlighterEnabled = document.isAttribute('source-highlighter', 'rouge')
if (isRougeSourceHighlighterEnabled) {
// Force the source highlighter to Highlight.js (since Rouge is not supported)
Expand Down Expand Up @@ -149,8 +149,7 @@ export class AsciidocEngine {
cursor,
antoraDocumentContext.getContentCatalog(),
antoraConfig
)
))
)))
}
if (context && editor) {
highlightjsAdapter.register(asciidoctorProcessor.highlightjsBuiltInSyntaxHighlighter, context, editor)
Expand All @@ -159,12 +158,26 @@ export class AsciidocEngine {
}
const antoraSupport = AntoraSupportManager.getInstance(context.workspaceState)
const antoraAttributes = await antoraSupport.getAttributes(textDocumentUri)
const baseDir = AsciidocTextDocument.fromTextDocument(textDocument).getBaseDir()
const asciidocTextDocument = AsciidocTextDocument.fromTextDocument(textDocument)
const baseDir = asciidocTextDocument.baseDir
const documentDirectory = asciidocTextDocument.dirName
const documentBasename = asciidocTextDocument.fileName
const documentExtensionName = asciidocTextDocument.extensionName
const documentFilePath = asciidocTextDocument.filePath
const templateDirs = this.getTemplateDirs()
const options: { [key: string]: any } = {
attributes: {
...attributes,
...antoraAttributes,
// The following attributes are "intrinsic attributes" but they are not set when the input is a string
// like we are doing, in that case it is expected that the attributes are set here for the API:
// https://docs.asciidoctor.org/asciidoc/latest/attributes/document-attributes-ref/#intrinsic-attributes
// this can be set since safe mode is 'UNSAFE'
...(documentDirectory && { docdir: documentDirectory }),
...(documentFilePath && { docfile: documentFilePath }),
...(documentBasename && { docname: documentBasename }),
docfilesuffix: documentExtensionName,
filetype: asciidoctorWebViewConverter.outfilesuffix.substring(1), // remove the leading '.'
'!data-uri': '', // disable data-uri since Asciidoctor.js is unable to read files from a VS Code workspace.
},
backend: 'webview-html5',
Expand Down
4 changes: 2 additions & 2 deletions src/asciidocLoader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export class AsciidocLoader {
memoryLogger,
registry,
} = await this.prepare(textDocument)
const baseDir = AsciidocTextDocument.fromTextDocument(textDocument).getBaseDir()
const baseDir = AsciidocTextDocument.fromTextDocument(textDocument).baseDir
const attributes = AsciidoctorAttributesConfig.getPreviewAttributes()
const doc = this.processor.load(textDocument.getText(), this.getOptions(attributes, registry, baseDir))
this.asciidoctorDiagnosticProvider.reportErrors(memoryLogger, textDocument)
Expand Down Expand Up @@ -94,7 +94,7 @@ export class AsciidocIncludeItemsLoader extends AsciidocLoader {
registry,
} = await this.prepare(textDocument)
this.asciidoctorIncludeItemsProvider.activate(registry)
const baseDir = AsciidocTextDocument.fromTextDocument(textDocument).getBaseDir()
const baseDir = AsciidocTextDocument.fromTextDocument(textDocument).baseDir
const attributes = AsciidoctorAttributesConfig.getPreviewAttributes()
this.asciidoctorIncludeItemsProvider.reset()
this.processor.load(textDocument.getText(), this.getOptions(attributes, registry, baseDir))
Expand Down
62 changes: 54 additions & 8 deletions src/asciidocTextDocument.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,31 +7,77 @@ interface DocumentWithUri {
}

export class AsciidocTextDocument {
private uri: Uri
public baseDir: string | undefined
public dir: string | undefined
public dirName: string | undefined
public extensionName: string
public fileName: string | undefined
public filePath: string | undefined

private constructor () {
private constructor (private uri: Uri) {
this.baseDir = AsciidocTextDocument.getBaseDir(uri)
this.dirName = AsciidocTextDocument.getDirName(uri)
this.extensionName = AsciidocTextDocument.getExtensionName(uri)
this.fileName = AsciidocTextDocument.getFileName(uri)
this.filePath = AsciidocTextDocument.getFilePath(uri)
}

public static fromTextDocument (textDocument: DocumentWithUri): AsciidocTextDocument {
const asciidocTextDocument = new AsciidocTextDocument()
asciidocTextDocument.uri = textDocument.uri
return asciidocTextDocument
return new AsciidocTextDocument(textDocument.uri)
}

/**
* Get the base directory.
* @private
*/
public getBaseDir (): string | undefined {
private static getBaseDir (uri: Uri): string | undefined {
const useWorkspaceAsBaseDir = vscode.workspace.getConfiguration('asciidoc', null).get('useWorkspaceRootAsBaseDirectory')
if (useWorkspaceAsBaseDir) {
const workspaceFolder = getWorkspaceFolder(this.uri)
const workspaceFolder = getWorkspaceFolder(uri)
if (workspaceFolder) {
return workspaceFolder.uri.fsPath
}
}
return AsciidocTextDocument.getDirName(uri)
}

private static getDirName (uri: Uri): string | undefined {
return 'browser' in process && (process as any).browser === true
? undefined
: path.dirname(path.resolve(this.uri.fsPath))
: path.dirname(path.resolve(uri.fsPath))
}

/**
* Return the extension name of the file without the '.'.
* @param uri
* @private
*/
private static getExtensionName (uri: Uri): string {
const textDocumentExt = path.extname(uri.path)
return textDocumentExt.startsWith('.') ? textDocumentExt.substring(1) : ''
}

/**
* Return the file name without the file extension.
* @param uri
* @private
*/
public static getFileName (uri: Uri): string | undefined {
if ('browser' in process && (process as any).browser === true) {
return undefined
}
return path.parse(uri.fsPath).name
}

/**
* Return the filesystem path of the URI.
* @param uri
* @private
*/
public static getFilePath (uri: Uri): string | undefined {
if ('browser' in process && (process as any).browser === true) {
return undefined
}
return uri.fsPath
}
}
19 changes: 8 additions & 11 deletions src/commands/exportAsPDF.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import { exec, spawn, SpawnOptions } from 'child_process'
import { uuidv4 } from 'uuid'
import { AsciidocEngine } from '../asciidocEngine'
import { Command } from '../commandManager'
import { Logger } from '../logger'
import { Asciidoctor } from '@asciidoctor/core'
import { AsciidocTextDocument } from '../asciidocTextDocument'
import { getAsciidoctorConfigContent } from '../features/asciidoctorConfig'
Expand All @@ -16,7 +15,7 @@ export class ExportAsPDF implements Command {
public readonly id = 'asciidoc.exportAsPDF'
private readonly exportAsPdfStatusBarItem = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Right, 100)

constructor (private readonly engine: AsciidocEngine, private readonly context: vscode.ExtensionContext, private readonly logger: Logger) {
constructor (private readonly engine: AsciidocEngine, private readonly context: vscode.ExtensionContext) {
}

public async execute () {
Expand All @@ -31,11 +30,9 @@ export class ExportAsPDF implements Command {
await vscode.window.showWarningMessage('Unable to get the workspace folder, aborting.')
return
}
const workspacePath = workspaceFolder.uri.fsPath
const docNameWithoutExtension = path.parse(doc.uri.fsPath).name

const baseDirectory = AsciidocTextDocument.fromTextDocument(doc).getBaseDir()
const pdfFilename = vscode.Uri.file(path.join(baseDirectory, docNameWithoutExtension + '.pdf'))
const asciidocTextDocument = AsciidocTextDocument.fromTextDocument(doc)
const baseDirectory = asciidocTextDocument.baseDir
const pdfFilename = vscode.Uri.file(path.join(baseDirectory, asciidocTextDocument.fileName + '.pdf'))

const asciidocPdfConfig = vscode.workspace.getConfiguration('asciidoc.pdf')
const pdfOutputUri = await vscode.window.showSaveDialog({ defaultUri: pdfFilename })
Expand All @@ -51,9 +48,9 @@ export class ExportAsPDF implements Command {
text = `${asciidoctorConfigContent}
${text}`
}

const pdfEnfine = asciidocPdfConfig.get('engine')
if (pdfEnfine === 'asciidoctor-pdf') {
const workspacePath = workspaceFolder.uri.fsPath
const pdfEngine = asciidocPdfConfig.get('engine')
if (pdfEngine === 'asciidoctor-pdf') {
const asciidoctorPdfCommand = await this.resolveAsciidoctorPdfCommand(asciidocPdfConfig, workspacePath)
if (asciidoctorPdfCommand === undefined) {
return
Expand Down Expand Up @@ -84,7 +81,7 @@ ${text}`
} finally {
this.exportAsPdfStatusBarItem.hide()
}
} else if (pdfEnfine === 'wkhtmltopdf') {
} else if (pdfEngine === 'wkhtmltopdf') {
let wkhtmltopdfCommandPath = asciidocPdfConfig.get('wkhtmltopdfCommandPath', '')
if (wkhtmltopdfCommandPath === '') {
wkhtmltopdfCommandPath = `wkhtmltopdf${process.platform === 'win32' ? '.exe' : ''}`
Expand Down
2 changes: 1 addition & 1 deletion src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ export async function activate (context: vscode.ExtensionContext) {
commandManager.register(new commands.ShowPreviewSecuritySelectorCommand(previewSecuritySelector, previewManager))
commandManager.register(new commands.ShowAsciidoctorExtensionsTrustModeSelectorCommand(asciidoctorExtensionsTrustModeSelector))
commandManager.register(new commands.OpenDocumentLinkCommand(asciidocLoader))
commandManager.register(new commands.ExportAsPDF(asciidocEngine, context, logger))
commandManager.register(new commands.ExportAsPDF(asciidocEngine, context))
commandManager.register(new commands.PasteImage(asciidocLoader))
commandManager.register(new commands.ToggleLockCommand(previewManager))
commandManager.register(new commands.ShowPreviewCommand(previewManager))
Expand Down
Loading