Code Monkey home page Code Monkey logo

Comments (12)

fmoralesc avatar fmoralesc commented on June 1, 2024

I suppose we can leverage the foldlevel() function for this (check what is the folding level of the previous line). Let me figure out the logic to do so ;)

from vim-pandoc.

fmoralesc avatar fmoralesc commented on June 1, 2024

I was thinking of using foldlevel() this way: if foldlevel("."-1) - foldlevel(".") > 1 (there is a gap between the new foldlevel and the old one), set final foldlevel to natural foldlevel - (foldlevel("."-1) - foldlevel("."), and raise as before otherwise.

I've found a problem. If we have

 beggining-of-file
 ---
 ## header a 

foldlevel("."-1) at header a would be 0, so we could want to set the header line foldlevel to 1 instead of 2. However, we can't use that logic everywhere, because then

## header with foldlevel 1

text

## header b

header b's foldlevel would be 2 instead of 1, because the previous foldlevel (1) would not have a gap. This is not what we would want.

We could maybe work around this issue by having a buffer local variable that determines the top header level in the file, but then we could not mix headers like this:

## header a
## header b
# header c
## header d

Any ideas?

from vim-pandoc.

blaenk avatar blaenk commented on June 1, 2024

Yeah this is a tough one. I've encountered this very issue in two different ways when I generate a table of contents for my static generated site (with Hakyll). What I used to do (but no longer) was determine the lowest header level (i.e. #, not ##) and then normalize every other header level based on that. So if I only used ## in the document along with other header levels like ### and ####, they would act as #, ##, and ### in the generated table of contents.

Naturally, if the situation like yours presented itself:

## header a
## header b
# header c
## header d

Then it would see that # is there and "normalize" all of the others based on it, so nothing would change. I don't remember how the table of contents ended up in that case, since I specifically avoided it.

I also do similar trickery to get pure-CSS, nested header section numbering that accounts for this situation (though I think not exhaustively; the above scenario would fail). It's nasty, but I don't know if there's a better way. Basically I do something like this for h3 headers (and similar for every header level, unfortunately):

h1 ~ h2 ~ h3 .header-link:before { /* show it as e.g. 1.2.3 */ }
h2 ~ h3 .header-link:before { /* show it as e.g. 1.2 */ }
h3 .header-link:before { /* show it as e.g. 1 (i.e. h3 headers are top level) */ }

Basically this accounts for every gradual case. So you can have ### headers be "top-level" in the document and they will be numbered correctly as say 1, 2, etc. because the simple h3 rule would apply, and if you have #### later on, another rule something like h3 ~ h4 {} would apply because in that situation you have an h3 followed by an h4, so it would appropriately number that section as 1.2

I'm not quite sure which of these, if any, apply to this problem. One thing that is common in all of them though is that they are not fool-proof and it's up to the author to not enter ridiculous situations. Perhaps we can have an option to disable this "smarter" folding behavior, in case someone is backwards enough to use the problem scenario you mention ;) Opt-in or Opt-out, I don't feel strongly either way. It'd be nice enough if the option is there I suppose!

from vim-pandoc.

blaenk avatar blaenk commented on June 1, 2024

Just tried out the problem scenario on my site. So this scenario:

## header a
## header b
# header c
## header d

Ends up as:

1. header a
2. header b
3. header c
  3.1. header d

So the table of contents comes out fine, in my opinion that structuring kind of makes sense, I mean, if you can make sense from such a weird structure to begin with, this result seems reasonable. The table of contents CSS section numbering is also correct. The bare header section numbering I described in the previous post, however, breaks. It ends up something like this:

1. header a
2. header b
1. header c
  1.1. header d

The code that's responsible for this structuring follows. It basically groups every header with the previous one if the previous one is smaller (i.e. h1 is "smaller" than h2). So this naturally makes header a its own group and header b as well because the previous header, header a (level 2), is not smaller than header b (level 2).

When it gets to header c it also makes it its own group because header b (level 2) is not smaller than header c (level 1). Then it gets to header d (level 2) and it notices that header c (level 1) is smaller than itself (header d), so it branches header d under header c. The resulting structure is a forest, i.e. a list of trees. So every top level header is the root of a tree, which explains the resulting structure.

groupByHierarchy :: [Block] -> Forest Block
groupByHierarchy = map (\(x:xs) -> Node x (groupByHierarchy xs)) . groupBy ((<) `on` headerLevel)

I hadn't tried this scenario before but I have to say that it proved to be resilient. Like I said earlier, I think this resulting structuring makes sense, it seems to "naturally follow" from the weird input structure.

from vim-pandoc.

fmoralesc avatar fmoralesc commented on June 1, 2024

Indeed,that is what we would want in this case. (My first approach was similar to this, actually. )The problem now is how to implement it in the foldexpr function.

As an aside: a piece of me resists trying to solve this corner case, because it is sort of mixing the presentation and semantic layers. If someone had the

 ## a
 ## b
 # c
 ## d

structure, the a and b headers would be treated as different "styles" of top level headers, and "##" would literally mean something different there and in d.

from vim-pandoc.

blaenk avatar blaenk commented on June 1, 2024

Yeah, that's what I thought when I wrote my site's stuff as well. I think it'd be reasonable to not care about this corner case and perhaps add an option to disable it (and instead use the simpler forldexpr we use now) if it really bothers someone, or something.

from vim-pandoc.

fmoralesc avatar fmoralesc commented on June 1, 2024

As an update to this: I tried to implement this, but ended up messing things up in my local feature branch, so I'll have to start over. :( I don't have much time available atm, so this might get delayed unless someone tries to do it him/her-self.

from vim-pandoc.

blaenk avatar blaenk commented on June 1, 2024

No rush! It's hardly a priority. I'll probably give it a shot when I get a
chance. I do have experience with this very thing, just not in ways
expressible through vim.

On Thursday, February 20, 2014, Felipe Morales [email protected]
wrote:

As an update to this: I tried to implement this, but ended up messing
things up in my local feature branch, so I'll have to start over. :( I
don't have much time available atm, so this might get delayed unless
someone tries to do it him/her-self.


Reply to this email directly or view it on GitHubhttps://github.com//issues/9#issuecomment-35692631
.

  • Jorge Israel Peña

from vim-pandoc.

fmoralesc avatar fmoralesc commented on June 1, 2024

I just figured out a way to implement this.

I've recently created some functions that can help navigate headers for the keyboard module. One of those goes to the current header's parent header. Using this we can implement a function to search for the "ancestral" header (the top level header in a branch). Now:

  • If the current header is the ancestral header, we set the fold level to 1.
  • For every other case, assuming there are no gaps between the levels, we calculate the difference between the current level and the ancestral header, and adjust the foldlevel accordingly.

So for

## test a
## test b
### test c
# test d
## test e

a), b) and d) are ancestrals, and their fold level is 1. e) is level 2 because its ancestral is syntactically level 1, and e) is syntactically level 2. c) is level 2 because its ancestral is syntactically level 2, and c) is syntactically level 3.

If we wanted to allow gaps, we would need to retrieve the syntactic levels of every parent till the ancestral header. So in

## test a
#### test b
##### test c
### test d
#### test e

a) would be the ancestral for b), c), d) and e). From c) to a) syntactic levels are [2, 4, 5], but final fold levels should be [1, 2, 3].

Actually, now that I think about it, fold level could be just the length of the list of headers till the ancestral...

from vim-pandoc.

blaenk avatar blaenk commented on June 1, 2024

Sounds good to me.

from vim-pandoc.

fmoralesc avatar fmoralesc commented on June 1, 2024

Just pushed the needed changes. Enjoy!

captura de pantalla de 2014-05-31 15 18 47

from vim-pandoc.

blaenk avatar blaenk commented on June 1, 2024

Was late to see this, but it seems to be working gloriously. Very nice job!

from vim-pandoc.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.