From 024ebcf77ff0a8a0fe30680e96860fc054f2855b Mon Sep 17 00:00:00 2001 From: Alf Eaton Date: Mon, 20 Feb 2023 13:45:22 +0000 Subject: [PATCH] Merge pull request #11877 from overleaf/mj-undefined-control-sequence-help [web] Improve error messages around missing packages GitOrigin-RevId: d6f59f452cdc8a5a7e59b9809f68bd18f629ba32 --- .../pdf-preview/components/pdf-log-entry.js | 4 +- .../components/pdf-logs-entries.js | 1 + .../human-readable-logs/HumanReadableLogs.js | 12 ++ .../HumanReadableLogsHints.js | 103 +++++++++++------- .../HumanReadableLogsPackageSuggestions.js | 7 ++ .../HumanReadableLogsRules.js | 10 ++ 6 files changed, 94 insertions(+), 43 deletions(-) create mode 100644 services/web/frontend/js/ide/human-readable-logs/HumanReadableLogsPackageSuggestions.js diff --git a/services/web/frontend/js/features/pdf-preview/components/pdf-log-entry.js b/services/web/frontend/js/features/pdf-preview/components/pdf-log-entry.js index c72d3874a1..2f20aa9e96 100644 --- a/services/web/frontend/js/features/pdf-preview/components/pdf-log-entry.js +++ b/services/web/frontend/js/features/pdf-preview/components/pdf-log-entry.js @@ -19,12 +19,13 @@ function PdfLogEntry({ showCloseButton = false, entryAriaLabel = null, customClass, + contentDetails, onSourceLocationClick, onClose, }) { if (ruleId && HumanReadableLogsHints[ruleId]) { const hint = HumanReadableLogsHints[ruleId] - formattedContent = hint.formattedContent + formattedContent = hint.formattedContent(contentDetails) extraInfoURL = hint.extraInfoURL } @@ -84,6 +85,7 @@ PdfLogEntry.propTypes = { showSourceLocationLink: PropTypes.bool, showCloseButton: PropTypes.bool, entryAriaLabel: PropTypes.string, + contentDetails: PropTypes.arrayOf(PropTypes.string), onSourceLocationClick: PropTypes.func, onClose: PropTypes.func, } diff --git a/services/web/frontend/js/features/pdf-preview/components/pdf-logs-entries.js b/services/web/frontend/js/features/pdf-preview/components/pdf-logs-entries.js index c52f3f805b..a4352c49ab 100644 --- a/services/web/frontend/js/features/pdf-preview/components/pdf-logs-entries.js +++ b/services/web/frontend/js/features/pdf-preview/components/pdf-logs-entries.js @@ -53,6 +53,7 @@ function PdfLogsEntries({ entries, hasErrors }) { rawContent={logEntry.content} logType={logEntry.type} level={logEntry.level} + contentDetails={logEntry.contentDetails} entryAriaLabel={t('log_entry_description', { level: logEntry.level, })} diff --git a/services/web/frontend/js/ide/human-readable-logs/HumanReadableLogs.js b/services/web/frontend/js/ide/human-readable-logs/HumanReadableLogs.js index d97fa3f188..a80932f0d1 100644 --- a/services/web/frontend/js/ide/human-readable-logs/HumanReadableLogs.js +++ b/services/web/frontend/js/ide/human-readable-logs/HumanReadableLogs.js @@ -35,6 +35,18 @@ export default { ruleDetails.newMessage ) } + if (ruleDetails.contentRegex) { + const match = entry.content.match(ruleDetails.contentRegex) + if (match) { + entry.contentDetails = match.slice(1) + } + } + if (entry.contentDetails && ruleDetails.improvedTitle) { + entry.message = ruleDetails.improvedTitle( + entry.message, + entry.contentDetails + ) + } // suppress any entries that are known to cascade from previous error types if (ruleDetails.cascadesFrom != null) { for (type of ruleDetails.cascadesFrom) { diff --git a/services/web/frontend/js/ide/human-readable-logs/HumanReadableLogsHints.js b/services/web/frontend/js/ide/human-readable-logs/HumanReadableLogsHints.js index e3c60e524f..21a5d8b0b0 100644 --- a/services/web/frontend/js/ide/human-readable-logs/HumanReadableLogsHints.js +++ b/services/web/frontend/js/ide/human-readable-logs/HumanReadableLogsHints.js @@ -1,4 +1,5 @@ import PropTypes from 'prop-types' +import packageSuggestions from './HumanReadableLogsPackageSuggestions' function WikiLink({ url, children }) { if (window.wikiEnabled) { @@ -21,7 +22,7 @@ const hints = { hint_misplaced_alignment_tab_character: { extraInfoURL: 'https://www.overleaf.com/learn/Errors/Misplaced_alignment_tab_character_%26', - formattedContent: ( + formattedContent: () => ( <> You have placed an alignment tab character '&' in the wrong place. If you want to align something, you must write it inside an align @@ -37,7 +38,7 @@ const hints = { hint_extra_alignment_tab_has_been_changed: { extraInfoURL: 'https://www.overleaf.com/learn/Errors/Extra_alignment_tab_has_been_changed_to_%5Ccr', - formattedContent: ( + formattedContent: () => ( <> You have written too many alignment tabs in a table, causing one of them to be turned into a line break. Make sure you have specified the correct @@ -49,7 +50,7 @@ const hints = { hint_display_math_should_end_with: { extraInfoURL: 'https://www.overleaf.com/learn/Errors/Display_math_should_end_with_$$', - formattedContent: ( + formattedContent: () => ( <> You have forgotten a $ sign at the end of 'display math' mode. When writing in display math mode, you must always math write inside $$ … $$. @@ -59,7 +60,7 @@ const hints = { }, hint_missing_inserted: { extraInfoURL: 'https://www.overleaf.com/learn/Errors/Missing_$_inserted', - formattedContent: ( + formattedContent: () => ( <>

You need to enclose all mathematical expressions and symbols with @@ -82,7 +83,7 @@ const hints = { hint_reference_undefined: { extraInfoURL: 'https://www.overleaf.com/learn/Errors/There_were_undefined_references', - formattedContent: ( + formattedContent: () => ( <> You have referenced something which has not yet been labelled. If you have labelled it already, make sure that what is written inside \ref @@ -94,7 +95,7 @@ const hints = { hint_there_were_undefined_references: { extraInfoURL: 'https://www.overleaf.com/learn/Errors/There_were_undefined_references', - formattedContent: ( + formattedContent: () => ( <> You have referenced something which has not yet been labelled. If you have labelled it already, make sure that what is written inside \ref @@ -106,7 +107,7 @@ const hints = { hint_citation_on_page_undefined_on_input_line: { extraInfoURL: 'https://www.overleaf.com/learn/Errors/Citation_XXX_on_page_XXX_undefined_on_input_line_XXX', - formattedContent: ( + formattedContent: () => ( <> You have cited something which is not included in your bibliography. Make sure that the citation (\cite @@ -118,7 +119,7 @@ const hints = { hint_label_multiply_defined_labels: { extraInfoURL: 'https://www.overleaf.com/learn/Errors/There_were_multiply-defined_labels', - formattedContent: ( + formattedContent: () => ( <> You have used the same label more than once. Check that each \label {'{...}'} labels only one item. @@ -128,7 +129,7 @@ const hints = { hint_float_specifier_changed: { extraInfoURL: 'https://www.overleaf.com/learn/Errors/%60!h%27_float_specifier_changed_to_%60!ht%27', - formattedContent: ( + formattedContent: () => ( <> The float specifier 'h' is too strict of a demand for LaTeX to place your float in a nice way here. Try relaxing it by using 'ht', or even @@ -144,7 +145,7 @@ const hints = { hint_no_positions_in_optional_float_specifier: { extraInfoURL: 'https://www.overleaf.com/learn/Errors/No_positions_in_optional_float_specifier', - formattedContent: ( + formattedContent: () => ( <> You have forgotten to include a float specifier, which tells LaTeX where to position your figure. To fix this, either insert a float specifier @@ -163,20 +164,38 @@ const hints = { hint_undefined_control_sequence: { extraInfoURL: 'https://www.overleaf.com/learn/Errors/Undefined_control_sequence', - formattedContent: ( - <> - The compiler is having trouble understanding a command you have used. - Check that the command is spelled correctly. If the command is part of a - package, make sure you have included the package in your preamble using - \usepackage - {'{...}'}. - - ), + formattedContent: details => { + if (details?.length && packageSuggestions.has(details[0])) { + const command = details[0] + const suggestion = packageSuggestions.get(command) + return ( + <> + Undefined control sequence. You have used the command{' '} + {command}, which is part of the{' '} + {suggestion.name} package. Make sure to include the + package in your{' '} + + preamble + {' '} + using {suggestion.command}. + + ) + } + return ( + <> + The compiler is having trouble understanding a command you have used. + Check that the command is spelled correctly. If the command is part of + a package, make sure you have included the package in your preamble + using \usepackage + {'{...}'}. + + ) + }, }, hint_file_not_found: { extraInfoURL: 'https://www.overleaf.com/learn/Errors/File_XXX_not_found_on_input_line_XXX', - formattedContent: ( + formattedContent: () => ( <> The compiler cannot find the file you want to include. Make sure that you have{' '} @@ -194,7 +213,7 @@ const hints = { hint_unknown_graphics_extension: { extraInfoURL: 'https://www.overleaf.com/learn/Errors/LaTeX_Error:_Unknown_graphics_extension:_.XXX', - formattedContent: ( + formattedContent: () => ( <> The compiler does not recognise the file type of one of your images. Make sure you are using a{' '} @@ -209,7 +228,7 @@ const hints = { hint_unknown_float_option_h: { extraInfoURL: 'https://www.overleaf.com/learn/Errors/LaTeX_Error:_Unknown_float_option_%60H%27', - formattedContent: ( + formattedContent: () => ( <> The compiler isn't recognizing the float option 'H'. Include \usepackage {'{float}'} in your preamble to fix this. @@ -219,7 +238,7 @@ const hints = { hint_unknown_float_option_q: { extraInfoURL: 'https://www.overleaf.com/learn/Errors/LaTeX_Error:_Unknown_float_option_%60q%27', - formattedContent: ( + formattedContent: () => ( <> You have used a float specifier which the compiler does not understand. You can learn more about the different float options available for @@ -234,7 +253,7 @@ const hints = { hint_math_allowed_only_in_math_mode: { extraInfoURL: 'https://www.overleaf.com/learn/Errors/LaTeX_Error:_%5Cmathrm_allowed_only_in_math_mode', - formattedContent: ( + formattedContent: () => ( <> 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. $ … $ or \begin @@ -246,7 +265,7 @@ const hints = { ), }, hint_mismatched_environment: { - formattedContent: ( + formattedContent: () => ( <> You have used \begin {'{...}'} without a corresponding \end @@ -255,14 +274,14 @@ const hints = { ), }, hint_mismatched_brackets: { - formattedContent: ( + formattedContent: () => ( <>You have used an open bracket without a corresponding close bracket. ), }, hint_can_be_used_only_in_preamble: { extraInfoURL: 'https://www.overleaf.com/learn/Errors/LaTeX_Error:_Can_be_used_only_in_preamble', - formattedContent: ( + formattedContent: () => ( <> You have used a command in the main body of your document which should be used in the preamble. Make sure that \documentclass[…] @@ -275,7 +294,7 @@ const hints = { hint_missing_right_inserted: { extraInfoURL: 'https://www.overleaf.com/learn/Errors/Missing_%5Cright_insertede', - formattedContent: ( + formattedContent: () => ( <> You have started an expression with a \left command, but have not included a corresponding \right command. Make sure that your \left and @@ -290,7 +309,7 @@ const hints = { }, hint_double_superscript: { extraInfoURL: 'https://www.overleaf.com/learn/Errors/Double_superscript', - formattedContent: ( + formattedContent: () => ( <> You have written a double superscript incorrectly as a^b^c, or else you have written a prime with a superscript. Remember to include {'{and}'}{' '} @@ -301,7 +320,7 @@ const hints = { }, hint_double_subscript: { extraInfoURL: 'https://www.overleaf.com/learn/Errors/Double_subscript', - formattedContent: ( + formattedContent: () => ( <> You have written a double subscript incorrectly as a_b_c. Remember to include {'{and}'} when using multiple subscripts. Try a_ @@ -311,7 +330,7 @@ const hints = { }, hint_no_author_given: { extraInfoURL: 'https://www.overleaf.com/learn/Errors/No_%5Cauthor_given', - formattedContent: ( + formattedContent: () => ( <> You have used the \maketitle command, but have not specified any \author. To fix this, include an author in your preamble using the @@ -323,7 +342,7 @@ const hints = { hint_environment_undefined: { extraInfoURL: 'https://www.overleaf.com/learn/Errors%2FLaTeX%20Error%3A%20Environment%20XXX%20undefined', - formattedContent: ( + formattedContent: () => ( <> You have created an environment (using \begin {'{…}'} and \end @@ -336,7 +355,7 @@ const hints = { hint_somethings_wrong_perhaps_a_missing_item: { extraInfoURL: 'https://www.overleaf.com/learn/Errors/LaTeX_Error:_Something%27s_wrong--perhaps_a_missing_%5Citem', - formattedContent: ( + formattedContent: () => ( <> There are no entries found in a list you have created. Make sure you label list entries using the \item command, and that you have not used a @@ -346,7 +365,7 @@ const hints = { }, hint_misplaced_noalign: { extraInfoURL: 'https://www.overleaf.com/learn/Errors/Misplaced_%5Cnoalign', - formattedContent: ( + formattedContent: () => ( <> You have used a \hline command in the wrong place, probably outside a table. If the \hline command is written inside a table, try including \\ @@ -357,7 +376,7 @@ const hints = { hint_no_line_here_to_end: { extraInfoURL: 'https://www.overleaf.com/learn/Errors/LaTeX_Error:_There%27s_no_line_here_to_end', - formattedContent: ( + formattedContent: () => ( <> You have used a \\ or \newline command where LaTeX was not expecting one. Make sure that you only use line breaks after blocks of text, and @@ -368,7 +387,7 @@ const hints = { hint_verb_ended_by_end_of_line: { extraInfoURL: 'https://www.overleaf.com/learn/Errors/LaTeX_Error:_%5Cverb_ended_by_end_of_line', - formattedContent: ( + formattedContent: () => ( <> You have used a \verb command incorrectly. Try replacling the \verb command with \begin @@ -382,7 +401,7 @@ const hints = { hint_illegal_unit_of_measure_pt_inserted: { extraInfoURL: 'https://www.overleaf.com/learn/Errors%2FIllegal%20unit%20of%20measure%20(pt%20inserted)', - formattedContent: ( + formattedContent: () => ( <> You have written a length, but have not specified the appropriate units (pt, mm, cm etc.). If you have not written a length, check that you have @@ -392,7 +411,7 @@ const hints = { }, hint_extra_right: { extraInfoURL: 'https://www.overleaf.com/learn/Errors/Extra_%5Cright', - formattedContent: ( + formattedContent: () => ( <> You have written a \right command without a corresponding \left command. Check that all \left and \right commands balance everywhere. @@ -402,7 +421,7 @@ const hints = { hint_missing_begin_document_: { extraInfoURL: 'https://www.overleaf.com/learn/Errors%2FLaTeX%20Error%3A%20Missing%20%5Cbegin%20document', - formattedContent: ( + formattedContent: () => ( <> No \begin {'{document}'} command was found. Make sure you have included \begin @@ -412,7 +431,7 @@ const hints = { ), }, hint_mismatched_environment2: { - formattedContent: ( + formattedContent: () => ( <> You have used \begin {'{}'} without a corresponding \end @@ -421,7 +440,7 @@ const hints = { ), }, hint_mismatched_environment3: { - formattedContent: ( + formattedContent: () => ( <> You have used \begin {'{}'} without a corresponding \end @@ -430,7 +449,7 @@ const hints = { ), }, hint_mismatched_environment4: { - formattedContent: ( + formattedContent: () => ( <> You have used \begin {'{}'} without a corresponding \end diff --git a/services/web/frontend/js/ide/human-readable-logs/HumanReadableLogsPackageSuggestions.js b/services/web/frontend/js/ide/human-readable-logs/HumanReadableLogsPackageSuggestions.js new file mode 100644 index 0000000000..ba043588c1 --- /dev/null +++ b/services/web/frontend/js/ide/human-readable-logs/HumanReadableLogsPackageSuggestions.js @@ -0,0 +1,7 @@ +const suggestions = [ + [ + '\\includegraphics', + { name: 'graphicx', command: '\\usepackage{graphicx}' }, + ], +] +export default new Map(suggestions) diff --git a/services/web/frontend/js/ide/human-readable-logs/HumanReadableLogsRules.js b/services/web/frontend/js/ide/human-readable-logs/HumanReadableLogsRules.js index 3c87f98d42..85a39ca970 100644 --- a/services/web/frontend/js/ide/human-readable-logs/HumanReadableLogsRules.js +++ b/services/web/frontend/js/ide/human-readable-logs/HumanReadableLogsRules.js @@ -1,4 +1,5 @@ /* eslint-disable no-useless-escape */ +import packageSuggestions from './HumanReadableLogsPackageSuggestions' const rules = [ { @@ -44,6 +45,15 @@ const rules = [ { ruleId: 'hint_undefined_control_sequence', regexToMatch: /Undefined control sequence/, + contentRegex: /^l\.[0-9]+\s*(\\\S+)/, + improvedTitle: (currentTitle, details) => { + if (details?.length && packageSuggestions.has(details[0])) { + const command = details[0] + const suggestion = packageSuggestions.get(command) + return `${suggestion.command} is missing.` + } + return currentTitle + }, }, { ruleId: 'hint_file_not_found',