From 7e1eee7ff78262083c2e82b4f658c19b45604b84 Mon Sep 17 00:00:00 2001 From: Ben Bader Date: Sat, 15 Feb 2014 13:32:18 -0800 Subject: [PATCH 1/2] Adding directives to selectively disable comment parsing. This change adds so-called 'directives' to our comments. A directive is a comment line whose only contents are a hash, followed by the directive name, e.g. ``` ;; #DirectiveName ``` Directives are not included in the `*comments*` vector in any case. The two directives implemented here are "#MargDisable" and "#MargEnable". The former, when encountered, causes comments read by `read-comment` to be ignored. The latter re-enables it. The rationale for this change is to accommodate e.g. license-header boilerplate without polluting the generated docs. --- src/marginalia/parser.clj | 45 +++++++++++++++++++++++++++++++++------ 1 file changed, 39 insertions(+), 6 deletions(-) diff --git a/src/marginalia/parser.clj b/src/marginalia/parser.clj index 730ff3c..21c1e97 100644 --- a/src/marginalia/parser.clj +++ b/src/marginalia/parser.clj @@ -42,6 +42,36 @@ (def sub-level-comments (atom [])) (def ^{:dynamic true} *comments* nil) +(def ^{:dynamic true} *comments-enabled* nil) + +(defn comments-enabled? + [] + @*comments-enabled*) + +(def directives + "Marginalia can be given directives in comments. A directive is a comment + line containing a directive name, in the form `;; #DirectiveName`. + Directives change the behavior of the parser within the files that contain + them. + + The following directives are defined: + + * `#MargDisable` suppresses subsequent comments from the docs + * `#MargEnable` includes subsequent comments in the docs" + {"MargDisable" (fn [] (swap! *comments-enabled* (constantly false))) + "MargEnable" (fn [] (swap! *comments-enabled* (constantly true)))}) + +(defn process-directive! + "If the given line is a directive, applies it. Returns a value + indicating whether the line should be included in the comments + list." + [line] + (let [directive (->> (re-find #"^;+\s*#(\w+)" line) + (last) + (get directives))] + (when directive + (directive)) + (not directive))) (defn read-comment [reader semicolon] (let [sb (StringBuilder.)] @@ -50,11 +80,13 @@ (let [ch (char c)] (if (or (= ch \newline) (= ch \return)) - (let [line (dec (.getLineNumber reader))] - (swap! *comments* conj - {:form (Comment. (.toString sb)) - :start line - :end line}) + (let [line (dec (.getLineNumber reader)) + text (.toString sb) + include? (process-directive! text)] + (when (and include? (comments-enabled?)) + (swap! *comments* conj {:form (Comment. text) + :start line + :end line})) reader) (do (.append sb (Character/toString ch)) @@ -363,5 +395,6 @@ (let [readers (if (cljs-file? file) (->> default-data-readers (merge *cljs-data-readers*)) default-data-readers)] - (binding [*data-readers* readers] + (binding [*data-readers* readers + *comments-enabled* (atom true)] (parse (slurp file))))) From 28eff57a6941488a6c4e291f4a3af9f59b1493e5 Mon Sep 17 00:00:00 2001 From: Ben Bader Date: Sun, 16 Feb 2014 15:57:54 -0800 Subject: [PATCH 2/2] Replacing "#" with "@" as the directive-start character. In the excitement of getting something working and polished, I overlooked the fact that "#" is indeed part of Markdown syntax, and that there is little to distinguish `;; #Directive` from `;; # Title`. "@" is visually distinctive, and is not currently part of Markdown. --- src/marginalia/parser.clj | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/marginalia/parser.clj b/src/marginalia/parser.clj index 21c1e97..709d5ae 100644 --- a/src/marginalia/parser.clj +++ b/src/marginalia/parser.clj @@ -50,14 +50,14 @@ (def directives "Marginalia can be given directives in comments. A directive is a comment - line containing a directive name, in the form `;; #DirectiveName`. + line containing a directive name, in the form `;; @DirectiveName`. Directives change the behavior of the parser within the files that contain them. The following directives are defined: - * `#MargDisable` suppresses subsequent comments from the docs - * `#MargEnable` includes subsequent comments in the docs" + * `@MargDisable` suppresses subsequent comments from the docs + * `@MargEnable` includes subsequent comments in the docs" {"MargDisable" (fn [] (swap! *comments-enabled* (constantly false))) "MargEnable" (fn [] (swap! *comments-enabled* (constantly true)))}) @@ -66,7 +66,7 @@ indicating whether the line should be included in the comments list." [line] - (let [directive (->> (re-find #"^;+\s*#(\w+)" line) + (let [directive (->> (re-find #"^;+\s*@(\w+)" line) (last) (get directives))] (when directive