├── README.md ├── index.html └── js └── Markdown.Converter.js /README.md: -------------------------------------------------------------------------------- 1 | HTML5 games hosted on GitHub 2 | ================ 3 | 4 | ### SELECTION CRITERIA 5 | 6 | The aim of this curated list is to be a collection of quality, completed HTML5 games on GitHub which provide the complete source code (not minified, etc.) for the purpose of learning from the best-in-class examples in each genre. 7 | 8 | Games should be purely client-side and be able to run on a local server without any additional requirements. 9 | 10 | **ACTION** 11 | 12 | - [Monster Wants Candy](https://github.com/EnclaveGames/Monster-Wants-Candy) 13 | 14 | **ARCADE** 15 | 16 | - [Circus Charlie](https://github.com/eugenioclrc/circushtml5) 17 | - [Space Invaders](https://github.com/StrykerKKD/SpaceInvaders) 18 | - [Space Crusade](https://github.com/Loopeex/space-crusade) 19 | 20 | **PLATFORMER** 21 | 22 | - [Elemental One](https://github.com/voithos/elemental-one) 23 | 24 | **PUZZLE** 25 | 26 | - [Monkey Rally](https://github.com/antila/ludum-dare-28) 27 | 28 | **RACING** 29 | 30 | - [HexGL](https://github.com/BKcore/HexGL) 31 | - [Chacket Valleyparker: Drill Bunny](https://github.com/DreamShowAdventures/LudumDare29) 32 | 33 | **SHOOTER** 34 | 35 | - [Dental Defender](https://github.com/cshepp/candyjam/) 36 | 37 | **MULTIPLAYER** 38 | 39 | - [BrowserQuest](https://github.com/mozilla/BrowserQuest) 40 | 41 | **ENGINE DEMOS** 42 | 43 | - [Breakouts](https://github.com/city41/breakouts) (Multiple engines) 44 | - [Flying Dog](https://github.com/ekelokorpi/flyingdog) (req PandaJS) 45 | - [WhackAThing](https://github.com/ekelokorpi/whackathing) (req PandaJS) 46 | 47 | 48 | ### USEFUL LINKS 49 | - [GitHub Game Off 2012](https://github.com/blog/1303-github-game-off) 50 | - [Winners](https://github.com/blog/1337-github-game-off-winners) 51 | - [GitHub Game Off 2013](https://github.com/blog/1674-github-game-off-ii) 52 | - [Winners](https://github.com/blog/1731-github-game-off-ii-winners) 53 | - Phaser HTML5 Engine 54 | - [Examples](https://github.com/photonstorm/phaser-examples) 55 | - [List of Games](http://pgl.ilinov.eu/) 56 | - [Game Mechanic Explorer](http://gamemechanicexplorer.com/) -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 5 |s around 362 | // "paragraphs" that are wrapped in non-block-level tags, such as anchors, 363 | // phrase emphasis, and spans. The list of tags we're looking for is 364 | // hard-coded: 365 | var block_tags_a = "p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|script|noscript|form|fieldset|iframe|math|ins|del" 366 | var block_tags_b = "p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|script|noscript|form|fieldset|iframe|math" 367 | 368 | // First, look for nested blocks, e.g.: 369 | //
tags around block-level tags.
516 | text = _HashHTMLBlocks(text);
517 | text = _FormParagraphs(text, doNotUnhash);
518 |
519 | return text;
520 | }
521 |
522 | function _RunSpanGamut(text) {
523 | //
524 | // These are all the transformations that occur *within* block-level
525 | // tags like paragraphs, headers, and list items.
526 | //
527 |
528 | text = pluginHooks.preSpanGamut(text);
529 |
530 | text = _DoCodeSpans(text);
531 | text = _EscapeSpecialCharsWithinTagAttributes(text);
532 | text = _EncodeBackslashEscapes(text);
533 |
534 | // Process anchor and image tags. Images must come first,
535 | // because ![foo][f] looks like an anchor.
536 | text = _DoImages(text);
537 | text = _DoAnchors(text);
538 |
539 | // Make links out of things like ` Just type tags
1253 | //
1254 |
1255 | // Strip leading and trailing lines:
1256 | text = text.replace(/^\n+/g, "");
1257 | text = text.replace(/\n+$/g, "");
1258 |
1259 | var grafs = text.split(/\n{2,}/g);
1260 | var grafsOut = [];
1261 |
1262 | var markerRe = /~K(\d+)K/;
1263 |
1264 | //
1265 | // Wrap tags.
1266 | //
1267 | var end = grafs.length;
1268 | for (var i = 0; i < end; i++) {
1269 | var str = grafs[i];
1270 |
1271 | // if this is an HTML marker, copy it
1272 | if (markerRe.test(str)) {
1273 | grafsOut.push(str);
1274 | }
1275 | else if (/\S/.test(str)) {
1276 | str = _RunSpanGamut(str);
1277 | str = str.replace(/^([ \t]*)/g, " ");
1278 | str += "
\n");
551 |
552 | text = pluginHooks.postSpanGamut(text);
553 |
554 | return text;
555 | }
556 |
557 | function _EscapeSpecialCharsWithinTagAttributes(text) {
558 | //
559 | // Within tags -- meaning between < and > -- encode [\ ` * _] so they
560 | // don't conflict with their use in Markdown for code, italics and strong.
561 | //
562 |
563 | // Build a regex to find HTML tags and comments. See Friedl's
564 | // "Mastering Regular Expressions", 2nd Ed., pp. 200-201.
565 |
566 | // SE: changed the comment part of the regex
567 |
568 | var regex = /(<[a-z\/!$]("[^"]*"|'[^']*'|[^'">])*>|-]|-[^>])(?:[^-]|-[^-])*)--)>)/gi;
569 |
570 | text = text.replace(regex, function (wholeMatch) {
571 | var tag = wholeMatch.replace(/(.)<\/?code>(?=.)/g, "$1`");
572 | tag = escapeCharacters(tag, wholeMatch.charAt(1) == "!" ? "\\`*_/" : "\\`*_"); // also escape slashes in comments to prevent autolinking there -- http://meta.stackexchange.com/questions/95987
573 | return tag;
574 | });
575 |
576 | return text;
577 | }
578 |
579 | function _DoAnchors(text) {
580 | //
581 | // Turn Markdown link shortcuts into XHTML tags.
582 | //
583 | //
584 | // First, handle reference-style links: [link text] [id]
585 | //
586 |
587 | /*
588 | text = text.replace(/
589 | ( // wrap whole match in $1
590 | \[
591 | (
592 | (?:
593 | \[[^\]]*\] // allow brackets nested one level
594 | |
595 | [^\[] // or anything else
596 | )*
597 | )
598 | \]
599 |
600 | [ ]? // one optional space
601 | (?:\n[ ]*)? // one optional newline followed by spaces
602 |
603 | \[
604 | (.*?) // id = $3
605 | \]
606 | )
607 | ()()()() // pad remaining backreferences
608 | /g, writeAnchorTag);
609 | */
610 | text = text.replace(/(\[((?:\[[^\]]*\]|[^\[\]])*)\][ ]?(?:\n[ ]*)?\[(.*?)\])()()()()/g, writeAnchorTag);
611 |
612 | //
613 | // Next, inline-style links: [link text](url "optional title")
614 | //
615 |
616 | /*
617 | text = text.replace(/
618 | ( // wrap whole match in $1
619 | \[
620 | (
621 | (?:
622 | \[[^\]]*\] // allow brackets nested one level
623 | |
624 | [^\[\]] // or anything else
625 | )*
626 | )
627 | \]
628 | \( // literal paren
629 | [ \t]*
630 | () // no id, so leave $3 empty
631 | ( // href = $4
632 | (?:
633 | \([^)]*\) // allow one level of (correctly nested) parens (think MSDN)
634 | |
635 | [^()\s]
636 | )*?
637 | )>?
638 | [ \t]*
639 | ( // $5
640 | (['"]) // quote char = $6
641 | (.*?) // Title = $7
642 | \6 // matching quote
643 | [ \t]* // ignore any spaces/tabs between closing quote and )
644 | )? // title is optional
645 | \)
646 | )
647 | /g, writeAnchorTag);
648 | */
649 |
650 | text = text.replace(/(\[((?:\[[^\]]*\]|[^\[\]])*)\]\([ \t]*()((?:\([^)]*\)|[^()\s])*?)>?[ \t]*((['"])(.*?)\6[ \t]*)?\))/g, writeAnchorTag);
651 |
652 | //
653 | // Last, handle reference-style shortcuts: [link text]
654 | // These must come last in case you've also got [link test][1]
655 | // or [link test](/foo)
656 | //
657 |
658 | /*
659 | text = text.replace(/
660 | ( // wrap whole match in $1
661 | \[
662 | ([^\[\]]+) // link text = $2; can't contain '[' or ']'
663 | \]
664 | )
665 | ()()()()() // pad rest of backreferences
666 | /g, writeAnchorTag);
667 | */
668 | text = text.replace(/(\[([^\[\]]+)\])()()()()()/g, writeAnchorTag);
669 |
670 | return text;
671 | }
672 |
673 | function writeAnchorTag(wholeMatch, m1, m2, m3, m4, m5, m6, m7) {
674 | if (m7 == undefined) m7 = "";
675 | var whole_match = m1;
676 | var link_text = m2.replace(/:\/\//g, "~P"); // to prevent auto-linking withing the link. will be converted back after the auto-linker runs
677 | var link_id = m3.toLowerCase();
678 | var url = m4;
679 | var title = m7;
680 |
681 | if (url == "") {
682 | if (link_id == "") {
683 | // lower-case and turn embedded newlines into spaces
684 | link_id = link_text.toLowerCase().replace(/ ?\n/g, " ");
685 | }
686 | url = "#" + link_id;
687 |
688 | if (g_urls.get(link_id) != undefined) {
689 | url = g_urls.get(link_id);
690 | if (g_titles.get(link_id) != undefined) {
691 | title = g_titles.get(link_id);
692 | }
693 | }
694 | else {
695 | if (whole_match.search(/\(\s*\)$/m) > -1) {
696 | // Special case for explicit empty url
697 | url = "";
698 | } else {
699 | return whole_match;
700 | }
701 | }
702 | }
703 | url = encodeProblemUrlChars(url);
704 | url = escapeCharacters(url, "*_");
705 | var result = "" + link_text + "";
714 |
715 | return result;
716 | }
717 |
718 | function _DoImages(text) {
719 | //
720 | // Turn Markdown image shortcuts into tags.
721 | //
722 |
723 | //
724 | // First, handle reference-style labeled images: ![alt text][id]
725 | //
726 |
727 | /*
728 | text = text.replace(/
729 | ( // wrap whole match in $1
730 | !\[
731 | (.*?) // alt text = $2
732 | \]
733 |
734 | [ ]? // one optional space
735 | (?:\n[ ]*)? // one optional newline followed by spaces
736 |
737 | \[
738 | (.*?) // id = $3
739 | \]
740 | )
741 | ()()()() // pad rest of backreferences
742 | /g, writeImageTag);
743 | */
744 | text = text.replace(/(!\[(.*?)\][ ]?(?:\n[ ]*)?\[(.*?)\])()()()()/g, writeImageTag);
745 |
746 | //
747 | // Next, handle inline images: 
748 | // Don't forget: encode * and _
749 |
750 | /*
751 | text = text.replace(/
752 | ( // wrap whole match in $1
753 | !\[
754 | (.*?) // alt text = $2
755 | \]
756 | \s? // One optional whitespace character
757 | \( // literal paren
758 | [ \t]*
759 | () // no id, so leave $3 empty
760 | (\S+?)>? // src url = $4
761 | [ \t]*
762 | ( // $5
763 | (['"]) // quote char = $6
764 | (.*?) // title = $7
765 | \6 // matching quote
766 | [ \t]*
767 | )? // title is optional
768 | \)
769 | )
770 | /g, writeImageTag);
771 | */
772 | text = text.replace(/(!\[(.*?)\]\s?\([ \t]*()(\S+?)>?[ \t]*((['"])(.*?)\6[ \t]*)?\))/g, writeImageTag);
773 |
774 | return text;
775 | }
776 |
777 | function attributeEncode(text) {
778 | // unconditionally replace angle brackets here -- what ends up in an attribute (e.g. alt or title)
779 | // never makes sense to have verbatim HTML in it (and the sanitizer would totally break it)
780 | return text.replace(/>/g, ">").replace(/";
824 |
825 | return result;
826 | }
827 |
828 | function _DoHeaders(text) {
829 |
830 | // Setext-style headers:
831 | // Header 1
832 | // ========
833 | //
834 | // Header 2
835 | // --------
836 | //
837 | text = text.replace(/^(.+)[ \t]*\n=+[ \t]*\n+/gm,
838 | function (wholeMatch, m1) { return "
" + _RunSpanGamut(m1) + "
\n\n"; }
839 | );
840 |
841 | text = text.replace(/^(.+)[ \t]*\n-+[ \t]*\n+/gm,
842 | function (matchFound, m1) { return "" + _RunSpanGamut(m1) + "
\n\n"; }
843 | );
844 |
845 | // atx-style headers:
846 | // # Header 1
847 | // ## Header 2
848 | // ## Header 2 with closing hashes ##
849 | // ...
850 | // ###### Header 6
851 | //
852 |
853 | /*
854 | text = text.replace(/
855 | ^(\#{1,6}) // $1 = string of #'s
856 | [ \t]*
857 | (.+?) // $2 = Header text
858 | [ \t]*
859 | \#* // optional closing #'s (not counted)
860 | \n+
861 | /gm, function() {...});
862 | */
863 |
864 | text = text.replace(/^(\#{1,6})[ \t]*(.+?)[ \t]*\#*\n+/gm,
865 | function (wholeMatch, m1, m2) {
866 | var h_level = m1.length;
867 | return "` blocks.
1041 | //
1042 |
1043 | /*
1044 | text = text.replace(/
1045 | (?:\n\n|^)
1046 | ( // $1 = the code block -- one or more lines, starting with a space/tab
1047 | (?:
1048 | (?:[ ]{4}|\t) // Lines must start with a tab or a tab-width of spaces - attacklab: g_tab_width
1049 | .*\n+
1050 | )+
1051 | )
1052 | (\n*[ ]{0,3}[^ \t\n]|(?=~0)) // attacklab: g_tab_width
1053 | /g ,function(){...});
1054 | */
1055 |
1056 | // attacklab: sentinel workarounds for lack of \A and \Z, safari\khtml bug
1057 | text += "~0";
1058 |
1059 | text = text.replace(/(?:\n\n|^\n?)((?:(?:[ ]{4}|\t).*\n+)+)(\n*[ ]{0,3}[^ \t\n]|(?=~0))/g,
1060 | function (wholeMatch, m1, m2) {
1061 | var codeblock = m1;
1062 | var nextChar = m2;
1063 |
1064 | codeblock = _EncodeCode(_Outdent(codeblock));
1065 | codeblock = _Detab(codeblock);
1066 | codeblock = codeblock.replace(/^\n+/g, ""); // trim leading newlines
1067 | codeblock = codeblock.replace(/\n+$/g, ""); // trim trailing whitespace
1068 |
1069 | codeblock = "
";
1070 |
1071 | return "\n\n" + codeblock + "\n\n" + nextChar;
1072 | }
1073 | );
1074 |
1075 | // attacklab: strip sentinel
1076 | text = text.replace(/~0/, "");
1077 |
1078 | return text;
1079 | }
1080 |
1081 | function _DoCodeSpans(text) {
1082 | //
1083 | // * Backtick quotes are used for " + codeblock + "\n
spans.
1084 | //
1085 | // * You can use multiple backticks as the delimiters if you want to
1086 | // include literal backticks in the code span. So, this input:
1087 | //
1088 | // Just type ``foo `bar` baz`` at the prompt.
1089 | //
1090 | // Will translate to:
1091 | //
1092 | //
foo `bar` baz
at the prompt.`bar`
...
1105 | //
1106 |
1107 | /*
1108 | text = text.replace(/
1109 | (^|[^\\`]) // Character before opening ` can't be a backslash or backtick
1110 | (`+) // $2 = Opening run of `
1111 | (?!`) // and no more backticks -- match the full run
1112 | ( // $3 = The code block
1113 | [^\r]*?
1114 | [^`] // attacklab: work around lack of lookbehind
1115 | )
1116 | \2 // Matching closer
1117 | (?!`)
1118 | /gm, function(){...});
1119 | */
1120 |
1121 | text = text.replace(/(^|[^\\`])(`+)(?!`)([^\r]*?[^`])\2(?!`)/gm,
1122 | function (wholeMatch, m1, m2, m3, m4) {
1123 | var c = m3;
1124 | c = c.replace(/^([ \t]*)/g, ""); // leading whitespace
1125 | c = c.replace(/[ \t]*$/g, ""); // trailing whitespace
1126 | c = _EncodeCode(c);
1127 | c = c.replace(/:\/\//g, "~P"); // to prevent auto-linking. Not necessary in code *blocks*, but in code spans. Will be converted back after the auto-linker runs.
1128 | return m1 + "" + c + "
";
1129 | }
1130 | );
1131 |
1132 | return text;
1133 | }
1134 |
1135 | function _EncodeCode(text) {
1136 | //
1137 | // Encode/escape certain characters inside Markdown code runs.
1138 | // The point is that in code, these characters are literals,
1139 | // and lose their special Markdown meanings.
1140 | //
1141 | // Encode all ampersands; HTML entities are not
1142 | // entities within a Markdown code span.
1143 | text = text.replace(/&/g, "&");
1144 |
1145 | // Do the angle bracket song and dance:
1146 | text = text.replace(//g, ">");
1148 |
1149 | // Now, escape characters that are magic in Markdown:
1150 | text = escapeCharacters(text, "\*_{}[]\\", false);
1151 |
1152 | // jj the line above breaks this:
1153 | //---
1154 |
1155 | //* Item
1156 |
1157 | // 1. Subitem
1158 |
1159 | // special char: *
1160 | //---
1161 |
1162 | return text;
1163 | }
1164 |
1165 | function _DoItalicsAndBold(text) {
1166 |
1167 | text = asciify(text);
1168 |
1169 | // must go first:
1170 |
1171 | // (^|[\W_]) Start with a non-letter or beginning of string. Store in \1.
1172 | // (?:(?!\1)|(?=^)) Either the next character is *not* the same as the previous,
1173 | // or we started at the end of the string (in which case the previous
1174 | // group had zero width, so we're still there). Because the next
1175 | // character is the marker, this means that if there are e.g. multiple
1176 | // underscores in a row, we can only match the left-most ones (which
1177 | // prevents foo___bar__ from getting bolded)
1178 | // (\*|_) The marker character itself, asterisk or underscore. Store in \2.
1179 | // \2 The marker again, since bold needs two.
1180 | // (?=\S) The first bolded character cannot be a space.
1181 | // ([^\r]*?\S) The actual bolded string. At least one character, and it cannot *end*
1182 | // with a space either. Note that like in many other places, [^\r] is
1183 | // just a workaround for JS' lack of single-line regexes; it's equivalent
1184 | // to a . in an /s regex, because the string cannot contain any \r (they
1185 | // are removed in the normalizing step).
1186 | // \2\2 The marker character, twice -- end of bold.
1187 | // (?!\2) Not followed by another marker character (ensuring that we match the
1188 | // rightmost two in a longer row)...
1189 | // (?=[\W_]|$) ...but by any other non-word character or the end of string.
1190 | text = text.replace(/(^|[\W_])(?:(?!\1)|(?=^))(\*|_)\2(?=\S)([^\r]*?\S)\2\2(?!\2)(?=[\W_]|$)/g,
1191 | "$1$3");
1192 |
1193 | // This is almost identical to the regex, except 1) there's obviously just one marker
1194 | // character, and 2) the italicized string cannot contain the marker character.
1195 | text = text.replace(/(^|[\W_])(?:(?!\1)|(?=^))(\*|_)(?=\S)((?:(?!\2)[^\r])*?\S)\2(?!\2)(?=[\W_]|$)/g,
1196 | "$1$3");
1197 |
1198 | return deasciify(text);
1199 | }
1200 |
1201 | function _DoBlockQuotes(text) {
1202 |
1203 | /*
1204 | text = text.replace(/
1205 | ( // Wrap whole match in $1
1206 | (
1207 | ^[ \t]*>[ \t]? // '>' at the start of a line
1208 | .+\n // rest of the first line
1209 | (.+\n)* // subsequent consecutive lines
1210 | \n* // blanks
1211 | )+
1212 | )
1213 | /gm, function(){...});
1214 | */
1215 |
1216 | text = text.replace(/((^[ \t]*>[ \t]?.+\n(.+\n)*\n*)+)/gm,
1217 | function (wholeMatch, m1) {
1218 | var bq = m1;
1219 |
1220 | // attacklab: hack around Konqueror 3.5.4 bug:
1221 | // "----------bug".replace(/^-/g,"") == "bug"
1222 |
1223 | bq = bq.replace(/^[ \t]*>[ \t]?/gm, "~0"); // trim one level of quoting
1224 |
1225 | // attacklab: clean up hack
1226 | bq = bq.replace(/~0/g, "");
1227 |
1228 | bq = bq.replace(/^[ \t]+$/gm, ""); // trim whitespace-only lines
1229 | bq = _RunBlockGamut(bq); // recurse
1230 |
1231 | bq = bq.replace(/(^|\n)/g, "$1 ");
1232 | // These leading spaces screw with content, so we need to fix that:
1233 | bq = bq.replace(
1234 | /(\s*
[^\r]+?<\/pre>)/gm,
1235 | function (wholeMatch, m1) {
1236 | var pre = m1;
1237 | // attacklab: hack around Konqueror 3.5.4 bug:
1238 | pre = pre.replace(/^ /mg, "~0");
1239 | pre = pre.replace(/~0/g, "");
1240 | return pre;
1241 | });
1242 |
1243 | return hashBlock("
\n" + bq + "\n
");
1244 | }
1245 | );
1246 | return text;
1247 | }
1248 |
1249 | function _FormParagraphs(text, doNotUnhash) {
1250 | //
1251 | // Params:
1252 | // $text - string to process with html