Repository files navigation

RSParser

This framework was developed for NetNewsWire and is made available here for developers who just need the parsing code. It has no depencies that aren’t provided by the system.

Update 6 Feb. 2018: RSParser is now a CocoaPod, with the much-appreciated help of Silver Fox. (We think it worked, anyway. Looked like it did.)

What’s inside

This framework includes parsers for:

It also includes Objective-C wrappers for libXML2’s XML SAX and HTML SAX parsers. You can write your own parsers on top of these.

This framework builds for macOS. It could be made to build for iOS also, but I haven’t gotten around to it yet.

How to parse feeds

To get the type of a feed, even with partial data, call FeedParser.feedType(parserData), which will return a FeedType.

To parse a feed, call FeedParser.parse(parserData), which will return a ParsedFeed. Also see related structs: ParsedAuthor, ParsedItem, ParsedAttachment, and ParsedHub.

You do not need to know the type of feed when calling FeedParser.parse — it will figure it out and use the correct concrete parser.

However, if you do want to use a concrete parser directly, see RSSInJSONParser, JSONFeedParser, RSSParser, and AtomParser.

(Note: if you want to write a feed reader app, please do! You have my blessing and encouragement. Let me know when it’s shipping so I can check it out.)

How to parse OPML

Call +[RSOPMLParser parseOPMLWithParserData:error:], which returns an RSOPMLDocument. See related objects: RSOPMLItem, RSOPMLAttributes, RSOPMLFeedSpecifier, and RSOPMLError.

How to parse dates

Call RSDateWithString or RSDateWithBytes (see RSDateParser). These handle the common internet date formats. You don’t need to know which format.

How to parse HTML

To get an array of <a href=… links from from an HTML document, call +[RSHTMLLinkParser htmlLinksWithParserData:]. It returns an array of RSHTMLLink.

To parse the metadata in an HTML document, call +[RSHTMLMetadataParser HTMLMetadataWithParserData:]. It returns an RSHTMLMetadata object.

To write your own HTML parser, see RSSAXHTMLParser. The two parsers above can serve as examples.

How to parse HTML entities

When you have a string with things like &#8212; and &euml; and you want to turn those into the correct characters, call -[NSString rsparser_stringByDecodingHTMLEntities]. (See NSString+RSParser.h.)

How to parse XML

If you need to parse some XML that isn’t RSS, Atom, or OPML, you can use RSSAXParser. Don’t subclass it — instead, create an RSSAXParserDelegate. See RSRSSParser, RSAtomParser, and RSOPMLParser as examples.

Why use libXML2’s SAX API?

SAX is kind of a pain because of all the state you have to manage.

An alternative is to use NSXMLParser, which is event-driven like SAX. However, RSSAXParser was written to avoid allocating Objective-C objects except when absolutely needed. You’ll note use of things like memcp and strncmp.

Normally I avoid this kind of thing strenuously. I prefer to work at the highest level possible.

But my more-than-a-decade of experience parsing XML has led me to this solution, which — last time I checked, which was, admittedly, a few years ago — was not only fastest but also uses the least memory. (The two things are related, of course: creating objects is bad for performance, so this code attempts to do the minimum possible.)

All that low-level stuff is encapsulated, however. If you just want to parse one of the popular feed formats, see FeedParser, which makes it easy and Swift-y.

Thread safety

Everything here is thread-safe.

Everything’s pretty fast, too, so you probably could just use the main thread/queue. But it’s totally a-okay to use a non-serial background queue.

About

Parser for RSS, Atom, JSON Feed, RSS-inJSON, OPML, and HTML.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Repository files navigation

RSParser

This framework was developed for NetNewsWire and is made available here for developers who just need the parsing code. It has no depencies that aren’t provided by the system.

Update 6 Feb. 2018: RSParser is now a CocoaPod, with the much-appreciated help of Silver Fox. (We think it worked, anyway. Looked like it did.)

What’s inside

This framework includes parsers for:

It also includes Objective-C wrappers for libXML2’s XML SAX and HTML SAX parsers. You can write your own parsers on top of these.

This framework builds for macOS. It could be made to build for iOS also, but I haven’t gotten around to it yet.

How to parse feeds

To get the type of a feed, even with partial data, call FeedParser.feedType(parserData), which will return a FeedType.

To parse a feed, call FeedParser.parse(parserData), which will return a ParsedFeed. Also see related structs: ParsedAuthor, ParsedItem, ParsedAttachment, and ParsedHub.

You do not need to know the type of feed when calling FeedParser.parse — it will figure it out and use the correct concrete parser.

However, if you do want to use a concrete parser directly, see RSSInJSONParser, JSONFeedParser, RSSParser, and AtomParser.

(Note: if you want to write a feed reader app, please do! You have my blessing and encouragement. Let me know when it’s shipping so I can check it out.)

How to parse OPML

Call +[RSOPMLParser parseOPMLWithParserData:error:], which returns an RSOPMLDocument. See related objects: RSOPMLItem, RSOPMLAttributes, RSOPMLFeedSpecifier, and RSOPMLError.

How to parse dates

Call RSDateWithString or RSDateWithBytes (see RSDateParser). These handle the common internet date formats. You don’t need to know which format.

How to parse HTML

To get an array of <a href=… links from from an HTML document, call +[RSHTMLLinkParser htmlLinksWithParserData:]. It returns an array of RSHTMLLink.

To parse the metadata in an HTML document, call +[RSHTMLMetadataParser HTMLMetadataWithParserData:]. It returns an RSHTMLMetadata object.

To write your own HTML parser, see RSSAXHTMLParser. The two parsers above can serve as examples.

How to parse HTML entities

When you have a string with things like &#8212; and &euml; and you want to turn those into the correct characters, call -[NSString rsparser_stringByDecodingHTMLEntities]. (See NSString+RSParser.h.)

How to parse XML

If you need to parse some XML that isn’t RSS, Atom, or OPML, you can use RSSAXParser. Don’t subclass it — instead, create an RSSAXParserDelegate. See RSRSSParser, RSAtomParser, and RSOPMLParser as examples.

Why use libXML2’s SAX API?

SAX is kind of a pain because of all the state you have to manage.

An alternative is to use NSXMLParser, which is event-driven like SAX. However, RSSAXParser was written to avoid allocating Objective-C objects except when absolutely needed. You’ll note use of things like memcp and strncmp.

Normally I avoid this kind of thing strenuously. I prefer to work at the highest level possible.

But my more-than-a-decade of experience parsing XML has led me to this solution, which — last time I checked, which was, admittedly, a few years ago — was not only fastest but also uses the least memory. (The two things are related, of course: creating objects is bad for performance, so this code attempts to do the minimum possible.)

All that low-level stuff is encapsulated, however. If you just want to parse one of the popular feed formats, see FeedParser, which makes it easy and Swift-y.

Thread safety

Everything here is thread-safe.

Everything’s pretty fast, too, so you probably could just use the main thread/queue. But it’s totally a-okay to use a non-serial background queue.

About

Parser for RSS, Atom, JSON Feed, RSS-inJSON, OPML, and HTML.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

RSParser

This framework was developed for NetNewsWire and is made available here for developers who just need the parsing code. It has no depencies that aren’t provided by the system.

Update 6 Feb. 2018: RSParser is now a CocoaPod, with the much-appreciated help of Silver Fox. (We think it worked, anyway. Looked like it did.)

What’s inside

This framework includes parsers for:

It also includes Objective-C wrappers for libXML2’s XML SAX and HTML SAX parsers. You can write your own parsers on top of these.

This framework builds for macOS. It could be made to build for iOS also, but I haven’t gotten around to it yet.

How to parse feeds

To get the type of a feed, even with partial data, call FeedParser.feedType(parserData), which will return a FeedType.

To parse a feed, call FeedParser.parse(parserData), which will return a ParsedFeed. Also see related structs: ParsedAuthor, ParsedItem, ParsedAttachment, and ParsedHub.

You do not need to know the type of feed when calling FeedParser.parse — it will figure it out and use the correct concrete parser.

However, if you do want to use a concrete parser directly, see RSSInJSONParser, JSONFeedParser, RSSParser, and AtomParser.

(Note: if you want to write a feed reader app, please do! You have my blessing and encouragement. Let me know when it’s shipping so I can check it out.)

How to parse OPML

Call +[RSOPMLParser parseOPMLWithParserData:error:], which returns an RSOPMLDocument. See related objects: RSOPMLItem, RSOPMLAttributes, RSOPMLFeedSpecifier, and RSOPMLError.

How to parse dates

Call RSDateWithString or RSDateWithBytes (see RSDateParser). These handle the common internet date formats. You don’t need to know which format.

How to parse HTML

To get an array of <a href=… links from from an HTML document, call +[RSHTMLLinkParser htmlLinksWithParserData:]. It returns an array of RSHTMLLink.

To parse the metadata in an HTML document, call +[RSHTMLMetadataParser HTMLMetadataWithParserData:]. It returns an RSHTMLMetadata object.

To write your own HTML parser, see RSSAXHTMLParser. The two parsers above can serve as examples.

How to parse HTML entities

When you have a string with things like &#8212; and &euml; and you want to turn those into the correct characters, call -[NSString rsparser_stringByDecodingHTMLEntities]. (See NSString+RSParser.h.)

How to parse XML

If you need to parse some XML that isn’t RSS, Atom, or OPML, you can use RSSAXParser. Don’t subclass it — instead, create an RSSAXParserDelegate. See RSRSSParser, RSAtomParser, and RSOPMLParser as examples.

Why use libXML2’s SAX API?

SAX is kind of a pain because of all the state you have to manage.

An alternative is to use NSXMLParser, which is event-driven like SAX. However, RSSAXParser was written to avoid allocating Objective-C objects except when absolutely needed. You’ll note use of things like memcp and strncmp.

Normally I avoid this kind of thing strenuously. I prefer to work at the highest level possible.

But my more-than-a-decade of experience parsing XML has led me to this solution, which — last time I checked, which was, admittedly, a few years ago — was not only fastest but also uses the least memory. (The two things are related, of course: creating objects is bad for performance, so this code attempts to do the minimum possible.)

All that low-level stuff is encapsulated, however. If you just want to parse one of the popular feed formats, see FeedParser, which makes it easy and Swift-y.

Thread safety

Everything here is thread-safe.

Everything’s pretty fast, too, so you probably could just use the main thread/queue. But it’s totally a-okay to use a non-serial background queue.

About

Parser for RSS, Atom, JSON Feed, RSS-inJSON, OPML, and HTML.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

RSParser

This framework was developed for NetNewsWire and is made available here for developers who just need the parsing code. It has no depencies that aren’t provided by the system.

Update 6 Feb. 2018: RSParser is now a CocoaPod, with the much-appreciated help of Silver Fox. (We think it worked, anyway. Looked like it did.)

What’s inside

This framework includes parsers for:

It also includes Objective-C wrappers for libXML2’s XML SAX and HTML SAX parsers. You can write your own parsers on top of these.

This framework builds for macOS. It could be made to build for iOS also, but I haven’t gotten around to it yet.

How to parse feeds

To get the type of a feed, even with partial data, call FeedParser.feedType(parserData), which will return a FeedType.

To parse a feed, call FeedParser.parse(parserData), which will return a ParsedFeed. Also see related structs: ParsedAuthor, ParsedItem, ParsedAttachment, and ParsedHub.

You do not need to know the type of feed when calling FeedParser.parse — it will figure it out and use the correct concrete parser.

However, if you do want to use a concrete parser directly, see RSSInJSONParser, JSONFeedParser, RSSParser, and AtomParser.

(Note: if you want to write a feed reader app, please do! You have my blessing and encouragement. Let me know when it’s shipping so I can check it out.)

How to parse OPML

Call +[RSOPMLParser parseOPMLWithParserData:error:], which returns an RSOPMLDocument. See related objects: RSOPMLItem, RSOPMLAttributes, RSOPMLFeedSpecifier, and RSOPMLError.

How to parse dates

Call RSDateWithString or RSDateWithBytes (see RSDateParser). These handle the common internet date formats. You don’t need to know which format.

How to parse HTML

To get an array of <a href=… links from from an HTML document, call +[RSHTMLLinkParser htmlLinksWithParserData:]. It returns an array of RSHTMLLink.

To parse the metadata in an HTML document, call +[RSHTMLMetadataParser HTMLMetadataWithParserData:]. It returns an RSHTMLMetadata object.

To write your own HTML parser, see RSSAXHTMLParser. The two parsers above can serve as examples.

How to parse HTML entities

When you have a string with things like &#8212; and &euml; and you want to turn those into the correct characters, call -[NSString rsparser_stringByDecodingHTMLEntities]. (See NSString+RSParser.h.)

How to parse XML

If you need to parse some XML that isn’t RSS, Atom, or OPML, you can use RSSAXParser. Don’t subclass it — instead, create an RSSAXParserDelegate. See RSRSSParser, RSAtomParser, and RSOPMLParser as examples.

Why use libXML2’s SAX API?

SAX is kind of a pain because of all the state you have to manage.

An alternative is to use NSXMLParser, which is event-driven like SAX. However, RSSAXParser was written to avoid allocating Objective-C objects except when absolutely needed. You’ll note use of things like memcp and strncmp.

Normally I avoid this kind of thing strenuously. I prefer to work at the highest level possible.

But my more-than-a-decade of experience parsing XML has led me to this solution, which — last time I checked, which was, admittedly, a few years ago — was not only fastest but also uses the least memory. (The two things are related, of course: creating objects is bad for performance, so this code attempts to do the minimum possible.)

All that low-level stuff is encapsulated, however. If you just want to parse one of the popular feed formats, see FeedParser, which makes it easy and Swift-y.

Thread safety

Everything here is thread-safe.

Everything’s pretty fast, too, so you probably could just use the main thread/queue. But it’s totally a-okay to use a non-serial background queue.

About

Parser for RSS, Atom, JSON Feed, RSS-inJSON, OPML, and HTML.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Repository files navigation

RSParser

This framework was developed for NetNewsWire and is made available here for developers who just need the parsing code. It has no depencies that aren’t provided by the system.

Update 6 Feb. 2018: RSParser is now a CocoaPod, with the much-appreciated help of Silver Fox. (We think it worked, anyway. Looked like it did.)

What’s inside

This framework includes parsers for:

It also includes Objective-C wrappers for libXML2’s XML SAX and HTML SAX parsers. You can write your own parsers on top of these.

This framework builds for macOS. It could be made to build for iOS also, but I haven’t gotten around to it yet.

How to parse feeds

To get the type of a feed, even with partial data, call FeedParser.feedType(parserData), which will return a FeedType.

To parse a feed, call FeedParser.parse(parserData), which will return a ParsedFeed. Also see related structs: ParsedAuthor, ParsedItem, ParsedAttachment, and ParsedHub.

You do not need to know the type of feed when calling FeedParser.parse — it will figure it out and use the correct concrete parser.

However, if you do want to use a concrete parser directly, see RSSInJSONParser, JSONFeedParser, RSSParser, and AtomParser.

(Note: if you want to write a feed reader app, please do! You have my blessing and encouragement. Let me know when it’s shipping so I can check it out.)

How to parse OPML

Call +[RSOPMLParser parseOPMLWithParserData:error:], which returns an RSOPMLDocument. See related objects: RSOPMLItem, RSOPMLAttributes, RSOPMLFeedSpecifier, and RSOPMLError.

How to parse dates

Call RSDateWithString or RSDateWithBytes (see RSDateParser). These handle the common internet date formats. You don’t need to know which format.

How to parse HTML

To get an array of <a href=… links from from an HTML document, call +[RSHTMLLinkParser htmlLinksWithParserData:]. It returns an array of RSHTMLLink.

To parse the metadata in an HTML document, call +[RSHTMLMetadataParser HTMLMetadataWithParserData:]. It returns an RSHTMLMetadata object.

To write your own HTML parser, see RSSAXHTMLParser. The two parsers above can serve as examples.

How to parse HTML entities

When you have a string with things like &#8212; and &euml; and you want to turn those into the correct characters, call -[NSString rsparser_stringByDecodingHTMLEntities]. (See NSString+RSParser.h.)

How to parse XML

If you need to parse some XML that isn’t RSS, Atom, or OPML, you can use RSSAXParser. Don’t subclass it — instead, create an RSSAXParserDelegate. See RSRSSParser, RSAtomParser, and RSOPMLParser as examples.

Why use libXML2’s SAX API?

SAX is kind of a pain because of all the state you have to manage.

An alternative is to use NSXMLParser, which is event-driven like SAX. However, RSSAXParser was written to avoid allocating Objective-C objects except when absolutely needed. You’ll note use of things like memcp and strncmp.

Normally I avoid this kind of thing strenuously. I prefer to work at the highest level possible.

But my more-than-a-decade of experience parsing XML has led me to this solution, which — last time I checked, which was, admittedly, a few years ago — was not only fastest but also uses the least memory. (The two things are related, of course: creating objects is bad for performance, so this code attempts to do the minimum possible.)

All that low-level stuff is encapsulated, however. If you just want to parse one of the popular feed formats, see FeedParser, which makes it easy and Swift-y.

Thread safety

Everything here is thread-safe.

Everything’s pretty fast, too, so you probably could just use the main thread/queue. But it’s totally a-okay to use a non-serial background queue.

About

Parser for RSS, Atom, JSON Feed, RSS-inJSON, OPML, and HTML.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

RSParser

This framework was developed for NetNewsWire and is made available here for developers who just need the parsing code. It has no depencies that aren’t provided by the system.

Update 6 Feb. 2018: RSParser is now a CocoaPod, with the much-appreciated help of Silver Fox. (We think it worked, anyway. Looked like it did.)

What’s inside

This framework includes parsers for:

It also includes Objective-C wrappers for libXML2’s XML SAX and HTML SAX parsers. You can write your own parsers on top of these.

This framework builds for macOS. It could be made to build for iOS also, but I haven’t gotten around to it yet.

How to parse feeds

To get the type of a feed, even with partial data, call FeedParser.feedType(parserData), which will return a FeedType.

To parse a feed, call FeedParser.parse(parserData), which will return a ParsedFeed. Also see related structs: ParsedAuthor, ParsedItem, ParsedAttachment, and ParsedHub.

You do not need to know the type of feed when calling FeedParser.parse — it will figure it out and use the correct concrete parser.

However, if you do want to use a concrete parser directly, see RSSInJSONParser, JSONFeedParser, RSSParser, and AtomParser.

(Note: if you want to write a feed reader app, please do! You have my blessing and encouragement. Let me know when it’s shipping so I can check it out.)

How to parse OPML

Call +[RSOPMLParser parseOPMLWithParserData:error:], which returns an RSOPMLDocument. See related objects: RSOPMLItem, RSOPMLAttributes, RSOPMLFeedSpecifier, and RSOPMLError.

How to parse dates

Call RSDateWithString or RSDateWithBytes (see RSDateParser). These handle the common internet date formats. You don’t need to know which format.

How to parse HTML

To get an array of <a href=… links from from an HTML document, call +[RSHTMLLinkParser htmlLinksWithParserData:]. It returns an array of RSHTMLLink.

To parse the metadata in an HTML document, call +[RSHTMLMetadataParser HTMLMetadataWithParserData:]. It returns an RSHTMLMetadata object.

To write your own HTML parser, see RSSAXHTMLParser. The two parsers above can serve as examples.

How to parse HTML entities

When you have a string with things like &#8212; and &euml; and you want to turn those into the correct characters, call -[NSString rsparser_stringByDecodingHTMLEntities]. (See NSString+RSParser.h.)

How to parse XML

If you need to parse some XML that isn’t RSS, Atom, or OPML, you can use RSSAXParser. Don’t subclass it — instead, create an RSSAXParserDelegate. See RSRSSParser, RSAtomParser, and RSOPMLParser as examples.

Why use libXML2’s SAX API?

SAX is kind of a pain because of all the state you have to manage.

An alternative is to use NSXMLParser, which is event-driven like SAX. However, RSSAXParser was written to avoid allocating Objective-C objects except when absolutely needed. You’ll note use of things like memcp and strncmp.

Normally I avoid this kind of thing strenuously. I prefer to work at the highest level possible.

But my more-than-a-decade of experience parsing XML has led me to this solution, which — last time I checked, which was, admittedly, a few years ago — was not only fastest but also uses the least memory. (The two things are related, of course: creating objects is bad for performance, so this code attempts to do the minimum possible.)

All that low-level stuff is encapsulated, however. If you just want to parse one of the popular feed formats, see FeedParser, which makes it easy and Swift-y.

Thread safety

Everything here is thread-safe.

Everything’s pretty fast, too, so you probably could just use the main thread/queue. But it’s totally a-okay to use a non-serial background queue.

About

Parser for RSS, Atom, JSON Feed, RSS-inJSON, OPML, and HTML.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

RSParser

This framework was developed for NetNewsWire and is made available here for developers who just need the parsing code. It has no depencies that aren’t provided by the system.

Update 6 Feb. 2018: RSParser is now a CocoaPod, with the much-appreciated help of Silver Fox. (We think it worked, anyway. Looked like it did.)

What’s inside

This framework includes parsers for:

It also includes Objective-C wrappers for libXML2’s XML SAX and HTML SAX parsers. You can write your own parsers on top of these.

This framework builds for macOS. It could be made to build for iOS also, but I haven’t gotten around to it yet.

How to parse feeds

To get the type of a feed, even with partial data, call FeedParser.feedType(parserData), which will return a FeedType.

To parse a feed, call FeedParser.parse(parserData), which will return a ParsedFeed. Also see related structs: ParsedAuthor, ParsedItem, ParsedAttachment, and ParsedHub.

You do not need to know the type of feed when calling FeedParser.parse — it will figure it out and use the correct concrete parser.

However, if you do want to use a concrete parser directly, see RSSInJSONParser, JSONFeedParser, RSSParser, and AtomParser.

(Note: if you want to write a feed reader app, please do! You have my blessing and encouragement. Let me know when it’s shipping so I can check it out.)

How to parse OPML

Call +[RSOPMLParser parseOPMLWithParserData:error:], which returns an RSOPMLDocument. See related objects: RSOPMLItem, RSOPMLAttributes, RSOPMLFeedSpecifier, and RSOPMLError.

How to parse dates

Call RSDateWithString or RSDateWithBytes (see RSDateParser). These handle the common internet date formats. You don’t need to know which format.

How to parse HTML

To get an array of <a href=… links from from an HTML document, call +[RSHTMLLinkParser htmlLinksWithParserData:]. It returns an array of RSHTMLLink.

To parse the metadata in an HTML document, call +[RSHTMLMetadataParser HTMLMetadataWithParserData:]. It returns an RSHTMLMetadata object.

To write your own HTML parser, see RSSAXHTMLParser. The two parsers above can serve as examples.

How to parse HTML entities

When you have a string with things like &#8212; and &euml; and you want to turn those into the correct characters, call -[NSString rsparser_stringByDecodingHTMLEntities]. (See NSString+RSParser.h.)

How to parse XML

If you need to parse some XML that isn’t RSS, Atom, or OPML, you can use RSSAXParser. Don’t subclass it — instead, create an RSSAXParserDelegate. See RSRSSParser, RSAtomParser, and RSOPMLParser as examples.

Why use libXML2’s SAX API?

SAX is kind of a pain because of all the state you have to manage.

An alternative is to use NSXMLParser, which is event-driven like SAX. However, RSSAXParser was written to avoid allocating Objective-C objects except when absolutely needed. You’ll note use of things like memcp and strncmp.

Normally I avoid this kind of thing strenuously. I prefer to work at the highest level possible.

But my more-than-a-decade of experience parsing XML has led me to this solution, which — last time I checked, which was, admittedly, a few years ago — was not only fastest but also uses the least memory. (The two things are related, of course: creating objects is bad for performance, so this code attempts to do the minimum possible.)

All that low-level stuff is encapsulated, however. If you just want to parse one of the popular feed formats, see FeedParser, which makes it easy and Swift-y.

Thread safety

Everything here is thread-safe.

Everything’s pretty fast, too, so you probably could just use the main thread/queue. But it’s totally a-okay to use a non-serial background queue.

About

Parser for RSS, Atom, JSON Feed, RSS-inJSON, OPML, and HTML.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Repository files navigation

RSParser

This framework was developed for NetNewsWire and is made available here for developers who just need the parsing code. It has no depencies that aren’t provided by the system.

Update 6 Feb. 2018: RSParser is now a CocoaPod, with the much-appreciated help of Silver Fox. (We think it worked, anyway. Looked like it did.)

What’s inside

This framework includes parsers for:

It also includes Objective-C wrappers for libXML2’s XML SAX and HTML SAX parsers. You can write your own parsers on top of these.

This framework builds for macOS. It could be made to build for iOS also, but I haven’t gotten around to it yet.

How to parse feeds

To get the type of a feed, even with partial data, call FeedParser.feedType(parserData), which will return a FeedType.

To parse a feed, call FeedParser.parse(parserData), which will return a ParsedFeed. Also see related structs: ParsedAuthor, ParsedItem, ParsedAttachment, and ParsedHub.

You do not need to know the type of feed when calling FeedParser.parse — it will figure it out and use the correct concrete parser.

However, if you do want to use a concrete parser directly, see RSSInJSONParser, JSONFeedParser, RSSParser, and AtomParser.

(Note: if you want to write a feed reader app, please do! You have my blessing and encouragement. Let me know when it’s shipping so I can check it out.)

How to parse OPML

Call +[RSOPMLParser parseOPMLWithParserData:error:], which returns an RSOPMLDocument. See related objects: RSOPMLItem, RSOPMLAttributes, RSOPMLFeedSpecifier, and RSOPMLError.

How to parse dates

Call RSDateWithString or RSDateWithBytes (see RSDateParser). These handle the common internet date formats. You don’t need to know which format.

How to parse HTML

To get an array of <a href=… links from from an HTML document, call +[RSHTMLLinkParser htmlLinksWithParserData:]. It returns an array of RSHTMLLink.

To parse the metadata in an HTML document, call +[RSHTMLMetadataParser HTMLMetadataWithParserData:]. It returns an RSHTMLMetadata object.

To write your own HTML parser, see RSSAXHTMLParser. The two parsers above can serve as examples.

How to parse HTML entities

When you have a string with things like &#8212; and &euml; and you want to turn those into the correct characters, call -[NSString rsparser_stringByDecodingHTMLEntities]. (See NSString+RSParser.h.)

How to parse XML

If you need to parse some XML that isn’t RSS, Atom, or OPML, you can use RSSAXParser. Don’t subclass it — instead, create an RSSAXParserDelegate. See RSRSSParser, RSAtomParser, and RSOPMLParser as examples.

Why use libXML2’s SAX API?

SAX is kind of a pain because of all the state you have to manage.

An alternative is to use NSXMLParser, which is event-driven like SAX. However, RSSAXParser was written to avoid allocating Objective-C objects except when absolutely needed. You’ll note use of things like memcp and strncmp.

Normally I avoid this kind of thing strenuously. I prefer to work at the highest level possible.

But my more-than-a-decade of experience parsing XML has led me to this solution, which — last time I checked, which was, admittedly, a few years ago — was not only fastest but also uses the least memory. (The two things are related, of course: creating objects is bad for performance, so this code attempts to do the minimum possible.)

All that low-level stuff is encapsulated, however. If you just want to parse one of the popular feed formats, see FeedParser, which makes it easy and Swift-y.

Thread safety

Everything here is thread-safe.

Everything’s pretty fast, too, so you probably could just use the main thread/queue. But it’s totally a-okay to use a non-serial background queue.

About

Parser for RSS, Atom, JSON Feed, RSS-inJSON, OPML, and HTML.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages