mirror of
https://github.com/overleaf/overleaf.git
synced 2025-04-08 21:00:45 +00:00
commit
abcfb2dd16
9 changed files with 122 additions and 31 deletions
|
@ -147,6 +147,7 @@ module.exports = ClsiManager =
|
|||
timeout: options.timeout
|
||||
imageName: project.imageName
|
||||
draft: !!options.draft
|
||||
check: options.check
|
||||
rootResourcePath: rootResourcePath
|
||||
resources: resources
|
||||
}
|
||||
|
|
|
@ -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?
|
||||
|
|
|
@ -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()"
|
||||
|
|
|
@ -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 () =>
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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?
|
||||
|
|
|
@ -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.
|
||||
"""
|
||||
|
||||
]
|
||||
|
|
|
@ -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) ->
|
||||
|
|
|
@ -174,6 +174,7 @@ describe "ClsiManager", ->
|
|||
timeout : 100
|
||||
imageName: @image
|
||||
draft: false
|
||||
check: undefined
|
||||
rootResourcePath: "main.tex"
|
||||
resources: [{
|
||||
path: "main.tex"
|
||||
|
|
Loading…
Add table
Reference in a new issue