Last active
September 26, 2018 18:44
-
-
Save Bombe/6838a8992ac35b7522b3a714648f8c46 to your computer and use it in GitHub Desktop.
Creates an SVG-File with a calender for a whole year
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.awt.* | |
import java.awt.SystemColor.* | |
import java.io.* | |
import java.nio.charset.* | |
import java.nio.file.* | |
import java.time.* | |
import java.time.DayOfWeek.* | |
import java.time.Month.* | |
import java.time.temporal.* | |
val year = 2021 | |
val marginLeft = 4 | |
val marginRight = 6 | |
val marginTop = 4 | |
val marginBottom = 4 | |
val availableWidth = 297.0 - marginLeft - marginRight | |
val availableHeight = 210.0 - marginTop - marginBottom | |
val monthFields = generateSequence(LocalDate.of(year, 1, 1)!!) { date -> | |
date.plusDays(1).takeIf { it.year == year } | |
} | |
.groupBy { it.get(ChronoField.MONTH_OF_YEAR) } | |
.map { (month, days) -> | |
val dayOfWeekOnFirst = days.first().dayOfWeek!! | |
month to (1.rangeTo(dayOfWeekOnFirst.value).map { index -> | |
Cell(right = CellText("%02d".format(month), "rgb(0%,0%,100%")) | |
.takeIf { index == dayOfWeekOnFirst.value } | |
} + | |
days.map { day -> | |
val week = day.get(WeekFields.ISO.weekOfWeekBasedYear()) | |
val dayOfWeek = day.dayOfWeek!! | |
val weekYear = day.get(WeekFields.ISO.weekBasedYear()) | |
val leftCellText = when { | |
(day.dayOfMonth == 1) && (month == 1) -> CellText("%02d".format(week), "rgb(60%,60%,60%)") | |
dayOfWeek == WeekFields.ISO.firstDayOfWeek -> CellText("%02d".format(week), "rgb(60%,60%,60%)") | |
(weekYear != year) && ((day.dayOfMonth == 2) && (day.month == JANUARY)) -> CellText("%02d".format(weekYear % 100), "rgb(40%,40%,40%)") | |
(weekYear != year) && (dayOfWeek == WeekFields.ISO.firstDayOfWeek.plus(1)) -> CellText("%02d".format(weekYear % 100), "rgb(40%,40%,40%)") | |
else -> null | |
} | |
val rightCellText = CellText("%02d".format(day.dayOfMonth), when (dayOfWeek) { | |
SATURDAY -> "rgb(85%,0%,0%)" | |
SUNDAY -> "rgb(100%,0%,0%)" | |
else -> null | |
}) | |
Cell(leftCellText, rightCellText) | |
}) | |
} | |
val maxFields = monthFields.maxBy { it.second.size }!!.second.size | |
val svg = svg { svg -> | |
monthFields | |
.forEach { (month, days) -> | |
days.forEachIndexed { index, field -> | |
field?.run { | |
left?.run { | |
svg.text(marginLeft + availableWidth / 12 * (month - 1), marginTop + availableHeight / (maxFields + 1) * (index + 1), text, color) | |
} | |
svg.text(marginLeft + availableWidth / 12 * (month - 1) + 4, marginTop + availableHeight / (maxFields + 1) * (index + 1), right.text, right.color) | |
} | |
} | |
} | |
} | |
File("calender-$year.svg").writeText(svg.toString(), Charsets.UTF_8) | |
data class Cell(val left: CellText? = null, val right: CellText) | |
data class CellText(val text: String, val color: String? = null) | |
fun svg(body: (Svg) -> Unit) = | |
Svg().apply { | |
body(this) | |
} | |
class Svg { | |
private val texts: MutableList<Text> = mutableListOf() | |
fun text(x: Double, y: Double, text: String, color: String? = null) { | |
texts += Text(x, y, text, color) | |
} | |
override fun toString(): String { | |
return "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + | |
"<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" version=\"1.1\" baseProfile=\"full\" width=\"297mm\" height=\"210mm\" viewBox=\"0 0 297 210\">" + | |
texts.joinToString(separator = "", transform = Any::toString) + | |
"</svg>" | |
} | |
} | |
class Text(private val x: Double, private val y: Double, private val text: String, private val color: String? = null) { | |
private val font = "MonoSpatial" | |
override fun toString() = "<text x=\"$x\" y=\"$y\" font-family=\"$font\" font-size=\"3.75\"${color?.let { " fill=\"$it\"" } | |
?: ""}>$text</text>" | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment