Skip to content

Commit

Permalink
Adds scopelines (issue #38) (#39)
Browse files Browse the repository at this point in the history
Added `scopeLines`

Added an optional parameter named `scopeLines` that renders vertical lines showing block scope.

Co-authored-by: Saswat Padhi <saswatpadhi@protonmail.com>
  • Loading branch information
marcosroriz and SaswatPadhi authored May 27, 2023
1 parent 1c53f91 commit 95c57df
Show file tree
Hide file tree
Showing 9 changed files with 255 additions and 9 deletions.
56 changes: 55 additions & 1 deletion docs/katex-samples.html
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,49 @@
\end{algorithmic}
\end{algorithm}
</pre>
<script>
<pre id="scopeline-euclid" style="display:none">
\begin{algorithm}
\caption{Classical Euclidean Algorithm}
\begin{algorithmic}
\PROCEDURE{Euclid}{$a,b$}
\WHILE{$a \neq b$}
\IF{$a > b$}
\STATE $a \gets a - b$
\ELSE
\STATE $b \gets b - a$
\ENDIF
\ENDWHILE
\STATE return $a$
\ENDPROCEDURE
\end{algorithmic}
\end{algorithm}
</pre>
<pre id="scopeline-dbscan" style="display:none">
\begin{algorithm}
\caption{DBSCAN}
\begin{algorithmic}
\INPUT A dataset $D$, the $\varepsilon$ distance threshold, and the minimum number of points $minPts$
\OUTPUT A set of clusters $K$
\PROCEDURE{DBSCAN}{$D, \varepsilon, minPts$}
\STATE $K \gets \emptyset$
\FORALL{$p \in D$}
\IF{$p$ has not been visited}
\STATE mark $p$ as visited
\STATE $N_{\varepsilon}(p) \gets $ \textsc{RangeQuery}$(p, \varepsilon, D)$
\IF{$N_{\varepsilon}(p) < minPts$}
\STATE mark $p$ as noise
\ELSE
\COMMENT{p is a core object}
\STATE $C \gets $ \textsc{ExpandCluster}$(p, N_{\varepsilon}(p))$
\STATE $K \gets K \cup \{C\}$
\ENDIF
\ENDIF
\ENDFOR
\STATE return $K$
\ENDPROCEDURE
\end{algorithmic}
\end{algorithm}
</pre> <script>
pseudocode.renderElement(document.getElementById("test-basics"),
{
lineNumber: false,
Expand All @@ -218,6 +260,18 @@
noEnd: false,
titlePrefix: "My pretty Algorithm"
});
pseudocode.renderElement(document.getElementById("scopeline-euclid"),
{
lineNumber: false,
noEnd: true,
scopeLines: true
});
pseudocode.renderElement(document.getElementById("scopeline-dbscan"),
{
lineNumber: true,
noEnd: false,
scopeLines: true
});
</script>
</body>
</html>
56 changes: 55 additions & 1 deletion docs/mathjax-v2-samples.html
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,49 @@
\end{algorithmic}
\end{algorithm}
</pre>
<script>
<pre id="scopeline-euclid" style="display:none">
\begin{algorithm}
\caption{Classical Euclidean Algorithm}
\begin{algorithmic}
\PROCEDURE{Euclid}{$a,b$}
\WHILE{$a \neq b$}
\IF{$a > b$}
\STATE $a \gets a - b$
\ELSE
\STATE $b \gets b - a$
\ENDIF
\ENDWHILE
\STATE return $a$
\ENDPROCEDURE
\end{algorithmic}
\end{algorithm}
</pre>
<pre id="scopeline-dbscan" style="display:none">
\begin{algorithm}
\caption{DBSCAN}
\begin{algorithmic}
\INPUT A dataset $D$, the $\varepsilon$ distance threshold, and the minimum number of points $minPts$
\OUTPUT A set of clusters $K$
\PROCEDURE{DBSCAN}{$D, \varepsilon, minPts$}
\STATE $K \gets \emptyset$
\FORALL{$p \in D$}
\IF{$p$ has not been visited}
\STATE mark $p$ as visited
\STATE $N_{\varepsilon}(p) \gets $ \textsc{RangeQuery}$(p, \varepsilon, D)$
\IF{$N_{\varepsilon}(p) < minPts$}
\STATE mark $p$ as noise
\ELSE
\COMMENT{p is a core object}
\STATE $C \gets $ \textsc{ExpandCluster}$(p, N_{\varepsilon}(p))$
\STATE $K \gets K \cup \{C\}$
\ENDIF
\ENDIF
\ENDFOR
\STATE return $K$
\ENDPROCEDURE
\end{algorithmic}
\end{algorithm}
</pre> <script>
pseudocode.renderElement(document.getElementById("test-basics"),
{
lineNumber: false,
Expand All @@ -228,6 +270,18 @@
noEnd: false,
titlePrefix: "My pretty Algorithm"
});
pseudocode.renderElement(document.getElementById("scopeline-euclid"),
{
lineNumber: false,
noEnd: true,
scopeLines: true
});
pseudocode.renderElement(document.getElementById("scopeline-dbscan"),
{
lineNumber: true,
noEnd: false,
scopeLines: true
});
</script>
</body>
</html>
56 changes: 55 additions & 1 deletion docs/mathjax-v3-samples.html
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,49 @@
\end{algorithmic}
\end{algorithm}
</pre>
<script>
<pre id="scopeline-euclid" style="display:none">
\begin{algorithm}
\caption{Classical Euclidean Algorithm}
\begin{algorithmic}
\PROCEDURE{Euclid}{$a,b$}
\WHILE{$a \neq b$}
\IF{$a > b$}
\STATE $a \gets a - b$
\ELSE
\STATE $b \gets b - a$
\ENDIF
\ENDWHILE
\STATE return $a$
\ENDPROCEDURE
\end{algorithmic}
\end{algorithm}
</pre>
<pre id="scopeline-dbscan" style="display:none">
\begin{algorithm}
\caption{DBSCAN}
\begin{algorithmic}
\INPUT A dataset $D$, the $\varepsilon$ distance threshold, and the minimum number of points $minPts$
\OUTPUT A set of clusters $K$
\PROCEDURE{DBSCAN}{$D, \varepsilon, minPts$}
\STATE $K \gets \emptyset$
\FORALL{$p \in D$}
\IF{$p$ has not been visited}
\STATE mark $p$ as visited
\STATE $N_{\varepsilon}(p) \gets $ \textsc{RangeQuery}$(p, \varepsilon, D)$
\IF{$N_{\varepsilon}(p) < minPts$}
\STATE mark $p$ as noise
\ELSE
\COMMENT{p is a core object}
\STATE $C \gets $ \textsc{ExpandCluster}$(p, N_{\varepsilon}(p))$
\STATE $K \gets K \cup \{C\}$
\ENDIF
\ENDIF
\ENDFOR
\STATE return $K$
\ENDPROCEDURE
\end{algorithmic}
\end{algorithm}
</pre> <script>
pseudocode.renderElement(document.getElementById("test-basics"),
{
lineNumber: false,
Expand All @@ -228,6 +270,18 @@
noEnd: false,
titlePrefix: "My pretty Algorithm"
});
pseudocode.renderElement(document.getElementById("scopeline-euclid"),
{
lineNumber: false,
noEnd: true,
scopeLines: true
});
pseudocode.renderElement(document.getElementById("scopeline-dbscan"),
{
lineNumber: true,
noEnd: false,
scopeLines: true
});
</script>
</body>
</html>
2 changes: 1 addition & 1 deletion docs/pseudocode.css

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion docs/pseudocode.js

Large diffs are not rendered by default.

23 changes: 20 additions & 3 deletions src/Renderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -425,6 +425,7 @@ function RendererOptions(options) {
this.lineNumberPunc = options.lineNumberPunc !== undefined ? options.lineNumberPunc : ':';
this.lineNumber = options.lineNumber !== undefined ? options.lineNumber : false;
this.noEnd = options.noEnd !== undefined ? options.noEnd : false;
this.scopeLines = options.scopeLines !== undefined ? options.scopeLines : false;
if (options.captionCount !== undefined)
Renderer.captionCount = options.captionCount;
this.titlePrefix = options.titlePrefix !== undefined ? options.titlePrefix : 'Algorithm';
Expand Down Expand Up @@ -512,6 +513,11 @@ Renderer.prototype._beginBlock = function() {
this._options.lineNumber && this._blockLevel === 0 ? 0.6 : 0;
var blockIndent = this._options.indentSize + extraIndentForFirstBlock;

// We also need to handle the extra margin for scope lines
// We divide the block indent by 2 because the other margin will be after the indent symbol
if (this._options.scopeLines)
blockIndent /= 2;

this._beginGroup('block', null, {
'margin-left': blockIndent + 'em',
});
Expand All @@ -538,10 +544,17 @@ Renderer.prototype._newLine = function() {
this._numLOC++;

this._html.beginP('ps-line ps-code', this._globalTextStyle.toCSS());

// We need to consider the indent width for linenumbers and scopelines
var extraIndentSize = this._options.lineNumber ? indentSize * 1.25 : 0;
extraIndentSize += this._options.scopeLines ? indentSize * 0.1 : 0;

// We add this width if we need to pad the line (e.g., with linenumber).
// We don't need to handle scope lines here, as they do not add any extra text in the line.
if (this._options.lineNumber) {
this._html
.beginSpan('ps-linenum', {
'left': -((this._blockLevel - 1) * (indentSize * 1.25)) + 'em',
'left': -((this._blockLevel - 1) * (extraIndentSize)) + 'em',
})
.putText(this._numLOC + this._options.lineNumberPunc)
.endSpan();
Expand Down Expand Up @@ -628,8 +641,12 @@ Renderer.prototype._buildTree = function(node) {
this._endGroup();
break;
case 'algorithmic':
if (this._options.lineNumber) {
this._beginGroup('algorithmic', 'with-linenum');
// Check if we need to add additional classes for the provided options
var divClasses = this._options.lineNumber ? ' with-linenum ' : '';
divClasses += this._options.scopeLines ? ' with-scopelines ' : '';

if (divClasses) {
this._beginGroup('algorithmic', divClasses);
this._numLOC = 0;
}
else {
Expand Down
43 changes: 43 additions & 0 deletions static/body.html.part
Original file line number Diff line number Diff line change
Expand Up @@ -181,3 +181,46 @@
\end{algorithmic}
\end{algorithm}
</pre>
<pre id="scopeline-euclid" style="display:none">
\begin{algorithm}
\caption{Classical Euclidean Algorithm}
\begin{algorithmic}
\PROCEDURE{Euclid}{$a,b$}
\WHILE{$a \neq b$}
\IF{$a > b$}
\STATE $a \gets a - b$
\ELSE
\STATE $b \gets b - a$
\ENDIF
\ENDWHILE
\STATE return $a$
\ENDPROCEDURE
\end{algorithmic}
\end{algorithm}
</pre>
<pre id="scopeline-dbscan" style="display:none">
\begin{algorithm}
\caption{DBSCAN}
\begin{algorithmic}
\INPUT A dataset $D$, the $\varepsilon$ distance threshold, and the minimum number of points $minPts$
\OUTPUT A set of clusters $K$
\PROCEDURE{DBSCAN}{$D, \varepsilon, minPts$}
\STATE $K \gets \emptyset$
\FORALL{$p \in D$}
\IF{$p$ has not been visited}
\STATE mark $p$ as visited
\STATE $N_{\varepsilon}(p) \gets $ \textsc{RangeQuery}$(p, \varepsilon, D)$
\IF{$N_{\varepsilon}(p) < minPts$}
\STATE mark $p$ as noise
\ELSE
\COMMENT{p is a core object}
\STATE $C \gets $ \textsc{ExpandCluster}$(p, N_{\varepsilon}(p))$
\STATE $K \gets K \cup \{C\}$
\ENDIF
\ENDIF
\ENDFOR
\STATE return $K$
\ENDPROCEDURE
\end{algorithmic}
\end{algorithm}
</pre>
12 changes: 12 additions & 0 deletions static/footer.html.part
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,18 @@
noEnd: false,
titlePrefix: "My pretty Algorithm"
});
pseudocode.renderElement(document.getElementById("scopeline-euclid"),
{
lineNumber: false,
noEnd: true,
scopeLines: true
});
pseudocode.renderElement(document.getElementById("scopeline-dbscan"),
{
lineNumber: true,
noEnd: false,
scopeLines: true
});
</script>
</body>
</html>
14 changes: 13 additions & 1 deletion static/pseudocode.css
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
font-style: normal;
text-transform: none;
}

/* line number support */
.ps-root .ps-linenum {
font-size: 0.8em;
Expand All @@ -63,6 +64,17 @@
.ps-root .ps-algorithmic.with-linenum .ps-line.ps-code {
text-indent: -1.6em;
}
.ps-root .ps-algorithmic.with-linenum .ps-line.ps-code > span{
.ps-root .ps-algorithmic.with-linenum .ps-line.ps-code > span {
text-indent: 0em;
}

/* scope lines support */
.ps-root .ps-algorithmic.with-scopelines div.ps-block {
border-left-style: solid;
border-left-width: 0.1em;
padding-left: 0.6em;
}

.ps-root .ps-algorithmic.with-scopelines > div.ps-block {
border-left: none;
}

0 comments on commit 95c57df

Please sign in to comment.