diff --git a/mustache_lint/mustache_lint.php b/mustache_lint/mustache_lint.php
index 3e324b65..0984f2af 100644
--- a/mustache_lint/mustache_lint.php
+++ b/mustache_lint/mustache_lint.php
@@ -233,11 +233,39 @@ function print_message($severity, $mesage) {
echo "$FILENAME - $severity: $mesage\n";
}
+/**
+ * If the template content has a top‐level tag that needs a container,
+ * wrap it in the appropriate parent before validation.
+ *
+ * @param string $content Raw HTML snippet from Mustache render.
+ * @return string The potentially wrapped snippet.
+ */
+function wrap_disallowed_root_elements($content) {
+ // Map of tag → [open wrapper, close wrapper].
+ $wrappers = [
+ 'li' => ['
'],
+ 'tr' => [''],
+ 'td' => [''],
+ ];
+
+ $trimmed = ltrim($content);
+ foreach ($wrappers as $tag => list($open, $close)) {
+ // If the very first tag is this one, wrap it.
+ if (stripos($trimmed, "<{$tag}") === 0) {
+ return $open . "\n" . $content . "\n" . $close;
+ }
+ }
+
+ return $content;
+}
+
/**
* Wrap the template content in a html5 wrapper and validate it
*/
function check_html_validation($content) {
if (strpos($content, '') === false) {
+ // Wrap lone , , etc., into valid wrappers.
+ $content = wrap_disallowed_root_elements($content);
// Primative detection if we have full html body, if not, wrap it.
// (This isn't bulletproof, obviously).
$wrappedcontent = "Validate\n{$content}\n";