diff --git a/doc/issues/0004tn7.rst b/doc/issues/0004tn7.rst
deleted file mode 100644
index 0c31c02..0000000
--- a/doc/issues/0004tn7.rst
+++ /dev/null
@@ -1,16 +0,0 @@
-Fix delimited doc block behavior.
-=================================
-
-Delimited doc blocks require that the start token be the first non-space token
-on the line it is on and that the end token be on it's own line. This is not in
-line with the general nature of delimited comment blocks, which do not place
-any restrictions on what comes before the start delimiter or after the end
-delimiter.
-
-
-----
-
-========= ===================
-Created : 2011-09-07
-Resolved: 2011-12-25T23:26:07
-========= ===================
diff --git a/doc/issues/0004ts7.rst b/doc/issues/0004ts7.rst
index b227c37..0c31c02 100644
--- a/doc/issues/0004ts7.rst
+++ b/doc/issues/0004ts7.rst
@@ -7,9 +7,10 @@ line with the general nature of delimited comment blocks, which do not place
any restrictions on what comes before the start delimiter or after the end
delimiter.
+
----
-========= ==========
-Created: 2011-09-07
-Resolved: YYYY-MM-DD
-========= ==========
+========= ===================
+Created : 2011-09-07
+Resolved: 2011-12-25T23:26:07
+========= ===================
diff --git a/doc/issues/0008fn5.rst b/doc/issues/0008fv5.rst
similarity index 100%
rename from doc/issues/0008fn5.rst
rename to doc/issues/0008fv5.rst
diff --git a/doc/issues/0010fs5.rst b/doc/issues/0010fs5.rst
new file mode 100644
index 0000000..9fd4a1a
--- /dev/null
+++ b/doc/issues/0010fs5.rst
@@ -0,0 +1,18 @@
+Modify `org` behavior to include simple anchors.
+================================================
+
+Currently JLP supports at most one `org` directive per block which identifies the block.
+It would be useful to support multiple `org` directives within a block, particularly
+when there is a large block that may have many interesting internal targets. Maybe the
+`org` directive should be handled differently when it is used multiple times within a
+block. This would be discovered in the generator parse phase and we could change the
+LinkAnchor type at that time. During the parse phase we emit the new type of anchors
+as `` into the document. We would also change our search for block
+ids to inly look for the single-occurance type of `orgs`.
+
+----
+
+========= ===================
+Created : 2012-01-05T11:40:35
+Resolved: 2012-01-06T14:32:46
+========= ===================
diff --git a/project.properties b/project.properties
index 329670f..763b9d8 100644
--- a/project.properties
+++ b/project.properties
@@ -1,7 +1,7 @@
-#Wed, 04 Jan 2012 18:05:01 -0600
+#Fri, 06 Jan 2012 12:20:57 -0600
name=jlp
-version=1.4
-build.number=11
+version=1.5
+build.number=6
lib.local=true
release.dir=release
main.class=com.jdblabs.jlp.JLPMain
diff --git a/resources/main/css/jlp.css b/resources/main/css/jlp.css
index 354451b..3ecb1f2 100644
--- a/resources/main/css/jlp.css
+++ b/resources/main/css/jlp.css
@@ -15,6 +15,12 @@ h1, h2, h3, h4, h5, h6 { margin: 0 0 15px 0; }
h1 { margin-top: 40px; }
+hr {
+ background-color: black;
+ color: black;
+ border: none;
+ height: 1px; }
+
dt { font-weight: bold; }
ul {
@@ -36,17 +42,17 @@ td.docs, th.docs {
vertical-align: top;
text-align: left; }
-.docs pre {
- background: #f8f8ff;
- border: 1px solid #dedede;
- margin: 15px 0 15px;
- padding-left: 15px; }
-
-.docs tt, .docs code {
+.docs tt, .docs code, .docs pre {
background: #f8f8ff;
border: 1px solid #dedede;
padding: 0 0.2em; }
+.docs pre {
+ margin: 15px 0 15px;
+ padding-left: 15px; }
+
+.docs pre > code { border: none; }
+
.docs table {
border: thin solid #dedede;
margin-left: 60px; }
diff --git a/src/main/com/jdblabs/jlp/JLPMain.groovy b/src/main/com/jdblabs/jlp/JLPMain.groovy
index b0a8f0a..285b496 100644
--- a/src/main/com/jdblabs/jlp/JLPMain.groovy
+++ b/src/main/com/jdblabs/jlp/JLPMain.groovy
@@ -18,7 +18,7 @@ import org.slf4j.LoggerFactory
*/
public class JLPMain {
- public static final String VERSION = "1.4"
+ public static final String VERSION = "1.5"
private static Logger log = LoggerFactory.getLogger(JLPMain.class)
diff --git a/src/main/com/jdblabs/jlp/LinkAnchor.groovy b/src/main/com/jdblabs/jlp/LinkAnchor.groovy
index 1fe59b0..bf111ae 100644
--- a/src/main/com/jdblabs/jlp/LinkAnchor.groovy
+++ b/src/main/com/jdblabs/jlp/LinkAnchor.groovy
@@ -20,12 +20,12 @@ import com.jdblabs.jlp.ast.ASTNode
*/
public class LinkAnchor {
- public enum LinkType { OrgLink, FileLink }
+ public enum LinkType { InlineLink, BlockLink, FileLink }
/// The anchor id. This comes from the text after the directive.
public String id
- public LinkType type
+ public LinkType type = LinkType.BlockLink
public ASTNode source
public String sourceDocId
diff --git a/src/main/com/jdblabs/jlp/LiterateMarkdownGenerator.groovy b/src/main/com/jdblabs/jlp/LiterateMarkdownGenerator.groovy
index e7ad382..e629884 100644
--- a/src/main/com/jdblabs/jlp/LiterateMarkdownGenerator.groovy
+++ b/src/main/com/jdblabs/jlp/LiterateMarkdownGenerator.groovy
@@ -5,6 +5,7 @@
package com.jdblabs.jlp
import com.jdblabs.jlp.ast.*
+import com.jdblabs.jlp.LinkAnchor.LinkType
import com.jdblabs.jlp.ast.Directive.DirectiveType
import org.pegdown.Extensions
@@ -38,6 +39,56 @@ public class LiterateMarkdownGenerator extends JLPBaseGenerator {
/** ### Parse phase implementation. ### */
// ===================================
+ /** Override the parse phase for [`SourceFile`] nodes. We are interested in
+ * detecting an `org` directive in the first DocBlock, or automatically
+ * creating one if it is not defined. The first `org` directive (found or
+ * created) will create a FileLink type LinkAnchor.
+ */
+
+ protected void parse(SourceFile sourceFile) {
+ /// First we look for an `org` directive in the first block.
+ def firstOrg = sourceFile.blocks[0].docBlock.directives.find {
+ it.type == DirectiveType.Org }
+
+ /// And we create one if there are none.
+ if (!firstOrg) {
+ def docBlock = sourceFile.blocks[0].docBlock
+ firstOrg = new Directive(processor.currentDocId, 'org', 0, docBlock)
+ docBlock.directives << firstOrg }
+
+ /// Now parse the file as usual.
+ super.parse(sourceFile)
+
+ /// And mark the first `org` as a FileLink
+ processor.linkAnchors[firstOrg.value].type = LinkType.FileLink}
+
+ /** Override the parse phase for [`DocBlock`] nodes. We are interested in
+ * detecting a block that has multilple `org` directives. When there are
+ * multiple org directives in one block we change the LinkAnchor type from
+ * block-level links to specific anchors in the text. This allows the
+ * author to create a link to exact points within the document.
+ *
+ * [`DocBlock`]: jlp://jlp.jdb-labs.com/ast/DocBlock
+ */
+ protected void parse(DocBlock docBlock) {
+ /// First parse the block as usual.
+ super.parse(docBlock)
+
+ /// Look for multiple `org` directives.
+ def orgDirectives = docBlock.directives.findAll {it.type == DirectiveType.Org }
+
+ /// If we have multiple `org` directives in one [`DocBlock`] then we
+ /// want to change the corresponding [`LinkAnchors`] to type
+ /// `AnchorType`.
+ ///
+ /// [`DocBlock`]: jlp://jlp.jdb-labs.com/ast/DocBlock
+ /// [`LinkAnchors`]: jlp://jlp.jdb-labs.com/LinkAnchor
+ if (orgDirectives.size() > 1) {
+ orgDirectives.each { directive ->
+ /// Get the LinkAnchor for this `org` link.
+ def linkAnchor = processor.linkAnchors[directive.value]
+ linkAnchor.type = LinkType.InlineLink }}}
+
/** Implement the parse phase for [`Directive`] nodes. We are interested
* specifically in saving the link anchor information from *org*
* directives.
@@ -139,10 +190,12 @@ public class LiterateMarkdownGenerator extends JLPBaseGenerator {
protected String emit(Block block) {
StringBuilder sb = new StringBuilder()
- /// Look for an `@org` directive in the `Block` (already found in the
- /// parse phase)..
- Directive orgDir = block.docBlock.directives.find {
- it.type == DirectiveType.Org }
+ /// Look for an `@org` directive in the `Block` that is marked as a
+ /// block link (we may have many `orgs` in a block that are not block
+ /// links).
+ Directive orgDir = block.docBlock.directives.find { directive ->
+ directive.type == DirectiveType.Org &&
+ processor.linkAnchors[directive.value]?.type == LinkType.BlockLink }
/// Create the `tr` that will hold the `Block`. If we found an `@org`
/// directive we will add the id here.
@@ -172,42 +225,15 @@ public class LiterateMarkdownGenerator extends JLPBaseGenerator {
/// Later we will need a string builder to hold our result.
StringBuilder sb
- /** Add all the directives. We are also assigning priorities here that
- * we will use along with the line numbers to sort the elements. Our
- * goal is to preserve the order of doc blocks and doc-block-like
- * elements (examples, api documentation, etc.) while pushing orgs
- * and potentially other directives to the top. We used to re-order
- * authorship and copyright tags but stopped: in literate-style docs
- * the author should have control over their placement and in api-style
- * docs we are chopping the whole block up anyways (and this is not
- * that code). Given that the only item being re-ordered is *orgs*,
- * which do not print anyways, it may be better to cut this out and
- * just emit the blocks in their original order, or sort by line number
- * only. */
- emitQueue = docBlock.directives.collect { directive ->
- def queueItem = [lineNumber: directive.lineNumber, value: directive]
- switch(directive.type) {
- case DirectiveType.Org: queueItem.priority = 0; break
- default: queueItem.priority = 50; break }
-
- return queueItem }
-
- /// Add all the doc text blocks.
- emitQueue.addAll(docBlock.docTexts.collect { docText ->
- [lineNumber: docText.lineNumber, priority: 50, value: docText] })
-
-
- /// Sort the emit queue by priority, then line number.
- emitQueue.sort(
- {i1, i2 -> i1.priority != i2.priority ?
- i1.priority - i2.priority :
- i1.lineNumber - i2.lineNumber} as Comparator)
+ /** We want to treat the whole block as one markdown chunk so we will
+ * concatenate the directives and texts and send the whole block at
+ * once to the markdown processor.
+ */
+ emitQueue = docBlock.directives + docBlock.docTexts
+ emitQueue.sort { it.lineNumber }
- /** Finally, we want to treat the whole block as one markdown chunk so
- * we will concatenate the values in the emit queue and then send the
- * whole block at once to the markdown processor. */
sb = new StringBuilder()
- emitQueue.each { queueItem -> sb.append(emit(queueItem.value)) }
+ emitQueue.each { queueItem -> sb.append(emit(queueItem)) }
return processMarkdown(sb.toString())
}
@@ -244,7 +270,6 @@ public class LiterateMarkdownGenerator extends JLPBaseGenerator {
processMarkdown(directive.value) + "\n"
/// `@author` directive is turned into a definition list.
-
case DirectiveType.Author:
return "Author\n: ${directive.value}\n"
@@ -258,9 +283,15 @@ public class LiterateMarkdownGenerator extends JLPBaseGenerator {
// TODO:
// case DirectiveType.Include:
- /// An `@org` directive is ignored here. We already emitted the id
- /// when we started the block.
- case DirectiveType.Org: return "" } }
+ /// An `@org` directive may be emitted if the [`LinkAnchor`] is an
+ /// `InlineLink` type.
+ ///
+ /// [`LinkAnchor`]: jlp://jlp.jdb-labs.com/LinkAnchor
+ case DirectiveType.Org:
+ def link = processor.linkAnchors[directive.value]
+ if (link.type == LinkType.InlineLink) {
+ return "\n" }
+ else { return "" }}}
/** This is a helper method to process a block of text as Markdown. We need
* to do some additional processing to deal with `jlp://` org links that
diff --git a/src/main/com/jdblabs/jlp/Processor.groovy b/src/main/com/jdblabs/jlp/Processor.groovy
index 86051d8..d47194c 100644
--- a/src/main/com/jdblabs/jlp/Processor.groovy
+++ b/src/main/com/jdblabs/jlp/Processor.groovy
@@ -4,6 +4,7 @@
*/
package com.jdblabs.jlp
+import com.jdblabs.jlp.LinkAnchor.LinkType
import com.jdbernard.util.JarUtils
import java.util.jar.JarInputStream
import org.parboiled.BaseParser
@@ -213,11 +214,15 @@ public class Processor {
if (!linkAnchor) {
// We do not have any reference to this id.
- /* TODO: log error */
+ log.warn("Unable to resolve a jlp link: {}.", link)
return "broken_link(${linkId})" }
+ /// If this is a `FileLink` then we do not need the actual
+ /// linkId, just the file being linked to.
+ if (linkAnchor.type == LinkType.FileLink) { linkId = "" }
+
/// This link points to a location in this document.
- else if (targetDoc.sourceDocId == linkAnchor.sourceDocId) {
+ if (targetDoc.sourceDocId == linkAnchor.sourceDocId) {
return "#${linkId}" }
/// The link should point to a different document.