Merge pull request #290 from sharelatex/enable-chktex

Enable chktex
This commit is contained in:
Brian Gough 2016-08-10 11:49:31 +01:00 committed by GitHub
commit abcfb2dd16
9 changed files with 122 additions and 31 deletions

View file

@ -147,6 +147,7 @@ module.exports = ClsiManager =
timeout: options.timeout
imageName: project.imageName
draft: !!options.draft
check: options.check
rootResourcePath: rootResourcePath
resources: resources
}

View file

@ -29,6 +29,8 @@ module.exports = CompileController =
options.compiler = req.body.compiler
if req.body?.draft
options.draft = req.body.draft
if req.body?.check
options.check = if req.body.check is "validate" then "validate" else undefined
logger.log {options:options, project_id:project_id, user_id:user_id}, "got compile request"
CompileManager.compile project_id, user_id, options, (error, status, outputFiles, clsiServerId, limits, validationProblems) ->
return next(error) if error?

View file

@ -25,7 +25,7 @@ div.full-size.pdf(ng-controller="PdfController")
dropdown-toggle
)
span.caret
ul.dropdown-menu.dropdown-menu-right
ul.dropdown-menu.dropdown-menu-left
li.dropdown-header #{translate("compile_mode")}
li
a(href, ng-click="draft = false")
@ -36,6 +36,13 @@ div.full-size.pdf(ng-controller="PdfController")
i.fa.fa-fw(ng-class="{'fa-check': draft}")
|  #{translate("fast")} 
span.subdued [draft]
if user.betaProgram
li.dropdown-header #{translate("file_checks")}
li
a(href, ng-click="recompile({check:true})")
i.fa.fa-fw()
|  #{translate("run_syntax_check")}
span.beta-feature-badge
a(
href
ng-click="stop()"
@ -115,7 +122,8 @@ div.full-size.pdf(ng-controller="PdfController")
|  
span(ng-show="entry.file") {{ entry.file }}
span(ng-show="entry.line") , line {{ entry.line }}
p.entry-message(ng-show="entry.message") {{ entry.message }}
p.entry-message(ng-show="entry.message")
| {{ entry.type }} {{ entry.message }}
.card.card-hint(
ng-if="entry.humanReadableHint"
stop-propagation="click"
@ -126,7 +134,7 @@ div.full-size.pdf(ng-controller="PdfController")
ng-show="entry.humanReadableHint",
ng-bind-html="wikiEnabled ? entry.humanReadableHint : stripHTMLFromString(entry.humanReadableHint)")
.card-hint-actions.clearfix
.card-hint-ext-link(ng-if="wikiEnabled")
.card-hint-ext-link(ng-if="wikiEnabled && entry.extraInfoURL")
a(
ng-href="{{ entry.extraInfoURL }}",
ng-click="trackLogHintsLearnMore()"

View file

@ -46,7 +46,7 @@ define [
done = () =>
if options.gotoLine?
@$scope.$broadcast "editor:gotoLine", options.gotoLine
@$scope.$broadcast "editor:gotoLine", options.gotoLine, options.gotoColumn
if doc.id == @$scope.editor.open_doc_id and !options.forceReopen
@$scope.$apply () =>

View file

@ -23,10 +23,10 @@ define [], () ->
@storeCursorPosition(@editor.getSession())
@storeScrollTopPosition(@editor.getSession())
@$scope.$on "#{@$scope.name}:gotoLine", (editor, value) =>
if value?
@$scope.$on "#{@$scope.name}:gotoLine", (editor, line, column) =>
if line?
setTimeout () =>
@gotoLine(value)
@gotoLine(line, column)
, 10 # Hack: Must happen after @gotoStoredPosition
storeScrollTopPosition: (session) ->
@ -53,6 +53,6 @@ define [], () ->
@editor.getSession().setScrollTop(pos.scrollTop or 0)
delete @ignoreCursorPositionChanges
gotoLine: (line) ->
@editor.gotoLine(line)
@editor.focus()
gotoLine: (line, column) ->
@editor.gotoLine(line, column)
@editor.focus()

View file

@ -3,7 +3,10 @@ define [
"ide/human-readable-logs/HumanReadableLogsRules"
], (LogParser, ruleset) ->
parse : (rawLog, options) ->
parsedLogEntries = LogParser.parse(rawLog, options)
if typeof rawLog is 'string'
parsedLogEntries = LogParser.parse(rawLog, options)
else
parsedLogEntries = rawLog
_getRule = (logMessage) ->
return rule for rule in ruleset when rule.regexToMatch.test logMessage
@ -12,7 +15,12 @@ define [
ruleDetails = _getRule entry.message
if (ruleDetails?)
entry.ruleId = 'hint_' + ruleDetails.regexToMatch.toString().replace(/\s/g, '_').slice(1, -1) if ruleDetails.regexToMatch?
if ruleDetails.ruleId?
entry.ruleId = ruleDetails.ruleId
else if ruleDetails.regexToMatch?
entry.ruleId = 'hint_' + ruleDetails.regexToMatch.toString().replace(/\s/g, '_').slice(1, -1)
if ruleDetails.newMessage?
entry.message = entry.message.replace ruleDetails.regexToMatch, ruleDetails.newMessage
entry.humanReadableHint = ruleDetails.humanReadableHint if ruleDetails.humanReadableHint?
entry.extraInfoURL = ruleDetails.extraInfoURL if ruleDetails.extraInfoURL?

View file

@ -88,4 +88,19 @@ define -> [
humanReadableHint: """
You have used a font command which is only available in math mode. To use this command, you must be in maths mode (E.g. $ \u2026 $ or \\begin{math} \u2026 \\end{math}). If you want to use it outside of math mode, use the text version instead: \\textrm, \\textit, etc.
"""
,
ruleId: "hint_mismatched_environment"
regexToMatch: /Error: `([^']{2,})' expected, found `([^']{2,})'.*/
newMessage: "Error: environment does not match \\begin{$1} ... \\end{$2}"
humanReadableHint: """
You have used \\begin{...} without a corresponding \\end{...}.
"""
,
ruleId: "hint_mismatched_brackets"
regexToMatch: /Error: `([^a-zA-Z0-9])' expected, found `([^a-zA-Z0-9])'.*/
newMessage: "Error: brackets do not match, found '$2' instead of '$1'"
humanReadableHint: """
You have used an open bracket without a corresponding close bracket.
"""
]

View file

@ -86,11 +86,15 @@ define [
return $http.post url, {
rootDoc_id: options.rootDocOverride_id or null
draft: $scope.draft
check: if options.check then "validate" else null
_csrf: window.csrfToken
}, {params: params}
parseCompileResponse = (response) ->
# keep last url
last_pdf_url = $scope.pdf.url
# Reset everything
$scope.pdf.error = false
$scope.pdf.timedout = false
@ -120,11 +124,23 @@ define [
if response.status == "timedout"
$scope.pdf.view = 'errors'
$scope.pdf.timedout = true
fetchLogs(fileByPath['output.log'], fileByPath['output.blg'])
fetchLogs(fileByPath)
else if response.status == "terminated"
$scope.pdf.view = 'errors'
$scope.pdf.compileTerminated = true
fetchLogs(fileByPath['output.log'], fileByPath['output.blg'])
fetchLogs(fileByPath)
else if response.status in ["validation-fail", "validation-pass"]
$scope.pdf.view = 'pdf'
$scope.pdf.compileExited = true
$scope.pdf.url = last_pdf_url
$scope.shouldShowLogs = true
fetchLogs(fileByPath, { validation: true })
else if response.status == "exited"
$scope.pdf.view = 'pdf'
$scope.pdf.compileExited = true
$scope.pdf.url = last_pdf_url
$scope.shouldShowLogs = true
fetchLogs(fileByPath)
else if response.status == "autocompile-backoff"
$scope.pdf.view = 'uncompiled'
else if response.status == "project-too-large"
@ -134,7 +150,7 @@ define [
$scope.pdf.view = 'errors'
$scope.pdf.failure = true
$scope.shouldShowLogs = true
fetchLogs(fileByPath['output.log'], fileByPath['output.blg'])
fetchLogs(fileByPath)
else if response.status == 'clsi-maintenance'
$scope.pdf.view = 'errors'
$scope.pdf.clsiMaintenance = true
@ -165,7 +181,7 @@ define [
qs.popupDownload = true
$scope.pdf.downloadUrl = "/project/#{$scope.project_id}/output/output.pdf" + createQueryString(qs)
fetchLogs(fileByPath['output.log'], fileByPath['output.blg'])
fetchLogs(fileByPath)
IGNORE_FILES = ["output.fls", "output.fdb_latexmk"]
$scope.pdf.outputFiles = []
@ -186,7 +202,13 @@ define [
}
fetchLogs = (logFile, blgFile) ->
fetchLogs = (fileByPath, options) ->
if options?.validation
chktexFile = fileByPath['output.chktex']
else
logFile = fileByPath['output.log']
blgFile = fileByPath['output.blg']
getFile = (name, file) ->
opts =
@ -213,6 +235,8 @@ define [
accumulateResults = (newEntries) ->
for key in ['all', 'errors', 'warnings']
if newEntries.type?
entry.type = newEntries.type for entry in newEntries[key]
logEntries[key] = logEntries[key].concat newEntries[key]
# use the parsers for each file type
@ -222,10 +246,24 @@ define [
all = [].concat errors, warnings, typesetting
accumulateResults {all, errors, warnings}
processChkTex = (log) ->
errors = []
warnings = []
for line in log.split("\n")
if m = line.match /^(\S+):(\d+):(\d+): (Error|Warning): (.*)/
result = { file:m[1], line:m[2], column:m[3], level:m[4].toLowerCase(), message: "#{m[4]}: #{m[5]}"}
if result.level is 'error'
errors.push result
else
warnings.push result
all = [].concat errors, warnings
logHints = HumanReadableLogs.parse {type: "Validation", all, errors, warnings}
accumulateResults logHints
processBiber = (log) ->
{errors, warnings} = BibLogParser.parse(log, {})
all = [].concat errors, warnings
accumulateResults {all, errors, warnings}
accumulateResults {type: "BibTeX", all, errors, warnings}
# output the results
handleError = () ->
@ -248,19 +286,35 @@ define [
}
# retrieve the logfile and process it
response = getFile('output.log', logFile)
.success processLog
.error handleError
if logFile?
response = getFile('output.log', logFile)
.then (response) -> processLog(response.data)
if blgFile? # retrieve the blg file if present
response.success () ->
getFile('output.blg', blgFile)
# ignore errors in biber file
.success processBiber
# display the combined result
.then annotateFiles
else # otherwise just display the result
response.success annotateFiles
if blgFile? # retrieve the blg file if present
response = response.then () ->
getFile('output.blg', blgFile)
.then(
(response) -> processBiber(response.data),
() -> true # ignore errors in biber file
)
if response?
response.catch handleError
else
handleError()
if chktexFile?
getChkTex = () ->
getFile('output.chktex', chktexFile)
.then (response) -> processChkTex(response.data)
# always retrieve the chktex file if present
if response?
response = response.then getChkTex, getChkTex
else
response = getChkTex()
# display the combined result
response.finally annotateFiles
getRootDocOverride_id = () ->
doc = ide.editorManager.getCurrentDocValue()
@ -504,7 +558,9 @@ define [
return if !entity? or entity.type != "doc"
if entry.line?
line = entry.line
ide.editorManager.openDoc(entity, gotoLine: line)
if entry.column?
column = entry.column
ide.editorManager.openDoc(entity, gotoLine: line, gotoColumn: column)
]
App.controller 'ClearCacheModalController', ["$scope", "$modalInstance", ($scope, $modalInstance) ->

View file

@ -174,6 +174,7 @@ describe "ClsiManager", ->
timeout : 100
imageName: @image
draft: false
check: undefined
rootResourcePath: "main.tex"
resources: [{
path: "main.tex"