rewrite stripmd, fix some typos

doesn't work any better, but more efficient and doesn't require
eyebleach after viewing.
pull/75/head
Harvey Tindall 4 years ago
parent 9875458b01
commit a0a25d64f1
No known key found for this signature in database
GPG Key ID: BBC65952848FB1A2

@ -16,12 +16,12 @@ I chose to rewrite the python [jellyfin-accounts](https://github.com/hrfee/jelly
* Granular control over invites: Validity period as well as number of uses can be specified. * Granular control over invites: Validity period as well as number of uses can be specified.
* Account profiles: Assign settings profiles to invites so new users have your predefined permissions, homescreen layout, etc. applied to their account on creation. * Account profiles: Assign settings profiles to invites so new users have your predefined permissions, homescreen layout, etc. applied to their account on creation.
* Password validation: Ensure users choose a strong password. * Password validation: Ensure users choose a strong password.
* ⌛ User expiry: Specify a validity period, and new user's accounts will be disabled/deleted after it. The period can be manually extended too. * ⌛ User expiry: Specify a validity period, and new users accounts will be disabled/deleted after it. The period can be manually extended too.
* 🔗 Ombi Integration: Automatically creates Ombi accounts for new users using their email address and login details, and your own defined set of permissions. * 🔗 Ombi Integration: Automatically creates Ombi accounts for new users using their email address and login details, and your own defined set of permissions.
* Account management: Apply settings to your users individually or en masse, and delete users, optionally sending them an email notification with a reason. * Account management: Apply settings to your users individually or en masse, and delete users, optionally sending them an email notification with a reason.
* 📨 Email storage: Add your existing users email addresses through the UI, and jfa-go will ask new users for them on account creation. * 📨 Email storage: Add your existing users email addresses through the UI, and jfa-go will ask new users for them on account creation.
* Email addresses can optionally be used instead of usernames * Email addresses can optionally be used instead of usernames
* 🔑 Password resets: When user's forget their passwords and request a change in Jellyfin, jfa-go reads the PIN from the created file and sends it straight to the user via email. * 🔑 Password resets: When users forget their passwords and request a change in Jellyfin, jfa-go reads the PIN from the created file and sends it straight to the user via email.
* Notifications: Get notified when someone creates an account, or an invite expires. * Notifications: Get notified when someone creates an account, or an invite expires.
* 📣 Announcements: Bulk email your users with announcements about your server. * 📣 Announcements: Bulk email your users with announcements about your server.
* Authentication via Jellyfin: Instead of using separate credentials for jfa-go and Jellyfin, jfa-go can use it as the authentication provider. * Authentication via Jellyfin: Instead of using separate credentials for jfa-go and Jellyfin, jfa-go can use it as the authentication provider.

@ -6,50 +6,41 @@ import (
stripmd "github.com/writeas/go-strip-markdown" stripmd "github.com/writeas/go-strip-markdown"
) )
func stripMarkdown(md string) string { // StripAltText removes Markdown alt text from links and images and replaces them with just the URL.
// Search for markdown-formatted urls, and replace them with just the url, then use a library to strip any traces of markdown. You'll need some eyebleach after this. // Currently uses the deepest alt text when links/images are nested.
foundOpenSquare := false func StripAltText(md string) string {
openSquare := -1 altTextStart := -1 // Start of alt text (between '[' & ']')
openBracket := -1 URLStart := -1 // Start of url (between '(' & ')')
closeBracket := -1 URLEnd := -1
openSquares := []int{} previousURLEnd := -2
closeBrackets := []int{} out := ""
links := []string{} for i := range md {
foundOpen := false if altTextStart != -1 && URLStart != -1 && md[i] == ')' {
for i, c := range md { URLEnd = i - 1
if !foundOpenSquare && !foundOpen && c != '[' && c != ']' { out += md[previousURLEnd+2:altTextStart-1] + md[URLStart:URLEnd+1]
previousURLEnd = URLEnd
altTextStart, URLStart, URLEnd = -1, -1, -1
continue continue
} }
if c == '[' && md[i-1] != '!' { if md[i] == '[' && altTextStart == -1 {
foundOpenSquare = true altTextStart = i + 1
openSquare = i if i > 0 && md[i-1] == '!' {
} else if c == ']' { altTextStart--
if md[i+1] == '(' {
foundOpenSquare = false
foundOpen = true
openBracket = i + 1
continue
} }
} else if c == ')' {
closeBracket = i
openSquares = append(openSquares, openSquare)
closeBrackets = append(closeBrackets, closeBracket)
links = append(links, md[openBracket+1:closeBracket])
openBracket = -1
closeBracket = -1
openSquare = -1
foundOpenSquare = false
foundOpen = false
} }
} if i > 0 && md[i-1] == ']' && md[i] == '(' && URLStart == -1 {
fullLinks := make([]string, len(openSquares)) URLStart = i + 1
for i := range openSquares {
if openSquares[i] != -1 && closeBrackets[i] != -1 {
fullLinks[i] = md[openSquares[i] : closeBrackets[i]+1]
} }
} }
for i, _ := range openSquares { if previousURLEnd+1 != len(md)-1 {
md = strings.Replace(md, fullLinks[i], links[i], 1) out += md[previousURLEnd+2:]
}
if out == "" {
return md
} }
return strings.TrimPrefix(strings.TrimSuffix(stripmd.Strip(md), "</p>"), "<p>") return out
}
func stripMarkdown(md string) string {
return strings.TrimPrefix(strings.TrimSuffix(stripmd.Strip(StripAltText(md)), "</p>"), "<p>")
} }

@ -1,49 +1,40 @@
const removeMd = require("remove-markdown"); const removeMd = require("remove-markdown");
export function stripMarkdown(md: string): string { function stripAltText(md: string): string {
let foundOpenSquare = false; let altStart = -1; // Start of alt text (between '[' & ']')
let openSquare = -1; let urlStart = -1; // Start of url (between '(' & ')')
let openBracket = -1; let urlEnd = -1;
let closeBracket = -1; let prevURLEnd = -2;
let openSquares: number[] = []; let out = "";
let closeBrackets: number[] = [];
let links: string[] = [];
let foundOpen = false;
for (let i = 0; i < md.length; i++) { for (let i = 0; i < md.length; i++) {
const c = md.charAt(i); if (altStart != -1 && urlStart != -1 && md.charAt(i) == ')') {
if (!foundOpenSquare && !foundOpen && c != '[' && c != ']') { urlEnd = i - 1;
out += md.substring(prevURLEnd+2, altStart-1) + md.substring(urlStart, urlEnd+1);
prevURLEnd = urlEnd;
altStart = -1;
urlStart = -1;
urlEnd = -1;
continue; continue;
} }
if (c == '[' && md.charAt(i-1) != '!') { if (md.charAt(i) == '[' && altStart == -1) {
foundOpenSquare = true; altStart = i + 1
openSquare = i; if (i > 0 && md.charAt(i-1) == '!') {
} else if (c == ']') { altStart--
if (md.charAt(i+1) == '(') {
foundOpenSquare = false;
foundOpen = true;
openBracket = i + 1;
continue;
} }
} else if (c == ')') {
closeBracket = i;
openSquares.push(openSquare);
closeBrackets.push(closeBracket);
links.push(md.slice(openBracket+1, closeBracket))
openBracket = -1;
closeBracket = -1;
openSquare = -1;
foundOpenSquare = false;
foundOpen = false;
} }
} if (i > 0 && md.charAt(i-1) == ']' && md.charAt(i) == '(' && urlStart == -1) {
let fullLinks: string[] = new Array(openSquares.length); urlStart = i + 1
for (let i = 0; i < openSquares.length; i++) {
if (openSquares[i] != -1 && closeBrackets[i] != -1) {
fullLinks[i] = md.slice(openSquares[i], closeBrackets[i]+1)
} }
} }
for (let i = 0; i < openSquares.length; i++) { if (prevURLEnd + 1 != md.length - 1) {
md = md.replace(fullLinks[i], links[i]); out += md.substring(prevURLEnd+2)
} }
return removeMd(md); if (out == "") {
return md
}
return out
}
export function stripMarkdown(md: string): string {
return removeMd(stripAltText(md));
} }

Loading…
Cancel
Save