@@ -110,6 +110,35 @@ function getRequestedTheme(array $params): array
110
110
return $ theme ;
111
111
}
112
112
113
+ /**
114
+ * Split lines of text using <tspan> elements if it contains a newline or exceeds a maximum number of characters
115
+ *
116
+ * @param string $text Text to split
117
+ * @param int $maxChars Maximum number of characters per line
118
+ * @param int $line1Offset Offset for the first line
119
+ *
120
+ * @return string Original text if one line, or split text with <tspan> elements
121
+ */
122
+ function splitLines (string $ text , int $ maxChars , int $ line1Offset ): string
123
+ {
124
+ // if too many characters, insert \n before a " " or "-" if possible
125
+ if (mb_strlen ($ text ) > $ maxChars && strpos ($ text , "\n" ) === false ) {
126
+ // prefer splitting at " - " if possible
127
+ if (strpos ($ text , " - " ) !== false ) {
128
+ $ text = str_replace (" - " , "\n- " , $ text );
129
+ }
130
+ // otherwise, use word wrap to split at " "
131
+ else {
132
+ $ text = wordwrap ($ text , $ maxChars , "\n" , true );
133
+ }
134
+ }
135
+ return preg_replace (
136
+ "/^(.*) \n(.*)$/ " ,
137
+ "<tspan x='81.5' dy=' {$ line1Offset }'>$1</tspan><tspan x='81.5' dy='16'>$2</tspan> " ,
138
+ $ text
139
+ );
140
+ }
141
+
113
142
/**
114
143
* Generate SVG output for a stats array
115
144
*
@@ -171,6 +200,16 @@ function generateCard(array $stats, array $params = null): string
171
200
$ longestStreakRange .= " - " . $ longestStreakEnd ;
172
201
}
173
202
203
+ // if the translations contain a newline, split the text into two tspan elements
204
+ $ totalContributionsText = splitLines ($ localeTranslations ["Total Contributions " ], 24 , -9 );
205
+ $ currentStreakText = splitLines ($ localeTranslations ["Current Streak " ], 22 , -9 );
206
+ $ longestStreakText = splitLines ($ localeTranslations ["Longest Streak " ], 24 , -9 );
207
+
208
+ // if the ranges contain over 28 characters, split the text into two tspan elements
209
+ $ totalContributionsRange = splitLines ($ totalContributionsRange , 28 , 0 );
210
+ $ currentStreakRange = splitLines ($ currentStreakRange , 28 , 0 );
211
+ $ longestStreakRange = splitLines ($ longestStreakRange , 28 , 0 );
212
+
174
213
return "<svg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'
175
214
style='isolation:isolate' viewBox='0 0 495 195' width='495px' height='195px' direction=' {$ direction }'>
176
215
<style>
@@ -204,23 +243,20 @@ function generateCard(array $stats, array $params = null): string
204
243
<g style='isolation:isolate'>
205
244
<!-- Total Contributions Big Number -->
206
245
<g transform='translate(1,48)'>
207
- <rect width='163' height='50' stroke='none' fill='none'></rect>
208
246
<text x='81.5' y='32' stroke-width='0' text-anchor='middle' style='font-family:Segoe UI, Ubuntu, sans-serif;font-weight:700;font-size:28px;font-style:normal;fill: {$ theme ["sideNums " ]};stroke:none; opacity: 0; animation: fadein 0.5s linear forwards 0.6s;'>
209
247
{$ totalContributions }
210
248
</text>
211
249
</g>
212
250
213
251
<!-- Total Contributions Label -->
214
252
<g transform='translate(1,84)'>
215
- <rect width='163' height='50' stroke='none' fill='none'></rect>
216
253
<text x='81.5' y='32' stroke-width='0' text-anchor='middle' style='font-family:Segoe UI, Ubuntu, sans-serif;font-weight:400;font-size:14px;font-style:normal;fill: {$ theme ["sideLabels " ]};stroke:none; opacity: 0; animation: fadein 0.5s linear forwards 0.7s;'>
217
- {$ localeTranslations [ " Total Contributions " ] }
254
+ {$ totalContributionsText }
218
255
</text>
219
256
</g>
220
257
221
258
<!-- total contributions range -->
222
259
<g transform='translate(1,114)'>
223
- <rect width='163' height='50' stroke='none' fill='none'></rect>
224
260
<text x='81.5' y='32' stroke-width='0' text-anchor='middle' style='font-family:Segoe UI, Ubuntu, sans-serif;font-weight:400;font-size:12px;font-style:normal;fill: {$ theme ["dates " ]};stroke:none; opacity: 0; animation: fadein 0.5s linear forwards 0.8s;'>
225
261
{$ totalContributionsRange }
226
262
</text>
@@ -229,23 +265,20 @@ function generateCard(array $stats, array $params = null): string
229
265
<g style='isolation:isolate'>
230
266
<!-- Current Streak Big Number -->
231
267
<g transform='translate(166,48)'>
232
- <rect width='163' height='50' stroke='none' fill='none'></rect>
233
268
<text x='81.5' y='32' stroke-width='0' text-anchor='middle' style='font-family:Segoe UI, Ubuntu, sans-serif;font-weight:700;font-size:28px;font-style:normal;fill: {$ theme ["currStreakNum " ]};stroke:none;animation: currstreak 0.6s linear forwards;'>
234
269
{$ currentStreak }
235
270
</text>
236
271
</g>
237
272
238
273
<!-- Current Streak Label -->
239
274
<g transform='translate(166,108)'>
240
- <rect width='163' height='50' stroke='none' fill='none'></rect>
241
275
<text x='81.5' y='32' stroke-width='0' text-anchor='middle' style='font-family:Segoe UI, Ubuntu, sans-serif;font-weight:700;font-size:14px;font-style:normal;fill: {$ theme ["currStreakLabel " ]};stroke:none;opacity: 0; animation: fadein 0.5s linear forwards 0.9s;'>
242
- {$ localeTranslations [ " Current Streak " ] }
276
+ {$ currentStreakText }
243
277
</text>
244
278
</g>
245
279
246
280
<!-- Current Streak Range -->
247
281
<g transform='translate(166,145)'>
248
- <rect width='163' height='26' stroke='none' fill='none'></rect>
249
282
<text x='81.5' y='21' stroke-width='0' text-anchor='middle' style='font-family:Segoe UI, Ubuntu, sans-serif;font-weight:400;font-size:12px;font-style:normal;fill: {$ theme ["dates " ]};stroke:none;opacity: 0; animation: fadein 0.5s linear forwards 0.9s;'>
250
283
{$ currentStreakRange }
251
284
</text>
@@ -265,23 +298,20 @@ function generateCard(array $stats, array $params = null): string
265
298
<g style='isolation:isolate'>
266
299
<!-- Longest Streak Big Number -->
267
300
<g transform='translate(331,48)'>
268
- <rect width='163' height='50' stroke='none' fill='none'></rect>
269
301
<text x='81.5' y='32' stroke-width='0' text-anchor='middle' style='font-family:Segoe UI, Ubuntu, sans-serif;font-weight:700;font-size:28px;font-style:normal;fill: {$ theme ["sideNums " ]};stroke:none; opacity: 0; animation: fadein 0.5s linear forwards 1.2s;'>
270
302
{$ longestStreak }
271
303
</text>
272
304
</g>
273
305
274
306
<!-- Longest Streak Label -->
275
307
<g transform='translate(331,84)'>
276
- <rect width='163' height='50' stroke='none' fill='none'></rect>
277
308
<text x='81.5' y='32' stroke-width='0' text-anchor='middle' style='font-family:Segoe UI, Ubuntu, sans-serif;font-weight:400;font-size:14px;font-style:normal;fill: {$ theme ["sideLabels " ]};stroke:none;opacity: 0; animation: fadein 0.5s linear forwards 1.3s;'>
278
- {$ localeTranslations [ " Longest Streak " ] }
309
+ {$ longestStreakText }
279
310
</text>
280
311
</g>
281
312
282
313
<!-- Longest Streak Range -->
283
314
<g transform='translate(331,114)'>
284
- <rect width='163' height='50' stroke='none' fill='none'></rect>
285
315
<text x='81.5' y='32' stroke-width='0' text-anchor='middle' style='font-family:Segoe UI, Ubuntu, sans-serif;font-weight:400;font-size:12px;font-style:normal;fill: {$ theme ["dates " ]};stroke:none;opacity: 0; animation: fadein 0.5s linear forwards 1.4s;'>
286
316
{$ longestStreakRange }
287
317
</text>
@@ -328,7 +358,6 @@ function generateErrorCard(string $message, array $params = null): string
328
358
<g style='isolation:isolate'>
329
359
<!-- Error Label -->
330
360
<g transform='translate(166,108)'>
331
- <rect width='163' height='50' stroke='none' fill='none'></rect>
332
361
<text x='81.5' y='50' dy='0.25em' stroke-width='0' text-anchor='middle' style='font-family:Segoe UI, Ubuntu, sans-serif;font-weight:400;font-size:14px;font-style:normal;fill: {$ theme ["sideLabels " ]};stroke:none;'>
333
362
{$ message }
334
363
</text>
0 commit comments