Skip to content

Instantly share code, notes, and snippets.

@gubser
gubser / MultiLineText.tsx
Created Oct 28, 2020
Given maximum pixel width, create SVG text elements that wrap text around syllables (greedy)
View MultiLineText.tsx
import React from 'react';
export interface MultiLineTextProps extends React.SVGProps<SVGTextElement> {
children: string[];
}
export function MultiLineText({ children, ...rest }: MultiLineTextProps) {
if(children.length === 0) {
return <></>;
} else {
@gubser
gubser / computeTextLength.ts
Last active Oct 23, 2020
Compute width of SVG text using DOM
View computeTextLength.ts
export function computeTextLength(content: string, fontSize?: string) {
const svgns = "http://www.w3.org/2000/svg";
// create elements
const svg: SVGSVGElement = document.createElementNS(svgns, 'svg');
const text: SVGTextElement = document.createElementNS(svgns, 'text');
text.textContent = content;
if(fontSize) {
text.style.fontSize = fontSize;
}
// hook them into dom
@gubser
gubser / WrappedText.tsx
Created Oct 21, 2020
Create auto-wrapping text in SVG
View WrappedText.tsx
import React from 'react';
import { isArray } from 'lodash';
export function wrapText(s: string|undefined, maxLength: number): string[] {
if(s === undefined) {
return [];
} else if(s.length < maxLength) {
return [s];
} else {
const lastSpaceIndex = s.lastIndexOf(' ', maxLength);
@gubser
gubser / SuaveSerilogAdapter.fs
Last active May 9, 2020
Suave 2.5 to Serilog 2.9 adapter. Note: currently only handles Message, no Gauge
View SuaveSerilogAdapter.fs
type SuaveSerilogAdapter(logger: Serilog.ILogger) =
let parser = Serilog.Parsing.MessageTemplateParser()
let write (level: Suave.Logging.LogLevel) (messageFactory: Suave.Logging.LogLevel -> Suave.Logging.Message) =
let message = messageFactory level
let level =
match level with
| Suave.Logging.LogLevel.Debug -> Serilog.Events.LogEventLevel.Debug
| Suave.Logging.LogLevel.Verbose -> Serilog.Events.LogEventLevel.Verbose
| Suave.Logging.LogLevel.Info -> Serilog.Events.LogEventLevel.Information
@gubser
gubser / Log.fs
Created May 5, 2020
Simple console logging in F# (incomplete)
View Log.fs
module Turns.Log
open System
open System.Threading.Tasks
open NodaTime
module Logging =
type LogLevel =
| Debug
| Info
@gubser
gubser / analyzer.py
Last active Jun 22, 2019
Walk the abstract syntax tree to find the data dependencies of a python script
View analyzer.py
"""
Given the python code:
out.p = inp.x + inp.y
out.q = inp.y + 1
It finds these dependencies:
inputs are x, y
outputs are p, q
"""
@gubser
gubser / AsyncBoundedCacheTests.fs
Created Jan 30, 2019
Unit tests for bounded caching. Needs more.
View AsyncBoundedCacheTests.fs
module AsyncBoundedCacheTests
open System
open Xunit
[<Fact>]
let ``insert items`` () = async {
let f = fun x -> async {
do! Async.Sleep(1)
return x
@gubser
gubser / space-delimited-int-array-column.py
Created Jan 30, 2019
This python snippet parses the `vector` column as a list of integers delimited by space and adds it as a new column
View space-delimited-int-array-column.py
"""
| frame | which | center-x | center-y | vector | vector_array |
| 44 | 0 | 55.5 | 29.3 | "49 44 31 22 26 22 44 ..." | [49, 44, 31, 22, 26, 22, 44, ...] |
"""
import pandas as pd
df = pd.read_csv(r"C:\Users\egubser\Downloads\blobs.csv", sep=';')
df['vector_array'] = df.vector.apply(lambda v: [int(k) for k in v.split(' ')])
@gubser
gubser / AsyncBoundedCache.fs
Last active Jan 31, 2019
A bounded cache for async operations in F#
View AsyncBoundedCache.fs
module AsyncBoundedCache
open System
open System.Collections.Concurrent
open System.Threading
open System.Threading.Tasks
let startTime = DateTime.UtcNow.Ticks / 10000000L
let now () = int ((DateTime.UtcNow.Ticks / 10000000L) - startTime)
View text-symbol-halo.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no">
<title>TextSymbol with Halo - 4.9</title>
<style>
html,
body,
#viewDiv {
You can’t perform that action at this time.