@@ -44,6 +44,13 @@ var headingPrefixes = {
4444 bitbucket: '#markdown-header-'
4545}
4646
47+var lineLinks = {
48+ github: true,
49+ gitlab: true
50+}
51+
52+var lineExpression = /^#?l\d/i
53+
4754function validateLinks(options, fileSet) {
4855 var repo = (options || {}).repository
4956 var info
@@ -179,7 +186,11 @@ function transformerFactory(fileSet, info) {
179186 function mark(node) {
180187 var data = node.data || {}
181188 var props = data.hProperties || {}
182− var id = props.name || props.id || data.id || slugs.slug(toString(node))
189+ var id = props.name || props.id || data.id
190+
191+ if (!id && node.type === 'heading') {
192+ id = slugs.slug(toString(node))
193+ }
183194
184195 if (id) {
185196 landmarks[filePath + '#' + id] = true
@@ -251,6 +262,7 @@ function gatherReferences(file, tree, info, fileSet) {
251262 var getDefinition = definitions(tree)
252263 var prefix = ''
253264 var headingPrefix = '#'
265+ var lines
254266
255267 if (info && info.type in viewPaths) {
256268 prefix = '/' + info.path() + '/' + viewPaths[info.type] + '/'
@@ -260,6 +272,8 @@ function gatherReferences(file, tree, info, fileSet) {
260272 headingPrefix = headingPrefixes[info.type]
261273 }
262274
275+ lines = info && info.type in lineLinks ? lineLinks[info.type] : false
276+
263277 visit(tree, ['link', 'linkReference'], onlink)
264278
265279 return cache
@@ -291,6 +305,10 @@ function gatherReferences(file, tree, info, fileSet) {
291305 }
292306
293307 if (!uri.hostname) {
308+ if (lines && lineExpression.test(uri.hash)) {
309+ uri.hash = ''
310+ }
311+
294312 /* Handle hashes, or relative files. */
295313 if (!uri.pathname && uri.hash) {
296314 link = file.path + uri.hash
@@ -301,6 +319,7 @@ function gatherReferences(file, tree, info, fileSet) {
301319 if (uri.hash) {
302320 link += uri.hash
303321 }
322+
304323 uri = parse(link)
305324 }
306325 }
@@ -340,6 +359,10 @@ function gatherReferences(file, tree, info, fileSet) {
340359 } else {
341360 pathname = link.slice(0, index)
342361 hash = link.slice(index + headingPrefix.length)
362+
363+ if (lines && lineExpression.test(hash)) {
364+ hash = null
365+ }
343366 }
344367
345368 if (!cache[pathname]) {
@@ -360,7 +383,7 @@ function gatherReferences(file, tree, info, fileSet) {
360383 }
361384}
362385
363−/* Utilitity to warn `reason` for each node in `nodes` on `file`. */
386+/* Utility to warn `reason` for each node in `nodes` on `file`. */
364387function warnAll(file, nodes, reason, ruleId) {
365388 nodes.forEach(one)
366389