-
Notifications
You must be signed in to change notification settings - Fork 41
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
LSP Server Support #58
Open
b-studios
wants to merge
50
commits into
mathpoly
Choose a base branch
from
feature/lsp
base: mathpoly
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from 14 commits
Commits
Show all changes
50 commits
Select commit
Hold shift + click to select a range
781e276
Export webmain to use from typescript
b-studios 359c853
Export more information about labels
b-studios 3e47972
Backport null
b-studios a7df281
Strip down processing
b-studios deb8cde
Log warnings in analyze mode
b-studios 5837a88
Allow block extraction in public interface
b-studios 7e3a36b
Add comment
b-studios dc2841c
Also annotate range information on blocks
b-studios 8e1607c
Fix some copy&paste errors
b-studios 92781d5
Also export ranges of blocks
b-studios f358e3a
Move LSP api to a separate koka-file
b-studios 6777d34
Move processContent to api
b-studios 7f5a2bc
Fix whitespaces :lipstick:
b-studios 55c53d4
Revert dependency changes
b-studios b5d21a2
Simplify api.processContent
b-studios d56b958
Make processContent direct style
b-studios de9d174
Change signature of markdown to reuse it in API
b-studios a23c8bf
Write a few more aux files for static math
b-studios e79590e
Perform includes before running markdown
b-studios 58f30f4
Allow skipping of includes
b-studios 0a116d1
Merge LSP api with old public api for backwards compatability
b-studios efc9de1
Always provide second argument to avoid problems with trailing brackets
b-studios 1311ab6
fix doi url handling; add acmart bib style support (showISSN etc)
daanx db35fcc
Merge branch 'master' into lsp
b-studios a632ee1
update madoko-local for node 12+
daanx 0b9879d
update styles for TexLive1019
daanx 793f4a2
update acmart style
daanx f3c82f3
update version to 1.7
daanx 7850916
fix \Bbbk error
daanx b3c0e53
fix rmdirp version
daanx 999c2bc
add support for inline math and code in tables containing `|`
daanx 6fc6d9a
fix decipher on new nodejs
daanx 8e9f15d
fix github login and repo listinq
daanx e14ee95
update log message
daanx 59380ee
Merge branch 'master' of https://github.com/koka-lang/madoko
daanx f4d96a2
update version
daanx b2b5eda
Merge branch 'master' of https://github.com/koka-lang/madoko
daanx b341e21
fix table reformatting in the web UI with math/code that contains |
daanx 3a8b3b5
update build instructions
daanx 6680cfe
update madoko-local to have more liberal timeouts
daanx c13412a
enable running dvisvgm in parallel
daanx 0f75f9f
bump to version 1.1.9
daanx 5c877f0
allow math concurrency setting outside sandbox
daanx f36a7ac
update madoko local
daanx ee8ac1a
fix build
daanx 572cae4
2 minute process timeout in sandbox mode
daanx 6d582dd
update madoko local with concurrency flag
daanx 8d9806f
add svg-bbox-exact option to speed up svg genaration by default.
daanx 826f5c1
bump version to 1.2.0
daanx e6cbbf8
Merge master
b-studios File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
declare module 'madoko' { | ||
type Options = any; | ||
type Position = { path: string, line: number } | ||
type Range = { path: string, from: number, to: number } | ||
type ReferenceInfo = { | ||
id: string, | ||
element: string, | ||
caption: string, | ||
position?: Position | ||
} | ||
type DocumentInfo = { | ||
labels: ReferenceInfo[], | ||
blocks: Block[], | ||
context: any, | ||
log: string | ||
} | ||
type Block = { | ||
kind: string, | ||
// the element id, empty if not present | ||
id: string, | ||
// the tag name, empty if not present | ||
name: string, | ||
// the child nodes | ||
content: Block[], | ||
// the element classes | ||
classes: string[], | ||
// the annotated attributes | ||
attributes: any, | ||
// the range (lines are 1-based and inclusive) | ||
range?: Range | ||
} | ||
|
||
export function analyze( | ||
inputName: string, | ||
content: string, | ||
callback: (DocumentInfo) => any): any; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,234 @@ | ||
module api | ||
|
||
import std/dict | ||
import std/regex | ||
import std/log | ||
import std/path | ||
|
||
import backports | ||
import version | ||
|
||
import block // just for the type block | ||
import formatBlock // just for formatContext | ||
import common // for label, lineMap, and attrs | ||
import inline // for parseLineInfo | ||
import driver // for outputName, processContentLSP | ||
import metadata // for parseMeta | ||
import madoko // for normalizeSource, lastPathSegment | ||
import definitions // for parseBody | ||
import options | ||
import includes | ||
|
||
|
||
// Types that are part of the public API | ||
// ------------------------------------- | ||
|
||
// TODO also migrate to range | ||
public struct position (path: string, line: int) | ||
|
||
// Line information is 1-based and inclusive. | ||
public struct range (path: string, from: int, to: int) | ||
|
||
public struct referenceInfo ( | ||
id: string, | ||
element: string, | ||
caption: string, | ||
position: null<position> | ||
) | ||
|
||
public struct documentInfo ( | ||
labels: vector<referenceInfo>, | ||
blocks: vector<blockInfo>, | ||
// just for debugging purposes we also include the original formatContext | ||
context : formatContext, | ||
log: string | ||
) | ||
|
||
// the type of block nodes we export to js / typescript | ||
public struct blockInfo ( | ||
// the block kind | ||
kind: string, | ||
// the element id, empty if not present | ||
id: string, | ||
// the tag name, empty if not present | ||
name: string, | ||
// the child nodes | ||
content: vector<blockInfo>, | ||
// the text content | ||
text: string, | ||
// the classes | ||
classes: vector<string>, | ||
// attributes of the block node (like "caption") | ||
attributes: dict<string>, | ||
// TODO also include position and range information. | ||
position: null<range> | ||
) | ||
|
||
// Main Entrypoint | ||
// --------------- | ||
|
||
// Runs the frontend to parse and analyze the document but does not | ||
// generate an html or tex document. | ||
// | ||
// Resolves includes and also processes those files. | ||
// | ||
// TODO Currently the logs are very sparse... Did I omit too much of the | ||
// processing to catch errors? | ||
public function analyze( | ||
inputName : string, content : string, continue : (documentInfo) -> io () | ||
) : io () { | ||
printRedirect( fun(s) { log("stdout", s) }); | ||
|
||
withLog("stdout") { | ||
processContent(inputName, content) fun (blocks, ctx) { | ||
val stdout = getLog("stdout") | ||
val labeledElems = ctx.inlineContext.labels.list().map(labelInfo) | ||
val res = DocumentInfo(vector(labeledElems), blocks.toBlockInfos(inputName), ctx, stdout) | ||
continue(res) | ||
} | ||
} | ||
() | ||
} | ||
|
||
|
||
function processContent( | ||
inName : string, content : string, | ||
continue : (list<block>, formatContext) -> io () | ||
) : io () { | ||
// is this ever used? | ||
val outName = "/tmp/madoko/out.mdk" | ||
|
||
val searchDirs = [inName.dirname] | ||
|
||
val opts0 = Options( | ||
version=version/version, | ||
lineNoWeb=True, | ||
math=Mathoptions(mode = Dynamic), // don't generate math latex | ||
embedLimit=0, | ||
verbose=1, | ||
copyStyles=False) | ||
|
||
// running fastMode destroys positioning | ||
val fastMode = False | ||
|
||
content.include(fastMode, inName, outName, searchDirs, opts0) fun(icontent0,lmap) { | ||
// remove madoko comments | ||
val icontent = icontent0 //.removeMadokoComments | ||
|
||
val opts1 = opts0(lineMap=lmap, | ||
processTimeout=if (opts0.sandbox) then 60000 else opts0.processTimeout, | ||
metadata=opts0.metadata) | ||
|
||
// Just extract metadata and symbols (copied from markdownNormal) | ||
// first normalize the input: all tabs to 4 spaces. | ||
val (options, src) = parseMeta(opts1, FmtHtml, icontent.normalizeSource) | ||
|
||
val icontext = inlineContext(FmtHtml, | ||
options.metadata.dict, | ||
options.math.dim, | ||
options.embedinfos, | ||
options.citestyle.maybe(citeNumeric, id), | ||
options.sanitize, | ||
options.bench, | ||
options.verbose, | ||
options.math.mode.isStatic, | ||
options.highlight, | ||
options.starBold, | ||
options.sandbox, | ||
options.prettyAlign) | ||
|
||
val (warns0, (blocks, fcontext)) = withLog("warning") { | ||
parseBody( | ||
initialFormatContext(icontext, options.lineMap, options.headingBase, options.pedantic, FmtHtml), | ||
options.lineNo, | ||
src, | ||
options.metadata, options.tocDepth, options.sectionBase, options.sectionMax) | ||
} | ||
// TODO don't collect warnings stringly typed. | ||
log("stdout", warns0) | ||
// val warns = fixWarnings(warns0) | ||
// if (warns != "") { | ||
// log("stdout", warns) | ||
// } | ||
|
||
continue(blocks, fcontext) | ||
} | ||
} | ||
|
||
|
||
// Computing position and range information | ||
// --------------------------------------- | ||
|
||
function range(attr: attrs, inputName: string): maybe<range> { | ||
match (attr.hasKey("data-line-start")) { | ||
Just(start) -> catch({ | ||
val end = attr.lookupKey("data-line-end", start) | ||
val (path, startLine) = start.extractPosition(inputName) | ||
val (_, endLine) = end.extractPosition(inputName) | ||
Just(Range(path, startLine, endLine)) | ||
}, fun(exn) { Nothing }) | ||
Nothing -> Nothing | ||
} | ||
} | ||
|
||
function extractPosition(locationString: string, inputName: string): exn (string, int) { | ||
val locs = (inputName + ":" + locationString).split(";").list | ||
val last = locs.last.split(":") | ||
(last[0], last[1].parseInt.unJust) | ||
} | ||
|
||
// we need the inputName to normalize position information | ||
function toBlockInfos(bs: list<block>, inputName: string): div vector<blockInfo> { | ||
vector(bs.map(fun(b){ b.toBlockInfo(inputName) }).concatMaybe) | ||
} | ||
|
||
// TODO also include range information in extracted block structure | ||
function toBlockInfo(b: block, inputName: string): div maybe<blockInfo> { | ||
match(b) { | ||
HLine( attrs ) -> | ||
Just(BlockInfo("hline", attrs.name, attrs.elem, vector(), "", vector(attrs.classes), dict(attrs.keyvals), attrs.range(inputName).null)) | ||
Para( text, attrs ) -> | ||
Just(BlockInfo("para", attrs.name, attrs.elem, vector(), text, vector(attrs.classes), dict(attrs.keyvals), attrs.range(inputName).null)) | ||
Code( text, _, attrs) -> | ||
Just(BlockInfo("code", attrs.name, attrs.elem, vector(), text, vector(attrs.classes), dict(attrs.keyvals), attrs.range(inputName).null)) | ||
Quote( content, attrs) -> | ||
Just(BlockInfo("quote", attrs.name, attrs.elem, content.toBlockInfos(inputName), "", vector(attrs.classes), dict(attrs.keyvals), attrs.range(inputName).null)) | ||
List( _, content, attrs) -> | ||
Just(BlockInfo("list", attrs.name, attrs.elem, content.toBlockInfos(inputName), "", vector(attrs.classes), dict(attrs.keyvals), attrs.range(inputName).null)) | ||
Item( content, attrs) -> | ||
Just(BlockInfo("item", attrs.name, attrs.elem, content.toBlockInfos(inputName), "", vector(attrs.classes), dict(attrs.keyvals), attrs.range(inputName).null)) | ||
Heading( _, text, attrs) -> | ||
Just(BlockInfo("heading", attrs.name, attrs.elem, vector(), text, vector(attrs.classes), dict(attrs.keyvals), attrs.range(inputName).null)) | ||
// currently table cells are ignored | ||
Table( _, _, _, attrs) -> | ||
Just(BlockInfo("table", attrs.name, attrs.elem, vector(), "", vector(attrs.classes), dict(attrs.keyvals), attrs.range(inputName).null)) | ||
Div( content, attrs) -> | ||
Just(BlockInfo("div", attrs.name, attrs.elem, content.toBlockInfos(inputName), "", vector(attrs.classes), dict(attrs.keyvals), attrs.range(inputName).null)) | ||
Source( text, _, attrs) -> | ||
Just(BlockInfo("source", attrs.name, attrs.elem, vector(), text, vector(attrs.classes), dict(attrs.keyvals), attrs.range(inputName).null)) | ||
// DefLink( id, link) -> | ||
// DefFootnote( id, content) -> | ||
// Empty() -> | ||
// Special( name, value, attrs) -> | ||
// Line( text, _, attrs) -> | ||
_ -> Nothing | ||
} | ||
} | ||
|
||
|
||
function labelInfo(elem: (string, label)): referenceInfo { | ||
val (id, label) = elem | ||
ReferenceInfo(id, label.element, label.labelCaption, null(label.labelPosition)) | ||
} | ||
|
||
// TODO change to labelRange | ||
function labelPosition(label : label) : maybe<position> { | ||
match(label.labelAttrs.hasKey("data-line")) { // || label.labelAttrs.hasKey("data-line-first") | ||
Just(info) -> { | ||
val (path, lineno) = parseLineInfo(info) | ||
Just(Position(path.lastPathSegment, lineno)) | ||
// if (lineno <= 0 || info.startsWith("0;")) then Nothing else Just((path.lastPathSegment, lineno)) | ||
} | ||
Nothing -> Nothing | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
module backports | ||
|
||
// backporting null from newer Koka versions: | ||
|
||
// Abstract type used for passing `null` values to external functions | ||
public type null<a> | ||
|
||
// Transform a `:maybe` type to a `:null` type (using `null` for `Nothing`). | ||
public external null(x : maybe<a>) : null<a> { | ||
cs inline "(#1.tag_ == __std_core._maybe_Tag.Nothing ? default(##1) : #1.@value)" | ||
js inline "(#1==null ? null : #1.unJust)" | ||
} | ||
|
||
// Transform a `:null` type to a `:maybe` type. Note that it is not | ||
// always the case that `id(x) == maybe(null(x))` (e.g. when `x = Just(Nothing)`). | ||
public external maybe( n : null<a> ) : maybe<a> { | ||
cs inline "(EqualityComparer<##1>.Default.Equals(#1,default(##1)) ? __std_core._maybe<##1>.Nothing_ : new __std_core._maybe<##1>(#1))" | ||
js inline "(#1==null ? $std_core.Nothing : $std_core.Just(#1))" | ||
} | ||
|
||
function unjust( m : maybe<a> ) : exn a { | ||
match(m) { | ||
Just(x) -> x | ||
} | ||
} | ||
|
||
function (||)( m1 : maybe<a>, m2: maybe<a> ) : maybe<a> { | ||
match(m1) { | ||
Nothing -> m2 | ||
_ -> m1 | ||
} | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here I changed the main file to access
analyze
instead ofmadoko
. We need to change this to allow both.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I merged the two interfaces and changed it back, so it should be mostly backwards compatible , modulo the change of the return type of
markdown
: