From 6b3746c699088dff64cfc0166c6e6b35f09ff014 Mon Sep 17 00:00:00 2001 From: liana Date: Fri, 2 Dec 2022 15:14:36 +0300 Subject: [PATCH] Builders are inherited --- .../checker/rule/list/ListRuleBuilder.kt | 26 -- .../checker/rule/symbol/SymbolRule.kt | 1 + .../TableOfContentRuleBuilder.kt | 16 - .../checker/rule/url/URLRuleBuilder.kt | 25 -- .../checker/rule/word/BasicWordRule.kt | 1 + .../checker/rule/word/WordRule.kt | 1 + .../rulebuilder/NotRegionRuleBuilder.kt | 20 + .../checker/rulebuilder/RegionRuleBuilder.kt | 18 + .../listbuilder/ListRuleBuilder.kt | 21 + .../regexbuilder}/RegexRuleBuilder.kt | 20 +- .../symbolbuilder}/SymbolRuleBuilder.kt | 28 +- .../TableOfContentRuleBuilder.kt | 20 + .../rulebuilder/urlbuilder/URLRuleBuilder.kt | 21 + .../wordbuilder}/WordRuleBuilder.kt | 25 +- .../rules/ListRules.kt | 13 + .../rules/RegexRules.kt | 48 ++ .../mundaneassignmentpolice/rules/Rules.kt | 415 ------------------ .../rules/SymbolRules.kt | 164 +++++++ .../rules/TableOfContentRules.kt | 74 ++++ .../mundaneassignmentpolice/rules/URLRules.kt | 90 ++++ .../rules/WordRules.kt | 55 +++ .../checker/ListRuleTests.kt | 6 +- .../checker/RulesTests.kt | 4 +- .../checker/SymbolRuleTests.kt | 12 +- 24 files changed, 589 insertions(+), 535 deletions(-) delete mode 100644 src/main/kotlin/com/github/darderion/mundaneassignmentpolice/checker/rule/list/ListRuleBuilder.kt delete mode 100644 src/main/kotlin/com/github/darderion/mundaneassignmentpolice/checker/rule/tableofcontent/TableOfContentRuleBuilder.kt delete mode 100644 src/main/kotlin/com/github/darderion/mundaneassignmentpolice/checker/rule/url/URLRuleBuilder.kt create mode 100644 src/main/kotlin/com/github/darderion/mundaneassignmentpolice/checker/rulebuilder/NotRegionRuleBuilder.kt create mode 100644 src/main/kotlin/com/github/darderion/mundaneassignmentpolice/checker/rulebuilder/RegionRuleBuilder.kt create mode 100644 src/main/kotlin/com/github/darderion/mundaneassignmentpolice/checker/rulebuilder/listbuilder/ListRuleBuilder.kt rename src/main/kotlin/com/github/darderion/mundaneassignmentpolice/checker/{rule/regex => rulebuilder/regexbuilder}/RegexRuleBuilder.kt (64%) rename src/main/kotlin/com/github/darderion/mundaneassignmentpolice/checker/{rule/symbol => rulebuilder/symbolbuilder}/SymbolRuleBuilder.kt (77%) create mode 100644 src/main/kotlin/com/github/darderion/mundaneassignmentpolice/checker/rulebuilder/tableofcontentbuilder/TableOfContentRuleBuilder.kt create mode 100644 src/main/kotlin/com/github/darderion/mundaneassignmentpolice/checker/rulebuilder/urlbuilder/URLRuleBuilder.kt rename src/main/kotlin/com/github/darderion/mundaneassignmentpolice/checker/{rule/word => rulebuilder/wordbuilder}/WordRuleBuilder.kt (84%) create mode 100644 src/main/kotlin/com/github/darderion/mundaneassignmentpolice/rules/ListRules.kt create mode 100644 src/main/kotlin/com/github/darderion/mundaneassignmentpolice/rules/RegexRules.kt delete mode 100644 src/main/kotlin/com/github/darderion/mundaneassignmentpolice/rules/Rules.kt create mode 100644 src/main/kotlin/com/github/darderion/mundaneassignmentpolice/rules/SymbolRules.kt create mode 100644 src/main/kotlin/com/github/darderion/mundaneassignmentpolice/rules/TableOfContentRules.kt create mode 100644 src/main/kotlin/com/github/darderion/mundaneassignmentpolice/rules/URLRules.kt create mode 100644 src/main/kotlin/com/github/darderion/mundaneassignmentpolice/rules/WordRules.kt diff --git a/src/main/kotlin/com/github/darderion/mundaneassignmentpolice/checker/rule/list/ListRuleBuilder.kt b/src/main/kotlin/com/github/darderion/mundaneassignmentpolice/checker/rule/list/ListRuleBuilder.kt deleted file mode 100644 index 201db9d6..00000000 --- a/src/main/kotlin/com/github/darderion/mundaneassignmentpolice/checker/rule/list/ListRuleBuilder.kt +++ /dev/null @@ -1,26 +0,0 @@ -package com.github.darderion.mundaneassignmentpolice.checker.rule.list - -import com.github.darderion.mundaneassignmentpolice.checker.RuleViolationType -import com.github.darderion.mundaneassignmentpolice.pdfdocument.PDFArea -import com.github.darderion.mundaneassignmentpolice.pdfdocument.list.PDFList -import com.github.darderion.mundaneassignmentpolice.pdfdocument.PDFRegion -import com.github.darderion.mundaneassignmentpolice.pdfdocument.text.Line - -class ListRuleBuilder { - private var region: PDFRegion = PDFRegion.EVERYWHERE - private val predicates: MutableList<(list: PDFList) -> List> = mutableListOf() - private var type: RuleViolationType = RuleViolationType.Error - private var name: String = "Rule name" - - fun disallow(predicate: (list: PDFList) -> List) = this.also { predicates.add(predicate) } - - infix fun inArea(area: PDFArea) = this.also { region = PDFRegion.NOWHERE.except(area) } - - infix fun inArea(region: PDFRegion) = this.also { this.region = region } - - fun called(name: String) = this.also { this.name = name } - - infix fun type(type: RuleViolationType) = this.also { this.type = type } - - fun getRule() = ListRule(predicates, type, region, name) -} diff --git a/src/main/kotlin/com/github/darderion/mundaneassignmentpolice/checker/rule/symbol/SymbolRule.kt b/src/main/kotlin/com/github/darderion/mundaneassignmentpolice/checker/rule/symbol/SymbolRule.kt index d4d94c07..98b77907 100644 --- a/src/main/kotlin/com/github/darderion/mundaneassignmentpolice/checker/rule/symbol/SymbolRule.kt +++ b/src/main/kotlin/com/github/darderion/mundaneassignmentpolice/checker/rule/symbol/SymbolRule.kt @@ -3,6 +3,7 @@ package com.github.darderion.mundaneassignmentpolice.checker.rule.symbol import com.github.darderion.mundaneassignmentpolice.checker.RuleViolation import com.github.darderion.mundaneassignmentpolice.checker.RuleViolationType import com.github.darderion.mundaneassignmentpolice.checker.rule.Rule +import com.github.darderion.mundaneassignmentpolice.checker.rulebuilder.symbolbuilder.indicesOf import com.github.darderion.mundaneassignmentpolice.pdfdocument.PDFDocument import com.github.darderion.mundaneassignmentpolice.pdfdocument.PDFRegion import com.github.darderion.mundaneassignmentpolice.pdfdocument.inside diff --git a/src/main/kotlin/com/github/darderion/mundaneassignmentpolice/checker/rule/tableofcontent/TableOfContentRuleBuilder.kt b/src/main/kotlin/com/github/darderion/mundaneassignmentpolice/checker/rule/tableofcontent/TableOfContentRuleBuilder.kt deleted file mode 100644 index 1569babf..00000000 --- a/src/main/kotlin/com/github/darderion/mundaneassignmentpolice/checker/rule/tableofcontent/TableOfContentRuleBuilder.kt +++ /dev/null @@ -1,16 +0,0 @@ -package com.github.darderion.mundaneassignmentpolice.checker.rule.tableofcontent - -import com.github.darderion.mundaneassignmentpolice.checker.RuleViolationType -import com.github.darderion.mundaneassignmentpolice.pdfdocument.text.Line - -class TableOfContentRuleBuilder { - private val predicates: MutableList<(list: List) -> List> = mutableListOf() - private var type: RuleViolationType = RuleViolationType.Error - private var name: String = "Rule name" - - fun disallow(predicate: (list: List) -> List) = this.also { predicates.add(predicate) } - - fun called(name: String) = this.also { this.name = name } - - fun getRule() = TableOfContentRule(predicates, type, name) -} diff --git a/src/main/kotlin/com/github/darderion/mundaneassignmentpolice/checker/rule/url/URLRuleBuilder.kt b/src/main/kotlin/com/github/darderion/mundaneassignmentpolice/checker/rule/url/URLRuleBuilder.kt deleted file mode 100644 index dd666d0d..00000000 --- a/src/main/kotlin/com/github/darderion/mundaneassignmentpolice/checker/rule/url/URLRuleBuilder.kt +++ /dev/null @@ -1,25 +0,0 @@ -package com.github.darderion.mundaneassignmentpolice.checker.rule.url - -import com.github.darderion.mundaneassignmentpolice.checker.RuleViolationType -import com.github.darderion.mundaneassignmentpolice.pdfdocument.PDFArea -import com.github.darderion.mundaneassignmentpolice.pdfdocument.PDFRegion -import com.github.darderion.mundaneassignmentpolice.pdfdocument.text.Line - -class URLRuleBuilder { - private val predicates: MutableList<(urls: List) -> List>>> = mutableListOf() - private var type: RuleViolationType = RuleViolationType.Error - private var name: String = "Rule name" - private var region: PDFRegion = PDFRegion.EVERYWHERE - - fun disallow(predicate: (urls: List) -> List>>) = this.also { predicates.add(predicate) } - - infix fun called(name: String) = this.also { this.name = name } - - infix fun inArea(area: PDFArea) = this.also { region = PDFRegion.NOWHERE.except(area) } - - infix fun inArea(region: PDFRegion) = this.also { this.region = region } - - infix fun type(type: RuleViolationType) = this.also { this.type = type } - - fun getRule() = URLRule(predicates, type, region, name) -} diff --git a/src/main/kotlin/com/github/darderion/mundaneassignmentpolice/checker/rule/word/BasicWordRule.kt b/src/main/kotlin/com/github/darderion/mundaneassignmentpolice/checker/rule/word/BasicWordRule.kt index e5310909..bd1012b6 100644 --- a/src/main/kotlin/com/github/darderion/mundaneassignmentpolice/checker/rule/word/BasicWordRule.kt +++ b/src/main/kotlin/com/github/darderion/mundaneassignmentpolice/checker/rule/word/BasicWordRule.kt @@ -2,6 +2,7 @@ package com.github.darderion.mundaneassignmentpolice.checker.rule.word import com.github.darderion.mundaneassignmentpolice.checker.Direction import com.github.darderion.mundaneassignmentpolice.checker.RuleViolationType +import com.github.darderion.mundaneassignmentpolice.checker.rulebuilder.wordbuilder.splitToWordsAndPunctuations import com.github.darderion.mundaneassignmentpolice.pdfdocument.PDFDocument import com.github.darderion.mundaneassignmentpolice.pdfdocument.PDFRegion diff --git a/src/main/kotlin/com/github/darderion/mundaneassignmentpolice/checker/rule/word/WordRule.kt b/src/main/kotlin/com/github/darderion/mundaneassignmentpolice/checker/rule/word/WordRule.kt index 1e3b608f..f9a0317b 100644 --- a/src/main/kotlin/com/github/darderion/mundaneassignmentpolice/checker/rule/word/WordRule.kt +++ b/src/main/kotlin/com/github/darderion/mundaneassignmentpolice/checker/rule/word/WordRule.kt @@ -3,6 +3,7 @@ package com.github.darderion.mundaneassignmentpolice.checker.rule.word import com.github.darderion.mundaneassignmentpolice.checker.RuleViolation import com.github.darderion.mundaneassignmentpolice.checker.RuleViolationType import com.github.darderion.mundaneassignmentpolice.checker.rule.Rule +import com.github.darderion.mundaneassignmentpolice.checker.rulebuilder.wordbuilder.splitToWordsAndPunctuations import com.github.darderion.mundaneassignmentpolice.pdfdocument.PDFDocument import com.github.darderion.mundaneassignmentpolice.pdfdocument.PDFRegion import com.github.darderion.mundaneassignmentpolice.pdfdocument.inside diff --git a/src/main/kotlin/com/github/darderion/mundaneassignmentpolice/checker/rulebuilder/NotRegionRuleBuilder.kt b/src/main/kotlin/com/github/darderion/mundaneassignmentpolice/checker/rulebuilder/NotRegionRuleBuilder.kt new file mode 100644 index 00000000..c5e2570a --- /dev/null +++ b/src/main/kotlin/com/github/darderion/mundaneassignmentpolice/checker/rulebuilder/NotRegionRuleBuilder.kt @@ -0,0 +1,20 @@ +package com.github.darderion.mundaneassignmentpolice.checker.rulebuilder + +import com.github.darderion.mundaneassignmentpolice.checker.RuleViolationType +import com.github.darderion.mundaneassignmentpolice.checker.rule.Rule +import com.github.darderion.mundaneassignmentpolice.pdfdocument.PDFArea +import com.github.darderion.mundaneassignmentpolice.pdfdocument.PDFRegion + +abstract class NotRegionRuleBuilder>( + var type: RuleViolationType, + var name: String, + var region : PDFRegion +) +{ + fun called(name: String) = apply { this.name = name } as TBuilder + fun type(type: RuleViolationType)= apply { this.type = type } as TBuilder + fun inArea(area: PDFArea) = this.also { region = PDFRegion.NOWHERE.except(area) } as TBuilder + fun inArea(region: PDFRegion) = this.also { this.region = region } as TBuilder + + abstract fun getRule(): Rule +} \ No newline at end of file diff --git a/src/main/kotlin/com/github/darderion/mundaneassignmentpolice/checker/rulebuilder/RegionRuleBuilder.kt b/src/main/kotlin/com/github/darderion/mundaneassignmentpolice/checker/rulebuilder/RegionRuleBuilder.kt new file mode 100644 index 00000000..5d1857bf --- /dev/null +++ b/src/main/kotlin/com/github/darderion/mundaneassignmentpolice/checker/rulebuilder/RegionRuleBuilder.kt @@ -0,0 +1,18 @@ +package com.github.darderion.mundaneassignmentpolice.checker.rulebuilder + +import com.github.darderion.mundaneassignmentpolice.checker.RuleViolationType +import com.github.darderion.mundaneassignmentpolice.checker.rule.Rule +import com.github.darderion.mundaneassignmentpolice.pdfdocument.PDFRegion + + +abstract class RegionRuleBuilder>( + var type: RuleViolationType, + var name: String, + var region : PDFRegion +) +{ + fun called(name: String) = apply { this.name = name } as TBuilder + fun type(type: RuleViolationType)= apply { this.type = type } as TBuilder + + abstract fun getRule(): Rule +} \ No newline at end of file diff --git a/src/main/kotlin/com/github/darderion/mundaneassignmentpolice/checker/rulebuilder/listbuilder/ListRuleBuilder.kt b/src/main/kotlin/com/github/darderion/mundaneassignmentpolice/checker/rulebuilder/listbuilder/ListRuleBuilder.kt new file mode 100644 index 00000000..57c7ea8a --- /dev/null +++ b/src/main/kotlin/com/github/darderion/mundaneassignmentpolice/checker/rulebuilder/listbuilder/ListRuleBuilder.kt @@ -0,0 +1,21 @@ +package com.github.darderion.mundaneassignmentpolice.checker.rulebuilder.listbuilder + +import com.github.darderion.mundaneassignmentpolice.checker.RuleViolationType +import com.github.darderion.mundaneassignmentpolice.checker.rule.list.ListRule +import com.github.darderion.mundaneassignmentpolice.checker.rulebuilder.NotRegionRuleBuilder +import com.github.darderion.mundaneassignmentpolice.pdfdocument.PDFRegion +import com.github.darderion.mundaneassignmentpolice.pdfdocument.list.PDFList +import com.github.darderion.mundaneassignmentpolice.pdfdocument.text.Line + +class ListRuleBuilder>( + type: RuleViolationType = RuleViolationType.Error, + name: String = "Rule name", + region: PDFRegion = PDFRegion.EVERYWHERE +) : NotRegionRuleBuilder(type,name, region){ + + private var predicates: MutableList<(list: PDFList) -> List> = mutableListOf() + + fun disallow(predicate: (list: PDFList) -> List) = this.also { predicates.add(predicate) } + + override fun getRule() = ListRule(predicates, type, region, name) +} \ No newline at end of file diff --git a/src/main/kotlin/com/github/darderion/mundaneassignmentpolice/checker/rule/regex/RegexRuleBuilder.kt b/src/main/kotlin/com/github/darderion/mundaneassignmentpolice/checker/rulebuilder/regexbuilder/RegexRuleBuilder.kt similarity index 64% rename from src/main/kotlin/com/github/darderion/mundaneassignmentpolice/checker/rule/regex/RegexRuleBuilder.kt rename to src/main/kotlin/com/github/darderion/mundaneassignmentpolice/checker/rulebuilder/regexbuilder/RegexRuleBuilder.kt index b6001a4e..c4e21e6b 100644 --- a/src/main/kotlin/com/github/darderion/mundaneassignmentpolice/checker/rule/regex/RegexRuleBuilder.kt +++ b/src/main/kotlin/com/github/darderion/mundaneassignmentpolice/checker/rulebuilder/regexbuilder/RegexRuleBuilder.kt @@ -1,16 +1,19 @@ -package com.github.darderion.mundaneassignmentpolice.checker.rule.regex +package com.github.darderion.mundaneassignmentpolice.checker.rulebuilder.regexbuilder import com.github.darderion.mundaneassignmentpolice.checker.RuleViolationType +import com.github.darderion.mundaneassignmentpolice.checker.rule.regex.RegexRule +import com.github.darderion.mundaneassignmentpolice.checker.rulebuilder.NotRegionRuleBuilder import com.github.darderion.mundaneassignmentpolice.pdfdocument.PDFRegion import com.github.darderion.mundaneassignmentpolice.pdfdocument.text.Line -class RegexRuleBuilder { +class RegexRuleBuilder>( + type: RuleViolationType = RuleViolationType.Error, + name: String = "Rule name", + region: PDFRegion = PDFRegion.EVERYWHERE +) : NotRegionRuleBuilder(type,name, region){ private var regex: Regex = Regex("") private val predicates: MutableList<(matches: List>>) -> List>> = mutableListOf() private var numberOfNearestLinesToSearch: Int = 0 - private var type: RuleViolationType = RuleViolationType.Error - private var region: PDFRegion = PDFRegion.EVERYWHERE - private var name: String = "Rule name" fun regex(regex: Regex) = this.also { this.regex = regex } @@ -20,13 +23,8 @@ class RegexRuleBuilder { fun searchIn(numberOfNearestLines: Int) = this.also { this.numberOfNearestLinesToSearch = numberOfNearestLines } - fun type(type: RuleViolationType) = this.also { this.type = type } - fun inArea(region: PDFRegion) = this.also { this.region = region } - - fun called(name: String) = this.also { this.name = name } - - fun getRule() = RegexRule( + override fun getRule() = RegexRule( regex, predicates, numberOfNearestLinesToSearch, diff --git a/src/main/kotlin/com/github/darderion/mundaneassignmentpolice/checker/rule/symbol/SymbolRuleBuilder.kt b/src/main/kotlin/com/github/darderion/mundaneassignmentpolice/checker/rulebuilder/symbolbuilder/SymbolRuleBuilder.kt similarity index 77% rename from src/main/kotlin/com/github/darderion/mundaneassignmentpolice/checker/rule/symbol/SymbolRuleBuilder.kt rename to src/main/kotlin/com/github/darderion/mundaneassignmentpolice/checker/rulebuilder/symbolbuilder/SymbolRuleBuilder.kt index f0226641..d1aeaf43 100644 --- a/src/main/kotlin/com/github/darderion/mundaneassignmentpolice/checker/rule/symbol/SymbolRuleBuilder.kt +++ b/src/main/kotlin/com/github/darderion/mundaneassignmentpolice/checker/rulebuilder/symbolbuilder/SymbolRuleBuilder.kt @@ -1,11 +1,11 @@ -package com.github.darderion.mundaneassignmentpolice.checker.rule.symbol +package com.github.darderion.mundaneassignmentpolice.checker.rulebuilder.symbolbuilder import com.github.darderion.mundaneassignmentpolice.checker.Direction import com.github.darderion.mundaneassignmentpolice.checker.RuleViolationType -import com.github.darderion.mundaneassignmentpolice.pdfdocument.PDFArea +import com.github.darderion.mundaneassignmentpolice.checker.rule.symbol.BasicSymbolRule +import com.github.darderion.mundaneassignmentpolice.checker.rule.symbol.SymbolRule +import com.github.darderion.mundaneassignmentpolice.checker.rulebuilder.NotRegionRuleBuilder import com.github.darderion.mundaneassignmentpolice.pdfdocument.PDFRegion -import com.github.darderion.mundaneassignmentpolice.pdfdocument.PDFRegion.Companion.EVERYWHERE -import com.github.darderion.mundaneassignmentpolice.pdfdocument.PDFRegion.Companion.NOWHERE import java.util.regex.Pattern // Extension method @@ -16,7 +16,12 @@ fun CharSequence.indicesOf(input: String): List = .map { it.range.first } // get the index .toCollection(mutableListOf()) // collect the result as list -class SymbolRuleBuilder { +class SymbolRuleBuilder>( + type: RuleViolationType = RuleViolationType.Error, + name: String = "Rule name", + region: PDFRegion = PDFRegion.EVERYWHERE +): NotRegionRuleBuilder(type,name, region){ + private var symbol: Char = ' ' private var ignoredNeighbors: MutableList = mutableListOf() private var notIgnoredNeighbors: MutableList = mutableListOf() @@ -25,14 +30,9 @@ class SymbolRuleBuilder { private var requiredNeighbors: MutableList = mutableListOf() private var direction: Direction = Direction.BIDIRECTIONAL private var neighborhoodSize: Int = 1 - private var type: RuleViolationType = RuleViolationType.Error - private var name: String = "Rule name" - private var region: PDFRegion = EVERYWHERE infix fun symbol(symbol: Char) = this.also { this.symbol = symbol } - infix fun called(name: String) = this.also { this.name = name } - fun ignoringAdjusting(vararg symbols: Char) = this.also { if (notIgnoredNeighbors.isEmpty()) ignoredNeighbors.addAll(symbols.toList()) else throw Exception("Up to one of the following methods can be used:" + " ignoringAdjusting() or ignoringEveryCharacterExcept().")} @@ -55,15 +55,9 @@ class SymbolRuleBuilder { infix fun from(direction: Direction) = this.also { this.direction = direction } - infix fun inArea(area: PDFArea) = this.also { region = NOWHERE.except(area) } - - infix fun inArea(region: PDFRegion) = this.also { this.region = region } - - infix fun type(type: RuleViolationType) = this.also { this.type = type } - fun inNeighborhood(size: Int) = this.also { this.neighborhoodSize = size } - fun getRule() = BasicSymbolRule( + override fun getRule() = BasicSymbolRule( symbol, ignoredNeighbors, notIgnoredNeighbors, diff --git a/src/main/kotlin/com/github/darderion/mundaneassignmentpolice/checker/rulebuilder/tableofcontentbuilder/TableOfContentRuleBuilder.kt b/src/main/kotlin/com/github/darderion/mundaneassignmentpolice/checker/rulebuilder/tableofcontentbuilder/TableOfContentRuleBuilder.kt new file mode 100644 index 00000000..d79f6dbe --- /dev/null +++ b/src/main/kotlin/com/github/darderion/mundaneassignmentpolice/checker/rulebuilder/tableofcontentbuilder/TableOfContentRuleBuilder.kt @@ -0,0 +1,20 @@ +package com.github.darderion.mundaneassignmentpolice.checker.rulebuilder.tableofcontentbuilder + +import com.github.darderion.mundaneassignmentpolice.checker.RuleViolationType +import com.github.darderion.mundaneassignmentpolice.checker.rule.tableofcontent.TableOfContentRule +import com.github.darderion.mundaneassignmentpolice.checker.rulebuilder.RegionRuleBuilder +import com.github.darderion.mundaneassignmentpolice.pdfdocument.PDFArea +import com.github.darderion.mundaneassignmentpolice.pdfdocument.PDFRegion +import com.github.darderion.mundaneassignmentpolice.pdfdocument.text.Line + +class TableOfContentRuleBuilder>( + type: RuleViolationType = RuleViolationType.Error, + name: String = "Rule name" +) : RegionRuleBuilder(type,name, PDFRegion.NOWHERE.except(PDFArea.TABLE_OF_CONTENT)){ + + private var predicates: MutableList<(list: List) -> List> = mutableListOf() + + fun disallow(predicate: (list: List) -> List) = this.also { predicates.add(predicate) } + + override fun getRule() = TableOfContentRule(predicates, type, name) +} diff --git a/src/main/kotlin/com/github/darderion/mundaneassignmentpolice/checker/rulebuilder/urlbuilder/URLRuleBuilder.kt b/src/main/kotlin/com/github/darderion/mundaneassignmentpolice/checker/rulebuilder/urlbuilder/URLRuleBuilder.kt new file mode 100644 index 00000000..72dee90d --- /dev/null +++ b/src/main/kotlin/com/github/darderion/mundaneassignmentpolice/checker/rulebuilder/urlbuilder/URLRuleBuilder.kt @@ -0,0 +1,21 @@ +package com.github.darderion.mundaneassignmentpolice.checker.rulebuilder.urlbuilder + +import com.github.darderion.mundaneassignmentpolice.checker.RuleViolationType +import com.github.darderion.mundaneassignmentpolice.checker.rule.url.URLRule +import com.github.darderion.mundaneassignmentpolice.checker.rule.url.Url +import com.github.darderion.mundaneassignmentpolice.checker.rulebuilder.NotRegionRuleBuilder +import com.github.darderion.mundaneassignmentpolice.pdfdocument.PDFRegion +import com.github.darderion.mundaneassignmentpolice.pdfdocument.text.Line + +class URLRuleBuilder>( + type: RuleViolationType = RuleViolationType.Error, + name: String = "Rule name", + region: PDFRegion = PDFRegion.EVERYWHERE +) : NotRegionRuleBuilder(type,name, region){ + + private val predicates: MutableList<(urls: List) -> List>>> = mutableListOf() + + fun disallow(predicate: (urls: List) -> List>>) = this.also { predicates.add(predicate) } + + override fun getRule() = URLRule(predicates, type, region, name) +} \ No newline at end of file diff --git a/src/main/kotlin/com/github/darderion/mundaneassignmentpolice/checker/rule/word/WordRuleBuilder.kt b/src/main/kotlin/com/github/darderion/mundaneassignmentpolice/checker/rulebuilder/wordbuilder/WordRuleBuilder.kt similarity index 84% rename from src/main/kotlin/com/github/darderion/mundaneassignmentpolice/checker/rule/word/WordRuleBuilder.kt rename to src/main/kotlin/com/github/darderion/mundaneassignmentpolice/checker/rulebuilder/wordbuilder/WordRuleBuilder.kt index 0be85cb1..dff3ff53 100644 --- a/src/main/kotlin/com/github/darderion/mundaneassignmentpolice/checker/rule/word/WordRuleBuilder.kt +++ b/src/main/kotlin/com/github/darderion/mundaneassignmentpolice/checker/rulebuilder/wordbuilder/WordRuleBuilder.kt @@ -1,8 +1,10 @@ -package com.github.darderion.mundaneassignmentpolice.checker.rule.word +package com.github.darderion.mundaneassignmentpolice.checker.rulebuilder.wordbuilder import com.github.darderion.mundaneassignmentpolice.checker.Direction import com.github.darderion.mundaneassignmentpolice.checker.RuleViolationType -import com.github.darderion.mundaneassignmentpolice.pdfdocument.PDFArea +import com.github.darderion.mundaneassignmentpolice.checker.rule.word.BasicWordRule +import com.github.darderion.mundaneassignmentpolice.checker.rule.word.WordRule +import com.github.darderion.mundaneassignmentpolice.checker.rulebuilder.NotRegionRuleBuilder import com.github.darderion.mundaneassignmentpolice.pdfdocument.PDFRegion fun splitToWordsAndPunctuations(str: String): List { @@ -20,7 +22,11 @@ fun splitToWordsAndPunctuations(str: String): List { return wordsAndPunctuations.filter { it != "" } } -class WordRuleBuilder { +class WordRuleBuilder>( + type: RuleViolationType = RuleViolationType.Error, + name: String = "Rule name", + region: PDFRegion = PDFRegion.EVERYWHERE +) : NotRegionRuleBuilder(type,name, region){ private var word: String = " " private var ignoredNeighbors: MutableList = mutableListOf() private var notIgnoredNeighbors: MutableList = mutableListOf() @@ -32,14 +38,9 @@ class WordRuleBuilder { private var direction: Direction = Direction.BIDIRECTIONAL private var neighborhoodSize: Int = 1 private var numberOfNeighbors: Int = 1 - private var type: RuleViolationType = RuleViolationType.Error - private var name: String = "Rule name" - private var region: PDFRegion = PDFRegion.EVERYWHERE infix fun word(word: String) = this.also { this.word = word } - infix fun called(name: String) = this.also { this.name = name } - fun ignoringAdjusting(vararg words: Regex) = this.also { if (notIgnoredNeighbors.isEmpty()) ignoredNeighbors.addAll(words.toList()) else throw Exception( @@ -86,17 +87,11 @@ class WordRuleBuilder { fun fromBothSides() = this.also { direction = Direction.BIDIRECTIONAL } - infix fun inArea(area: PDFArea) = this.also { region = PDFRegion.NOWHERE.except(area) } - - infix fun inArea(region: PDFRegion) = this.also { this.region = region } - - infix fun type(type: RuleViolationType) = this.also { this.type = type } - fun inNeighborhood(size: Int) = this.also { this.neighborhoodSize = size } fun shouldHaveNumberOfNeighbors(number: Int) = this.also { this.numberOfNeighbors = number } - fun getRule() = BasicWordRule( + override fun getRule() = BasicWordRule( word, ignoredNeighbors, notIgnoredNeighbors, diff --git a/src/main/kotlin/com/github/darderion/mundaneassignmentpolice/rules/ListRules.kt b/src/main/kotlin/com/github/darderion/mundaneassignmentpolice/rules/ListRules.kt new file mode 100644 index 00000000..aae87166 --- /dev/null +++ b/src/main/kotlin/com/github/darderion/mundaneassignmentpolice/rules/ListRules.kt @@ -0,0 +1,13 @@ +package com.github.darderion.mundaneassignmentpolice.rules + +import com.github.darderion.mundaneassignmentpolice.checker.rulebuilder.listbuilder.ListRuleBuilder +import com.github.darderion.mundaneassignmentpolice.pdfdocument.PDFArea +import com.github.darderion.mundaneassignmentpolice.pdfdocument.PDFRegion + +val RULE_SINGLE_SUBSECTION = ListRuleBuilder>() + .inArea(PDFRegion.NOWHERE.except(PDFArea.TABLE_OF_CONTENT)) + //.called("Only 1 subsection in a section") + .called("Одна подсекция в секции") + .disallow { + if (it.nodes.count() == 1) it.nodes.first().getText() else listOf() + }.getRule() diff --git a/src/main/kotlin/com/github/darderion/mundaneassignmentpolice/rules/RegexRules.kt b/src/main/kotlin/com/github/darderion/mundaneassignmentpolice/rules/RegexRules.kt new file mode 100644 index 00000000..51a494a5 --- /dev/null +++ b/src/main/kotlin/com/github/darderion/mundaneassignmentpolice/rules/RegexRules.kt @@ -0,0 +1,48 @@ +package com.github.darderion.mundaneassignmentpolice.rules + +import com.github.darderion.mundaneassignmentpolice.checker.rulebuilder.regexbuilder.RegexRuleBuilder +import com.github.darderion.mundaneassignmentpolice.pdfdocument.PDFArea +import com.github.darderion.mundaneassignmentpolice.pdfdocument.PDFRegion + + +val RULE_ORDER_OF_REFERENCES = RegexRuleBuilder>() + .called("Неверный порядок ссылок на литературу") + .regex(Regex("""\[[0-9,\s]+\]""")) + .searchIn(1) + .disallow { matches -> + matches.filter { pair -> + val references = pair.first + val referencesInIntList = references + .slice(IntRange(1, references.length - 2)) + .split(Regex(""",""")) + .map { it.trim() } + .filter { it.isNotEmpty() } + .map { it.toInt() } + referencesInIntList != referencesInIntList.sorted() + }.map { it.second } + }.getRule() + +val RULE_VARIOUS_ABBREVIATIONS = RegexRuleBuilder>() + .called("Использованы различные версии сокращения") + .regex(Regex("""[a-zA-Zа-яА-Я]+""")) + .inArea(PDFRegion.EVERYWHERE.except(PDFArea.BIBLIOGRAPHY)) + .disallow { matches -> + val abbreviations = hashSetOf() + val allWords = hashMapOf>() + matches.forEach { pair -> + val word = pair.first + if (word.slice(IntRange(1, word.length - 1)) + .count { it.isUpperCase() } > 0) + abbreviations.add(word.uppercase()) + if (!allWords.containsKey(word.lowercase())) + allWords.put(word.lowercase(), hashSetOf()) + allWords[word.lowercase()]?.add(word) + } + matches.filter { pair -> + val word = pair.first + if (abbreviations.contains(word.uppercase())) + allWords[word.lowercase()]?.size!! > 1 + else + false + }.map { it.second } + }.getRule() \ No newline at end of file diff --git a/src/main/kotlin/com/github/darderion/mundaneassignmentpolice/rules/Rules.kt b/src/main/kotlin/com/github/darderion/mundaneassignmentpolice/rules/Rules.kt deleted file mode 100644 index d621c374..00000000 --- a/src/main/kotlin/com/github/darderion/mundaneassignmentpolice/rules/Rules.kt +++ /dev/null @@ -1,415 +0,0 @@ -package com.github.darderion.mundaneassignmentpolice.rules - -import com.github.darderion.mundaneassignmentpolice.checker.RuleViolationType -import com.github.darderion.mundaneassignmentpolice.checker.Section -import com.github.darderion.mundaneassignmentpolice.checker.rule.list.ListRuleBuilder -import com.github.darderion.mundaneassignmentpolice.checker.rule.regex.RegexRuleBuilder -import com.github.darderion.mundaneassignmentpolice.checker.rule.symbol.SymbolRuleBuilder -import com.github.darderion.mundaneassignmentpolice.checker.rule.symbol.and -import com.github.darderion.mundaneassignmentpolice.checker.rule.symbol.or -import com.github.darderion.mundaneassignmentpolice.checker.rule.tableofcontent.TableOfContentRuleBuilder -import com.github.darderion.mundaneassignmentpolice.checker.rule.url.URLRuleBuilder -import com.github.darderion.mundaneassignmentpolice.checker.rule.url.then -import com.github.darderion.mundaneassignmentpolice.checker.rule.word.WordRule -import com.github.darderion.mundaneassignmentpolice.checker.rule.word.WordRuleBuilder -import com.github.darderion.mundaneassignmentpolice.checker.rule.word.or -import com.github.darderion.mundaneassignmentpolice.pdfdocument.PDFArea -import com.github.darderion.mundaneassignmentpolice.pdfdocument.PDFRegion -import com.github.darderion.mundaneassignmentpolice.utils.InvalidOperationException -import com.github.darderion.mundaneassignmentpolice.utils.LowQualityConferencesUtil -import com.github.darderion.mundaneassignmentpolice.utils.URLUtil -import java.util.* - -private val enLetters = "abcdefghijklmnopqrstuvwxyz" -private val enCapitalLetters = enLetters.uppercase(Locale.getDefault()) -private val EN = enLetters + enCapitalLetters - -private val rusLetters = "абвгдеёжзийклмнопрстуфхцчшщъыьэюя" -private val rusCapitalLetters = rusLetters.uppercase(Locale.getDefault()) -private val RU = rusLetters + rusCapitalLetters - -private val numbers = "0123456789" - -val RULE_LITLINK = SymbolRuleBuilder() - .symbol('?') - .ignoringAdjusting(*" ,$numbers".toCharArray()) - .shouldNotHaveNeighbor(*"[]".toCharArray()) - //.called("Symbol '?' in litlink") - .called("Символ ? в ссылке на литературу") - .getRule() - -val shortDash = '-' - -// 3-way road -// one-sided battle - -val shortDashRules = SymbolRuleBuilder() - .symbol(shortDash) - .shouldHaveNeighbor(*EN.toCharArray()) - .shouldHaveNeighbor(*RU.toCharArray()) - .shouldHaveNeighbor(*numbers.toCharArray()) - //.called("Incorrect usage of '-' symbol") - .called("Неправильное использование дефиса") - .inArea(PDFRegion.EVERYWHERE.except(PDFArea.BIBLIOGRAPHY, PDFArea.FOOTNOTE, PDFArea.TITLE_PAGE)) - -val RULE_SHORT_DASH = shortDashRules.getRule() and ( - shortDashRules.fromLeft().shouldHaveNeighbor('.') - .shouldNotHaveNeighbor(*numbers.toCharArray()).getRule() or - shortDashRules.fromRight().shouldHaveNeighbor('\n') - .shouldNotHaveNeighbor(*numbers.toCharArray()).getRule() - ) - -val mediumDash = '–' - -val RULE_MEDIUM_DASH = SymbolRuleBuilder() - .symbol(mediumDash) - .shouldHaveNeighbor(*numbers.toCharArray()) - //.called("Incorrect usage of '--' symbol") - .called("Неправильное использование короткого тире") - .inArea(PDFRegion.EVERYWHERE.except(PDFArea.BIBLIOGRAPHY, PDFArea.FOOTNOTE)) - .ignoringIfIndex(0) - .getRule() - -val longDash = '—' - -val RULE_LONG_DASH = SymbolRuleBuilder() - .symbol(longDash) - .ignoringAdjusting(' ') - .shouldNotHaveNeighbor(*numbers.toCharArray()) - //.called("Incorrect usage of '---' symbol") - .called("Неправильное использование длинного тире") - .inArea(PDFRegion.EVERYWHERE.except(PDFArea.BIBLIOGRAPHY, PDFArea.FOOTNOTE)) - .getRule() and SymbolRuleBuilder() - .symbol(longDash) - .shouldHaveNeighbor(' ') - .inArea(PDFRegion.EVERYWHERE.except(PDFArea.BIBLIOGRAPHY, PDFArea.FOOTNOTE)) - .getRule() - -val closingQuote = '”' -val openingQuote = '“' - -val RULE_CLOSING_QUOTATION = SymbolRuleBuilder() - .symbol(closingQuote) - .ignoringEveryCharacterExcept(*"$closingQuote$openingQuote".toCharArray()) - .fromLeft().shouldHaveNeighbor(openingQuote) - .inNeighborhood(20) - .called("Неправильное использование закрывающей кавычки") - .getRule() - -val RULE_OPENING_QUOTATION = SymbolRuleBuilder() - .symbol(openingQuote) - .ignoringEveryCharacterExcept(*"$closingQuote$openingQuote".toCharArray()) - .fromRight().shouldHaveNeighbor(closingQuote) - .inNeighborhood(20) - .called("Неправильное использование открывающей кавычки") - .getRule() - -const val squareClosingBracket = ']' -const val squareOpeningBracket = '[' - -val RULE_MULTIPLE_LITLINKS = SymbolRuleBuilder() - .symbol(squareClosingBracket) - .ignoringAdjusting(' ', ',') - .fromRight().shouldNotHaveNeighbor(squareOpeningBracket) - .called("Неправильное оформление нескольких ссылок") - .getRule() - -const val bracket = '(' - -val RULE_BRACKETS_LETTERS = List(2) { - SymbolRuleBuilder() - .symbol(bracket) - .ignoringAdjusting(' ') - .called("Большая русская буква после скобки") - .type(RuleViolationType.Warning) -}.apply { - first() - .fromLeft() - .shouldNotHaveNeighbor('.') - last() - .fromRight() - .shouldNotHaveNeighbor(*rusCapitalLetters.toCharArray()) -}.map { it.getRule() } - .reduce { acc, symbolRule -> - acc and symbolRule - } - -private const val openingBrackets = "([{<" -private const val closingBrackets = ")]}>" -private const val closingQuotes = "”»" -private const val punctuationSymbols = ".,;:!?" - -private val spaceAroundBracketsRuleBuilders = List(2) { SymbolRuleBuilder() } - .map { it.shouldHaveNeighbor(' ', '\n') } - .map { it.called("Отсутствует пробел с внешней стороны скобок") } - .apply { - // setting up a rule that should look for a space before opening brackets - first().fromLeft().ignoringAdjusting(*openingBrackets.toCharArray()) - // and this rule should look for after closing brackets - last().fromRight() - .ignoringAdjusting(*"$punctuationSymbols$closingQuotes$closingBrackets".toCharArray()) - } - -// For case when round brackets are empty: "function()" -private val openingRoundBracketExceptionalRule = SymbolRuleBuilder() - .symbol('(') - .fromRight().shouldHaveNeighbor(')') - .getRule() - -val RULES_SPACE_AROUND_BRACKETS = spaceAroundBracketsRuleBuilders - .zip(listOf(openingBrackets, closingBrackets).map { it.toCharArray() }) - .map { pair -> pair.second.map { pair.first.symbol(it).getRule() } } - .flatten() - .map { - if (it.symbol == '(') it or openingRoundBracketExceptionalRule - else it - } - -val RULE_CITATION = SymbolRuleBuilder() - .symbol('[') - .ignoringAdjusting(' ', '\n') - .fromLeft().shouldNotHaveNeighbor('.') - .called("Некорректное цитирование") - .inArea(PDFArea.SECTION) - .getRule() - -val RULE_SINGLE_SUBSECTION = ListRuleBuilder() - .inArea(PDFRegion.NOWHERE.except(PDFArea.TABLE_OF_CONTENT)) - //.called("Only 1 subsection in a section") - .called("Одна подсекция в секции") - .disallow { - if (it.nodes.count() == 1) it.nodes.first().getText() else listOf() - }.getRule() - -val RULE_TABLE_OF_CONTENT_NUMBERS = TableOfContentRuleBuilder() - .disallow { - it.filter { - // println("${it.text.count()} -> ${it.content}") - val text = it.text.filter { it.text.trim().isNotEmpty() } - ((text.count() == 3 && (text[1].text == Section.INTRODUCTION.title || - text[1].text == Section.CONCLUSION.title)) || - (text.count() == 4 && (text[1].text + " " + text[2].text) == Section.BIBLIOGRAPHY.title)) - } - }.called("Введение, заключение и список литературы не нумеруются") - .getRule() - -val RULE_SYMBOLS_IN_SECTION_NAMES = TableOfContentRuleBuilder() - .disallow { listOfLines -> - listOfLines.filter { line -> - val text = line.text.filterNot { it.text == "." } // remove leaders - .filterNot { it.text.contains("[0-9]+\\.".toRegex()) } // remove numbering - .joinToString("") - text.contains("[:.,]".toRegex()) - } - }.called("""Символы ":", ".", "," в названии секции""") - .getRule() - -val sectionsThatMayPrecedeThis = mapOf>( - Section.INTRODUCTION.title to hashSetOf(""), - Section.PROBLEM_STATEMENT.title to hashSetOf(Section.INTRODUCTION.title), - Section.REVIEW.title to hashSetOf(Section.PROBLEM_STATEMENT.title), - Section.CONTENT.title to hashSetOf(Section.REVIEW.title, Section.CONTENT.title), - Section.CONCLUSION.title to hashSetOf(Section.CONTENT.title), - Section.BIBLIOGRAPHY.title to hashSetOf(Section.CONCLUSION.title) -) - -val RULE_SECTIONS_ORDER = TableOfContentRuleBuilder() - .disallow { listOfLines -> - var nameOfPreviousSection = "" - listOfLines - .filterNot { line -> - val words = line.text - .filter { it.text.trim().isNotEmpty() } - .filterNot { it.text.contains("[0-9]+\\.".toRegex()) } // remove numbering - words.isEmpty() || words[0].text == Section.TABLE_OF_CONTENT.title - } - .filter { line -> - val words = line.text - .filter { it.text.trim().isNotEmpty() } - .filterNot { it.text.contains("[0-9]+\\.".toRegex()) } // remove numbering - - val sectionName = - if ((words[0].text + " " + words[1].text) == Section.BIBLIOGRAPHY.title || - (words[0].text + " " + words[1].text) == Section.PROBLEM_STATEMENT.title - ) - words[0].text + " " + words[1].text - else if (sectionsThatMayPrecedeThis.contains(words[0].text)) - words[0].text - else - Section.CONTENT.title - - val isRuleViolation = - !sectionsThatMayPrecedeThis[sectionName]!!.contains(nameOfPreviousSection) - nameOfPreviousSection = sectionName - isRuleViolation - } - } - .called("Неверный порядок секций") - .getRule() - -val smallNumbersRuleName = "Неправильное написание целых чисел от 1 до 9" -val smallNumbersRuleArea = - PDFRegion.EVERYWHERE.except(PDFArea.PAGE_INDEX, PDFArea.TABLE_OF_CONTENT, PDFArea.BIBLIOGRAPHY) -val allowedWordsOnLeft = arrayOf( - Regex("""[Рр]ис[a-я]*"""), - Regex("""[Тт]абл[a-я]*"""), Regex("""[Сс]х[a-я]*"""), - Regex("""[Dd]ef[a-z]*"""), Regex("""[Оо]пр[а-я]*"""), - Regex("""[Tt]h[a-z]*"""), Regex("""[Тт]еорема""") -) -val allowedWordsOnRight = arrayOf( - Regex("""[Gg][Bb]"""), Regex("""[Гг][Бб]"""), - Regex("""[Mm][Bb]"""), Regex("""[Мм][Бб]"""), - Regex("""[Gg][Hh][Zz]"""), Regex("""[Гг][Цц]"""), - Regex("""→""") -) - -val smallNumbersRuleBuilder1 = WordRuleBuilder() //for nearest words - .called(smallNumbersRuleName) - .inArea(smallNumbersRuleArea) - .ignoringAdjusting(Regex("""\s"""), Regex("""\.""")) - .ignoringIfIndex(0) - -val smallNumbersRuleBuilder2 = WordRuleBuilder() //for decimal fractions and version numbers - .called(smallNumbersRuleName) - .inArea(smallNumbersRuleArea) - .shouldHaveNeighbor(Regex("""\."""), Regex(""","""), - Regex("""[0-9]+""")) - .shouldHaveNumberOfNeighbors(2) - -val smallNumbersRuleBuilder3 = WordRuleBuilder() //for links - .called(smallNumbersRuleName) - .inArea(smallNumbersRuleArea) - .fromLeft() - .ignoringWords(true) - .ignoringAdjusting(Regex(""","""), Regex("""\s""")) - .shouldHaveNeighbor(Regex("""\[""")) - -val RULES_SMALL_NUMBERS = List(9) { index -> - smallNumbersRuleBuilder1.word((index + 1).toString()) - .fromLeft().shouldHaveNeighbor(*allowedWordsOnLeft).getRule() or - smallNumbersRuleBuilder1.word((index + 1).toString()) - .fromRight().shouldHaveNeighbor(*allowedWordsOnRight).getRule() or - smallNumbersRuleBuilder2.word((index + 1).toString()).fromLeft().getRule() or - smallNumbersRuleBuilder2.fromRight().getRule() or - smallNumbersRuleBuilder3.word((index + 1).toString()).getRule() -} - -const val shortenedUrlRuleName = "Сокращённая ссылка" -val shortenedUrlRuleArea = PDFRegion.NOWHERE.except(PDFArea.FOOTNOTE, PDFArea.BIBLIOGRAPHY) - -val urlShortenersListRule = URLRuleBuilder() - .called(shortenedUrlRuleName) - .inArea(shortenedUrlRuleArea) - .type(RuleViolationType.Error) - .disallow { urls -> - val urlShorteners = URLUtil.getUrlShorteners() - urls.filter { url -> - urlShorteners.any { URLUtil.equalDomainName(it, url.text) } - }.map { it to it.lines } - }.getRule() - -val shortUrlRule = URLRuleBuilder() - .called(shortenedUrlRuleName) - .inArea(shortenedUrlRuleArea) - .type(RuleViolationType.Warning) - .disallow { urls -> - urls.filter { url -> - URLUtil.getDomainName(url.text).replace(".", "").length in (3..5) - }.map { it to it.lines } - }.getRule() - -val allowedDomainNamesWithRedirect = listOf("doi.org", "dx.doi.org") - -val urlWithRedirectRule = URLRuleBuilder() - .called(shortenedUrlRuleName) - .inArea(shortenedUrlRuleArea) - .type(RuleViolationType.Warning) - .disallow { urls -> - urls.filterNot { url -> - allowedDomainNamesWithRedirect.any { URLUtil.equalDomainName(it, url.text) } - }.filter { url -> - try { - URLUtil.isRedirect(url.text) - } catch (_: InvalidOperationException) { - false - } - }.map { it to it.lines } - }.getRule() - -val RULE_SHORTENED_URLS = urlShortenersListRule then shortUrlRule then urlWithRedirectRule - -val RULE_URLS_UNIFORMITY = URLRuleBuilder() - .called("Ссылки разных видов") - .inArea(PDFRegion.NOWHERE.except(PDFArea.FOOTNOTE, PDFArea.BIBLIOGRAPHY)) - .disallow { urls -> - var filteredUrls = urls.filter { url -> - !url.text.startsWith("https://www") - } - if (urls.size == filteredUrls.size) { - filteredUrls = filteredUrls.filter { url -> - !url.text.startsWith("www") - } - if (urls.size == filteredUrls.size) { - filteredUrls = filteredUrls.filter { url -> - !url.text.startsWith("htt") - } - } - } - filteredUrls.map { it to it.lines } - }.getRule() - -val RULE_ORDER_OF_REFERENCES = RegexRuleBuilder() - .called("Неверный порядок ссылок на литературу") - .regex(Regex("""\[[0-9,\s]+\]""")) - .searchIn(1) - .disallow { matches -> - matches.filter { pair -> - val references = pair.first - val referencesInIntList = references - .slice(IntRange(1, references.length - 2)) - .split(Regex(""",""")) - .map { it.trim() } - .filter { it.isNotEmpty() } - .map { it.toInt() } - referencesInIntList != referencesInIntList.sorted() - }.map { it.second } - }.getRule() - -val RULE_VARIOUS_ABBREVIATIONS = RegexRuleBuilder() - .called("Использованы различные версии сокращения") - .regex(Regex("""[a-zA-Zа-яА-Я]+""")) - .inArea(PDFRegion.EVERYWHERE.except(PDFArea.BIBLIOGRAPHY)) - .disallow { matches -> - val abbreviations = hashSetOf() - val allWords = hashMapOf>() - matches.forEach { pair -> - val word = pair.first - if (word.slice(IntRange(1, word.length - 1)) - .count { it.isUpperCase() } > 0) - abbreviations.add(word.uppercase()) - if (!allWords.containsKey(word.lowercase())) - allWords.put(word.lowercase(), hashSetOf()) - allWords[word.lowercase()]?.add(word) - } - matches.filter { pair -> - val word = pair.first - if (abbreviations.contains(word.uppercase())) - allWords[word.lowercase()]?.size!! > 1 - else - false - }.map { it.second } - }.getRule() - -val RULE_LOW_QUALITY_CONFERENCES = URLRuleBuilder() - .called("Ссылка на низкокачественную конференцию") - .inArea(PDFArea.BIBLIOGRAPHY) - .disallow { urls -> - val lowQualityConferencesList = LowQualityConferencesUtil.getList() - .map { - it.removePrefix("http://").removePrefix("https://") - } - urls.filter { url -> - lowQualityConferencesList - .any { conference -> url.text.contains(conference) } - }.map { it to it.lines } - }.getRule() diff --git a/src/main/kotlin/com/github/darderion/mundaneassignmentpolice/rules/SymbolRules.kt b/src/main/kotlin/com/github/darderion/mundaneassignmentpolice/rules/SymbolRules.kt new file mode 100644 index 00000000..919aeaf7 --- /dev/null +++ b/src/main/kotlin/com/github/darderion/mundaneassignmentpolice/rules/SymbolRules.kt @@ -0,0 +1,164 @@ +package com.github.darderion.mundaneassignmentpolice.rules + +import com.github.darderion.mundaneassignmentpolice.checker.RuleViolationType +import com.github.darderion.mundaneassignmentpolice.checker.rule.symbol.and +import com.github.darderion.mundaneassignmentpolice.checker.rule.symbol.or +import com.github.darderion.mundaneassignmentpolice.checker.rulebuilder.symbolbuilder.SymbolRuleBuilder +import com.github.darderion.mundaneassignmentpolice.pdfdocument.PDFArea +import com.github.darderion.mundaneassignmentpolice.pdfdocument.PDFRegion +import java.util.* + +private val enLetters = "abcdefghijklmnopqrstuvwxyz" +private val enCapitalLetters = enLetters.uppercase(Locale.getDefault()) +private val EN = enLetters + enCapitalLetters + +private val rusLetters = "абвгдеёжзийклмнопрстуфхцчшщъыьэюя" +private val rusCapitalLetters = rusLetters.uppercase(Locale.getDefault()) +private val RU = rusLetters + rusCapitalLetters + +private val numbers = "0123456789" + +val RULE_LITLINK = SymbolRuleBuilder>() + .symbol('?') + .ignoringAdjusting(*" ,$numbers".toCharArray()) + .shouldNotHaveNeighbor(*"[]".toCharArray()) + //.called("Symbol '?' in litlink") + .called("Символ ? в ссылке на литературу") + .getRule() + +val shortDash = '-' + +// 3-way road +// one-sided battle + +val shortDashRules = SymbolRuleBuilder>() + .symbol(shortDash) + .shouldHaveNeighbor(*EN.toCharArray()) + .shouldHaveNeighbor(*RU.toCharArray()) + .shouldHaveNeighbor(*numbers.toCharArray()) + //.called("Incorrect usage of '-' symbol") + .called("Неправильное использование дефиса") + .inArea(PDFRegion.EVERYWHERE.except(PDFArea.BIBLIOGRAPHY, PDFArea.FOOTNOTE, PDFArea.TITLE_PAGE)) + +val RULE_SHORT_DASH = shortDashRules.getRule() and ( + shortDashRules.fromLeft().shouldHaveNeighbor('.') + .shouldNotHaveNeighbor(*numbers.toCharArray()).getRule() or + shortDashRules.fromRight().shouldHaveNeighbor('\n') + .shouldNotHaveNeighbor(*numbers.toCharArray()).getRule() + ) + +val mediumDash = '–' + +val RULE_MEDIUM_DASH = SymbolRuleBuilder>() + .symbol(mediumDash) + .ignoringIfIndex(0) + .shouldHaveNeighbor(*numbers.toCharArray()) + //.called("Incorrect usage of '--' symbol") + .called("Неправильное использование короткого тире") + .inArea(PDFRegion.EVERYWHERE.except(PDFArea.BIBLIOGRAPHY, PDFArea.FOOTNOTE)) + .getRule() + +val longDash = '—' + +val RULE_LONG_DASH = SymbolRuleBuilder>() + .symbol(longDash) + .ignoringAdjusting(' ') + .shouldNotHaveNeighbor(*numbers.toCharArray()) + //.called("Incorrect usage of '---' symbol") + .called("Неправильное использование длинного тире") + .inArea(PDFRegion.EVERYWHERE.except(PDFArea.BIBLIOGRAPHY, PDFArea.FOOTNOTE)) + .getRule() and SymbolRuleBuilder>() + .symbol(longDash) + .shouldHaveNeighbor(' ') + .inArea(PDFRegion.EVERYWHERE.except(PDFArea.BIBLIOGRAPHY, PDFArea.FOOTNOTE)) + .getRule() + +val closingQuote = '”' +val openingQuote = '“' + +val RULE_CLOSING_QUOTATION = SymbolRuleBuilder>() + .symbol(closingQuote) + .ignoringEveryCharacterExcept(*"$closingQuote$openingQuote".toCharArray()) + .fromLeft().shouldHaveNeighbor(openingQuote) + .inNeighborhood(20) + .called("Неправильное использование закрывающей кавычки") + .getRule() + +val RULE_OPENING_QUOTATION = SymbolRuleBuilder>() + .symbol(openingQuote) + .ignoringEveryCharacterExcept(*"$closingQuote$openingQuote".toCharArray()) + .fromRight().shouldHaveNeighbor(closingQuote) + .inNeighborhood(20) + .called("Неправильное использование открывающей кавычки") + .getRule() + +const val squareClosingBracket = ']' +const val squareOpeningBracket = '[' + +val RULE_MULTIPLE_LITLINKS = SymbolRuleBuilder>() + .symbol(squareClosingBracket) + .ignoringAdjusting(' ', ',') + .fromRight().shouldNotHaveNeighbor(squareOpeningBracket) + .called("Неправильное оформление нескольких ссылок") + .getRule() + +const val bracket = '(' + +val RULE_BRACKETS_LETTERS = List(2) { + SymbolRuleBuilder>() + .symbol(bracket) + .ignoringAdjusting(' ') + .called("Большая русская буква после скобки") + .type(RuleViolationType.Warning) +}.apply { + first() + .fromLeft() + .shouldNotHaveNeighbor('.') + last() + .fromRight() + .shouldNotHaveNeighbor(*rusCapitalLetters.toCharArray()) +}.map { it.getRule() } + .reduce { acc, symbolRule -> + acc and symbolRule + } + +private const val openingBrackets = "([{<" +private const val closingBrackets = ")]}>" +private const val closingQuotes = "”»" +private const val punctuationSymbols = ".,;:!?" + + +private val spaceAroundBracketsRuleBuilders = List(2) { SymbolRuleBuilder>() } + .map { it.shouldHaveNeighbor(' ', '\n') } + .map { it.called("Отсутствует пробел с внешней стороны скобок") } + .apply { + // setting up a rule that should look for a space before opening brackets + first().fromLeft().ignoringAdjusting(*openingBrackets.toCharArray()) + // and this rule should look for after closing brackets + last().fromRight() + .ignoringAdjusting(*"$punctuationSymbols$closingQuotes$closingBrackets".toCharArray()) + } + +// For case when round brackets are empty: "function()" +private val openingRoundBracketExceptionalRule = SymbolRuleBuilder>() + .symbol('(') + .fromRight().shouldHaveNeighbor(')') + .getRule() + +val RULES_SPACE_AROUND_BRACKETS = spaceAroundBracketsRuleBuilders + .zip(listOf(openingBrackets, closingBrackets).map { it.toCharArray() }) + .map { pair -> pair.second.map { pair.first.symbol(it).getRule() } } + .flatten() + .map { + if (it.symbol == '(') it or openingRoundBracketExceptionalRule + else it + } + +val RULE_CITATION = SymbolRuleBuilder>() + .symbol('[') + .called("Некорректное цитирование") + .inArea(PDFArea.SECTION) + .ignoringAdjusting(' ', '\n') + .fromLeft().shouldNotHaveNeighbor('.') + .getRule() + diff --git a/src/main/kotlin/com/github/darderion/mundaneassignmentpolice/rules/TableOfContentRules.kt b/src/main/kotlin/com/github/darderion/mundaneassignmentpolice/rules/TableOfContentRules.kt new file mode 100644 index 00000000..5e6dc9df --- /dev/null +++ b/src/main/kotlin/com/github/darderion/mundaneassignmentpolice/rules/TableOfContentRules.kt @@ -0,0 +1,74 @@ +package com.github.darderion.mundaneassignmentpolice.rules + +import com.github.darderion.mundaneassignmentpolice.checker.Section +import com.github.darderion.mundaneassignmentpolice.checker.rulebuilder.tableofcontentbuilder.TableOfContentRuleBuilder +import java.util.HashSet + + +val RULE_TABLE_OF_CONTENT_NUMBERS = TableOfContentRuleBuilder>() + .called("Введение, заключение и список литературы не нумеруются") + .disallow { + it.filter { + // println("${it.text.count()} -> ${it.content}") + val text = it.text.filter { it.text.trim().isNotEmpty() } + ((text.count() == 3 && (text[1].text == Section.INTRODUCTION.title || + text[1].text == Section.CONCLUSION.title)) || + (text.count() == 4 && (text[1].text + " " + text[2].text) == Section.BIBLIOGRAPHY.title)) + } + } + .getRule() + + +val RULE_SYMBOLS_IN_SECTION_NAMES = TableOfContentRuleBuilder>() + .disallow { listOfLines -> + listOfLines.filter { line -> + val text = line.text.filterNot { it.text == "." } // remove leaders + .filterNot { it.text.contains("[0-9]+\\.".toRegex()) } // remove numbering + .joinToString("") + text.contains("[:.,]".toRegex()) + } + }.called("""Символы ":", ".", "," в названии секции""") + .getRule() + +val sectionsThatMayPrecedeThis = mapOf>( + Section.INTRODUCTION.title to hashSetOf(""), + Section.PROBLEM_STATEMENT.title to hashSetOf(Section.INTRODUCTION.title), + Section.REVIEW.title to hashSetOf(Section.PROBLEM_STATEMENT.title), + Section.CONTENT.title to hashSetOf(Section.REVIEW.title, Section.CONTENT.title), + Section.CONCLUSION.title to hashSetOf(Section.CONTENT.title), + Section.BIBLIOGRAPHY.title to hashSetOf(Section.CONCLUSION.title) +) + +val RULE_SECTIONS_ORDER = TableOfContentRuleBuilder>() + .disallow { listOfLines -> + var nameOfPreviousSection = "" + listOfLines + .filterNot { line -> + val words = line.text + .filter { it.text.trim().isNotEmpty() } + .filterNot { it.text.contains("[0-9]+\\.".toRegex()) } // remove numbering + words.isEmpty() || words[0].text == Section.TABLE_OF_CONTENT.title + } + .filter { line -> + val words = line.text + .filter { it.text.trim().isNotEmpty() } + .filterNot { it.text.contains("[0-9]+\\.".toRegex()) } // remove numbering + + val sectionName = + if ((words[0].text + " " + words[1].text) == Section.BIBLIOGRAPHY.title || + (words[0].text + " " + words[1].text) == Section.PROBLEM_STATEMENT.title + ) + words[0].text + " " + words[1].text + else if (sectionsThatMayPrecedeThis.contains(words[0].text)) + words[0].text + else + Section.CONTENT.title + + val isRuleViolation = + !sectionsThatMayPrecedeThis[sectionName]!!.contains(nameOfPreviousSection) + nameOfPreviousSection = sectionName + isRuleViolation + } + } + .called("Неверный порядок секций") + .getRule() \ No newline at end of file diff --git a/src/main/kotlin/com/github/darderion/mundaneassignmentpolice/rules/URLRules.kt b/src/main/kotlin/com/github/darderion/mundaneassignmentpolice/rules/URLRules.kt new file mode 100644 index 00000000..d031c283 --- /dev/null +++ b/src/main/kotlin/com/github/darderion/mundaneassignmentpolice/rules/URLRules.kt @@ -0,0 +1,90 @@ +package com.github.darderion.mundaneassignmentpolice.rules + +import com.github.darderion.mundaneassignmentpolice.checker.RuleViolationType +import com.github.darderion.mundaneassignmentpolice.checker.rule.url.then +import com.github.darderion.mundaneassignmentpolice.checker.rulebuilder.urlbuilder.URLRuleBuilder +import com.github.darderion.mundaneassignmentpolice.pdfdocument.PDFArea +import com.github.darderion.mundaneassignmentpolice.pdfdocument.PDFRegion +import com.github.darderion.mundaneassignmentpolice.utils.InvalidOperationException +import com.github.darderion.mundaneassignmentpolice.utils.LowQualityConferencesUtil +import com.github.darderion.mundaneassignmentpolice.utils.URLUtil + +const val shortenedUrlRuleName = "Сокращённая ссылка" +val shortenedUrlRuleArea = PDFRegion.NOWHERE.except(PDFArea.FOOTNOTE, PDFArea.BIBLIOGRAPHY) + +val urlShortenersListRule = URLRuleBuilder>() + .called(shortenedUrlRuleName) + .inArea(shortenedUrlRuleArea) + .type(RuleViolationType.Error) + .disallow { urls -> + val urlShorteners = URLUtil.getUrlShorteners() + urls.filter { url -> + urlShorteners.any { URLUtil.equalDomainName(it, url.text) } + }.map { it to it.lines } + }.getRule() + +val shortUrlRule = URLRuleBuilder>() + .called(shortenedUrlRuleName) + .inArea(shortenedUrlRuleArea) + .type(RuleViolationType.Warning) + .disallow { urls -> + urls.filter { url -> + URLUtil.getDomainName(url.text).replace(".", "").length in (3..5) + }.map { it to it.lines } + }.getRule() + +val allowedDomainNamesWithRedirect = listOf("doi.org", "dx.doi.org") + +val urlWithRedirectRule = URLRuleBuilder>() + .called(shortenedUrlRuleName) + .inArea(shortenedUrlRuleArea) + .type(RuleViolationType.Warning) + .disallow { urls -> + urls.filterNot { url -> + allowedDomainNamesWithRedirect.any { URLUtil.equalDomainName(it, url.text) } + }.filter { url -> + try { + URLUtil.isRedirect(url.text) + } catch (_: InvalidOperationException) { + false + } + }.map { it to it.lines } + }.getRule() + +val RULE_SHORTENED_URLS = urlShortenersListRule then shortUrlRule then urlWithRedirectRule + +val RULE_URLS_UNIFORMITY = URLRuleBuilder>() + .called("Ссылки разных видов") + .inArea(PDFRegion.NOWHERE.except(PDFArea.FOOTNOTE, PDFArea.BIBLIOGRAPHY)) + .disallow { urls -> + var filteredUrls = urls.filter { url -> + !url.text.startsWith("https://www") + } + if (urls.size == filteredUrls.size) { + filteredUrls = filteredUrls.filter { url -> + !url.text.startsWith("www") + } + if (urls.size == filteredUrls.size) { + filteredUrls = filteredUrls.filter { url -> + !url.text.startsWith("htt") + } + } + } + filteredUrls.map { it to it.lines } + }.getRule() + + + +val RULE_LOW_QUALITY_CONFERENCES = URLRuleBuilder>() + .called("Ссылка на низкокачественную конференцию") + .inArea(PDFArea.BIBLIOGRAPHY) + .disallow { urls -> + val lowQualityConferencesList = LowQualityConferencesUtil.getList() + .map { + it.removePrefix("http://").removePrefix("https://") + } + urls.filter { url -> + lowQualityConferencesList + .any { conference -> url.text.contains(conference) } + }.map { it to it.lines } + }.getRule() \ No newline at end of file diff --git a/src/main/kotlin/com/github/darderion/mundaneassignmentpolice/rules/WordRules.kt b/src/main/kotlin/com/github/darderion/mundaneassignmentpolice/rules/WordRules.kt new file mode 100644 index 00000000..741333a2 --- /dev/null +++ b/src/main/kotlin/com/github/darderion/mundaneassignmentpolice/rules/WordRules.kt @@ -0,0 +1,55 @@ +package com.github.darderion.mundaneassignmentpolice.rules + +import com.github.darderion.mundaneassignmentpolice.checker.rule.word.WordRule +import com.github.darderion.mundaneassignmentpolice.checker.rule.word.or +import com.github.darderion.mundaneassignmentpolice.checker.rulebuilder.wordbuilder.WordRuleBuilder +import com.github.darderion.mundaneassignmentpolice.pdfdocument.PDFArea +import com.github.darderion.mundaneassignmentpolice.pdfdocument.PDFRegion + + +val smallNumbersRuleName = "Неправильное написание целых чисел от 1 до 9" +val smallNumbersRuleArea = + PDFRegion.EVERYWHERE.except(PDFArea.PAGE_INDEX, PDFArea.TABLE_OF_CONTENT, PDFArea.BIBLIOGRAPHY) +val allowedWordsOnLeft = arrayOf( + Regex("""[Рр]ис[a-я]*"""), + Regex("""[Тт]абл[a-я]*"""), Regex("""[Сс]х[a-я]*"""), + Regex("""[Dd]ef[a-z]*"""), Regex("""[Оо]пр[а-я]*"""), + Regex("""[Tt]h[a-z]*"""), Regex("""[Тт]еорема""") +) +val allowedWordsOnRight = arrayOf( + Regex("""[Gg][Bb]"""), Regex("""[Гг][Бб]"""), + Regex("""[Mm][Bb]"""), Regex("""[Мм][Бб]"""), + Regex("""[Gg][Hh][Zz]"""), Regex("""[Гг][Цц]"""), + Regex("""→""") +) + +val smallNumbersRuleBuilder1 = WordRuleBuilder>() //for nearest words + .called(smallNumbersRuleName) + .inArea(smallNumbersRuleArea) + .ignoringAdjusting(Regex("""\s"""), Regex("""\.""")) + .ignoringIfIndex(0) + +val smallNumbersRuleBuilder2 = WordRuleBuilder>() //for decimal fractions and version numbers + .called(smallNumbersRuleName) + .inArea(smallNumbersRuleArea) + .shouldHaveNeighbor(Regex("""\."""), Regex(""","""), + Regex("""[0-9]+""")) + .shouldHaveNumberOfNeighbors(2) + +val smallNumbersRuleBuilder3 = WordRuleBuilder>() //for links + .called(smallNumbersRuleName) + .inArea(smallNumbersRuleArea) + .fromLeft() + .ignoringWords(true) + .ignoringAdjusting(Regex(""","""), Regex("""\s""")) + .shouldHaveNeighbor(Regex("""\[""")) + +val RULES_SMALL_NUMBERS = List(9) { index -> + smallNumbersRuleBuilder1.word((index + 1).toString()) + .fromLeft().shouldHaveNeighbor(*allowedWordsOnLeft).getRule() or + smallNumbersRuleBuilder1.word((index + 1).toString()) + .fromRight().shouldHaveNeighbor(*allowedWordsOnRight).getRule() or + smallNumbersRuleBuilder2.word((index + 1).toString()).fromLeft().getRule() or + smallNumbersRuleBuilder2.fromRight().getRule() or + smallNumbersRuleBuilder3.word((index + 1).toString()).getRule() +} diff --git a/src/test/kotlin/com/github/darderion/mundaneassignmentpolice/checker/ListRuleTests.kt b/src/test/kotlin/com/github/darderion/mundaneassignmentpolice/checker/ListRuleTests.kt index 155f251c..e0c279f8 100644 --- a/src/test/kotlin/com/github/darderion/mundaneassignmentpolice/checker/ListRuleTests.kt +++ b/src/test/kotlin/com/github/darderion/mundaneassignmentpolice/checker/ListRuleTests.kt @@ -1,16 +1,16 @@ package com.github.darderion.mundaneassignmentpolice.checker -import com.github.darderion.mundaneassignmentpolice.checker.rule.list.ListRuleBuilder import com.github.darderion.mundaneassignmentpolice.pdfdocument.PDFArea.TABLE_OF_CONTENT import com.github.darderion.mundaneassignmentpolice.wrapper.PDFBox import io.kotest.core.spec.style.StringSpec import io.kotest.matchers.ints.shouldBeExactly import com.github.darderion.mundaneassignmentpolice.TestsConfiguration.Companion.resourceFolder +import com.github.darderion.mundaneassignmentpolice.checker.rulebuilder.listbuilder.ListRuleBuilder import com.github.darderion.mundaneassignmentpolice.pdfdocument.PDFArea.SECTION class ListRuleTests: StringSpec({ "List rule should detect lists of incorrect size in TABLE_OF_CONTENT" { - ListRuleBuilder() + ListRuleBuilder>() .inArea(TABLE_OF_CONTENT) .disallow { if (it.nodes.count() == 1) it.getText() else listOf() @@ -18,7 +18,7 @@ class ListRuleTests: StringSpec({ .process(PDFBox().getPDF(filePathTableOfContent)).count() shouldBeExactly 2 } "List rule should detect lists of incorrect size in SECTION" { - ListRuleBuilder() + ListRuleBuilder>() .inArea(SECTION) .disallow { if (it.nodes.count() == 1) it.getText() else listOf() diff --git a/src/test/kotlin/com/github/darderion/mundaneassignmentpolice/checker/RulesTests.kt b/src/test/kotlin/com/github/darderion/mundaneassignmentpolice/checker/RulesTests.kt index ab57bce4..0338228c 100644 --- a/src/test/kotlin/com/github/darderion/mundaneassignmentpolice/checker/RulesTests.kt +++ b/src/test/kotlin/com/github/darderion/mundaneassignmentpolice/checker/RulesTests.kt @@ -41,7 +41,8 @@ class RulesTests : StringSpec({ RULES_SMALL_NUMBERS.sumOf { it.process(PDFBox().getPDF(filePathSmallNumbers)).count() } shouldBeExactly 6 } "Symbol rule should detect the lack of space around brackets" { - RULES_SPACE_AROUND_BRACKETS.map { it.process(PDFBox().getPDF(filePathSpaceAroundBrackets)) } + RULES_SPACE_AROUND_BRACKETS.map { it.process(PDFBox().getPDF(filePathSpaceAroundBrackets)) + } .flatten() .count() shouldBeExactly 16 } @@ -145,3 +146,4 @@ class RulesTests : StringSpec({ "${TestsConfiguration.resourceFolder}checker/MultilineCitation.pdf" } } + diff --git a/src/test/kotlin/com/github/darderion/mundaneassignmentpolice/checker/SymbolRuleTests.kt b/src/test/kotlin/com/github/darderion/mundaneassignmentpolice/checker/SymbolRuleTests.kt index c69434cb..57424dca 100644 --- a/src/test/kotlin/com/github/darderion/mundaneassignmentpolice/checker/SymbolRuleTests.kt +++ b/src/test/kotlin/com/github/darderion/mundaneassignmentpolice/checker/SymbolRuleTests.kt @@ -1,6 +1,5 @@ package com.github.darderion.mundaneassignmentpolice.checker -import com.github.darderion.mundaneassignmentpolice.checker.rule.symbol.SymbolRuleBuilder import com.github.darderion.mundaneassignmentpolice.pdfdocument.PDFArea import com.github.darderion.mundaneassignmentpolice.pdfdocument.PDFRegion import com.github.darderion.mundaneassignmentpolice.pdfdocument.PDFArea.* @@ -10,12 +9,13 @@ import io.kotest.matchers.ints.shouldBeExactly import com.github.darderion.mundaneassignmentpolice.TestsConfiguration.Companion.resourceFolder import com.github.darderion.mundaneassignmentpolice.checker.rule.symbol.and import com.github.darderion.mundaneassignmentpolice.checker.rule.symbol.or +import com.github.darderion.mundaneassignmentpolice.checker.rulebuilder.symbolbuilder.SymbolRuleBuilder class SymbolRuleTests: StringSpec({ "Symbol rule should only search for rule violations in its region" { val mediumDash = '–' - val symbolBuilder = SymbolRuleBuilder() + val symbolBuilder = SymbolRuleBuilder>() .symbol(mediumDash) .shouldHaveNeighbor(*"0123456789".toCharArray()) @@ -28,24 +28,24 @@ class SymbolRuleTests: StringSpec({ "Combined symbol rule should search for rule violations in its region" { val longDash = '—' - (SymbolRuleBuilder() + (SymbolRuleBuilder>() .symbol(longDash) .shouldHaveNeighbor(' ') .getRule() and - SymbolRuleBuilder() + SymbolRuleBuilder>() .symbol(longDash) .ignoringAdjusting(' ') .shouldNotHaveNeighbor(*"0123456789".toCharArray()) .getRule()) .process(PDFBox().getPDF(filePathQuestionMarkAndDashes)).count() shouldBeExactly 2 - (SymbolRuleBuilder() + (SymbolRuleBuilder>() .symbol(longDash) .shouldHaveNeighbor(' ') .getRule() or - SymbolRuleBuilder() + SymbolRuleBuilder>() .symbol(longDash) .ignoringAdjusting(' ') .shouldNotHaveNeighbor(*"0123456789".toCharArray())