Skip to content

Commit

Permalink
Merge pull request #155 from ichsteffen/feature-alphabetical-order
Browse files Browse the repository at this point in the history
Script to create structure for alphabetical order of terms in non-English version
  • Loading branch information
programming-wolf authored Nov 23, 2022
2 parents e08051a + aa607a1 commit d928d60
Show file tree
Hide file tree
Showing 6 changed files with 175 additions and 32 deletions.
4 changes: 4 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -112,15 +112,19 @@ task renderDE(type: RenderCurriculumTask,
doLast {
addSuffixToCurriculum("-de")
}
dependsOn "sortTermsAlphabetically"
}

task renderEN(type: RenderCurriculumTask,
constructorArgs: [curriculumFileName, versionDate, "EN", false]) {
doLast {
addSuffixToCurriculum("-en")
}
dependsOn "sortTermsAlphabetically"
}

apply from: 'scripts/generateTermTables.gradle'
apply from: 'scripts/sortTermsAlphabetically.gradle'


defaultTasks "buildDocs"
31 changes: 4 additions & 27 deletions docs/1-terms/0-structure.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -5,37 +5,14 @@

// tag::DE[]
== Begriffe

include::0-structure-DE.adoc[{include_configuration}]
// end::DE[]

// tag::EN[]
== Terms
// end::EN[]

include::0-structure-EN.adoc[{include_configuration}]

include::A/0-structure.adoc[]
include::B/0-structure.adoc[]
include::C/0-structure.adoc[]
include::D/0-structure.adoc[]
include::E/0-structure.adoc[]
include::F/0-structure.adoc[]
include::G/0-structure.adoc[]
include::H/0-structure.adoc[]
include::I/0-structure.adoc[]
// include::J/0-structure.adoc[]
include::K/0-structure.adoc[]
include::L/0-structure.adoc[]
include::M/0-structure.adoc[]
include::N/0-structure.adoc[]
include::O/0-structure.adoc[]
include::P/0-structure.adoc[]
include::Q/0-structure.adoc[]
include::R/0-structure.adoc[]
include::S/0-structure.adoc[]
include::T/0-structure.adoc[]
include::U/0-structure.adoc[]
include::V/0-structure.adoc[]
include::W/0-structure.adoc[]
// include::X/0-structure.adoc[]
// include::Y/0-structure.adoc[]
// include::Z/0-structure.adoc[]
// end::EN[]

3 changes: 1 addition & 2 deletions docs/1-terms/Q/term-quality-attribute.adoc
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[#term-quality-attribute]

// tag::EN[]

[#term-quality-attribute]
==== Quality Attribute

Software quality is the degree to which a system possesses the desired combination of _attributes_ (see: <<term-software-quality,software quality>>).
Expand Down Expand Up @@ -61,7 +61,6 @@ Examples of non-runtime quality attributes are modifiability, portability, under

// tag::DE[]

[#term-quality-attribute]
==== Qualitätsmerkmal

Die Softwarequalität ist das Maß, in dem ein System die gewünschte
Expand Down
2 changes: 1 addition & 1 deletion docs/1-terms/T/term-togaf.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ link:http://www.opengroup.org/subjectareas/enterprise/togaf[_The Open Group Arch
// end::EN[]

// tag::DE[]
==== link:http://www.opengroup.org/subjectareas/enterprise/togaf[TOGAF]
==== TOGAF

link:http://www.opengroup.org/subjectareas/enterprise/togaf[_The Open Group Architecture Framework_]

Expand Down
3 changes: 1 addition & 2 deletions docs/1-terms/W/term-waterfall-development.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

// tag::EN[]

[#term-waterfall-development]
==== Waterfall Development

Development approach "where you gather all the requirements up front, do all necessary design, down to a detailed level, then hand the specs to the coders, who write the code; then you do testing (possibly with a side trip to IntegrationHell) and deliver the whole thing in one big end-all release. Everything is big including the risk of failure." (quoted from the http://c2.com/cgi/wiki?IterativeDevelopment[C2 wiki])
Expand All @@ -12,7 +11,7 @@ See also <<term-iterative-development,_iterative development_>>.
// end::EN[]

// tag::DE[]
[[term-waterfall-development]]

==== Wasserfall-Entwicklung

Entwicklungsansatz, „bei dem man alle Anforderungen vorab
Expand Down
164 changes: 164 additions & 0 deletions scripts/sortTermsAlphabetically.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
import static groovy.io.FileType.FILES
import java.util.regex.Matcher

class Term {
String term
String captionEN
String captionDE
String includeFragment

Term(String term, String captionEN, String captionDE, String includeFragment) {
this.term = term
this.captionEN = captionEN
this.captionDE = captionDE
this.includeFragment = includeFragment
}
}

/** This task collects all term captions and creates language dependent alphabetically ordered structure file
*
* Overall approach:
* 1. collect all terms to include into structure file
* 1.1. traverse all ascii doc files inside /docs/1-terms/
* 1.2. for each term file:
* 1.2.1 extract term-anchor and language specific caption
* 1.2.2 create Term-Object with language specific captions and ascii doc fragment to include
* 1.2.3 add Term-Object into terms set
* 1.3. add "Letter Captions" as Term-Object into terms set (ascii doc fragment is level-2 caption with Letter)
* 2. create language specific structure file (loop for each language supported)
* 2.1. sort terms set language specific
* 2.2. create structure file "0-structure-<<language-code>> in directory /docs/1-terms
*
* Details about 1.2.1: Extraction of term-anchor and language specific caption
* 1.2.1.1 term-anchor
* Each term file has a term-anchor at the files head, e.g. '[#term-blackbox]'
* So the first match of regex '[#.*?]' contains the term-anchor.
* To be a bit more gentle, any characters before and after the anchor can be conceivable and allowed.
* To make matching non-greed, add ?
* This results in .*?[#.*?].*?
* To make the term as group 1 add brackets, .*?([#.*?]).*?
*
* 1.2.1.2 language specific caption
* Language specific captions are the first level-3 caption within the specific language block
* // tag::EN[]
* ...
* ==== Black Box
* ...
* // end::EN[]
*
* To find this block with one regex, regex evaluation must be multi-line, dot-match-all, case-insensitiv (?msi)
*
* Regex for language specific start tag: 'TAG::'+languageCode+'\\[\\]'
* Regex for caption (line starting '^' with '====' and any character '.*' until the first '?' end of line '$'): (^====.*?$)
* Regex for language specific end tag: 'END::'+languageCode+'\\[\\]'
* Regex for anything but as little as possible until the next part matchs: '.*?'
*
* Combination of this regex into one:
* <start tag> <anything but non greedy> <caption> <anything but non greedy> <end tag>
* results into
* '(?msi)TAG::'+languageCode+'\\[\\].*?(^====.*?$).*?END::'+languageCode+'\\[\\]'
*
* To execute this task, start gradle as follows:
* './gradlew -q sortTermsAlphabetically'
*
*/
task sortTermsAlphabetically(
description: 'collect terms and create an alphabetically ordered structure',
group: 'isaqb-glossary'
) {
doLast {
println "start task sortTermsAlphabetically"
logger.lifecycle("start task sortTermsAlphabetically")
def terms = createTermsContent()

sortTermsEN(terms)
writeTermsStructure(terms, "EN")

sortTermsDE(terms)
writeTermsStructure(terms, "DE")

logger.lifecycle("done task sortTermsAlphabetically")
println "done task sortTermsAlphabetically"
}

ext.createTermsContent = {
def terms = collectTerms()
List alphabet = ('A'..'Z').collect { it }
alphabet.each(
letter -> terms.add(new Term(/==== $letter/, /==== $letter/, /==== $letter/, /=== $letter/))
)
return terms
}

ext.collectTerms = {
def termsFolder = new File(projectDir, '/docs/1-terms')
def terms = []

termsFolder.traverse(type: FILES) { file ->

if (file.name ==~ 'term.*[.](ad|adoc|asciidoc)$') {
logger.debug( "Learning term from file: " + file.getAbsolutePath() )
def content = file.text

def term
def refPath = termsFolder.toPath().relativize( file.toPath() ).toFile()
def includeFragment = "include::${refPath}[{include_configuration}]";
def caption_EN
def caption_DE

if (content =~ ~/.*?(\[#.*?\]).*?/) {
term = Matcher.lastMatcher[0][1]
} else {
term = refPath;
}
def languageCode;
languageCode = 'EN'
if (content =~ ~('(?msi)TAG::'+languageCode+'\\[\\].*?(^====.*?$).*?END::'+languageCode+'\\[\\]') ) {
def caption = Matcher.lastMatcher[0][1];
caption_EN = caption.replaceAll('\\s{2,}', ' ') // shrink multiple spaces into one
} else {
caption_EN = "==== $term (EN)";
}
languageCode = 'DE'
if (content =~ ~('(?msi)TAG::'+languageCode+'\\[\\].*?(^====.*?$).*?END::'+languageCode+'\\[\\]') ) {
def caption = Matcher.lastMatcher[0][1];
caption_DE = caption.replaceAll('\\s{2,}', ' ') // shrink multiple spaces into one
} else {
caption_DE = "==== $term (DE)"
}

logger.debug( "TERM $term EN $caption_EN DE $caption_DE $includeFragment" )
terms.add(new Term(term, caption_EN, caption_DE, includeFragment))
}
}

return terms
}
}

ext.sortTermsEN = { terms ->
terms.sort { a, b ->
a.captionEN.compareToIgnoreCase(b.captionEN)
}
}

ext.sortTermsDE = { terms ->
terms.sort { a, b ->
a.captionDE.compareToIgnoreCase(b.captionDE)
}
}

ext.writeTermsStructure = { terms, languageCode ->
def termsFolder = new File(projectDir, '/docs/1-terms')
def outFile = new File(termsFolder, "/0-structure-${languageCode}.adoc")
logger.debug( "Structure file: " + outFile.getAbsolutePath() )

outFile.createNewFile()

outFile.withWriter('UTF-8') { writer ->
writer.writeLine("// This file is autogenerated by task sortTermAlphabetically - please do not modify manually!\n")
terms.each(
term -> writer.writeLine(term.includeFragment)
)
}
}

0 comments on commit d928d60

Please sign in to comment.