Initial bonus 2 implementation

git-svn-id: svn+ssh://atelier.inf.usi.ch/home/bevilj/group-1@153 a672b425-5310-4d7a-af5c-997e18724b81
This commit is contained in:
bevilj 2018-11-12 18:16:45 +00:00
parent 41c838f196
commit 2b3e9fa689
12 changed files with 508 additions and 0 deletions

13
bonus2/.svnignore Normal file
View File

@ -0,0 +1,13 @@
*.iml
.idea
.gradle
/local.properties
/.idea/workspace.xml
/.idea/libraries
.DS_Store
/build
/captures
/lib
*.jar
/dist

13
bonus2/bonus2.iml Normal file
View File

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<module external.linked.project.id="bonus2" external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$" external.system.id="GRADLE" external.system.module.group="" external.system.module.version="unspecified" type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<excludeFolder url="file://$MODULE_DIR$/.gradle" />
<excludeFolder url="file://$MODULE_DIR$/build" />
<excludeFolder url="file://$MODULE_DIR$/out" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

55
bonus2/build.gradle Normal file
View File

@ -0,0 +1,55 @@
/*
* Copyright (c) 2018. Bevilacqua Joey
*/
buildscript {
ext.kotlin_version = '1.3.0'
repositories {
mavenCentral()
jcenter()
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath 'com.github.jengelman.gradle.plugins:shadow:2.0.0'
}
}
apply plugin: 'kotlin'
apply plugin: 'com.github.johnrengelman.shadow'
apply plugin: 'application'
defaultTasks 'run'
repositories {
mavenCentral()
}
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
implementation 'org.jsoup:jsoup:1.11.3'
}
mainClassName = 'ch.usi.inf.atelier.group1.Main'
sourceSets {
main.java.srcDirs += 'src'
}
task sourcesJar(type: Jar) {
classifier = 'sources'
from 'src'
}
jar {
manifest {
attributes 'Main-Class': 'ch.usi.inf.atelier.group1.MainKt'
}
}
shadowJar {
baseName = 'bonus2'
classifier = null
version = null
}

59
bonus2/res/test.html Normal file
View File

@ -0,0 +1,59 @@
---
layout: page
category-title: Basic commands
category-page: basic
tags: directory change navigate
author: Alessandro Marinelli
title: cd
previous-page: pages/cmd/basic/open.html
next-page: pages/cmd/basic/ls.html
---
<!--
Copyright (c) 2018. Bevilacqua Joey
-->
<p>
The <code>cd</code> command is used to change the working directory<br>
The name stands for <i>Change Directory</i>.<br>
The default cd command syntax is:
<pre>
cd [flags] [path]
</pre>
Where [flags] are the cd flags, read below for more info,and [path] is the
path (absolute or relative), of the directory which we want to make as working directory.<br><br>
<h3>Change the working directory</h3>
Let's see how to use the command <code>cd</code> in order to change the working directory
<pre>
pwd
~
cd Desktop/multimedia
pwd
~/Desktop/multimedia
</pre>
As you can see, we changed the working directory from ~ (which stands for HOME),
to "multimedia". Now our Shell will work on the directory "multimedia"
until a new cd will occour.<br>
<b>Notice:</b> If you want to move to a directory which is not contained in the
current working directory, you <u>MUST</u> use the <a href="foo.html">absolute path</a>.
<h1>Header 1</h1>
<h2>Header 2</h2>
<h4>Header 4</h4>
<ul>
<li>A</li>
<li>B: Hello there</li>
<li>C</li>
<li>D</li>
</ul>
</p>

View File

@ -0,0 +1,17 @@
/*
* Copyright (c) 2018. Bevilacqua Joey
*/
package ch.usi.inf.atelier.group1
import ch.usi.inf.atelier.group1.html.HtmlParser
object Main {
@JvmStatic
fun main(args: Array<String>) {
for (arg in args) {
println(HtmlParser(arg).parse())
}
}
}

View File

@ -0,0 +1,83 @@
/*
* Copyright (c) 2018. Bevilacqua Joey
*/
package ch.usi.inf.atelier.group1.html
import ch.usi.inf.atelier.group1.tex.TexDocument
import ch.usi.inf.atelier.group1.util.Log
import ch.usi.inf.atelier.group1.util.extensions.writeJekyllHeader
import org.jsoup.Jsoup
import org.jsoup.nodes.Element
import java.io.File
class HtmlParser(path: String) {
private val file = JekyllHtmlFile(File(path))
private val document = Jsoup.parse(file.content)
private val texDocument = TexDocument()
fun parse(): String {
if (!file.isValid()) {
return ""
}
texDocument.start()
texDocument.writeJekyllHeader(file)
texDocument.beginDocument()
document.body().children().forEach { element -> parseToTex(element) }
texDocument.endDocument()
return texDocument.toString()
}
private fun parseToTex(element: Element) {
val text = element.ownText()
// TODO: fix span elements inside the paragraph senteces (tag-less items)
texDocument.apply {
when (element.tagName()) {
TAG_BOLD -> addBold(text)
TAG_BR -> addBr()
TAG_CODE -> addCode(text)
TAG_H1 -> addSection(text)
TAG_H2 -> addSubSection(text)
TAG_H3, TAG_H4 -> addSubSubSection(text)
TAG_ITALICS -> addItalics(text)
TAG_LINK -> addLink(text, element.attr("href"))
TAG_P -> addParagraph(text)
TAG_PRE -> addPre(text)
TAG_UL -> element.parseList()
"", null -> addText(element.text())
}
}
}
private fun Element.parseList() {
texDocument.apply {
beginList()
children().filter { TAG_LI == it.tagName() }
.forEach { e -> addListItem(e.text()) }
endList()
}
}
companion object {
private const val TAG_BOLD = "b"
private const val TAG_BR = "br"
private const val TAG_CODE = "code"
private const val TAG_H1 = "h1"
private const val TAG_H2 = "h2"
private const val TAG_H3 = "h3"
private const val TAG_H4 = "h4"
private const val TAG_ITALICS = "i"
private const val TAG_LI = "li"
private const val TAG_LINK = "a"
private const val TAG_P = "p"
private const val TAG_PRE = "pre"
private const val TAG_UL = "ul"
}
}

View File

@ -0,0 +1,55 @@
/*
* Copyright (c) 2018. Bevilacqua Joey
*/
package ch.usi.inf.atelier.group1.html
import ch.usi.inf.atelier.group1.util.extensions.getContent
import java.io.BufferedReader
import java.io.File
import java.io.StringReader
class JekyllHtmlFile(file: File) {
val header = HashMap<String, String>()
val content: String
init {
val fileContent = file.getContent()
val contentBuilder = StringBuilder()
var isIteratingInHeader = false
var line: String? = ""
val reader = BufferedReader(StringReader(fileContent))
while (line != null) {
if (!isIteratingInHeader && HEADER_START == line) {
isIteratingInHeader = true
} else if (isIteratingInHeader) {
isIteratingInHeader = HEADER_END != line
if (isIteratingInHeader) {
val values = line.split(":")
if (values.size == 2) {
header[values[0]] = values[1].trim()
}
}
} else {
contentBuilder.append(line).append('\n')
}
line = reader.readLine()
}
content = contentBuilder.toString()
}
fun isValid() = header.isNotEmpty() && content.isNotBlank()
override fun toString() =
"Header:\n$header\nContent:\n$content"
companion object {
private const val HEADER_START = "---"
private const val HEADER_END = "---"
}
}

View File

@ -0,0 +1,128 @@
/*
* Copyright (c) 2018. Bevilacqua Joey
*/
package ch.usi.inf.atelier.group1.tex
class TexDocument {
private val document = StringBuilder()
fun start() {
document.clear()
insert(HEADER, false, true)
}
fun beginDocument() {
insert("\\begin{document}", false, true)
insert("\\maketitle", false, true)
insert("\\tableofcontents", false, true)
insert("\\newpage", false, true)
}
fun endDocument() {
insert("\\end{document}", false, true)
}
fun addParagraph(content: String) {
if (content.isNotBlank()) {
insert(content, true, true)
}
}
fun addText(content: String) {
if (content.isNotBlank()) {
insert(content, false, true)
}
}
fun addSection(content: String) {
insert(SECTION.format(content, content.trim().toLowerCase()), false, true)
}
fun addSubSection(content: String) {
insert(SUB_SECTION.format(content), false, true)
}
fun addSubSubSection(content: String) {
insert(SUB_SUB_SECTION.format(content), false, true)
}
fun addBold(content: String) {
insert(BOLD.format(content), false, false)
}
fun addItalics(content: String) {
insert(ITALICS.format(content), false, false)
}
fun addCode(content: String) {
insert(CODE.format(content), false, false)
}
fun addPre(content: String) {
insert(PRE.format(content), false, true)
}
fun addLink(content: String, url: String) {
insert(LINK.format(content, url), false, true)
}
fun beginList() {
insert("\\begin{itemize}", false, true)
}
fun endList() {
insert("\\end{itemize}", false, true)
}
fun addListItem(content: String) {
insert(LIST_ITEM.format(content), false, true)
}
fun addBr() {
insert("", false, false)
}
fun setAuthor(content: String) {
insert(AUTHOR.format(content), false, true)
}
fun setTitle(content: String) {
insert(TITLE.format(content), false, true)
}
private fun insert(string: String, newLine: Boolean, endLine: Boolean) {
document.apply {
append(string)
if(newLine) {
append("\\\\")
}
if (endLine) {
append("\n")
}
}
}
override fun toString() = document.toString()
companion object {
private const val AUTHOR = "\\author{%1\$s}\n"
private const val BOLD = "\\textbf{%1\$s}"
private const val CODE = "\\texttt{%1\$s}"
private const val ITALICS = "\\emph{%1\$s}"
private const val LINK = "\\emph{%1\$s} \\footnote{\\url{%2\$s}}"
private const val LIST_ITEM = "\\item %1\$s"
private const val PRE = "\n\\begin{verbatim}\n%1\$s\n\\end{verbatim}"
private const val SECTION = "\\section{%1\$s}\\label{%2\$s}"
private const val SUB_SECTION = "\\subsection{%1\$s}"
private const val SUB_SUB_SECTION = "\\subsubsection{%1\$s}"
private const val TITLE = "\\title{%1\$s}\n"
private const val HEADER =
"\\documentclass[hidelinks,12pt,a4paper,numbers=enddot]{scrartcl}\n\n" +
"\\usepackage[margin=2cm]{geometry}\n" +
"\\usepackage{hyperref}\n"
}
}

View File

@ -0,0 +1,21 @@
/*
* Copyright (c) 2018. Bevilacqua Joey
*/
package ch.usi.inf.atelier.group1.util
import java.lang.Exception
object Log {
fun e(message: String = "", exception: Exception) {
e("$message: ${exception.message ?: "Unknown error"}")
}
fun e(message: String) {
System.err.println(message)
}
fun i(obj: Any) {
println(obj.toString())
}
}

View File

@ -0,0 +1,28 @@
/*
* Copyright (c) 2018. Bevilacqua Joey
*/
package ch.usi.inf.atelier.group1.util.extensions
import ch.usi.inf.atelier.group1.util.Log
import java.io.BufferedReader
import java.io.File
import java.io.FileReader
import java.io.IOException
fun File.getContent(): String {
val content = StringBuilder()
try {
val reader = BufferedReader(FileReader(this))
var line: String? = ""
while (line != null) {
content.append(line)
.append('\n')
line = reader.readLine()
}
} catch (e: IOException) {
Log.e(exception = e)
}
return content.toString()
}

View File

@ -0,0 +1,21 @@
/*
* Copyright (c) 2018. Bevilacqua Joey
*/
package ch.usi.inf.atelier.group1.util.extensions
import ch.usi.inf.atelier.group1.util.Log
import java.io.File
import java.io.IOException
fun String.toFile(): File? {
try {
File(this)
} catch (e: IOException) {
Log.e("Failed to open $this as File", e)
throw e
}
return null
}
fun String.getClosingTag() = "</${substring(1, length)}"

View File

@ -0,0 +1,15 @@
/*
* Copyright (c) 2018. Bevilacqua Joey
*/
package ch.usi.inf.atelier.group1.util.extensions
import ch.usi.inf.atelier.group1.html.JekyllHtmlFile
import ch.usi.inf.atelier.group1.tex.TexDocument
fun TexDocument.writeJekyllHeader(file: JekyllHtmlFile) {
val title = file.header["title"] ?: "Unknown title"
val author = file.header["author"] ?: "Unknown author"
setTitle(title)
setAuthor(author)
}