summaryrefslogtreecommitdiff
path: root/support/arara/source/src/test/kotlin/org/islandoftex/arara/localization/LanguageReport.kt
blob: addcd0262cc3631e666f8b96e7a05938b01c3c15 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
// SPDX-License-Identifier: BSD-3-Clause
package org.islandoftex.arara.localization

import java.io.File

/**
 * Implements the language report model.
 *
 * @author Island of TeX
 * @version 5.0
 * @since 5.0
 */
data class LanguageReport(
    /**
     * The file reference.
     */
    val reference: File,
    /**
     * Total of checked lines.
     */
    val total: Int,
    /**
     * List of problematic lines and their corresponding error types.
     */
    val lines: Map<Int, Char>
) {
    /**
     * Language coverage of the file.
     */
    val coverage: Float
        get() = if (lines.isEmpty()) {
            100f
        } else {
            (1f - lines.size.toFloat() / total) * 100f
        }

    companion object {
        /**
         * Analyzes the list of lines.
         *
         * @param file The file to read.
         * @return The language report.
         */
        internal fun analyze(file: File): LanguageReport {
            // holds the current line number
            var number = 1
            // holds the number of checked lines
            var checked = 0

            // flag that holds the
            // current analysis
            var check: Int

            val reportLines = mutableMapOf<Int, Char>()

            // check every line of the language file
            file.forEachLine { line ->
                // let's only analyze lines
                // that are not comments
                if (!line.trim().startsWith("#")) {
                    // increment the checked
                    // line counter
                    checked++

                    // line is a parametrized message
                    check = if (line.contains("{0}")) {
                        // check the corresponding pattern
                        checkParametrizedMessage(line)
                    } else {
                        // check the corresponding pattern
                        checkMessage(line)
                    }

                    // we found an error,
                    // report it
                    if (check != 0) {
                        // add line and error type to the report
                        reportLines[number] = if (check == 1) 'P' else 'S'
                    }
                }

                // let's move to the next line
                number++
            }

            // return the language report
            return LanguageReport(
                    reference = file,
                    total = checked,
                    lines = reportLines)
        }

        /**
         * Checks if the provided message follows the simple format.
         *
         * @param text Message.
         * @return An integer value.
         */
        private fun checkMessage(text: String): Int {
            var i = 0
            var c: Char
            for (element in text) {
                c = element
                i = if (c == '\'') {
                    if (i == 1) {
                        return 2
                    } else {
                        1
                    }
                } else {
                    0
                }
            }
            return 0
        }

        /**
         * Checks if the provided message follows the parametrized format.
         *
         * @param text Message.
         * @return An integer value.
         */
        private fun checkParametrizedMessage(text: String): Int {
            var i = 0
            var c: Char
            for (element in text) {
                c = element
                if (c == '\'') {
                    i += 1
                } else {
                    if (i != 0) {
                        if (i != 2) {
                            return 1
                        } else {
                            i = 0
                        }
                    }
                }
            }
            return 0
        }
    }
}