changeset 1703:3a61451f8130

add bbcode video
author Franklin Schmidt <fschmidt@gmail.com>
date Fri, 01 Jul 2022 00:12:05 -0600
parents 8ad468cc88d4
children 19df8abc9805
files src/goodjava/bbcode/BBCode.java website/src/goodjava.html.luan
diffstat 2 files changed, 51 insertions(+), 21 deletions(-) [+]
line wrap: on
line diff
--- a/src/goodjava/bbcode/BBCode.java	Thu Jun 30 20:04:34 2022 -0600
+++ b/src/goodjava/bbcode/BBCode.java	Fri Jul 01 00:12:05 2022 -0600
@@ -2,6 +2,8 @@
 
 import java.util.List;
 import java.util.ArrayList;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 import goodjava.parser.Parser;
 
 
@@ -99,8 +101,8 @@
 			|| parser.testIgnoreCase("[/color]")
 			|| parser.testIgnoreCase("[size=")
 			|| parser.testIgnoreCase("[/size]")
-			|| parser.testIgnoreCase("[youtube]")
-			|| parser.testIgnoreCase("[/youtube]")
+			|| parser.testIgnoreCase("[video]")
+			|| parser.testIgnoreCase("[/video]")
 			|| parser.testIgnoreCase("[quote]")
 			|| parser.testIgnoreCase("[quote=")
 			|| parser.testIgnoreCase("[/quote]")
@@ -120,7 +122,7 @@
 		s = parseImg();  if(s!=null) return s;
 		s = parseColor();  if(s!=null) return s;
 		s = parseSize();  if(s!=null) return s;
-		s = parseYouTube();  if(s!=null) return s;
+		s = parseVideo();  if(s!=null) return s;
 		s = parseQuote1();  if(s!=null) return s;
 		s = parseQuote2();  if(s!=null) return s;
 		return null;
@@ -166,7 +168,7 @@
 		String url = parseRealUrl();
 		if( !parser.matchIgnoreCase("[/url]") )
 			return parser.failure(null);
-		String rtn = target==Target.HTML ? "<a href='"+url+"'>"+url+"</a>" : url;
+		String rtn = target==Target.HTML ? "<a href='" + url + "'>" + url + "</a>" : url;
 		return parser.success(rtn);
 	}
 
@@ -180,7 +182,7 @@
 		String content = parseWellFormed();
 		if( !parser.matchIgnoreCase("[/url]") )
 			return parser.failure(null);
-		String rtn = target==Target.HTML ? "<a href='"+url+"'>"+content+"</a>" : content;
+		String rtn = target==Target.HTML ? "<a href='" + url + "'>" + content + "</a>" : content;
 		return parser.success(rtn);
 	}
 
@@ -221,7 +223,7 @@
 		String url = parseRealUrl();
 		if( !parser.matchIgnoreCase("[/img]") )
 			return parser.failure(null);
-		String rtn = target==Target.HTML ? "<img src='"+url+"'>" : "";
+		String rtn = target==Target.HTML ? "<img src='" + url + "'>" : "";
 		return parser.success(rtn);
 	}
 
@@ -261,24 +263,52 @@
 		return parser.success(rtn);
 	}
 
-	private String parseYouTube() {
+	private static final Pattern youtubePtn1 = Pattern.compile("https://youtu.be/([a-zA-Z0-9_-]+)(?:\\?t=([0-9]+))?");
+	private static final Pattern youtubePtn2 = Pattern.compile("https://www.youtube.com/watch?v=([a-zA-Z0-9_-]+)(?:\\?t=([0-9]+)s)?");
+	private static final Pattern bitchutePtn = Pattern.compile("https://www.bitchute.com/video/([a-zA-Z0-9]+)/");
+
+	private static Matcher find(Pattern ptn,String s) {
+		Matcher m = ptn.matcher(s);
+		return m.find() ? m : null;
+	}
+
+	private String parseVideo() {
 		parser.begin();
-		if( !parser.matchIgnoreCase("[youtube]") )
+		if( !parser.matchIgnoreCase("[video]") )
+			return parser.failure(null);
+		String url = parseRealUrl();
+		if( !parser.matchIgnoreCase("[/video]") )
 			return parser.failure(null);
-		int start = parser.currentIndex();
-		while( parser.inCharRange('0','9')
-			|| parser.inCharRange('a','z')
-			|| parser.inCharRange('A','Z')
-			|| parser.match('-')
-			|| parser.match('_')
-		);
-		String id = parser.textFrom(start);
-		if( id.length()==0 || !parser.matchIgnoreCase("[/youtube]") )
-			return parser.failure(null);
-		String rtn = target==Target.HTML ? "<iframe width='420' height='315' src='https://www.youtube.com/embed/"+id+"' frameborder='0' allowfullscreen></iframe>" : "";
-		return parser.success(rtn);
+		if( target==Target.TEXT )
+			return parser.success( "" );
+		Matcher m;
+		m = find(youtubePtn1,url);
+		if( m == null )
+			m = find(youtubePtn2,url);
+		if( m != null ) {
+			StringBuilder sb = new StringBuilder();
+			sb.append( "<iframe width='420' height='315' src='https://www.youtube.com/embed/" );
+			sb.append( m.group(1) );
+			String t = m.group(2);
+			if( t != null ) {
+				sb.append( "?start=" );
+				sb.append( t );
+			}
+			sb.append( "' frameborder='0' allowfullscreen></iframe>" );
+			return parser.success( sb.toString() );
+		}
+		m = find(bitchutePtn,url);
+		if( m != null ) {
+			StringBuilder sb = new StringBuilder();
+			sb.append( "<iframe width='420' height='315' scrolling='no' frameborder='0' style='border: none;' src='https://www.bitchute.com/embed/" );
+			sb.append( m.group(1) );
+			sb.append( "/'></iframe>" );
+			return parser.success( sb.toString() );
+		}
+		return parser.success( "<a href='" + url + "'>" + url + "</a>" );
 	}
 
+
 	private String parseQuote1() {
 		parser.begin();
 		if( !parser.matchIgnoreCase("[quote]") )
--- a/website/src/goodjava.html.luan	Thu Jun 30 20:04:34 2022 -0600
+++ b/website/src/goodjava.html.luan	Fri Jul 01 00:12:05 2022 -0600
@@ -36,7 +36,7 @@
 		title = "goodjava.parser"
 		content = function()
 %>
-<p>In computer science, parsing is a big deal.  They make it complicated, of course.  But it shouldn't be.  I developed a new approach to parsing which is implemented <a href="https://hg.reactionary.software/repo/luan/file/default/src/goodjava/parser/">here</a>.  It is based on a simple stack of integers that are positions in what is effectively recursive descent parsing.  I use this idea to compile Luan but also to parse <a href="https://hg.reactionary.software/repo/luan/file/default/src/goodjava/json/JsonParser.java">JSON</a>, <a href="https://hg.reactionary.software/repo/luan/file/default/src/goodjava/lucene/queryparser/GoodQueryParser.java">Lucene queries</a>, <a href="https://hg.reactionary.software/repo/luan/file/default/src/goodjava/webserver/RequestParser.java">HTTP requests</a>, <a href="https://hg.reactionary.software/repo/luan/file/default/src/luan/modules/parsers/BBCode.java">BBCode</a>, <a href="https://hg.reactionary.software/repo/luan/file/default/src/luan/modules/parsers/Css.java">CSS</a>, <a href="https://hg.reactionary.software/repo/luan/file/default/src/luan/modules/parsers/Csv.java">CSV</a>, <a href="https://hg.reactionary.software/repo/luan/file/default/src/luan/modules/parsers/Html.java">HTML</a>, and other things.</p>
+<p>In computer science, parsing is a big deal.  They make it complicated, of course.  But it shouldn't be.  I developed a new approach to parsing which is implemented <a href="https://hg.reactionary.software/repo/luan/file/default/src/goodjava/parser/">here</a>.  It is based on a simple stack of integers that are positions in what is effectively recursive descent parsing.  I use this idea to compile Luan but also to parse <a href="https://hg.reactionary.software/repo/luan/file/default/src/goodjava/json/JsonParser.java">JSON</a>, <a href="https://hg.reactionary.software/repo/luan/file/default/src/goodjava/lucene/queryparser/GoodQueryParser.java">Lucene queries</a>, <a href="https://hg.reactionary.software/repo/luan/file/default/src/goodjava/webserver/RequestParser.java">HTTP requests</a>, <a href="https://hg.reactionary.software/repo/luan/file/default/src/goodjava/bbcode/BBCode.java">BBCode</a>, <a href="https://hg.reactionary.software/repo/luan/file/default/src/luan/modules/parsers/Css.java">CSS</a>, <a href="https://hg.reactionary.software/repo/luan/file/default/src/luan/modules/parsers/Csv.java">CSV</a>, <a href="https://hg.reactionary.software/repo/luan/file/default/src/luan/modules/parsers/Html.java">HTML</a>, and other things.</p>
 
 <p>When I wrote the <a href="https://hg.reactionary.software/repo/luan/file/default/src/goodjava/json/JsonParser.java">JSON parser</a>, it worked on the first run.  It is so much simpler than any other JSON parser.  I dare you to look for any JSON parser as simple as this one.  All my other parsers are similar.  My approach to parsing reflects my anti-modern values.  I hate theoretical nonsense and I hate needless complexity.  Think deeply about a problem (like parsing) until you see the essence of it.  Then write clean simple code to solve the problem.</p>
 <%