Skip to content

Commit

Permalink
Checks more rules
Browse files Browse the repository at this point in the history
  • Loading branch information
sylvainhalle committed Jun 19, 2018
1 parent 25ddede commit 44ec724
Show file tree
Hide file tree
Showing 14 changed files with 515 additions and 26 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

# Top-level jar, but not jars in subfolders (if any)
*.jar
*.zip
!*/*.jar

# File generated by the JaCoCo code coverage tool
Expand Down
41 changes: 41 additions & 0 deletions Rules.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
Rules checked by TeXtidote
==========================

Style
-----

- A section title should start with a capital letter. [sh:001]
- A section title should not end with a punctuation symbol. [sh:002]
- A section title should not be written in all caps. The LaTeX stylesheet
takes care of rendering titles in caps if needed. [sh:003]
- A figure caption should end with a period. [sh:004]

Citations and references
------------------------

- There should be one space before a \cite or \ref command [sh:c:001], and
no space after [sh:c:002].

Figures
-------
- Every figure should have a label, and every figure should be referenced at
least once in the text. [sh:figref]
- Figures should not refer to hard-coded local paths. [sh:relpath]

Typesetting
-----------

- You should not break lines manually in a paragraph. Either start a new
paragraph or stay in the current one. [sh:nobreak]

Structure
---------

- A section should not contain a single sub-section. More generally, a division
of level n should not contain a single division of level n+1. [sh:nsubdiv]

Potentially suspicious
----------------------

- There should be at least N words between two section headings (currently
N=50). [sh:seclen]
4 changes: 2 additions & 2 deletions Source/Core/src/ca/uqac/lif/textidote/Detexer.java
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ protected AnnotatedString removeAllMarkup(AnnotatedString as)
protected AnnotatedString removeMarkup(AnnotatedString as_out, int line_pos)
{
// Common environments
as_out = as_out.replaceAll("\\\\(begin|end)\\{(itemize|enumerate|document|thm|abstract|eqnarray|compactitem|query|center|minipage)\\}", "");
as_out = as_out.replaceAll("\\\\(begin|end)\\{(itemize|enumerate|inparaenum|document|thm|abstract|eqnarray|compactitem|query|center|minipage)\\}", "");
// List items
as_out = as_out.replaceAll("\\\\item\\s*", "");
// Images
Expand All @@ -166,7 +166,7 @@ protected AnnotatedString removeMarkup(AnnotatedString as_out, int line_pos)
// Footnotes (ignore)
as_out = as_out.replaceAll("\\\\footnote\\{.*?\\}", "");
// Replace citations by dummy placeholder
as_out = as_out.replaceAll("\\\\(cite|citep|citel)\\{.*?\\}", "[0]");
as_out = as_out.replaceAll("\\\\(cite|citep|citel)(\\[.*?\\])*\\{.*?\\}", "[0]");
// Replace verbatim by dummy placeholder
as_out = as_out.replaceAll("\\\\verb\\+[^\\+]*?\\+", "[0]");
// Replace references and URLs by dummy placeholder
Expand Down
8 changes: 7 additions & 1 deletion Source/Core/src/ca/uqac/lif/textidote/Main.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@
import ca.uqac.lif.textidote.rules.CheckFigurePaths;
import ca.uqac.lif.textidote.rules.CheckFigureReferences;
import ca.uqac.lif.textidote.rules.CheckLanguage;
import ca.uqac.lif.textidote.rules.CheckNoBreak;
import ca.uqac.lif.textidote.rules.CheckSubsectionSize;
import ca.uqac.lif.textidote.rules.CheckSubsections;
import ca.uqac.lif.textidote.rules.LanguageFactory;
import ca.uqac.lif.textidote.rules.RegexRule;
import ca.uqac.lif.util.AnsiPrinter;
Expand Down Expand Up @@ -214,7 +217,7 @@ public static void main(String[] args) throws IOException
{
System.err.println("No filename is specified");
System.err.println("");
cli_parser.printHelp("Usage: java -jar TeXtidote.jar [options] file1 [file2 ...]", System.err);
cli_parser.printHelp("Usage: java -jar textidote.jar [options] file1 [file2 ...]", System.err);
System.exit(1);
}
AnnotatedString last_string = null;
Expand Down Expand Up @@ -298,6 +301,9 @@ protected static void populateRules(Linter linter)
linter.addDetexed(readRules(REGEX_FILENAME_DETEX));
linter.add(new CheckFigureReferences());
linter.add(new CheckFigurePaths());
linter.add(new CheckSubsections());
linter.add(new CheckSubsectionSize());
linter.add(new CheckNoBreak());
}

protected static List<Rule> readRules(String filename)
Expand Down
25 changes: 16 additions & 9 deletions Source/Core/src/ca/uqac/lif/textidote/as/AnnotatedString.java
Original file line number Diff line number Diff line change
Expand Up @@ -559,7 +559,14 @@ public Match find(/* @non_null @*/ String regex)
}
for (int i = 1; i < m.groupCount(); i++)
{
to = to.replace("$" + i, m.group(i));
if (m.group(i) != null)
{
to = to.replace("$" + i, m.group(i));
}
else
{
to = to.replace("$" + i, "");
}
}
part_left.append(to);
AnnotatedString part_right = substring(new Position(found_pos.getLine(), found_pos.getColumn() + m.getMatch().length()));
Expand All @@ -576,19 +583,19 @@ public Match find(/* @non_null @*/ String regex)
{
int max_iterations = 1000;
AnnotatedString replaced = this;
Position last_pos = Position.ZERO;
for (int i = 0; i < max_iterations; i++)
{
AnnotatedString rep = replaced.replace(regex, to);
if (rep.toString().compareTo(replaced.toString()) != 0)
{
// Something changed
replaced = rep;
}
else
Match m = replaced.find(regex, last_pos);
if (m == null)
{
// No change: stop
// No cigarettes, no matches
break;
}
Position new_pos = m.getPosition();
AnnotatedString rep = replaced.replace(regex, to, last_pos);
replaced = rep;
last_pos = new_pos.moveBy(1);
}
return replaced;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<hr/>
Output produced by TeXtidote, &copy; 2018 Sylvain Hall&eacute; - All rights reserved.<br/>
See the <a href="https://github.com/sylvainhalle/texlint">TeXLint website</a> for more information.
See the <a href="https://sylvainhalle.github.io/sylvainhalle/textidote">TeXtidote website</a> for more information.
</body>
</html>
5 changes: 3 additions & 2 deletions Source/Core/src/ca/uqac/lif/textidote/render/preamble.html
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@
padding: 2pt;
border-radius: 4pt;
cursor: help;
opacity: 0.8;
opacity: 0.7;
border: dashed 1px;
}
.highlight {
background-color: red;
Expand Down Expand Up @@ -54,5 +55,5 @@
</style>
</head>
<body>
<h1 class="textidote"><span class="no-text">Results of TeXtidote analysis</span></h1>
<a href="https://sylvainhalle.github.io/textidote"><h1 class="textidote"><span class="no-text">Results of TeXtidote analysis</span></h1></a>
<p>Here is the result of analyzing your LaTeX file with TeXtidote.</p>
Original file line number Diff line number Diff line change
Expand Up @@ -61,18 +61,28 @@ public List<Advice> evaluate(AnnotatedString s, AnnotatedString original)
boolean in_figure = false;
Map<String,Position> figure_defs = new HashMap<String,Position>();
List<String> lines = s.getLines();
boolean found_label = false;
// Step 1: find all figure labels
for (int line_cnt = 0; line_cnt < lines.size(); line_cnt++)
{
String line = lines.get(line_cnt);
if (line.matches(".*\\\\begin\\s*\\{\\s*figure.*"))
{
in_figure = true;
found_label = false;
continue;
}
if (line.matches(".*\\\\end\\s*\\{\\s*figure.*"))
{
in_figure = false;
if (!found_label)
{
// This figure is missing a label
Position start_pos = s.getSourcePosition(new Position(line_cnt, 0));
Position end_pos = start_pos.moveBy(1);
Range r = new Range(start_pos, end_pos);
out_list.add(new Advice(this, r, "This figure is missing a label", original.getResourceName(), original.getLine(start_pos.getLine())));
}
continue;
}
if (in_figure)
Expand All @@ -83,14 +93,7 @@ public List<Advice> evaluate(AnnotatedString s, AnnotatedString original)
String fig_name = mat.group(1).trim();
Position fig_pos = s.getSourcePosition(new Position(line_cnt, mat.start(1)));
figure_defs.put(fig_name, fig_pos);
}
else
{
// This figure is missing a label
Position start_pos = s.getSourcePosition(new Position(line_cnt, 0));
Position end_pos = start_pos.moveBy(1);
Range r = new Range(start_pos, end_pos);
out_list.add(new Advice(this, r, "This figure is missing a label", original.getResourceName(), original.getLine(start_pos.getLine())));
found_label = true;
}
}
}
Expand Down
18 changes: 17 additions & 1 deletion Source/Core/src/ca/uqac/lif/textidote/rules/CheckLanguage.java
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,14 @@ public class CheckLanguage extends Rule
* that LaTeX ignores multiple spaces anyway, it is advisable to
* turn it off.
*/
protected boolean m_disableWhitespace = true;
protected boolean m_disableWhitespace = true;

/**
* Whether to disable Language Tool's "unpaired symbol" rule. The detexing
* of the string leaves a few unmatched "}", so we just ignore this rule
* when it concerns this particular character.
*/
protected boolean m_disableUnpaired = true;

/**
* Creates a new rule for checking a specific language
Expand Down Expand Up @@ -153,6 +160,15 @@ public List<Advice> evaluate(AnnotatedString s, AnnotatedString original)
r = new Range(start_src_pos, end_src_pos);
}
}
// Exception for the disable unpaired rule
if (m_disableUnpaired && rm.getRule().getId().startsWith("EN_UNPAIRED_BRACKETS"))
{
if (rm.getMessage().contains("{"))
{
// We ignore the unpaired symbol for this character
continue;
}
}
// Exception if spelling mistake and a dictionary is provided
String clean_line = s.getLine(start_pos.getLine());
int end_p = end_pos.getColumn();
Expand Down
81 changes: 81 additions & 0 deletions Source/Core/src/ca/uqac/lif/textidote/rules/CheckNoBreak.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
/*
TeXtidote, a linter for LaTeX documents
Copyright (C) 2018 Sylvain Hallé
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package ca.uqac.lif.textidote.rules;

import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import ca.uqac.lif.textidote.Advice;
import ca.uqac.lif.textidote.Rule;
import ca.uqac.lif.textidote.as.AnnotatedString;
import ca.uqac.lif.textidote.as.Position;
import ca.uqac.lif.textidote.as.Range;

/**
* Checks that text paragraphs do not contain forced line breaks.
*
* @author Sylvain Hallé
*
*/
public class CheckNoBreak extends Rule
{
/**
* The pattern for finding figure labels
*/
Pattern m_breakPattern = Pattern.compile("\\\\\\\\");

public CheckNoBreak()
{
super("sh:nobreak");
}

@Override
public List<Advice> evaluate(AnnotatedString s, AnnotatedString original)
{
List<Advice> out_list = new ArrayList<Advice>();
List<String> lines = s.getLines();
int env_level = 0;
for (int line_cnt = 0; line_cnt < lines.size(); line_cnt++)
{
String line = lines.get(line_cnt);
if (line.matches(".*\\\\begin\\s*\\{\\s*(equation|table|tabular|verbatim|lstlisting|IEEEkeywords|figure).*") || line.matches(".*\\\\\\[.*"))
{
env_level++;
}
if (env_level == 0)
{
Matcher mat = m_breakPattern.matcher(line);
if (mat.find())
{
// Forced break
Position start_pos = s.getSourcePosition(new Position(line_cnt, mat.start()));
Position end_pos = s.getSourcePosition(new Position(line_cnt, mat.start() + mat.group(0).length()));
Range r = new Range(start_pos, end_pos);
out_list.add(new Advice(this, r, "You should not break lines manually in a paragraph. Either start a new paragraph or stay in the current one.", original.getResourceName(), original.getLine(start_pos.getLine())));
}
}
if (line.matches(".*\\\\end\\s*\\{\\s*(equation|table|tabular|verbatim|lstlisting|IEEEkeywords|figure).*") || line.matches(".*\\\\\\].*"))
{
env_level--;
}
}
return out_list;
}
}
Loading

0 comments on commit 44ec724

Please sign in to comment.