List for cgit developers and users
 help / color / mirror / Atom feed
* Rendering of README.md inline with inner tree view dirs
@ 2018-06-11  7:08 andy
  2018-06-11  7:31 ` list
  0 siblings, 1 reply; 140+ messages in thread
From: andy @ 2018-06-11  7:08 UTC (permalink / raw)


Hi -

I have been using cgit for many years.

Currently I am detaching my (LGPL) project from github.

One noticeable problem diverting people from github to cgit is although 
it renders very well the toplevel "about" README.md

https://libwebsockets.org/git/libwebsockets/about/

It doesn't seem to have a way to render inline inner dir README.md as 
github does.  This is quite a small thing but very useful, eg

https://github.com/warmcat/libwebsockets/tree/master/minimal-examples

vs

https://libwebsockets.org/git/libwebsockets/tree/minimal-examples

Is there a way to do it already in the main cgit project?  For nonpublic 
projects, I screenscraped some patches from John Keeping from 2016 that 
do the same thing, but poking around, these don't seem to have made it in.

If there's no existing way to do it and those patches are shivering in 
the cold, all alone, can I suggest they would perhaps be extremely 
useful to people in a similar position, needing to decouple users from 
github but needing to generally present the same tree in a similar way?

-Andy


^ permalink raw reply	[flat|nested] 140+ messages in thread

* Rendering of README.md inline with inner tree view dirs
  2018-06-11  7:08 Rendering of README.md inline with inner tree view dirs andy
@ 2018-06-11  7:31 ` list
  2018-06-11  7:38   ` andy
  0 siblings, 1 reply; 140+ messages in thread
From: list @ 2018-06-11  7:31 UTC (permalink / raw)


Andy Green <andy at warmcat.com> on Mon, 2018/06/11 15:08:
> Hi -
> 
> I have been using cgit for many years.
> 
> Currently I am detaching my (LGPL) project from github.
> 
> One noticeable problem diverting people from github to cgit is although 
> it renders very well the toplevel "about" README.md
> 
> https://libwebsockets.org/git/libwebsockets/about/
> 
> It doesn't seem to have a way to render inline inner dir README.md as 
> github does.  This is quite a small thing but very useful, eg
> 
> https://github.com/warmcat/libwebsockets/tree/master/minimal-examples
> 
> vs
> 
> https://libwebsockets.org/git/libwebsockets/tree/minimal-examples
> 
> Is there a way to do it already in the main cgit project?  For nonpublic 
> projects, I screenscraped some patches from John Keeping from 2016 that 
> do the same thing, but poking around, these don't seem to have made it in.
> 
> If there's no existing way to do it and those patches are shivering in 
> the cold, all alone, can I suggest they would perhaps be extremely 
> useful to people in a similar position, needing to decouple users from 
> github but needing to generally present the same tree in a similar way?

This is what you want?

https://libwebsockets.org/git/libwebsockets/about/minimal-examples/README.md

-- 
main(a){char*c=/*    Schoene Gruesse                         */"B?IJj;MEH"
"CX:;",b;for(a/*    Best regards             my address:    */=0;b=c[a++];)
putchar(b-1/(/*    Chris            cc -ox -xc - && ./x    */b/42*2-3)*42);}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 488 bytes
Desc: OpenPGP digital signature
URL: <http://lists.zx2c4.com/pipermail/cgit/attachments/20180611/2298ac3c/attachment.asc>


^ permalink raw reply	[flat|nested] 140+ messages in thread

* Rendering of README.md inline with inner tree view dirs
  2018-06-11  7:31 ` list
@ 2018-06-11  7:38   ` andy
  2018-06-11  7:53     ` list
  0 siblings, 1 reply; 140+ messages in thread
From: andy @ 2018-06-11  7:38 UTC (permalink / raw)




On 06/11/2018 03:31 PM, Christian Hesse wrote:
> Andy Green <andy at warmcat.com> on Mon, 2018/06/11 15:08:
>> Hi -
>>
>> I have been using cgit for many years.
>>
>> Currently I am detaching my (LGPL) project from github.
>>
>> One noticeable problem diverting people from github to cgit is although
>> it renders very well the toplevel "about" README.md
>>
>> https://libwebsockets.org/git/libwebsockets/about/
>>
>> It doesn't seem to have a way to render inline inner dir README.md as
>> github does.  This is quite a small thing but very useful, eg
>>
>> https://github.com/warmcat/libwebsockets/tree/master/minimal-examples
>>
>> vs
>>
>> https://libwebsockets.org/git/libwebsockets/tree/minimal-examples
>>
>> Is there a way to do it already in the main cgit project?  For nonpublic
>> projects, I screenscraped some patches from John Keeping from 2016 that
>> do the same thing, but poking around, these don't seem to have made it in.
>>
>> If there's no existing way to do it and those patches are shivering in
>> the cold, all alone, can I suggest they would perhaps be extremely
>> useful to people in a similar position, needing to decouple users from
>> github but needing to generally present the same tree in a similar way?
> 
> This is what you want?
> 
> https://libwebsockets.org/git/libwebsockets/about/minimal-examples/README.md

Yeah.

But inline after the tree view, a la github.

This enables a scheme where inner dirs give their own overview without 
interrupting navigation.  Eg, a couple of levels down...

https://github.com/warmcat/libwebsockets/tree/master/lib/roles

-Andy


^ permalink raw reply	[flat|nested] 140+ messages in thread

* Rendering of README.md inline with inner tree view dirs
  2018-06-11  7:38   ` andy
@ 2018-06-11  7:53     ` list
  2018-06-11  8:05       ` andy
  0 siblings, 1 reply; 140+ messages in thread
From: list @ 2018-06-11  7:53 UTC (permalink / raw)


Andy Green <andy at warmcat.com> on Mon, 2018/06/11 15:38:
> On 06/11/2018 03:31 PM, Christian Hesse wrote:
> > Andy Green <andy at warmcat.com> on Mon, 2018/06/11 15:08:  
> >> Hi -
> >>
> >> I have been using cgit for many years.
> >>
> >> Currently I am detaching my (LGPL) project from github.
> >>
> >> One noticeable problem diverting people from github to cgit is although
> >> it renders very well the toplevel "about" README.md
> >>
> >> https://libwebsockets.org/git/libwebsockets/about/
> >>
> >> It doesn't seem to have a way to render inline inner dir README.md as
> >> github does.  This is quite a small thing but very useful, eg
> >>
> >> https://github.com/warmcat/libwebsockets/tree/master/minimal-examples
> >>
> >> vs
> >>
> >> https://libwebsockets.org/git/libwebsockets/tree/minimal-examples
> >>
> >> Is there a way to do it already in the main cgit project?  For nonpublic
> >> projects, I screenscraped some patches from John Keeping from 2016 that
> >> do the same thing, but poking around, these don't seem to have made it
> >> in.
> >>
> >> If there's no existing way to do it and those patches are shivering in
> >> the cold, all alone, can I suggest they would perhaps be extremely
> >> useful to people in a similar position, needing to decouple users from
> >> github but needing to generally present the same tree in a similar way?  
> > 
> > This is what you want?
> > 
> > https://libwebsockets.org/git/libwebsockets/about/minimal-examples/README.md  
> 
> Yeah.
> 
> But inline after the tree view, a la github.
> 
> This enables a scheme where inner dirs give their own overview without 
> interrupting navigation.  Eg, a couple of levels down...
> 
> https://github.com/warmcat/libwebsockets/tree/master/lib/roles

I think this is not possible with current code. What patches from John did
you apply?

BTW, linking withing formatted pages works, so this could be a step forward:

diff --git a/README.md b/README.md
index c6222b75..fee7dcae 100644
--- a/README.md
+++ b/README.md
@@ -9,7 +9,7 @@ News
 
 ## v3.0.0 released
 
-See the changelog for info https://libwebsockets.org/git/libwebsockets/tree/changelog?h=v3.0-stable
+See the [changelog](changelog?h=v3.0-stable) for info.
 
 ## Major CI improvements for QA
 
@@ -56,7 +56,7 @@ but the other browsers will catch up soon.
 
 ## New "minimal examples"
 
-https://libwebsockets.org/git/libwebsockets/tree/minimal-examples
+[minimal-examples](minimal-examples/README.md)
 
 These are like the test apps, but focus on doing one thing, the best way, with the minimum amount of code.  For example the minimal-http-server serves the cwd on http/1 or http/2 in 50 LOC.  Same thing with tls is just three more lines.

-- 
main(a){char*c=/*    Schoene Gruesse                         */"B?IJj;MEH"
"CX:;",b;for(a/*    Best regards             my address:    */=0;b=c[a++];)
putchar(b-1/(/*    Chris            cc -ox -xc - && ./x    */b/42*2-3)*42);}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 488 bytes
Desc: OpenPGP digital signature
URL: <http://lists.zx2c4.com/pipermail/cgit/attachments/20180611/3308b72d/attachment-0001.asc>


^ permalink raw reply	[flat|nested] 140+ messages in thread

* Rendering of README.md inline with inner tree view dirs
  2018-06-11  7:53     ` list
@ 2018-06-11  8:05       ` andy
  2018-06-11 15:38         ` john
  0 siblings, 1 reply; 140+ messages in thread
From: andy @ 2018-06-11  8:05 UTC (permalink / raw)




On 06/11/2018 03:53 PM, Christian Hesse wrote:
> Andy Green <andy at warmcat.com> on Mon, 2018/06/11 15:38:
>> On 06/11/2018 03:31 PM, Christian Hesse wrote:
>>> Andy Green <andy at warmcat.com> on Mon, 2018/06/11 15:08:
>>>> Hi -
>>>>
>>>> I have been using cgit for many years.
>>>>
>>>> Currently I am detaching my (LGPL) project from github.
>>>>
>>>> One noticeable problem diverting people from github to cgit is although
>>>> it renders very well the toplevel "about" README.md
>>>>
>>>> https://libwebsockets.org/git/libwebsockets/about/
>>>>
>>>> It doesn't seem to have a way to render inline inner dir README.md as
>>>> github does.  This is quite a small thing but very useful, eg
>>>>
>>>> https://github.com/warmcat/libwebsockets/tree/master/minimal-examples
>>>>
>>>> vs
>>>>
>>>> https://libwebsockets.org/git/libwebsockets/tree/minimal-examples
>>>>
>>>> Is there a way to do it already in the main cgit project?  For nonpublic
>>>> projects, I screenscraped some patches from John Keeping from 2016 that
>>>> do the same thing, but poking around, these don't seem to have made it
>>>> in.
>>>>
>>>> If there's no existing way to do it and those patches are shivering in
>>>> the cold, all alone, can I suggest they would perhaps be extremely
>>>> useful to people in a similar position, needing to decouple users from
>>>> github but needing to generally present the same tree in a similar way?
>>>
>>> This is what you want?
>>>
>>> https://libwebsockets.org/git/libwebsockets/about/minimal-examples/README.md
>>
>> Yeah.
>>
>> But inline after the tree view, a la github.
>>
>> This enables a scheme where inner dirs give their own overview without
>> interrupting navigation.  Eg, a couple of levels down...
>>
>> https://github.com/warmcat/libwebsockets/tree/master/lib/roles
> 
> I think this is not possible with current code. What patches from John did
> you apply?


Author: John Keeping <john at keeping.me.uk>
Date:   Wed Dec 14 20:35:47 2016 +0800

     Use string list strdup_strings for mimetypes

     This allows applying filters to files in the repository, for example to
     render Markdown or AsciiDoc as HTML.

     Signed-off-by: John Keeping <john at keeping.me.uk>

Author: John Keeping <john at keeping.me.uk>
Date:   Wed Dec 14 20:35:47 2016 +0800

     ui-tree: split out buffer printing

     Signed-off-by: John Keeping <john at keeping.me.uk>

Author: John Keeping <john at keeping.me.uk>
Date:   Wed Dec 14 20:41:11 2016 +0800

     Parse render filters from the config

     Render filters will be used to present rendered content in the tree
     view, for example to display Markdown source rendered as HTML.

     We will add support for using these from the tree view in the following
     commits.

     Signed-off-by: John Keeping <john at keeping.me.uk>

Author: John Keeping <john at keeping.me.uk>
Date:   Wed Dec 14 20:36:51 2016 +0800

     Add source page

     We are about to introduce rendering of content for the tree view.  This
     source page will allow bypassing the renderer and accessing the content
     of the current tree view.

     Signed-off-by: John Keeping <john at keeping.me.uk>

Author: John Keeping <john at keeping.me.uk>
Date:   Wed Dec 14 20:35:47 2016 +0800

     Use string list strdup_strings for mimetypes

     There's no need to do this manually with the string list API will do it
     for us.

     Signed-off-by: John Keeping <john at keeping.me.uk>

It's quite possible they aren't what I am asking for, and / or already 
applied.  They were "good enough" for what I needed to do a couple of 
years ago.  But now I am explicitly replacing github, so comparing the 
rendering is in scope for me when it just needed to be able to render 
anything at all back then.

> BTW, linking withing formatted pages works, so this could be a step forward:
> 
> diff --git a/README.md b/README.md
> index c6222b75..fee7dcae 100644
> --- a/README.md
> +++ b/README.md
> @@ -9,7 +9,7 @@ News
>   
>   ## v3.0.0 released
>   
> -See the changelog for info https://libwebsockets.org/git/libwebsockets/tree/changelog?h=v3.0-stable
> +See the [changelog](changelog?h=v3.0-stable) for info.
>   
>   ## Major CI improvements for QA
>   
> @@ -56,7 +56,7 @@ but the other browsers will catch up soon.
>   
>   ## New "minimal examples"
>   
> -https://libwebsockets.org/git/libwebsockets/tree/minimal-examples
> +[minimal-examples](minimal-examples/README.md)
>   
>   These are like the test apps, but focus on doing one thing, the best way, with the minimum amount of code.  For example the minimal-http-server serves the cwd on http/1 or http/2 in 50 LOC.  Same thing with tls is just three more lines.
> 

I think what github did comes into its own when you are in the mode of 
coming new to a project and trying to understand what you are even 
looking at from the project layout in the filespace.  So they may well 
be clicking around in the tree view, it's perfect if any project 
documentation in that dir just magically appears after the already 
expected navigation context explaining it.

Basically any available docs follow along contextually.

I think it's desirable under all circumstances, since it's only coming 
if someone bothered to put relevant docs right there... if no way to do 
it right now and no better ideas, I will try to understand how cgit 
works for this tomorrow and see if any ideas.

-Andy


^ permalink raw reply	[flat|nested] 140+ messages in thread

* Rendering of README.md inline with inner tree view dirs
  2018-06-11  8:05       ` andy
@ 2018-06-11 15:38         ` john
  2018-06-12  5:53           ` andy
  0 siblings, 1 reply; 140+ messages in thread
From: john @ 2018-06-11 15:38 UTC (permalink / raw)


On Mon, Jun 11, 2018 at 04:05:38PM +0800, Andy Green wrote:
> 
> 
> On 06/11/2018 03:53 PM, Christian Hesse wrote:
> > Andy Green <andy at warmcat.com> on Mon, 2018/06/11 15:38:
> >> On 06/11/2018 03:31 PM, Christian Hesse wrote:
> >>> Andy Green <andy at warmcat.com> on Mon, 2018/06/11 15:08:
> >>>> Hi -
> >>>>
> >>>> I have been using cgit for many years.
> >>>>
> >>>> Currently I am detaching my (LGPL) project from github.
> >>>>
> >>>> One noticeable problem diverting people from github to cgit is although
> >>>> it renders very well the toplevel "about" README.md
> >>>>
> >>>> https://libwebsockets.org/git/libwebsockets/about/
> >>>>
> >>>> It doesn't seem to have a way to render inline inner dir README.md as
> >>>> github does.  This is quite a small thing but very useful, eg
> >>>>
> >>>> https://github.com/warmcat/libwebsockets/tree/master/minimal-examples
> >>>>
> >>>> vs
> >>>>
> >>>> https://libwebsockets.org/git/libwebsockets/tree/minimal-examples
> >>>>
> >>>> Is there a way to do it already in the main cgit project?  For nonpublic
> >>>> projects, I screenscraped some patches from John Keeping from 2016 that
> >>>> do the same thing, but poking around, these don't seem to have made it
> >>>> in.
> >>>>
> >>>> If there's no existing way to do it and those patches are shivering in
> >>>> the cold, all alone, can I suggest they would perhaps be extremely
> >>>> useful to people in a similar position, needing to decouple users from
> >>>> github but needing to generally present the same tree in a similar way?
> >>>
> >>> This is what you want?
> >>>
> >>> https://libwebsockets.org/git/libwebsockets/about/minimal-examples/README.md
> >>
> >> Yeah.
> >>
> >> But inline after the tree view, a la github.
> >>
> >> This enables a scheme where inner dirs give their own overview without
> >> interrupting navigation.  Eg, a couple of levels down...
> >>
> >> https://github.com/warmcat/libwebsockets/tree/master/lib/roles
> > 
> > I think this is not possible with current code. What patches from John did
> > you apply?
> 
> 
> Author: John Keeping <john at keeping.me.uk>
> Date:   Wed Dec 14 20:35:47 2016 +0800
> 
>      Use string list strdup_strings for mimetypes
> 
>      This allows applying filters to files in the repository, for example to
>      render Markdown or AsciiDoc as HTML.
> 
>      Signed-off-by: John Keeping <john at keeping.me.uk>
> 
> Author: John Keeping <john at keeping.me.uk>
> Date:   Wed Dec 14 20:35:47 2016 +0800
> 
>      ui-tree: split out buffer printing
> 
>      Signed-off-by: John Keeping <john at keeping.me.uk>
> 
> Author: John Keeping <john at keeping.me.uk>
> Date:   Wed Dec 14 20:41:11 2016 +0800
> 
>      Parse render filters from the config
> 
>      Render filters will be used to present rendered content in the tree
>      view, for example to display Markdown source rendered as HTML.
> 
>      We will add support for using these from the tree view in the following
>      commits.
> 
>      Signed-off-by: John Keeping <john at keeping.me.uk>
> 
> Author: John Keeping <john at keeping.me.uk>
> Date:   Wed Dec 14 20:36:51 2016 +0800
> 
>      Add source page
> 
>      We are about to introduce rendering of content for the tree view.  This
>      source page will allow bypassing the renderer and accessing the content
>      of the current tree view.
> 
>      Signed-off-by: John Keeping <john at keeping.me.uk>
> 
> Author: John Keeping <john at keeping.me.uk>
> Date:   Wed Dec 14 20:35:47 2016 +0800
> 
>      Use string list strdup_strings for mimetypes
> 
>      There's no need to do this manually with the string list API will do it
>      for us.
> 
>      Signed-off-by: John Keeping <john at keeping.me.uk>
> 
> It's quite possible they aren't what I am asking for, and / or already 
> applied.  They were "good enough" for what I needed to do a couple of 
> years ago.  But now I am explicitly replacing github, so comparing the 
> rendering is in scope for me when it just needed to be able to render 
> anything at all back then.
> 
> > BTW, linking withing formatted pages works, so this could be a step forward:
> > 
> > diff --git a/README.md b/README.md
> > index c6222b75..fee7dcae 100644
> > --- a/README.md
> > +++ b/README.md
> > @@ -9,7 +9,7 @@ News
> >   
> >   ## v3.0.0 released
> >   
> > -See the changelog for info https://libwebsockets.org/git/libwebsockets/tree/changelog?h=v3.0-stable
> > +See the [changelog](changelog?h=v3.0-stable) for info.
> >   
> >   ## Major CI improvements for QA
> >   
> > @@ -56,7 +56,7 @@ but the other browsers will catch up soon.
> >   
> >   ## New "minimal examples"
> >   
> > -https://libwebsockets.org/git/libwebsockets/tree/minimal-examples
> > +[minimal-examples](minimal-examples/README.md)
> >   
> >   These are like the test apps, but focus on doing one thing, the best way, with the minimum amount of code.  For example the minimal-http-server serves the cwd on http/1 or http/2 in 50 LOC.  Same thing with tls is just three more lines.
> > 
> 
> I think what github did comes into its own when you are in the mode of 
> coming new to a project and trying to understand what you are even 
> looking at from the project layout in the filespace.  So they may well 
> be clicking around in the tree view, it's perfect if any project 
> documentation in that dir just magically appears after the already 
> expected navigation context explaining it.
> 
> Basically any available docs follow along contextually.
> 
> I think it's desirable under all circumstances, since it's only coming 
> if someone bothered to put relevant docs right there... if no way to do 
> it right now and no better ideas, I will try to understand how cgit 
> works for this tomorrow and see if any ideas.

I think this is a potentially useful feature; long before GitHub existed
web interfaces to file servers have included README content with the
directory listing.

Given the render mode patches you listed above, I think it should be
reasonably straightforward to add this feature in ui-tree.c with the
following changes:

- Add fields to walk_tree_context to remember the filename and object_id
  of a target README file (this needs some configuration to answer the
  question: what is a README file?) and populate these during the normal
  tree walk (probably in ls_item(), being careful to only accept blobs)
- In ls_tail(), if the walk_tree_context has valid values for those
  fields, then read the blob content from the object_id and call
  render_buffer()

This will re-use the existing render filter for "inline" README content,
which I think is a good thing.  I think the filenames for READMEs will
have to be a new configuration (the existing "readme" configuration
takes a blob ref whereas this option wants a simple filename).


John


^ permalink raw reply	[flat|nested] 140+ messages in thread

* Rendering of README.md inline with inner tree view dirs
  2018-06-11 15:38         ` john
@ 2018-06-12  5:53           ` andy
  2018-06-12  8:35             ` list
  2018-06-12  9:31             ` john
  0 siblings, 2 replies; 140+ messages in thread
From: andy @ 2018-06-12  5:53 UTC (permalink / raw)




On 06/11/2018 11:38 PM, John Keeping wrote:
> On Mon, Jun 11, 2018 at 04:05:38PM +0800, Andy Green wrote:

>> I think what github did comes into its own when you are in the mode of
>> coming new to a project and trying to understand what you are even
>> looking at from the project layout in the filespace.  So they may well
>> be clicking around in the tree view, it's perfect if any project
>> documentation in that dir just magically appears after the already
>> expected navigation context explaining it.
>>
>> Basically any available docs follow along contextually.
>>
>> I think it's desirable under all circumstances, since it's only coming
>> if someone bothered to put relevant docs right there... if no way to do
>> it right now and no better ideas, I will try to understand how cgit
>> works for this tomorrow and see if any ideas.
> 
> I think this is a potentially useful feature; long before GitHub existed
> web interfaces to file servers have included README content with the
> directory listing.

Yes indeed.

> Given the render mode patches you listed above, I think it should be
> reasonably straightforward to add this feature in ui-tree.c with the
> following changes:
> 
> - Add fields to walk_tree_context to remember the filename and object_id
>    of a target README file (this needs some configuration to answer the
>    question: what is a README file?) and populate these during the normal
>    tree walk (probably in ls_item(), being careful to only accept blobs)
> - In ls_tail(), if the walk_tree_context has valid values for those
>    fields, then read the blob content from the object_id and call
>    render_buffer()
> 
> This will re-use the existing render filter for "inline" README content,
> which I think is a good thing.  I think the filenames for READMEs will
> have to be a new configuration (the existing "readme" configuration
> takes a blob ref whereas this option wants a simple filename).

Thanks for the suggestions, and the patches that are doing most of the 
work here.

I got quite far with it, you can see

https://libwebsockets.org/git/libwebsockets/tree/

and

https://libwebsockets.org/git/libwebsockets/tree/minimal-examples

are basically there.  If it's helpful to post a WIP series happy to do it.

1) I did not attempt to have it learn about suitable filenames from the 
config yet, I just have ls_item() looking for "README.md".  I saw 
there's already a way (readme=) for the config to list them for the 
about page... basically now tree view becomes a superset of the 
operation of the about page; the about page content appears in tree view.

So do you have any thoughts about just re-using that list?

2) In the current patches, I allowed for ls_item to discover a 
linked-list of files and render them later one after the other.  Eg, a 
dir of READMEs would render them like that.  It's welcome or preferable 
to just restrict it to one?

3) You can see on the top level of the tree, the README.md references

<img alt="lws-overview" src="./doc-assets/lws-overview.png">

This url format works in github.  In the cgit About view, this resolves to

/git/libwebsockets/about/doc-assets/lws-overview.png

which also serves the right mimetype and content.  So that kind of URL 
format is useful.  But when we render the same markup and relative path 
via /tree/, it tries to show an html page containing the content. 
That's why the picture is missing in the /tree/ view... other pictures 
in that markup are coming with absolute URLs outside of cgit and are 
working.

I can have the direct content from cgit generally, but either the markup 
needs fixing up to

/git/libwebsockets/plain/doc-assets/lws-overview.png

or /tree/ needs to learn to do what /about/ does.

I'm wondering whether mmd2html might grow an environment var to know the 
base part for URLS that want to direct-render from cgit.  Or if better 
to follow what /about/ did in /tree/.

4) Looking at read_sha1_file() in print_object(), I can't immediately 
see who frees that.  Running cgit from the commandline, with valgrind, 
he seems to leak some things.  Since it's a cgi, the policy is we don't 
worry too much about that, or I just miss the idea about where it's freed?

5) I get some gcc 8.1 warnings, I made a couple of patches to get around 
them.  In a couple of places, the code seemed legit really.

     gcc8.1: fix strncpy bounds warnings

     These warnings are coming on default Fedora 28 build and probably 
others using gcc 8.1

     ../shared.c: In function ?expand_macro?:
     ../shared.c:483:3: warning: ?strncpy? specified bound depends on 
the length of the source argument [-Wstringop-overflow=]
        strncpy(name, value, len);
        ^~~~~~~~~~~~~~~~~~~~~~~~~
     ../shared.c:480:9: note: length computed here
        len = strlen(value);
              ^~~~~~~~~~~~~

     ../ui-shared.c: In function ?cgit_repobasename?:
     ../ui-shared.c:135:2: warning: ?strncpy? specified bound 1024 
equals destination size [-Wstringop-truncation]
       strncpy(rvbuf, reponame, sizeof(rvbuf));
       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

diff --git a/shared.c b/shared.c
index 21ac8f4..477db0a 100644
--- a/shared.c
+++ b/shared.c
@@ -480,7 +480,7 @@ static char *expand_macro(char *name, int maxlength)
                 len = strlen(value);
                 if (len > maxlength)
                         len = maxlength;
-               strncpy(name, value, len);
+               memcpy(name, value, len);
         }
         return name + len;
  }
diff --git a/ui-shared.c b/ui-shared.c
index 9d8f66b..6656bd5 100644
--- a/ui-shared.c
+++ b/ui-shared.c
@@ -129,11 +129,12 @@ char *cgit_pageurl(const char *reponame, const 
char *pagename,
  const char *cgit_repobasename(const char *reponame)
  {
         /* I assume we don't need to store more than one repo basename */
-       static char rvbuf[1024];
+       static char rvbuf[1025];
         int p;
         const char *rv;
-       strncpy(rvbuf, reponame, sizeof(rvbuf));
-       if (rvbuf[sizeof(rvbuf)-1])
+
+       strncpy(rvbuf, reponame, sizeof(rvbuf) - 1);
+       if (rvbuf[sizeof(rvbuf) - 2])
                 die("cgit_repobasename: truncated repository name 
'%s'", reponame);
         p = strlen(rvbuf)-1;
         /* strip trailing slashes */


and also

     gcc8.1: fix strcat warning

     ../ui-ssdiff.c: In function ?replace_tabs?:
     ../ui-ssdiff.c:142:4: warning: ?strncat? output truncated copying 
between 1 and 8 bytes from a string of length 8 [-Wstringop-truncation]
         strncat(result, spaces, 8 - (strlen(result) % 8));
         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

diff --git a/ui-ssdiff.c b/ui-ssdiff.c
index 7f261ed..e520b95 100644
--- a/ui-ssdiff.c
+++ b/ui-ssdiff.c
@@ -118,7 +118,6 @@ static char *replace_tabs(char *line)
         int n_tabs = 0;
         int i;
         char *result;
-       char *spaces = "        ";

         if (linelen == 0) {
                 result = xmalloc(1);
@@ -138,8 +137,17 @@ static char *replace_tabs(char *line)
                         strcat(result, prev_buf);
                         break;
                 } else {
+                       char *p;
+                       int n;
+
                         strncat(result, prev_buf, cur_buf - prev_buf);
-                       strncat(result, spaces, 8 - (strlen(result) % 8));
+
+                       n = strlen(result);
+                       p = result + n;
+                       n = 8 - (n % 8);
+                       while (n--)
+                               *p++ = ' ';
+                       *p = '\0';
                 }
                 prev_buf = cur_buf + 1;
         }

I should include these or the slightly dubious warnings are just 
regarded as an annoyance?

Thanks,

-Andy

> 
> John
> 


^ permalink raw reply	[flat|nested] 140+ messages in thread

* Rendering of README.md inline with inner tree view dirs
  2018-06-12  5:53           ` andy
@ 2018-06-12  8:35             ` list
  2018-06-12  9:24               ` john
  2018-06-12  9:31             ` john
  1 sibling, 1 reply; 140+ messages in thread
From: list @ 2018-06-12  8:35 UTC (permalink / raw)


Andy Green <andy at warmcat.com> on Tue, 2018/06/12 13:53:
> 5) I get some gcc 8.1 warnings, I made a couple of patches to get around 
> them.  In a couple of places, the code seemed legit really.

I do see these on Arch as well. :)
Did not find the time to address them.

> [inline patches]
> 
> I should include these or the slightly dubious warnings are just 
> regarded as an annoyance?

Definitely to be addressed. I pushed your changes here:

https://git.zx2c4.com/cgit/commit/?h=ch/gcc-8&id=e7ac824f

Builds without warnings and tests are happy, but I did not yet take a
detailed look.
-- 
main(a){char*c=/*    Schoene Gruesse                         */"B?IJj;MEH"
"CX:;",b;for(a/*    Best regards             my address:    */=0;b=c[a++];)
putchar(b-1/(/*    Chris            cc -ox -xc - && ./x    */b/42*2-3)*42);}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 488 bytes
Desc: OpenPGP digital signature
URL: <http://lists.zx2c4.com/pipermail/cgit/attachments/20180612/0844f555/attachment.asc>


^ permalink raw reply	[flat|nested] 140+ messages in thread

* Rendering of README.md inline with inner tree view dirs
  2018-06-12  8:35             ` list
@ 2018-06-12  9:24               ` john
  2018-06-12  9:27                 ` andy
  0 siblings, 1 reply; 140+ messages in thread
From: john @ 2018-06-12  9:24 UTC (permalink / raw)


On Tue, Jun 12, 2018 at 10:35:25AM +0200, Christian Hesse wrote:
> Andy Green <andy at warmcat.com> on Tue, 2018/06/12 13:53:
> > 5) I get some gcc 8.1 warnings, I made a couple of patches to get around 
> > them.  In a couple of places, the code seemed legit really.
> 
> I do see these on Arch as well. :)
> Did not find the time to address them.
> 
> > [inline patches]
> > 
> > I should include these or the slightly dubious warnings are just 
> > regarded as an annoyance?
> 
> Definitely to be addressed. I pushed your changes here:
> 
> https://git.zx2c4.com/cgit/commit/?h=ch/gcc-8&id=e7ac824f
> 
> Builds without warnings and tests are happy, but I did not yet take a
> detailed look.

We'll need those posted as proper patches with a sign-off though.  It
will also be easier to review them that way.


John


^ permalink raw reply	[flat|nested] 140+ messages in thread

* Rendering of README.md inline with inner tree view dirs
  2018-06-12  9:24               ` john
@ 2018-06-12  9:27                 ` andy
  2018-06-12 12:07                   ` john
  0 siblings, 1 reply; 140+ messages in thread
From: andy @ 2018-06-12  9:27 UTC (permalink / raw)




On June 12, 2018 5:24:37 PM GMT+08:00, John Keeping <john at keeping.me.uk> wrote:
>On Tue, Jun 12, 2018 at 10:35:25AM +0200, Christian Hesse wrote:
>> Andy Green <andy at warmcat.com> on Tue, 2018/06/12 13:53:
>> > 5) I get some gcc 8.1 warnings, I made a couple of patches to get
>around 
>> > them.  In a couple of places, the code seemed legit really.
>> 
>> I do see these on Arch as well. :)
>> Did not find the time to address them.
>> 
>> > [inline patches]
>> > 
>> > I should include these or the slightly dubious warnings are just 
>> > regarded as an annoyance?
>> 
>> Definitely to be addressed. I pushed your changes here:
>> 
>> https://git.zx2c4.com/cgit/commit/?h=ch/gcc-8&id=e7ac824f
>> 
>> Builds without warnings and tests are happy, but I did not yet take a
>> detailed look.
>
>We'll need those posted as proper patches with a sign-off though.  It
>will also be easier to review them that way.

No worries I'll send a series with everything including your rebased patches when the remaining things are sorted.  I was checking if anyone cared about the warnings.

-Andy

>
>John


^ permalink raw reply	[flat|nested] 140+ messages in thread

* Rendering of README.md inline with inner tree view dirs
  2018-06-12  5:53           ` andy
  2018-06-12  8:35             ` list
@ 2018-06-12  9:31             ` john
  2018-06-13  1:47               ` andy
  2018-06-18  2:56               ` [PATCH v2 00/15] Render READMEs inline in tree view andy
  1 sibling, 2 replies; 140+ messages in thread
From: john @ 2018-06-12  9:31 UTC (permalink / raw)


On Tue, Jun 12, 2018 at 01:53:27PM +0800, Andy Green wrote:
> On 06/11/2018 11:38 PM, John Keeping wrote:
> > On Mon, Jun 11, 2018 at 04:05:38PM +0800, Andy Green wrote:
> 
> >> I think what github did comes into its own when you are in the mode of
> >> coming new to a project and trying to understand what you are even
> >> looking at from the project layout in the filespace.  So they may well
> >> be clicking around in the tree view, it's perfect if any project
> >> documentation in that dir just magically appears after the already
> >> expected navigation context explaining it.
> >>
> >> Basically any available docs follow along contextually.
> >>
> >> I think it's desirable under all circumstances, since it's only coming
> >> if someone bothered to put relevant docs right there... if no way to do
> >> it right now and no better ideas, I will try to understand how cgit
> >> works for this tomorrow and see if any ideas.
> > 
> > I think this is a potentially useful feature; long before GitHub existed
> > web interfaces to file servers have included README content with the
> > directory listing.
> 
> Yes indeed.
> 
> > Given the render mode patches you listed above, I think it should be
> > reasonably straightforward to add this feature in ui-tree.c with the
> > following changes:
> > 
> > - Add fields to walk_tree_context to remember the filename and object_id
> >    of a target README file (this needs some configuration to answer the
> >    question: what is a README file?) and populate these during the normal
> >    tree walk (probably in ls_item(), being careful to only accept blobs)
> > - In ls_tail(), if the walk_tree_context has valid values for those
> >    fields, then read the blob content from the object_id and call
> >    render_buffer()
> > 
> > This will re-use the existing render filter for "inline" README content,
> > which I think is a good thing.  I think the filenames for READMEs will
> > have to be a new configuration (the existing "readme" configuration
> > takes a blob ref whereas this option wants a simple filename).
> 
> Thanks for the suggestions, and the patches that are doing most of the 
> work here.
> 
> I got quite far with it, you can see
> 
> https://libwebsockets.org/git/libwebsockets/tree/
> 
> and
> 
> https://libwebsockets.org/git/libwebsockets/tree/minimal-examples
> 
> are basically there.  If it's helpful to post a WIP series happy to do it.
> 
> 1) I did not attempt to have it learn about suitable filenames from the 
> config yet, I just have ls_item() looking for "README.md".  I saw 
> there's already a way (readme=) for the config to list them for the 
> about page... basically now tree view becomes a superset of the 
> operation of the about page; the about page content appears in tree view.
> 
> So do you have any thoughts about just re-using that list?

I think that list is refs to blobs, so you can specify something like:

	refs/heads/wiki:README.md

but here we need base filenames to look for in the current directory, so
it will have to be a new config variable.

> 2) In the current patches, I allowed for ls_item to discover a 
> linked-list of files and render them later one after the other.  Eg, a 
> dir of READMEs would render them like that.  It's welcome or preferable 
> to just restrict it to one?

My choice would be to take the first matching file, but I don't have a
strong opinion on what is the right behaviour.

> 3) You can see on the top level of the tree, the README.md references
> 
> <img alt="lws-overview" src="./doc-assets/lws-overview.png">
> 
> This url format works in github.  In the cgit About view, this resolves to
> 
> /git/libwebsockets/about/doc-assets/lws-overview.png
> 
> which also serves the right mimetype and content.  So that kind of URL 
> format is useful.  But when we render the same markup and relative path 
> via /tree/, it tries to show an html page containing the content. 
> That's why the picture is missing in the /tree/ view... other pictures 
> in that markup are coming with absolute URLs outside of cgit and are 
> working.
> 
> I can have the direct content from cgit generally, but either the markup 
> needs fixing up to
> 
> /git/libwebsockets/plain/doc-assets/lws-overview.png
> 
> or /tree/ needs to learn to do what /about/ does.
> 
> I'm wondering whether mmd2html might grow an environment var to know the 
> base part for URLS that want to direct-render from cgit.  Or if better 
> to follow what /about/ did in /tree/.

Making tree do this will break the normal use of tree unless we add some
extra query parameter or path element.  Given that, I think teaching the
renderer to use a path to /about/ is the right thing to do.

Does that affect the render mode patches as well?  (This is a genuine
question, it's been a while since I wrote that code and I don't remember
testing files with embedded assets.)

> 4) Looking at read_sha1_file() in print_object(), I can't immediately 
> see who frees that.  Running cgit from the commandline, with valgrind, 
> he seems to leak some things.  Since it's a cgi, the policy is we don't 
> worry too much about that, or I just miss the idea about where it's freed?

We don't generally worry about it too much, although it looks like
several other callers of read_sha1_file() do free the buffer.  Since
it's easy to fit in here, it's probably worth freeing it at the end of
print_object().


John


^ permalink raw reply	[flat|nested] 140+ messages in thread

* Rendering of README.md inline with inner tree view dirs
  2018-06-12  9:27                 ` andy
@ 2018-06-12 12:07                   ` john
  0 siblings, 0 replies; 140+ messages in thread
From: john @ 2018-06-12 12:07 UTC (permalink / raw)


On Tue, Jun 12, 2018 at 05:27:09PM +0800, Andy Green wrote:
> 
> 
> On June 12, 2018 5:24:37 PM GMT+08:00, John Keeping <john at keeping.me.uk> wrote:
> >On Tue, Jun 12, 2018 at 10:35:25AM +0200, Christian Hesse wrote:
> >> Andy Green <andy at warmcat.com> on Tue, 2018/06/12 13:53:
> >> > 5) I get some gcc 8.1 warnings, I made a couple of patches to get
> >around 
> >> > them.  In a couple of places, the code seemed legit really.
> >> 
> >> I do see these on Arch as well. :)
> >> Did not find the time to address them.
> >> 
> >> > [inline patches]
> >> > 
> >> > I should include these or the slightly dubious warnings are just 
> >> > regarded as an annoyance?
> >> 
> >> Definitely to be addressed. I pushed your changes here:
> >> 
> >> https://git.zx2c4.com/cgit/commit/?h=ch/gcc-8&id=e7ac824f
> >> 
> >> Builds without warnings and tests are happy, but I did not yet take a
> >> detailed look.
> >
> >We'll need those posted as proper patches with a sign-off though.  It
> >will also be easier to review them that way.
> 
> No worries I'll send a series with everything including your rebased
> patches when the remaining things are sorted.  I was checking if
> anyone cared about the warnings.

If the GCC-8 fixes are independent of the other changes (from a quick
skim I think they are), then please send them as a separate series so
that we can get the warnings fixes in without waiting for other changes.


John


^ permalink raw reply	[flat|nested] 140+ messages in thread

* Rendering of README.md inline with inner tree view dirs
  2018-06-12  9:31             ` john
@ 2018-06-13  1:47               ` andy
  2018-06-13  2:01                 ` [PATCH 00/11] Render READMEs inline in tree view andy
  2018-06-16 14:12                 ` Rendering of README.md inline with inner tree view dirs john
  2018-06-18  2:56               ` [PATCH v2 00/15] Render READMEs inline in tree view andy
  1 sibling, 2 replies; 140+ messages in thread
From: andy @ 2018-06-13  1:47 UTC (permalink / raw)




On 06/12/2018 05:31 PM, John Keeping wrote:
> On Tue, Jun 12, 2018 at 01:53:27PM +0800, Andy Green wrote:
>> On 06/11/2018 11:38 PM, John Keeping wrote:
>>> On Mon, Jun 11, 2018 at 04:05:38PM +0800, Andy Green wrote:

>> 1) I did not attempt to have it learn about suitable filenames from the
>> config yet, I just have ls_item() looking for "README.md".  I saw
>> there's already a way (readme=) for the config to list them for the
>> about page... basically now tree view becomes a superset of the
>> operation of the about page; the about page content appears in tree view.
>>
>> So do you have any thoughts about just re-using that list?
> 
> I think that list is refs to blobs, so you can specify something like:
> 
> 	refs/heads/wiki:README.md
> 
> but here we need base filenames to look for in the current directory, so
> it will have to be a new config variable.

OK.  I added a new cgit-scope variable that appends filenames to be 
considered for showing in tree view, eg,

tree-readme=README.md

>> 2) In the current patches, I allowed for ls_item to discover a
>> linked-list of files and render them later one after the other.  Eg, a
>> dir of READMEs would render them like that.  It's welcome or preferable
>> to just restrict it to one?
> 
> My choice would be to take the first matching file, but I don't have a
> strong opinion on what is the right behaviour.

I'll leave this as a list for the first try.  If it looks excessive I'll 
reduce it to just the one.

>> 3) You can see on the top level of the tree, the README.md references
>>
>> <img alt="lws-overview" src="./doc-assets/lws-overview.png">
>>
>> This url format works in github.  In the cgit About view, this resolves to
>>
>> /git/libwebsockets/about/doc-assets/lws-overview.png
>>
>> which also serves the right mimetype and content.  So that kind of URL
>> format is useful.  But when we render the same markup and relative path
>> via /tree/, it tries to show an html page containing the content.
>> That's why the picture is missing in the /tree/ view... other pictures
>> in that markup are coming with absolute URLs outside of cgit and are
>> working.
>>
>> I can have the direct content from cgit generally, but either the markup
>> needs fixing up to
>>
>> /git/libwebsockets/plain/doc-assets/lws-overview.png
>>
>> or /tree/ needs to learn to do what /about/ does.
>>
>> I'm wondering whether mmd2html might grow an environment var to know the
>> base part for URLS that want to direct-render from cgit.  Or if better
>> to follow what /about/ did in /tree/.
> 
> Making tree do this will break the normal use of tree unless we add some
> extra query parameter or path element.  Given that, I think teaching the
> renderer to use a path to /about/ is the right thing to do.

OK.  Unfortunately I don't know python very well.  It looks like the 
markdown python library is able to be told to use extensions that are 
capable to do this

https://python-markdown.github.io/extensions/api/

from the md2html wrapper.  But I don't know enough python to do it.

It's a shame, because in-tree assets correctly follow the ref context 
being viewed, eg, if you look at a v2 branch you see v2 pngs, master you 
see master pngs etc.

I'll "solve" this part for now by changing the README to use external URLs.

> Does that affect the render mode patches as well?  (This is a genuine
> question, it's been a while since I wrote that code and I don't remember
> testing files with embedded assets.)

Not sure what you are asking here... what's happening is the markup to 
be rendered has a relative URL in its un-rendered form.  The patches 
didn't generate it, it's a relative URL in the blob we pulled out from 
the repo to be rendered.

The only guy who knows how to understand there is a relative URL there 
is the renderer app, like md2html, not the patches that arrange for it 
to be called.

If you mean your series implies a /render/ or something, I don't know, I 
only use it from /tree/.

>> 4) Looking at read_sha1_file() in print_object(), I can't immediately
>> see who frees that.  Running cgit from the commandline, with valgrind,
>> he seems to leak some things.  Since it's a cgi, the policy is we don't
>> worry too much about that, or I just miss the idea about where it's freed?
> 
> We don't generally worry about it too much, although it looks like
> several other callers of read_sha1_file() do free the buffer.  Since
> it's easy to fit in here, it's probably worth freeing it at the end of
> print_object().

I audited all uses of it and fixed missing frees in ui-tree and ui-blame.

I'll check it over and post the series here shortly.

-Andy

> 
> John
> 


^ permalink raw reply	[flat|nested] 140+ messages in thread

* [PATCH 00/11] Render READMEs inline in tree view
  2018-06-13  1:47               ` andy
@ 2018-06-13  2:01                 ` andy
  2018-06-13  2:01                   ` [PATCH 01/11] Use string list strdup_strings for mimetypes andy
                                     ` (13 more replies)
  2018-06-16 14:12                 ` Rendering of README.md inline with inner tree view dirs john
  1 sibling, 14 replies; 140+ messages in thread
From: andy @ 2018-06-13  2:01 UTC (permalink / raw)


The following series adds config to allow rendering of
selected READMEs inline after the tree view, where
present in the directory being viewed.

It builds on John Keeping's RENDER mode series from 2016.

Typical config to enable it, if you have a README.md
looks like

tree-readme=README.md
render.md=/usr/libexec/cgit/filters/html-converters/md2html

---

Andy Green (6):
      ui-tree: free read_sha1_file() buffer after use
      ui-blame: free read_sha1_file() buffer after use
      ui-tree: print_object: add is_inline param
      ui-tree: ls_tail: add walk table param
      config: add tree-readme list
      ui-tree: render any matching README file in tree view

John Keeping (5):
      Use string list strdup_strings for mimetypes
      Add source page
      Parse render filters from the config
      ui-tree: split out buffer printing
      ui-tree: use render fileters to display content


 cgit.c       |   34 ++++++++-
 cgit.css     |    5 +
 cgit.h       |    5 +
 cgitrc.5.txt |   25 +++++++
 cmd.c        |    8 ++
 filter.c     |    1 
 shared.c     |   21 ++++++
 ui-blame.c   |    3 +
 ui-shared.c  |   10 +++
 ui-shared.h  |    3 +
 ui-tree.c    |  211 +++++++++++++++++++++++++++++++++++++++++++++++++++++-----
 ui-tree.h    |    2 -
 12 files changed, 301 insertions(+), 27 deletions(-)

--
Signature


^ permalink raw reply	[flat|nested] 140+ messages in thread

* [PATCH 01/11] Use string list strdup_strings for mimetypes
  2018-06-13  2:01                 ` [PATCH 00/11] Render READMEs inline in tree view andy
@ 2018-06-13  2:01                   ` andy
  2018-06-13  2:01                   ` [PATCH 02/11] Add source page andy
                                     ` (12 subsequent siblings)
  13 siblings, 0 replies; 140+ messages in thread
From: andy @ 2018-06-13  2:01 UTC (permalink / raw)


From: John Keeping <john at keeping.me.uk>

There's no need to do this manually with the string list API will do it
for us.

Signed-off-by: John Keeping <john at keeping.me.uk>
---
 cgit.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/cgit.c b/cgit.c
index bd9cb3f..b37d3e0 100644
--- a/cgit.c
+++ b/cgit.c
@@ -23,7 +23,7 @@ static void add_mimetype(const char *name, const char *value)
 {
 	struct string_list_item *item;
 
-	item = string_list_insert(&ctx.cfg.mimetypes, xstrdup(name));
+	item = string_list_insert(&ctx.cfg.mimetypes, name);
 	item->util = xstrdup(value);
 }
 
@@ -419,7 +419,7 @@ static void prepare_context(void)
 	ctx.page.modified = time(NULL);
 	ctx.page.expires = ctx.page.modified;
 	ctx.page.etag = NULL;
-	memset(&ctx.cfg.mimetypes, 0, sizeof(struct string_list));
+	string_list_init(&ctx.cfg.mimetypes, 1);
 	if (ctx.env.script_name)
 		ctx.cfg.script_name = xstrdup(ctx.env.script_name);
 	if (ctx.env.query_string)



^ permalink raw reply	[flat|nested] 140+ messages in thread

* [PATCH 02/11] Add source page
  2018-06-13  2:01                 ` [PATCH 00/11] Render READMEs inline in tree view andy
  2018-06-13  2:01                   ` [PATCH 01/11] Use string list strdup_strings for mimetypes andy
@ 2018-06-13  2:01                   ` andy
  2018-06-13  2:01                   ` [PATCH 03/11] Parse render filters from the config andy
                                     ` (11 subsequent siblings)
  13 siblings, 0 replies; 140+ messages in thread
From: andy @ 2018-06-13  2:01 UTC (permalink / raw)


From: John Keeping <john at keeping.me.uk>

We are about to introduce rendering of content for the tree view.  This
source page will allow bypassing the renderer and accessing the content
of the current tree view.

Signed-off-by: John Keeping <john at keeping.me.uk>
---
 cmd.c       |    6 ++++++
 ui-shared.c |   10 ++++++++++
 ui-shared.h |    3 +++
 3 files changed, 19 insertions(+)

diff --git a/cmd.c b/cmd.c
index 63f0ae5..56e21df 100644
--- a/cmd.c
+++ b/cmd.c
@@ -138,6 +138,11 @@ static void refs_fn(void)
 	cgit_print_refs();
 }
 
+static void source_fn(void)
+{
+	cgit_print_tree(ctx.qry.sha1, ctx.qry.path);
+}
+
 static void snapshot_fn(void)
 {
 	cgit_print_snapshot(ctx.qry.head, ctx.qry.sha1, ctx.qry.path,
@@ -187,6 +192,7 @@ struct cgit_cmd *cgit_get_cmd(void)
 		def_cmd(refs, 1, 0, 0),
 		def_cmd(repolist, 0, 0, 0),
 		def_cmd(snapshot, 1, 0, 0),
+		def_cmd(source, 1, 1, 0),
 		def_cmd(stats, 1, 1, 0),
 		def_cmd(summary, 1, 0, 0),
 		def_cmd(tag, 1, 0, 0),
diff --git a/ui-shared.c b/ui-shared.c
index 6656bd5..2ae5999 100644
--- a/ui-shared.c
+++ b/ui-shared.c
@@ -299,6 +299,12 @@ void cgit_tree_link(const char *name, const char *title, const char *class,
 	reporevlink("tree", name, title, class, head, rev, path);
 }
 
+void cgit_source_link(const char *name, const char *title, const char *class,
+		    const char *head, const char *rev, const char *path)
+{
+	reporevlink("source", name, title, class, head, rev, path);
+}
+
 void cgit_plain_link(const char *name, const char *title, const char *class,
 		     const char *head, const char *rev, const char *path)
 {
@@ -481,6 +487,10 @@ static void cgit_self_link(char *name, const char *title, const char *class)
 		cgit_tree_link(name, title, class, ctx.qry.head,
 			       ctx.qry.has_sha1 ? ctx.qry.sha1 : NULL,
 			       ctx.qry.path);
+	else if (!strcmp(ctx.qry.page, "source"))
+		cgit_source_link(name, title, class, ctx.qry.head,
+				 ctx.qry.has_sha1 ? ctx.qry.sha1 : NULL,
+				 ctx.qry.path);
 	else if (!strcmp(ctx.qry.page, "plain"))
 		cgit_plain_link(name, title, class, ctx.qry.head,
 				ctx.qry.has_sha1 ? ctx.qry.sha1 : NULL,
diff --git a/ui-shared.h b/ui-shared.h
index b760a17..5923aaf 100644
--- a/ui-shared.h
+++ b/ui-shared.h
@@ -23,6 +23,9 @@ extern void cgit_tag_link(const char *name, const char *title,
 extern void cgit_tree_link(const char *name, const char *title,
 			   const char *class, const char *head,
 			   const char *rev, const char *path);
+extern void cgit_source_link(const char *name, const char *title,
+			     const char *class, const char *head,
+			     const char *rev, const char *path);
 extern void cgit_plain_link(const char *name, const char *title,
 			    const char *class, const char *head,
 			    const char *rev, const char *path);



^ permalink raw reply	[flat|nested] 140+ messages in thread

* [PATCH 03/11] Parse render filters from the config
  2018-06-13  2:01                 ` [PATCH 00/11] Render READMEs inline in tree view andy
  2018-06-13  2:01                   ` [PATCH 01/11] Use string list strdup_strings for mimetypes andy
  2018-06-13  2:01                   ` [PATCH 02/11] Add source page andy
@ 2018-06-13  2:01                   ` andy
  2018-06-13  2:01                   ` [PATCH 04/11] ui-tree: split out buffer printing andy
                                     ` (10 subsequent siblings)
  13 siblings, 0 replies; 140+ messages in thread
From: andy @ 2018-06-13  2:01 UTC (permalink / raw)


From: John Keeping <john at keeping.me.uk>

Render filters will be used to present rendered content in the tree
view, for example to display Markdown source rendered as HTML.

We will add support for using these from the tree view in the following
commits.

Signed-off-by: John Keeping <john at keeping.me.uk>
---
 cgit.c       |   19 +++++++++++++++++--
 cgit.h       |    4 +++-
 cgitrc.5.txt |   18 ++++++++++++++++++
 filter.c     |    1 +
 shared.c     |   21 +++++++++++++++++++++
 5 files changed, 60 insertions(+), 3 deletions(-)

diff --git a/cgit.c b/cgit.c
index b37d3e0..975e573 100644
--- a/cgit.c
+++ b/cgit.c
@@ -27,6 +27,18 @@ static void add_mimetype(const char *name, const char *value)
 	item->util = xstrdup(value);
 }
 
+static void add_render_filter(const char *name, const char *cmd)
+{
+	struct string_list_item *item;
+	struct cgit_filter *filter = cgit_new_filter(cmd, RENDER);
+
+	if (!filter)
+		return;
+
+	item = string_list_insert(&ctx.cfg.render_filters, name);
+	item->util = filter;
+}
+
 static void process_cached_repolist(const char *path);
 
 static void repo_config(struct cgit_repo *repo, const char *name, const char *value)
@@ -285,8 +297,10 @@ static void config_cb(const char *name, const char *value)
 			ctx.cfg.branch_sort = 1;
 		if (!strcmp(value, "name"))
 			ctx.cfg.branch_sort = 0;
-	} else if (skip_prefix(name, "mimetype.", &arg))
-		add_mimetype(arg, value);
+	} else if (starts_with(name, "mimetype."))
+		add_mimetype(name + 9, value);
+	else if (starts_with(name, "render."))
+		add_render_filter(name + 7, value);
 	else if (!strcmp(name, "include"))
 		parse_configfile(expand_macros(value), config_cb);
 }
@@ -420,6 +434,7 @@ static void prepare_context(void)
 	ctx.page.expires = ctx.page.modified;
 	ctx.page.etag = NULL;
 	string_list_init(&ctx.cfg.mimetypes, 1);
+	string_list_init(&ctx.cfg.render_filters, 1);
 	if (ctx.env.script_name)
 		ctx.cfg.script_name = xstrdup(ctx.env.script_name);
 	if (ctx.env.query_string)
diff --git a/cgit.h b/cgit.h
index 005ae63..a19742f 100644
--- a/cgit.h
+++ b/cgit.h
@@ -55,7 +55,7 @@ typedef enum {
 } diff_type;
 
 typedef enum {
-	ABOUT, COMMIT, SOURCE, EMAIL, AUTH, OWNER
+	ABOUT, COMMIT, SOURCE, EMAIL, AUTH, OWNER, RENDER
 } filter_type;
 
 struct cgit_filter {
@@ -261,6 +261,7 @@ struct cgit_config {
 	int branch_sort;
 	int commit_sort;
 	struct string_list mimetypes;
+	struct string_list render_filters;
 	struct cgit_filter *about_filter;
 	struct cgit_filter *commit_filter;
 	struct cgit_filter *source_filter;
@@ -389,5 +390,6 @@ extern int readfile(const char *path, char **buf, size_t *size);
 extern char *expand_macros(const char *txt);
 
 extern char *get_mimetype_for_filename(const char *filename);
+extern struct cgit_filter *get_render_for_filename(const char *filename);
 
 #endif /* CGIT_H */
diff --git a/cgitrc.5.txt b/cgitrc.5.txt
index 4da166c..793a0c1 100644
--- a/cgitrc.5.txt
+++ b/cgitrc.5.txt
@@ -359,6 +359,17 @@ renamelimit::
 	 "-1" uses the compiletime value in git (for further info, look at
 	  `man git-diff`). Default value: "-1".
 
+render.<ext>::
+	Specifies a command which will be invoked to render files with the
+	extension `.<ext>`. The command will get the blob content on its STDIN
+	and the name of the blob as its only command line argument. The STDOUT
+	from the command will be included verbatim in the page content. If no
+	render filter is available for a given file extension but the mimetype
+	is specified then the content will be included as an iframe, otherwise
+	the normal source rendering will be used.
++
+Default value: none. See also: "FILTER API".
+
 repo.group::
 	Legacy alias for "section". This option is deprecated and will not be
 	supported in cgit-1.0.
@@ -699,6 +710,13 @@ source filter::
 	file that is to be filtered is available on standard input and the
 	filtered contents is expected on standard output.
 
+render filter::
+	This filter is given a single parameter: the filename of the source
+	file to render. The filter can use the filename to determine (for
+	example) the syntax highlighting mode. The contents of the file that
+	is to be rendered is available on standard input and the rendered
+	content is expected on standard output.
+
 auth filter::
 	The authentication filter receives 12 parameters:
 	  - filter action, explained below, which specifies which action the
diff --git a/filter.c b/filter.c
index 70f5b74..4ae4aaa 100644
--- a/filter.c
+++ b/filter.c
@@ -434,6 +434,7 @@ struct cgit_filter *cgit_new_filter(const char *cmd, filter_type filtertype)
 
 		case SOURCE:
 		case ABOUT:
+		case RENDER:
 			argument_count = 1;
 			break;
 
diff --git a/shared.c b/shared.c
index 477db0a..128c323 100644
--- a/shared.c
+++ b/shared.c
@@ -571,3 +571,24 @@ char *get_mimetype_for_filename(const char *filename)
 	fclose(file);
 	return NULL;
 }
+
+struct cgit_filter *get_render_for_filename(const char *filename)
+{
+	char *ext;
+	struct string_list_item *item;
+
+	if (!filename)
+		return NULL;
+
+	ext = strrchr(filename, '.');
+	if (!ext)
+		return NULL;
+	++ext;
+	if (!ext[0])
+		return NULL;
+	item = string_list_lookup(&ctx.cfg.render_filters, ext);
+	if (item)
+		return item->util;
+
+	return NULL;
+}



^ permalink raw reply	[flat|nested] 140+ messages in thread

* [PATCH 04/11] ui-tree: split out buffer printing
  2018-06-13  2:01                 ` [PATCH 00/11] Render READMEs inline in tree view andy
                                     ` (2 preceding siblings ...)
  2018-06-13  2:01                   ` [PATCH 03/11] Parse render filters from the config andy
@ 2018-06-13  2:01                   ` andy
  2018-06-13  2:01                   ` [PATCH 05/11] ui-tree: use render fileters to display content andy
                                     ` (9 subsequent siblings)
  13 siblings, 0 replies; 140+ messages in thread
From: andy @ 2018-06-13  2:01 UTC (permalink / raw)


From: John Keeping <john at keeping.me.uk>

Signed-off-by: John Keeping <john at keeping.me.uk>
---
 ui-tree.c |   25 +++++++++++++++----------
 1 file changed, 15 insertions(+), 10 deletions(-)

diff --git a/ui-tree.c b/ui-tree.c
index 67fd1bc..009e201 100644
--- a/ui-tree.c
+++ b/ui-tree.c
@@ -84,6 +84,20 @@ static void print_binary_buffer(char *buf, unsigned long size)
 	html("</table>\n");
 }
 
+static void print_buffer(const char *basename, char *buf, unsigned long size)
+{
+	if (ctx.cfg.max_blob_size && size / 1024 > ctx.cfg.max_blob_size) {
+		htmlf("<div class='error'>blob size (%ldKB) exceeds display size limit (%dKB).</div>",
+				size / 1024, ctx.cfg.max_blob_size);
+		return;
+	}
+
+	if (buffer_is_binary(buf, size))
+		print_binary_buffer(buf, size);
+	else
+		print_text_buffer(basename, buf, size);
+}
+
 static void print_object(const unsigned char *sha1, char *path, const char *basename, const char *rev)
 {
 	enum object_type type;
@@ -117,16 +131,7 @@ static void print_object(const unsigned char *sha1, char *path, const char *base
 	}
 	html(")\n");
 
-	if (ctx.cfg.max_blob_size && size / 1024 > ctx.cfg.max_blob_size) {
-		htmlf("<div class='error'>blob size (%ldKB) exceeds display size limit (%dKB).</div>",
-				size / 1024, ctx.cfg.max_blob_size);
-		return;
-	}
-
-	if (buffer_is_binary(buf, size))
-		print_binary_buffer(buf, size);
-	else
-		print_text_buffer(basename, buf, size);
+	print_buffer(basename, buf, size);
 }
 
 struct single_tree_ctx {



^ permalink raw reply	[flat|nested] 140+ messages in thread

* [PATCH 05/11] ui-tree: use render fileters to display content
  2018-06-13  2:01                 ` [PATCH 00/11] Render READMEs inline in tree view andy
                                     ` (3 preceding siblings ...)
  2018-06-13  2:01                   ` [PATCH 04/11] ui-tree: split out buffer printing andy
@ 2018-06-13  2:01                   ` andy
  2018-06-16 14:26                     ` john
  2018-06-13  2:02                   ` [PATCH 06/11] ui-tree: free read_sha1_file() buffer after use andy
                                     ` (8 subsequent siblings)
  13 siblings, 1 reply; 140+ messages in thread
From: andy @ 2018-06-13  2:01 UTC (permalink / raw)


From: John Keeping <john at keeping.me.uk>

This allows applying filters to files in the repository, for example to
render Markdown or AsciiDoc as HTML.

Signed-off-by: John Keeping <john at keeping.me.uk>
---
 cgit.css  |    5 +++
 cmd.c     |    4 +-
 ui-tree.c |  105 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---
 ui-tree.h |    2 +
 4 files changed, 107 insertions(+), 9 deletions(-)

diff --git a/cgit.css b/cgit.css
index 217a05a..da8d9b0 100644
--- a/cgit.css
+++ b/cgit.css
@@ -274,6 +274,11 @@ div#cgit div#blob {
 	border: solid 1px black;
 }
 
+div#cgit iframe {
+	width: 100%;
+	height: 40em;
+}
+
 div#cgit div.error {
 	color: red;
 	font-weight: bold;
diff --git a/cmd.c b/cmd.c
index 56e21df..ca48b2f 100644
--- a/cmd.c
+++ b/cmd.c
@@ -140,7 +140,7 @@ static void refs_fn(void)
 
 static void source_fn(void)
 {
-	cgit_print_tree(ctx.qry.sha1, ctx.qry.path);
+	cgit_print_tree(ctx.qry.sha1, ctx.qry.path, false);
 }
 
 static void snapshot_fn(void)
@@ -166,7 +166,7 @@ static void tag_fn(void)
 
 static void tree_fn(void)
 {
-	cgit_print_tree(ctx.qry.sha1, ctx.qry.path);
+	cgit_print_tree(ctx.qry.sha1, ctx.qry.path, true);
 }
 
 #define def_cmd(name, want_repo, want_vpath, is_clone) \
diff --git a/ui-tree.c b/ui-tree.c
index 009e201..723e16e 100644
--- a/ui-tree.c
+++ b/ui-tree.c
@@ -15,6 +15,7 @@ struct walk_tree_context {
 	char *curr_rev;
 	char *match_path;
 	int state;
+	bool use_render;
 };
 
 static void print_text_buffer(const char *name, char *buf, unsigned long size)
@@ -98,10 +99,70 @@ static void print_buffer(const char *basename, char *buf, unsigned long size)
 		print_text_buffer(basename, buf, size);
 }
 
-static void print_object(const unsigned char *sha1, char *path, const char *basename, const char *rev)
+static void render_buffer(struct cgit_filter *render, const char *name,
+		char *buf, unsigned long size)
+{
+	char *filter_arg = xstrdup(name);
+
+	html("<div class='blob'>");
+	cgit_open_filter(render, filter_arg);
+	html_raw(buf, size);
+	cgit_close_filter(render);
+	html("</div>");
+
+	free(filter_arg);
+}
+
+static void include_file(const unsigned char *sha1, const char *path,
+		const char *mimetype)
+{
+	const char *delim = "?";
+
+	html("<div class='blob'>");
+
+	if (!strncmp(mimetype, "image/", 6)) {
+		html("<img alt='");
+		html_attr(path);
+		html("' src='");
+	} else {
+		html("<iframe sandbox='allow-scripts' src='");
+	}
+
+	if (ctx.cfg.virtual_root) {
+		html_url_path(ctx.cfg.virtual_root);
+		html_url_path(ctx.repo->url);
+		if (ctx.repo->url[strlen(ctx.repo->url) - 1] != '/')
+			html("/");
+		html("plain/");
+		html_url_path(path);
+	} else {
+		html_url_path(ctx.cfg.script_name);
+		html("?url=");
+		html_url_arg(ctx.repo->url);
+		if (ctx.repo->url[strlen(ctx.repo->url) - 1] != '/')
+			html("/");
+		html("plain/");
+		if (path)
+			html_url_arg(path);
+		delim = "&";
+	}
+	if (ctx.qry.head && ctx.repo->defbranch &&
+	    strcmp(ctx.qry.head, ctx.repo->defbranch)) {
+		html(delim);
+		html("h=");
+		html_url_arg(ctx.qry.head);
+		delim = "&";
+	}
+
+	html("'></div>");
+}
+
+static void print_object(const unsigned char *sha1, char *path, const char *basename,
+			 const char *rev, bool use_render)
 {
 	enum object_type type;
-	char *buf;
+	struct cgit_filter *render;
+	char *buf, *mimetype;
 	unsigned long size;
 
 	type = sha1_object_info(sha1, &size);
@@ -118,20 +179,49 @@ static void print_object(const unsigned char *sha1, char *path, const char *base
 		return;
 	}
 
+	render = get_render_for_filename(path);
+	mimetype = render ? NULL : get_mimetype_for_filename(path);
+
 	cgit_set_title_from_path(path);
 
+	/*
+	 * If we don't have a render filter or a mimetype, we won't include the
+	 * file in the page.
+	 */
+	if (!render && !mimetype)
+		use_render = false;
+
 	cgit_print_layout_start();
 	htmlf("blob: %s (", sha1_to_hex(sha1));
 	cgit_plain_link("plain", NULL, NULL, ctx.qry.head,
 		        rev, path);
+
 	if (ctx.cfg.enable_blame) {
 		html(") (");
 		cgit_blame_link("blame", NULL, NULL, ctx.qry.head,
 			        rev, path);
 	}
+	if (use_render) {
+		html(", ");
+		cgit_source_link("source", NULL, NULL, ctx.qry.head,
+				rev, path);
+	} else if (render || mimetype) {
+		html(", ");
+		cgit_tree_link("render", NULL, NULL, ctx.qry.head,
+			       rev, path);
+	}
 	html(")\n");
 
-	print_buffer(basename, buf, size);
+	if (use_render) {
+		if (render)
+			render_buffer(render, basename, buf, size);
+		else
+			include_file(sha1, path, mimetype);
+	} else {
+		print_buffer(basename, buf, size);
+	}
+
+	free(mimetype);
 }
 
 struct single_tree_ctx {
@@ -323,8 +413,10 @@ static int walk_tree(const unsigned char *sha1, struct strbuf *base,
 			return READ_TREE_RECURSIVE;
 		} else {
 			walk_tree_ctx->state = 2;
-			print_object(sha1, buffer.buf, pathname, walk_tree_ctx->curr_rev);
+			print_object(sha1, buffer.buf, pathname, walk_tree_ctx->curr_rev,
+				     walk_tree_ctx->use_render);
 			strbuf_release(&buffer);
+
 			return 0;
 		}
 	}
@@ -337,7 +429,7 @@ static int walk_tree(const unsigned char *sha1, struct strbuf *base,
  *   rev:  the commit pointing at the root tree object
  *   path: path to tree or blob
  */
-void cgit_print_tree(const char *rev, char *path)
+void cgit_print_tree(const char *rev, char *path, bool use_render)
 {
 	struct object_id oid;
 	struct commit *commit;
@@ -351,7 +443,8 @@ void cgit_print_tree(const char *rev, char *path)
 	};
 	struct walk_tree_context walk_tree_ctx = {
 		.match_path = path,
-		.state = 0
+		.state = 0,
+		.use_render = use_render,
 	};
 
 	if (!rev)
diff --git a/ui-tree.h b/ui-tree.h
index bbd34e3..a0fc8e2 100644
--- a/ui-tree.h
+++ b/ui-tree.h
@@ -1,6 +1,6 @@
 #ifndef UI_TREE_H
 #define UI_TREE_H
 
-extern void cgit_print_tree(const char *rev, char *path);
+extern void cgit_print_tree(const char *rev, char *path, bool use_render);
 
 #endif /* UI_TREE_H */



^ permalink raw reply	[flat|nested] 140+ messages in thread

* [PATCH 06/11] ui-tree: free read_sha1_file() buffer after use
  2018-06-13  2:01                 ` [PATCH 00/11] Render READMEs inline in tree view andy
                                     ` (4 preceding siblings ...)
  2018-06-13  2:01                   ` [PATCH 05/11] ui-tree: use render fileters to display content andy
@ 2018-06-13  2:02                   ` andy
  2018-06-16 14:24                     ` john
  2018-06-13  2:02                   ` [PATCH 07/11] ui-blame: " andy
                                     ` (7 subsequent siblings)
  13 siblings, 1 reply; 140+ messages in thread
From: andy @ 2018-06-13  2:02 UTC (permalink / raw)


Free up the buffer allocated in read_sha1_file()

Signed-off-by: Andy Green <andy at warmcat.com>
---
 ui-tree.c |    1 +
 1 file changed, 1 insertion(+)

diff --git a/ui-tree.c b/ui-tree.c
index 723e16e..fe5dc75 100644
--- a/ui-tree.c
+++ b/ui-tree.c
@@ -222,6 +222,7 @@ static void print_object(const unsigned char *sha1, char *path, const char *base
 	}
 
 	free(mimetype);
+	free(buf);
 }
 
 struct single_tree_ctx {



^ permalink raw reply	[flat|nested] 140+ messages in thread

* [PATCH 07/11] ui-blame: free read_sha1_file() buffer after use
  2018-06-13  2:01                 ` [PATCH 00/11] Render READMEs inline in tree view andy
                                     ` (5 preceding siblings ...)
  2018-06-13  2:02                   ` [PATCH 06/11] ui-tree: free read_sha1_file() buffer after use andy
@ 2018-06-13  2:02                   ` andy
  2018-06-16 14:23                     ` john
  2018-06-13  2:02                   ` [PATCH 08/11] ui-tree: print_object: add is_inline param andy
                                     ` (6 subsequent siblings)
  13 siblings, 1 reply; 140+ messages in thread
From: andy @ 2018-06-13  2:02 UTC (permalink / raw)


Signed-off-by: Andy Green <andy at warmcat.com>
---
 ui-blame.c |    3 +++
 1 file changed, 3 insertions(+)

diff --git a/ui-blame.c b/ui-blame.c
index 17e2d60..a5c7d69 100644
--- a/ui-blame.c
+++ b/ui-blame.c
@@ -206,6 +206,9 @@ static void print_object(const unsigned char *sha1, const char *path,
 	} else {
 		html_txt(buf);
 	}
+
+	free(buf);
+
 	html("</code></pre>");
 
 	html("</div></td>\n");



^ permalink raw reply	[flat|nested] 140+ messages in thread

* [PATCH 08/11] ui-tree: print_object: add is_inline param
  2018-06-13  2:01                 ` [PATCH 00/11] Render READMEs inline in tree view andy
                                     ` (6 preceding siblings ...)
  2018-06-13  2:02                   ` [PATCH 07/11] ui-blame: " andy
@ 2018-06-13  2:02                   ` andy
  2018-06-16 14:38                     ` john
  2018-06-13  2:02                   ` [PATCH 09/11] ui-tree: ls_tail: add walk table param andy
                                     ` (5 subsequent siblings)
  13 siblings, 1 reply; 140+ messages in thread
From: andy @ 2018-06-13  2:02 UTC (permalink / raw)


We will reuse print_object to render things inline shortly.

Add a parameter that lets us adapt its behaviour slightly
for that case.

Signed-off-by: Andy Green <andy at warmcat.com>
---
 ui-tree.c |    7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/ui-tree.c b/ui-tree.c
index fe5dc75..bb10b17 100644
--- a/ui-tree.c
+++ b/ui-tree.c
@@ -158,7 +158,7 @@ static void include_file(const unsigned char *sha1, const char *path,
 }
 
 static void print_object(const unsigned char *sha1, char *path, const char *basename,
-			 const char *rev, bool use_render)
+			 const char *rev, bool use_render, bool is_inline)
 {
 	enum object_type type;
 	struct cgit_filter *render;
@@ -191,7 +191,8 @@ static void print_object(const unsigned char *sha1, char *path, const char *base
 	if (!render && !mimetype)
 		use_render = false;
 
-	cgit_print_layout_start();
+	if (!is_inline)
+		cgit_print_layout_start();
 	htmlf("blob: %s (", sha1_to_hex(sha1));
 	cgit_plain_link("plain", NULL, NULL, ctx.qry.head,
 		        rev, path);
@@ -415,7 +416,7 @@ static int walk_tree(const unsigned char *sha1, struct strbuf *base,
 		} else {
 			walk_tree_ctx->state = 2;
 			print_object(sha1, buffer.buf, pathname, walk_tree_ctx->curr_rev,
-				     walk_tree_ctx->use_render);
+				     walk_tree_ctx->use_render, 0);
 			strbuf_release(&buffer);
 
 			return 0;



^ permalink raw reply	[flat|nested] 140+ messages in thread

* [PATCH 09/11] ui-tree: ls_tail: add walk table param
  2018-06-13  2:01                 ` [PATCH 00/11] Render READMEs inline in tree view andy
                                     ` (7 preceding siblings ...)
  2018-06-13  2:02                   ` [PATCH 08/11] ui-tree: print_object: add is_inline param andy
@ 2018-06-13  2:02                   ` andy
  2018-06-16 14:38                     ` john
  2018-06-13  2:02                   ` [PATCH 10/11] config: add tree-readme list andy
                                     ` (4 subsequent siblings)
  13 siblings, 1 reply; 140+ messages in thread
From: andy @ 2018-06-13  2:02 UTC (permalink / raw)


Arrange that walk_tree_ctx is available in ls_tail, we
will make use of it shortly.

Signed-off-by: Andy Green <andy at warmcat.com>
---
 ui-tree.c |    6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/ui-tree.c b/ui-tree.c
index bb10b17..53b5594 100644
--- a/ui-tree.c
+++ b/ui-tree.c
@@ -368,7 +368,7 @@ static void ls_head(void)
 	html("</tr>\n");
 }
 
-static void ls_tail(void)
+static void ls_tail(struct walk_tree_context *walk_tree_ctx)
 {
 	html("</table>\n");
 	cgit_print_layout_end();
@@ -390,7 +390,7 @@ static void ls_tree(const struct object_id *oid, char *path, struct walk_tree_co
 
 	ls_head();
 	read_tree_recursive(tree, "", 0, 1, &paths, ls_item, walk_tree_ctx);
-	ls_tail();
+	ls_tail(walk_tree_ctx);
 }
 
 
@@ -473,7 +473,7 @@ void cgit_print_tree(const char *rev, char *path, bool use_render)
 
 	read_tree_recursive(commit->tree, "", 0, 0, &paths, walk_tree, &walk_tree_ctx);
 	if (walk_tree_ctx.state == 1)
-		ls_tail();
+		ls_tail(&walk_tree_ctx);
 	else if (walk_tree_ctx.state == 2)
 		cgit_print_layout_end();
 	else



^ permalink raw reply	[flat|nested] 140+ messages in thread

* [PATCH 10/11] config: add tree-readme list
  2018-06-13  2:01                 ` [PATCH 00/11] Render READMEs inline in tree view andy
                                     ` (8 preceding siblings ...)
  2018-06-13  2:02                   ` [PATCH 09/11] ui-tree: ls_tail: add walk table param andy
@ 2018-06-13  2:02                   ` andy
  2018-06-16 14:44                     ` john
  2018-06-13  2:02                   ` [PATCH 11/11] ui-tree: render any matching README file in tree view andy
                                     ` (3 subsequent siblings)
  13 siblings, 1 reply; 140+ messages in thread
From: andy @ 2018-06-13  2:02 UTC (permalink / raw)


Allows the user to specify a list of filenames that should be
rendered inline with tree view, if present in the directory.

Signed-off-by: Andy Green <andy at warmcat.com>
---
 cgit.c       |   11 ++++++++++-
 cgit.h       |    1 +
 cgitrc.5.txt |    7 +++++++
 3 files changed, 18 insertions(+), 1 deletion(-)

diff --git a/cgit.c b/cgit.c
index 975e573..017ce78 100644
--- a/cgit.c
+++ b/cgit.c
@@ -1,6 +1,6 @@
 /* cgit.c: cgi for the git scm
  *
- * Copyright (C) 2006-2014 cgit Development Team <cgit at lists.zx2c4.com>
+ * Copyright (C) 2006-2018 cgit Development Team <cgit at lists.zx2c4.com>
  *
  * Licensed under GNU General Public License v2
  *   (see COPYING for full license text)
@@ -39,6 +39,12 @@ static void add_render_filter(const char *name, const char *cmd)
 	item->util = filter;
 }
 
+static void add_tree_readme(const char *name)
+{
+	string_list_insert(&ctx.cfg.tree_readme, name);
+}
+
+
 static void process_cached_repolist(const char *path);
 
 static void repo_config(struct cgit_repo *repo, const char *name, const char *value)
@@ -301,6 +307,8 @@ static void config_cb(const char *name, const char *value)
 		add_mimetype(name + 9, value);
 	else if (starts_with(name, "render."))
 		add_render_filter(name + 7, value);
+	else if (!strcmp(name, "tree-readme"))
+		add_tree_readme(value);
 	else if (!strcmp(name, "include"))
 		parse_configfile(expand_macros(value), config_cb);
 }
@@ -435,6 +443,7 @@ static void prepare_context(void)
 	ctx.page.etag = NULL;
 	string_list_init(&ctx.cfg.mimetypes, 1);
 	string_list_init(&ctx.cfg.render_filters, 1);
+	string_list_init(&ctx.cfg.tree_readme, 1);
 	if (ctx.env.script_name)
 		ctx.cfg.script_name = xstrdup(ctx.env.script_name);
 	if (ctx.env.query_string)
diff --git a/cgit.h b/cgit.h
index a19742f..1076568 100644
--- a/cgit.h
+++ b/cgit.h
@@ -261,6 +261,7 @@ struct cgit_config {
 	int branch_sort;
 	int commit_sort;
 	struct string_list mimetypes;
+	struct string_list tree_readme;
 	struct string_list render_filters;
 	struct cgit_filter *about_filter;
 	struct cgit_filter *commit_filter;
diff --git a/cgitrc.5.txt b/cgitrc.5.txt
index 793a0c1..5111197 100644
--- a/cgitrc.5.txt
+++ b/cgitrc.5.txt
@@ -469,6 +469,13 @@ strict-export::
 	repositories to match those exported by git-daemon. This option must
 	be defined prior to scan-path.
 
+tree-readme::
+	Append given filename to the list of filenames to be rendered after the
+	tree navigation in tree view, if present in the directory being viewed.  Eg,
+	'tree-readme=README.md'.  There must also be a corresponding render.
+	entry for the readme suffix, eg,
+	'render.md=/usr/libexec/cgit/filters/html-converters/md2html'
+
 virtual-root::
 	Url which, if specified, will be used as root for all cgit links. It
 	will also cause cgit to generate 'virtual urls', i.e. urls like



^ permalink raw reply	[flat|nested] 140+ messages in thread

* [PATCH 11/11] ui-tree: render any matching README file in tree view
  2018-06-13  2:01                 ` [PATCH 00/11] Render READMEs inline in tree view andy
                                     ` (9 preceding siblings ...)
  2018-06-13  2:02                   ` [PATCH 10/11] config: add tree-readme list andy
@ 2018-06-13  2:02                   ` andy
  2018-06-16 14:58                     ` john
  2018-06-14  3:47                   ` [PATCH 00/11] Render READMEs inline " andy
                                     ` (2 subsequent siblings)
  13 siblings, 1 reply; 140+ messages in thread
From: andy @ 2018-06-13  2:02 UTC (permalink / raw)


While listing the items in tree view, we collect a list
of any filenames that match any tree-readme entries from the
config file.

After the tree view has been shown, we iterate through any
collected readme files rendering them inline.

Signed-off-by: Andy Green <andy at warmcat.com>
---
 ui-tree.c |   77 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 75 insertions(+), 2 deletions(-)

diff --git a/ui-tree.c b/ui-tree.c
index 53b5594..4dde2a5 100644
--- a/ui-tree.c
+++ b/ui-tree.c
@@ -1,6 +1,6 @@
 /* ui-tree.c: functions for tree output
  *
- * Copyright (C) 2006-2017 cgit Development Team <cgit at lists.zx2c4.com>
+ * Copyright (C) 2006-2018 cgit Development Team <cgit at lists.zx2c4.com>
  *
  * Licensed under GNU General Public License v2
  *   (see COPYING for full license text)
@@ -11,13 +11,58 @@
 #include "html.h"
 #include "ui-shared.h"
 
+struct file_list {
+	struct object_id oid;
+	struct file_list *next;
+	const char *path;
+};
+
 struct walk_tree_context {
 	char *curr_rev;
 	char *match_path;
+	struct file_list *render_list;
 	int state;
 	bool use_render;
 };
 
+static void
+walk_tree_cleanup(struct walk_tree_context *wt)
+{
+	struct file_list *f = wt->render_list;
+
+	free(wt->curr_rev);
+
+	while (f) {
+		struct file_list *tmp = f->next;
+
+		free((void *)f->path);
+		free(f);
+		f = tmp;
+	}
+}
+
+static int
+walk_tree_render_list_add(struct walk_tree_context *wt, const char *path,
+			  const unsigned char *sha1)
+{
+	struct file_list *f = xmalloc(sizeof(*f));
+
+	if (!f)
+		return 1;
+
+	f->next = wt->render_list;
+	f->path = xstrdup(path);
+	if (!f->path) {
+		free(f);
+
+		return 1;
+	}
+	memcpy(f->oid.hash, sha1, sizeof(f->oid.hash));
+	wt->render_list = f;
+
+	return 0;
+}
+
 static void print_text_buffer(const char *name, char *buf, unsigned long size)
 {
 	unsigned long lineno, idx;
@@ -327,12 +372,21 @@ static int ls_item(const unsigned char *sha1, struct strbuf *base,
 		write_tree_link(sha1, name, walk_tree_ctx->curr_rev,
 				&fullpath);
 	} else {
+		struct string_list_item *entry;
 		char *ext = strrchr(name, '.');
+	
 		strbuf_addstr(&class, "ls-blob");
 		if (ext)
 			strbuf_addf(&class, " %s", ext + 1);
+
 		cgit_tree_link(name, NULL, class.buf, ctx.qry.head,
 			       walk_tree_ctx->curr_rev, fullpath.buf);
+
+		for_each_string_list_item(entry, &ctx.cfg.tree_readme) {
+			if (!strcmp(name, entry->string))
+				walk_tree_render_list_add(walk_tree_ctx,
+							  pathname, sha1);
+		}
 	}
 	htmlf("</td><td class='ls-size'>%li</td>", size);
 
@@ -370,7 +424,24 @@ static void ls_head(void)
 
 static void ls_tail(struct walk_tree_context *walk_tree_ctx)
 {
+	struct file_list *f = walk_tree_ctx->render_list;
+	enum object_type type;
+	unsigned long size;
+
 	html("</table>\n");
+
+	while (f) {
+		/* create a vertical gap between tree nav / renders */
+		html("<table><tr><td>&nbsp;</td></tr></table>");
+
+		type = sha1_object_info(f->oid.hash, &size);
+		if (type != OBJ_BAD)
+			print_object(f->oid.hash, (char *)f->path,
+				     "", walk_tree_ctx->curr_rev, 1, 1);
+
+		f = f->next;
+	}
+
 	cgit_print_layout_end();
 }
 
@@ -444,7 +515,9 @@ void cgit_print_tree(const char *rev, char *path, bool use_render)
 		.items = &path_items
 	};
 	struct walk_tree_context walk_tree_ctx = {
+		.curr_rev = NULL,
 		.match_path = path,
+		.render_list = NULL,
 		.state = 0,
 		.use_render = use_render,
 	};
@@ -480,5 +553,5 @@ void cgit_print_tree(const char *rev, char *path, bool use_render)
 		cgit_print_error_page(404, "Not found", "Path not found");
 
 cleanup:
-	free(walk_tree_ctx.curr_rev);
+	walk_tree_cleanup(&walk_tree_ctx);
 }



^ permalink raw reply	[flat|nested] 140+ messages in thread

* [PATCH 00/11] Render READMEs inline in tree view
  2018-06-13  2:01                 ` [PATCH 00/11] Render READMEs inline in tree view andy
                                     ` (10 preceding siblings ...)
  2018-06-13  2:02                   ` [PATCH 11/11] ui-tree: render any matching README file in tree view andy
@ 2018-06-14  3:47                   ` andy
  2018-06-16 14:17                     ` john
  2018-06-19  9:01                   ` [PATCH v3 00/17] " andy
  2018-06-20 10:11                   ` [PATCH v4 00/16] Render READMEs inline in tree view andy
  13 siblings, 1 reply; 140+ messages in thread
From: andy @ 2018-06-14  3:47 UTC (permalink / raw)




On 06/13/2018 10:01 AM, Andy Green wrote:
> The following series adds config to allow rendering of
> selected READMEs inline after the tree view, where
> present in the directory being viewed.
> 
> It builds on John Keeping's RENDER mode series from 2016.
> 
> Typical config to enable it, if you have a README.md
> looks like
> 
> tree-readme=README.md
> render.md=/usr/libexec/cgit/filters/html-converters/md2html

I have updated this against Christian's git 2.18.0-rc2 patch from 
earlier, rather than post it to the list again before any comment you 
can find it here if you're interested.

https://warmcat.com/git/cgit/

Presumably this is what should be targeted for the next push rather than 
current master.

-Andy


^ permalink raw reply	[flat|nested] 140+ messages in thread

* Rendering of README.md inline with inner tree view dirs
  2018-06-13  1:47               ` andy
  2018-06-13  2:01                 ` [PATCH 00/11] Render READMEs inline in tree view andy
@ 2018-06-16 14:12                 ` john
  2018-06-16 17:35                   ` john
  1 sibling, 1 reply; 140+ messages in thread
From: john @ 2018-06-16 14:12 UTC (permalink / raw)


On Wed, Jun 13, 2018 at 09:47:38AM +0800, Andy Green wrote:
> 
> 
> On 06/12/2018 05:31 PM, John Keeping wrote:
> > On Tue, Jun 12, 2018 at 01:53:27PM +0800, Andy Green wrote:
> >> On 06/11/2018 11:38 PM, John Keeping wrote:
> >>> On Mon, Jun 11, 2018 at 04:05:38PM +0800, Andy Green wrote:
> 
> >> 1) I did not attempt to have it learn about suitable filenames from the
> >> config yet, I just have ls_item() looking for "README.md".  I saw
> >> there's already a way (readme=) for the config to list them for the
> >> about page... basically now tree view becomes a superset of the
> >> operation of the about page; the about page content appears in tree view.
> >>
> >> So do you have any thoughts about just re-using that list?
> > 
> > I think that list is refs to blobs, so you can specify something like:
> > 
> > 	refs/heads/wiki:README.md
> > 
> > but here we need base filenames to look for in the current directory, so
> > it will have to be a new config variable.
> 
> OK.  I added a new cgit-scope variable that appends filenames to be 
> considered for showing in tree view, eg,
> 
> tree-readme=README.md

This should be overridable at the repo level to match our other
configuration variables which affect this sort of behaviour.

Also, if this was my bikeshed I'd paint it as "inline-readme", but I
don't feel strongly about that.

> >> 2) In the current patches, I allowed for ls_item to discover a
> >> linked-list of files and render them later one after the other.  Eg, a
> >> dir of READMEs would render them like that.  It's welcome or preferable
> >> to just restrict it to one?
> > 
> > My choice would be to take the first matching file, but I don't have a
> > strong opinion on what is the right behaviour.
> 
> I'll leave this as a list for the first try.  If it looks excessive I'll 
> reduce it to just the one.

The code is definitely simpler if it's just one, and I'm not sure what
benefit we get from including multiple files.  But if you have a use
case for multiple readme files, then a list is okay.

> >> 3) You can see on the top level of the tree, the README.md references
> >>
> >> <img alt="lws-overview" src="./doc-assets/lws-overview.png">
> >>
> >> This url format works in github.  In the cgit About view, this resolves to
> >>
> >> /git/libwebsockets/about/doc-assets/lws-overview.png
> >>
> >> which also serves the right mimetype and content.  So that kind of URL
> >> format is useful.  But when we render the same markup and relative path
> >> via /tree/, it tries to show an html page containing the content.
> >> That's why the picture is missing in the /tree/ view... other pictures
> >> in that markup are coming with absolute URLs outside of cgit and are
> >> working.
> >>
> >> I can have the direct content from cgit generally, but either the markup
> >> needs fixing up to
> >>
> >> /git/libwebsockets/plain/doc-assets/lws-overview.png
> >>
> >> or /tree/ needs to learn to do what /about/ does.
> >>
> >> I'm wondering whether mmd2html might grow an environment var to know the
> >> base part for URLS that want to direct-render from cgit.  Or if better
> >> to follow what /about/ did in /tree/.
> > 
> > Making tree do this will break the normal use of tree unless we add some
> > extra query parameter or path element.  Given that, I think teaching the
> > renderer to use a path to /about/ is the right thing to do.
> 
> OK.  Unfortunately I don't know python very well.  It looks like the 
> markdown python library is able to be told to use extensions that are 
> capable to do this
> 
> https://python-markdown.github.io/extensions/api/
> 
> from the md2html wrapper.  But I don't know enough python to do it.
> 
> It's a shame, because in-tree assets correctly follow the ref context 
> being viewed, eg, if you look at a v2 branch you see v2 pngs, master you 
> see master pngs etc.
> 
> I'll "solve" this part for now by changing the README to use external URLs.

Yeah, I think we have to solve it by having the filter apply a mapping.
We have ui-plain which provides the right content for images, but what
should we do for link targets?

For the purpose of discussion, consider the following HTML fragment that
could be generated by rendering a README file:

	<img src="dataflow.png">
	<p>For more details see <a href="dataflow.html">the dedicated
	data flow document.</p>

If dataflow.html is generated from a source file in a similar way, then
it doesn't exist in the repository and we can't link to it, so the ideal
output ends up being something like:

	<img src="/repo/plain/dataflow.png">
	<p>For more details see <a href="dataflow.txt">the dedicated
	data flow document.</p>

The render filter API isn't finalised yet, so we can change the
parameters that are passed in order to add more information for the
renderer to use.  At the very least I think we should add a parameter
for the asset prefix which is essentially the tree path with /tree/
replaces with /plain/.

However, I'm not sure how to handle relative links: do we need to pass
additional parameters for this?  Or can we rely on a render filter doing
the right thing?


Regards,
John


^ permalink raw reply	[flat|nested] 140+ messages in thread

* [PATCH 00/11] Render READMEs inline in tree view
  2018-06-14  3:47                   ` [PATCH 00/11] Render READMEs inline " andy
@ 2018-06-16 14:17                     ` john
  0 siblings, 0 replies; 140+ messages in thread
From: john @ 2018-06-16 14:17 UTC (permalink / raw)


On Thu, Jun 14, 2018 at 11:47:41AM +0800, Andy Green wrote:
> On 06/13/2018 10:01 AM, Andy Green wrote:
> > The following series adds config to allow rendering of
> > selected READMEs inline after the tree view, where
> > present in the directory being viewed.
> > 
> > It builds on John Keeping's RENDER mode series from 2016.
> > 
> > Typical config to enable it, if you have a README.md
> > looks like
> > 
> > tree-readme=README.md
> > render.md=/usr/libexec/cgit/filters/html-converters/md2html
> 
> I have updated this against Christian's git 2.18.0-rc2 patch from 
> earlier, rather than post it to the list again before any comment you 
> can find it here if you're interested.
> 
> https://warmcat.com/git/cgit/
> 
> Presumably this is what should be targeted for the next push rather than 
> current master.

I think that makes sense, yes.  Git 2.18.0 final is due out tomorrow [1]
so we should get the version bump committed pretty soon.


[1] https://tinyurl.com/gitcal


^ permalink raw reply	[flat|nested] 140+ messages in thread

* [PATCH 07/11] ui-blame: free read_sha1_file() buffer after use
  2018-06-13  2:02                   ` [PATCH 07/11] ui-blame: " andy
@ 2018-06-16 14:23                     ` john
  2018-06-16 23:17                       ` andy
  0 siblings, 1 reply; 140+ messages in thread
From: john @ 2018-06-16 14:23 UTC (permalink / raw)


On Wed, Jun 13, 2018 at 10:02:05AM +0800, Andy Green wrote:
> Signed-off-by: Andy Green <andy at warmcat.com>
> ---
>  ui-blame.c |    3 +++
>  1 file changed, 3 insertions(+)
> 
> diff --git a/ui-blame.c b/ui-blame.c
> index 17e2d60..a5c7d69 100644
> --- a/ui-blame.c
> +++ b/ui-blame.c
> @@ -206,6 +206,9 @@ static void print_object(const unsigned char *sha1, const char *path,

There's an early return above here after allocating buf, I'm not sure if
we care about freeing buf on that path as well.

If we do, I guess we push free(buf) to the end and add a free_buf label
for the error path to jump to.

>  	} else {
>  		html_txt(buf);
>  	}
> +
> +	free(buf);
> +
>  	html("</code></pre>");
>  
>  	html("</div></td>\n");
> 


^ permalink raw reply	[flat|nested] 140+ messages in thread

* [PATCH 06/11] ui-tree: free read_sha1_file() buffer after use
  2018-06-13  2:02                   ` [PATCH 06/11] ui-tree: free read_sha1_file() buffer after use andy
@ 2018-06-16 14:24                     ` john
  0 siblings, 0 replies; 140+ messages in thread
From: john @ 2018-06-16 14:24 UTC (permalink / raw)


On Wed, Jun 13, 2018 at 10:02:00AM +0800, Andy Green wrote:
> Free up the buffer allocated in read_sha1_file()
> 
> Signed-off-by: Andy Green <andy at warmcat.com>

Reviewed-by: John Keeping <john at keeping.me.uk>

I've extracted this from the series and pushed it on my for-jason
branch: https://git.zx2c4.com/cgit/log/?h=jk/for-jason

> ---
>  ui-tree.c |    1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/ui-tree.c b/ui-tree.c
> index 723e16e..fe5dc75 100644
> --- a/ui-tree.c
> +++ b/ui-tree.c
> @@ -222,6 +222,7 @@ static void print_object(const unsigned char *sha1, char *path, const char *base
>  	}
>  
>  	free(mimetype);
> +	free(buf);
>  }
>  
>  struct single_tree_ctx {
> 


^ permalink raw reply	[flat|nested] 140+ messages in thread

* [PATCH 05/11] ui-tree: use render fileters to display content
  2018-06-13  2:01                   ` [PATCH 05/11] ui-tree: use render fileters to display content andy
@ 2018-06-16 14:26                     ` john
  2018-06-16 23:16                       ` andy
  0 siblings, 1 reply; 140+ messages in thread
From: john @ 2018-06-16 14:26 UTC (permalink / raw)


If you're including these patches in your series, please fix my typo in
the subject ("fileters" has a stray 'e')  :-)

On Wed, Jun 13, 2018 at 10:01:55AM +0800, Andy Green wrote:
> From: John Keeping <john at keeping.me.uk>
> 
> This allows applying filters to files in the repository, for example to
> render Markdown or AsciiDoc as HTML.
> 
> Signed-off-by: John Keeping <john at keeping.me.uk>


^ permalink raw reply	[flat|nested] 140+ messages in thread

* [PATCH 08/11] ui-tree: print_object: add is_inline param
  2018-06-13  2:02                   ` [PATCH 08/11] ui-tree: print_object: add is_inline param andy
@ 2018-06-16 14:38                     ` john
  0 siblings, 0 replies; 140+ messages in thread
From: john @ 2018-06-16 14:38 UTC (permalink / raw)


On Wed, Jun 13, 2018 at 10:02:10AM +0800, Andy Green wrote:
> We will reuse print_object to render things inline shortly.
> 
> Add a parameter that lets us adapt its behaviour slightly
> for that case.
> 
> Signed-off-by: Andy Green <andy at warmcat.com>
> ---
>  ui-tree.c |    7 ++++---
>  1 file changed, 4 insertions(+), 3 deletions(-)
> 
> diff --git a/ui-tree.c b/ui-tree.c
> index fe5dc75..bb10b17 100644
> --- a/ui-tree.c
> +++ b/ui-tree.c
> @@ -158,7 +158,7 @@ static void include_file(const unsigned char *sha1, const char *path,
>  }
>  
>  static void print_object(const unsigned char *sha1, char *path, const char *basename,
> -			 const char *rev, bool use_render)
> +			 const char *rev, bool use_render, bool is_inline)

I don't think this is the right way to handle this.  There's other
behaviour here that needs to be suppressed if this is inline content,
such as the call to cgit_set_title_from_path(), and I don't think we
want the object header above the readme content.

Additionally, if read_sha1_file() fails we'll output another page header
here.

Since it's not much code overall, I think we probably don't want to
reuse print_object() for the inline rendering, but can instead just do
the render & mimetype lookup and then do:

	if (render)
		render_buffer(render, basename, buf, size);
	else if (mimetype)
		include_file(sha1, path, mimetype);
	else
		print_buffer(basename, buf, size);

>  {
>  	enum object_type type;
>  	struct cgit_filter *render;
> @@ -191,7 +191,8 @@ static void print_object(const unsigned char *sha1, char *path, const char *base
>  	if (!render && !mimetype)
>  		use_render = false;
>  
> -	cgit_print_layout_start();
> +	if (!is_inline)
> +		cgit_print_layout_start();
>  	htmlf("blob: %s (", sha1_to_hex(sha1));
>  	cgit_plain_link("plain", NULL, NULL, ctx.qry.head,
>  		        rev, path);
> @@ -415,7 +416,7 @@ static int walk_tree(const unsigned char *sha1, struct strbuf *base,
>  		} else {
>  			walk_tree_ctx->state = 2;
>  			print_object(sha1, buffer.buf, pathname, walk_tree_ctx->curr_rev,
> -				     walk_tree_ctx->use_render);
> +				     walk_tree_ctx->use_render, 0);
>  			strbuf_release(&buffer);
>  
>  			return 0;
> 


^ permalink raw reply	[flat|nested] 140+ messages in thread

* [PATCH 09/11] ui-tree: ls_tail: add walk table param
  2018-06-13  2:02                   ` [PATCH 09/11] ui-tree: ls_tail: add walk table param andy
@ 2018-06-16 14:38                     ` john
  0 siblings, 0 replies; 140+ messages in thread
From: john @ 2018-06-16 14:38 UTC (permalink / raw)


On Wed, Jun 13, 2018 at 10:02:15AM +0800, Andy Green wrote:
> Arrange that walk_tree_ctx is available in ls_tail, we
> will make use of it shortly.
> 
> Signed-off-by: Andy Green <andy at warmcat.com>

Reviewed-by: John Keeping <john at keeping.me.uk>

> ---
>  ui-tree.c |    6 +++---
>  1 file changed, 3 insertions(+), 3 deletions(-)
> 
> diff --git a/ui-tree.c b/ui-tree.c
> index bb10b17..53b5594 100644
> --- a/ui-tree.c
> +++ b/ui-tree.c
> @@ -368,7 +368,7 @@ static void ls_head(void)
>  	html("</tr>\n");
>  }
>  
> -static void ls_tail(void)
> +static void ls_tail(struct walk_tree_context *walk_tree_ctx)
>  {
>  	html("</table>\n");
>  	cgit_print_layout_end();
> @@ -390,7 +390,7 @@ static void ls_tree(const struct object_id *oid, char *path, struct walk_tree_co
>  
>  	ls_head();
>  	read_tree_recursive(tree, "", 0, 1, &paths, ls_item, walk_tree_ctx);
> -	ls_tail();
> +	ls_tail(walk_tree_ctx);
>  }
>  
>  
> @@ -473,7 +473,7 @@ void cgit_print_tree(const char *rev, char *path, bool use_render)
>  
>  	read_tree_recursive(commit->tree, "", 0, 0, &paths, walk_tree, &walk_tree_ctx);
>  	if (walk_tree_ctx.state == 1)
> -		ls_tail();
> +		ls_tail(&walk_tree_ctx);
>  	else if (walk_tree_ctx.state == 2)
>  		cgit_print_layout_end();
>  	else
> 
> _______________________________________________
> CGit mailing list
> CGit at lists.zx2c4.com
> https://lists.zx2c4.com/mailman/listinfo/cgit


^ permalink raw reply	[flat|nested] 140+ messages in thread

* [PATCH 10/11] config: add tree-readme list
  2018-06-13  2:02                   ` [PATCH 10/11] config: add tree-readme list andy
@ 2018-06-16 14:44                     ` john
  0 siblings, 0 replies; 140+ messages in thread
From: john @ 2018-06-16 14:44 UTC (permalink / raw)


On Wed, Jun 13, 2018 at 10:02:20AM +0800, Andy Green wrote:
> Allows the user to specify a list of filenames that should be
> rendered inline with tree view, if present in the directory.
> 
> Signed-off-by: Andy Green <andy at warmcat.com>

As mentioned in reply to the cover leter, I think this needs to be a
repo config rather than just a global configuration.  It seems likely
that different repositories may have different preferences or
conventions for directory level readme files.

A few more comments below...

> ---
>  cgit.c       |   11 ++++++++++-
>  cgit.h       |    1 +
>  cgitrc.5.txt |    7 +++++++
>  3 files changed, 18 insertions(+), 1 deletion(-)
> 
> diff --git a/cgit.c b/cgit.c
> index 975e573..017ce78 100644
> --- a/cgit.c
> +++ b/cgit.c
> @@ -1,6 +1,6 @@
>  /* cgit.c: cgi for the git scm
>   *
> - * Copyright (C) 2006-2014 cgit Development Team <cgit at lists.zx2c4.com>
> + * Copyright (C) 2006-2018 cgit Development Team <cgit at lists.zx2c4.com>
>   *
>   * Licensed under GNU General Public License v2
>   *   (see COPYING for full license text)
> @@ -39,6 +39,12 @@ static void add_render_filter(const char *name, const char *cmd)
>  	item->util = filter;
>  }
>  
> +static void add_tree_readme(const char *name)
> +{
> +	string_list_insert(&ctx.cfg.tree_readme, name);
> +}
> +
> +

Extra blank line?

>  static void process_cached_repolist(const char *path);
>  
>  static void repo_config(struct cgit_repo *repo, const char *name, const char *value)
> @@ -301,6 +307,8 @@ static void config_cb(const char *name, const char *value)
>  		add_mimetype(name + 9, value);
>  	else if (starts_with(name, "render."))
>  		add_render_filter(name + 7, value);
> +	else if (!strcmp(name, "tree-readme"))
> +		add_tree_readme(value);
>  	else if (!strcmp(name, "include"))
>  		parse_configfile(expand_macros(value), config_cb);
>  }
> @@ -435,6 +443,7 @@ static void prepare_context(void)
>  	ctx.page.etag = NULL;
>  	string_list_init(&ctx.cfg.mimetypes, 1);
>  	string_list_init(&ctx.cfg.render_filters, 1);
> +	string_list_init(&ctx.cfg.tree_readme, 1);
>  	if (ctx.env.script_name)
>  		ctx.cfg.script_name = xstrdup(ctx.env.script_name);
>  	if (ctx.env.query_string)
> diff --git a/cgit.h b/cgit.h
> index a19742f..1076568 100644
> --- a/cgit.h
> +++ b/cgit.h
> @@ -261,6 +261,7 @@ struct cgit_config {
>  	int branch_sort;
>  	int commit_sort;
>  	struct string_list mimetypes;
> +	struct string_list tree_readme;
>  	struct string_list render_filters;
>  	struct cgit_filter *about_filter;
>  	struct cgit_filter *commit_filter;
> diff --git a/cgitrc.5.txt b/cgitrc.5.txt
> index 793a0c1..5111197 100644
> --- a/cgitrc.5.txt
> +++ b/cgitrc.5.txt
> @@ -469,6 +469,13 @@ strict-export::
>  	repositories to match those exported by git-daemon. This option must
>  	be defined prior to scan-path.
>  
> +tree-readme::
> +	Append given filename to the list of filenames to be rendered after the
> +	tree navigation in tree view, if present in the directory being viewed.  Eg,
> +	'tree-readme=README.md'.  There must also be a corresponding render.
> +	entry for the readme suffix, eg,
> +	'render.md=/usr/libexec/cgit/filters/html-converters/md2html'

I don't think there does need to be a render entry, there could be a
mimetype entry which will allow the content to be displayed in an
iframe, or in the absense of that the file will simply be included
verbatim which may be absolutely fine.

>  	will also cause cgit to generate 'virtual urls', i.e. urls like
> 
> _______________________________________________
> CGit mailing list
> CGit at lists.zx2c4.com
> https://lists.zx2c4.com/mailman/listinfo/cgit


^ permalink raw reply	[flat|nested] 140+ messages in thread

* [PATCH 11/11] ui-tree: render any matching README file in tree view
  2018-06-13  2:02                   ` [PATCH 11/11] ui-tree: render any matching README file in tree view andy
@ 2018-06-16 14:58                     ` john
  0 siblings, 0 replies; 140+ messages in thread
From: john @ 2018-06-16 14:58 UTC (permalink / raw)


On Wed, Jun 13, 2018 at 10:02:25AM +0800, Andy Green wrote:
> While listing the items in tree view, we collect a list
> of any filenames that match any tree-readme entries from the
> config file.
> 
> After the tree view has been shown, we iterate through any
> collected readme files rendering them inline.
> 
> Signed-off-by: Andy Green <andy at warmcat.com>
> ---
>  ui-tree.c |   77 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
>  1 file changed, 75 insertions(+), 2 deletions(-)
> 
> diff --git a/ui-tree.c b/ui-tree.c
> index 53b5594..4dde2a5 100644
> --- a/ui-tree.c
> +++ b/ui-tree.c
> @@ -1,6 +1,6 @@
>  /* ui-tree.c: functions for tree output
>   *
> - * Copyright (C) 2006-2017 cgit Development Team <cgit at lists.zx2c4.com>
> + * Copyright (C) 2006-2018 cgit Development Team <cgit at lists.zx2c4.com>
>   *
>   * Licensed under GNU General Public License v2
>   *   (see COPYING for full license text)
> @@ -11,13 +11,58 @@
>  #include "html.h"
>  #include "ui-shared.h"
>  
> +struct file_list {
> +	struct object_id oid;
> +	struct file_list *next;
> +	const char *path;
> +};

Can we use git/list.h for this?  (Although I still think we only need to
print a single file and can skip the list completely!)

>  struct walk_tree_context {
>  	char *curr_rev;
>  	char *match_path;
> +	struct file_list *render_list;
>  	int state;
>  	bool use_render;
>  };
>  
> +static void
> +walk_tree_cleanup(struct walk_tree_context *wt)
> +{
> +	struct file_list *f = wt->render_list;
> +
> +	free(wt->curr_rev);
> +
> +	while (f) {
> +		struct file_list *tmp = f->next;
> +
> +		free((void *)f->path);

Just make path "char *" and drop the const rather than casting it for
free().

> +		free(f);
> +		f = tmp;
> +	}
> +}
> +
> +static int
> +walk_tree_render_list_add(struct walk_tree_context *wt, const char *path,
> +			  const unsigned char *sha1)
> +{
> +	struct file_list *f = xmalloc(sizeof(*f));
> +
> +	if (!f)

xmalloc can't fail so there's no need to check for an error here.

> +		return 1;
> +
> +	f->next = wt->render_list;
> +	f->path = xstrdup(path);
> +	if (!f->path) {

xstrdup also can't fail.

> +		free(f);
> +
> +		return 1;
> +	}
> +	memcpy(f->oid.hash, sha1, sizeof(f->oid.hash));

oidcpy()?

> +	wt->render_list = f;
> +
> +	return 0;
> +}
> +
>  static void print_text_buffer(const char *name, char *buf, unsigned long size)
>  {
>  	unsigned long lineno, idx;
> @@ -327,12 +372,21 @@ static int ls_item(const unsigned char *sha1, struct strbuf *base,
>  		write_tree_link(sha1, name, walk_tree_ctx->curr_rev,
>  				&fullpath);
>  	} else {
> +		struct string_list_item *entry;
>  		char *ext = strrchr(name, '.');
> +	
>  		strbuf_addstr(&class, "ls-blob");
>  		if (ext)
>  			strbuf_addf(&class, " %s", ext + 1);
> +
>  		cgit_tree_link(name, NULL, class.buf, ctx.qry.head,
>  			       walk_tree_ctx->curr_rev, fullpath.buf);
> +
> +		for_each_string_list_item(entry, &ctx.cfg.tree_readme) {
> +			if (!strcmp(name, entry->string))
> +				walk_tree_render_list_add(walk_tree_ctx,
> +							  pathname, sha1);
> +		}

I'd extract the for_each_string_list_item() to a function here, but I
don't think it's too important.

>  	}
>  	htmlf("</td><td class='ls-size'>%li</td>", size);
>  
> @@ -370,7 +424,24 @@ static void ls_head(void)
>  
>  static void ls_tail(struct walk_tree_context *walk_tree_ctx)
>  {
> +	struct file_list *f = walk_tree_ctx->render_list;
> +	enum object_type type;
> +	unsigned long size;
> +
>  	html("</table>\n");
> +
> +	while (f) {
> +		/* create a vertical gap between tree nav / renders */
> +		html("<table><tr><td>&nbsp;</td></tr></table>");
> +
> +		type = sha1_object_info(f->oid.hash, &size);
> +		if (type != OBJ_BAD)
> +			print_object(f->oid.hash, (char *)f->path,
> +				     "", walk_tree_ctx->curr_rev, 1, 1);
> +
> +		f = f->next;
> +	}
> +

As mentioned in reply to a previous patch, I think we should just inline
the object lookup and call to the relevant rendering function.  This
avoids the slightly strange line like this appearing above the file
content:

	blob: 5111197086106552cb8d64dca537d45f8f5bc10a (plain) (blame)

In place of that, should we output the filename as a heading?

I also wonder if we should do something instead of print_buffer() when
there is no render filter or mimetype specified.  Maybe:

	if (buffer_is_binary(buf, size)) {
		/* suggestions on a postcard! */
	} else {
		html("<pre><code>");
		html_txt(buf);
		html("</code></pre>");
	}

>  	cgit_print_layout_end();
>  }
>  
> @@ -444,7 +515,9 @@ void cgit_print_tree(const char *rev, char *path, bool use_render)
>  		.items = &path_items
>  	};
>  	struct walk_tree_context walk_tree_ctx = {
> +		.curr_rev = NULL,
>  		.match_path = path,
> +		.render_list = NULL,

The language already guarantees this so there's no need to initialize
these explicitly.

>  		.state = 0,
>  		.use_render = use_render,
>  	};
> @@ -480,5 +553,5 @@ void cgit_print_tree(const char *rev, char *path, bool use_render)
>  		cgit_print_error_page(404, "Not found", "Path not found");
>  
>  cleanup:
> -	free(walk_tree_ctx.curr_rev);
> +	walk_tree_cleanup(&walk_tree_ctx);
>  }


^ permalink raw reply	[flat|nested] 140+ messages in thread

* Rendering of README.md inline with inner tree view dirs
  2018-06-16 14:12                 ` Rendering of README.md inline with inner tree view dirs john
@ 2018-06-16 17:35                   ` john
  2018-06-18  2:22                     ` andy
  0 siblings, 1 reply; 140+ messages in thread
From: john @ 2018-06-16 17:35 UTC (permalink / raw)


On Sat, Jun 16, 2018 at 03:12:09PM +0100, John Keeping wrote:
> > >> 3) You can see on the top level of the tree, the README.md references
> > >>
> > >> <img alt="lws-overview" src="./doc-assets/lws-overview.png">
> > >>
> > >> This url format works in github.  In the cgit About view, this resolves to
> > >>
> > >> /git/libwebsockets/about/doc-assets/lws-overview.png
> > >>
> > >> which also serves the right mimetype and content.  So that kind of URL
> > >> format is useful.  But when we render the same markup and relative path
> > >> via /tree/, it tries to show an html page containing the content.
> > >> That's why the picture is missing in the /tree/ view... other pictures
> > >> in that markup are coming with absolute URLs outside of cgit and are
> > >> working.
> > >>
> > >> I can have the direct content from cgit generally, but either the markup
> > >> needs fixing up to
> > >>
> > >> /git/libwebsockets/plain/doc-assets/lws-overview.png
> > >>
> > >> or /tree/ needs to learn to do what /about/ does.
> > >>
> > >> I'm wondering whether mmd2html might grow an environment var to know the
> > >> base part for URLS that want to direct-render from cgit.  Or if better
> > >> to follow what /about/ did in /tree/.
> > > 
> > > Making tree do this will break the normal use of tree unless we add some
> > > extra query parameter or path element.  Given that, I think teaching the
> > > renderer to use a path to /about/ is the right thing to do.
> > 
> > OK.  Unfortunately I don't know python very well.  It looks like the 
> > markdown python library is able to be told to use extensions that are 
> > capable to do this
> > 
> > https://python-markdown.github.io/extensions/api/
> > 
> > from the md2html wrapper.  But I don't know enough python to do it.
> > 
> > It's a shame, because in-tree assets correctly follow the ref context 
> > being viewed, eg, if you look at a v2 branch you see v2 pngs, master you 
> > see master pngs etc.
> > 
> > I'll "solve" this part for now by changing the README to use external URLs.
> 
> Yeah, I think we have to solve it by having the filter apply a mapping.
> We have ui-plain which provides the right content for images, but what
> should we do for link targets?
> 
> For the purpose of discussion, consider the following HTML fragment that
> could be generated by rendering a README file:
> 
> 	<img src="dataflow.png">
> 	<p>For more details see <a href="dataflow.html">the dedicated
> 	data flow document.</p>
> 
> If dataflow.html is generated from a source file in a similar way, then
> it doesn't exist in the repository and we can't link to it, so the ideal
> output ends up being something like:
> 
> 	<img src="/repo/plain/dataflow.png">
> 	<p>For more details see <a href="dataflow.txt">the dedicated
> 	data flow document.</p>
> 
> The render filter API isn't finalised yet, so we can change the
> parameters that are passed in order to add more information for the
> renderer to use.  At the very least I think we should add a parameter
> for the asset prefix which is essentially the tree path with /tree/
> replaces with /plain/.
> 
> However, I'm not sure how to handle relative links: do we need to pass
> additional parameters for this?  Or can we rely on a render filter doing
> the right thing?

Modifying md2html to use the extension API is reasonably
straightforward.  Below is a modified version which remaps the "src"
attribute on <img> elements according to a second command line argument,
you can try it out with:

	md2html <README.md README.md /path/to/plain/directory/

The trailing "/" is important.

The differences are the AssetMapping classes at the top and the
extension setup at the bottom; the rest is unchanged from the version in
CGit's source tree.

-- >8 --
#!/usr/bin/env python3
import markdown
import sys
import io
from markdown.util import etree
from pygments.formatters import HtmlFormatter
from urllib.parse import urljoin


class AssetMappingProcessor(markdown.treeprocessors.Treeprocessor):

    def __init__(self, asset_prefix):
        self.asset_prefix = asset_prefix

    def run(self, root):
        asset_prefix = self.asset_prefix
        for img in root.iter('img'):
            src = img.get('src')
            if src is None:
                continue
            img.set('src', urljoin(asset_prefix, src))


class AssetMappingExtension(markdown.extensions.Extension):

    def __init__(self, **kwargs):
        self.config = {'asset_prefix': ['', 'prefix for relative asset URLs']}
        super(AssetMappingExtension, self).__init__(**kwargs)

    def extendMarkdown(self, md, md_globals):
        asset_prefix = self.getConfig('asset_prefix')
        if not asset_prefix:
            return

        md.treeprocessors.add('asset_mapping',
                              AssetMappingProcessor(asset_prefix),
                              '_end')


sys.stdin = io.TextIOWrapper(sys.stdin.buffer, encoding='utf-8')
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')
sys.stdout.write('''
<style>
.markdown-body {
    font-size: 14px;
    line-height: 1.6;
    overflow: hidden;
}
.markdown-body>*:first-child {
    margin-top: 0 !important;
}
.markdown-body>*:last-child {
    margin-bottom: 0 !important;
}
.markdown-body a.absent {
    color: #c00;
}
.markdown-body a.anchor {
    display: block;
    padding-left: 30px;
    margin-left: -30px;
    cursor: pointer;
    position: absolute;
    top: 0;
    left: 0;
    bottom: 0;
}
.markdown-body h1, .markdown-body h2, .markdown-body h3, .markdown-body h4, .markdown-body h5, .markdown-body h6 {
    margin: 20px 0 10px;
    padding: 0;
    font-weight: bold;
    -webkit-font-smoothing: antialiased;
    cursor: text;
    position: relative;
}
.markdown-body h1 .mini-icon-link, .markdown-body h2 .mini-icon-link, .markdown-body h3 .mini-icon-link, .markdown-body h4 .mini-icon-link, .markdown-body h5 .mini-icon-link, .markdown-body h6 .mini-icon-link {
    display: none;
    color: #000;
}
.markdown-body h1:hover a.anchor, .markdown-body h2:hover a.anchor, .markdown-body h3:hover a.anchor, .markdown-body h4:hover a.anchor, .markdown-body h5:hover a.anchor, .markdown-body h6:hover a.anchor {
    text-decoration: none;
    line-height: 1;
    padding-left: 0;
    margin-left: -22px;
    top: 15%}
.markdown-body h1:hover a.anchor .mini-icon-link, .markdown-body h2:hover a.anchor .mini-icon-link, .markdown-body h3:hover a.anchor .mini-icon-link, .markdown-body h4:hover a.anchor .mini-icon-link, .markdown-body h5:hover a.anchor .mini-icon-link, .markdown-body h6:hover a.anchor .mini-icon-link {
    display: inline-block;
}
.markdown-body h1 tt, .markdown-body h1 code, .markdown-body h2 tt, .markdown-body h2 code, .markdown-body h3 tt, .markdown-body h3 code, .markdown-body h4 tt, .markdown-body h4 code, .markdown-body h5 tt, .markdown-body h5 code, .markdown-body h6 tt, .markdown-body h6 code {
    font-size: inherit;
}
.markdown-body h1 {
    font-size: 28px;
    color: #000;
}
.markdown-body h2 {
    font-size: 24px;
    border-bottom: 1px solid #ccc;
    color: #000;
}
.markdown-body h3 {
    font-size: 18px;
}
.markdown-body h4 {
    font-size: 16px;
}
.markdown-body h5 {
    font-size: 14px;
}
.markdown-body h6 {
    color: #777;
    font-size: 14px;
}
.markdown-body p, .markdown-body blockquote, .markdown-body ul, .markdown-body ol, .markdown-body dl, .markdown-body table, .markdown-body pre {
    margin: 15px 0;
}
.markdown-body hr {
    background: transparent url("/dirty-shade.png") repeat-x 0 0;
    border: 0 none;
    color: #ccc;
    height: 4px;
    padding: 0;
}
.markdown-body>h2:first-child, .markdown-body>h1:first-child, .markdown-body>h1:first-child+h2, .markdown-body>h3:first-child, .markdown-body>h4:first-child, .markdown-body>h5:first-child, .markdown-body>h6:first-child {
    margin-top: 0;
    padding-top: 0;
}
.markdown-body a:first-child h1, .markdown-body a:first-child h2, .markdown-body a:first-child h3, .markdown-body a:first-child h4, .markdown-body a:first-child h5, .markdown-body a:first-child h6 {
    margin-top: 0;
    padding-top: 0;
}
.markdown-body h1+p, .markdown-body h2+p, .markdown-body h3+p, .markdown-body h4+p, .markdown-body h5+p, .markdown-body h6+p {
    margin-top: 0;
}
.markdown-body li p.first {
    display: inline-block;
}
.markdown-body ul, .markdown-body ol {
    padding-left: 30px;
}
.markdown-body ul.no-list, .markdown-body ol.no-list {
    list-style-type: none;
    padding: 0;
}
.markdown-body ul li>:first-child, .markdown-body ul li ul:first-of-type, .markdown-body ul li ol:first-of-type, .markdown-body ol li>:first-child, .markdown-body ol li ul:first-of-type, .markdown-body ol li ol:first-of-type {
    margin-top: 0px;
}
.markdown-body ul li p:last-of-type, .markdown-body ol li p:last-of-type {
    margin-bottom: 0;
}
.markdown-body ul ul, .markdown-body ul ol, .markdown-body ol ol, .markdown-body ol ul {
    margin-bottom: 0;
}
.markdown-body dl {
    padding: 0;
}
.markdown-body dl dt {
    font-size: 14px;
    font-weight: bold;
    font-style: italic;
    padding: 0;
    margin: 15px 0 5px;
}
.markdown-body dl dt:first-child {
    padding: 0;
}
.markdown-body dl dt>:first-child {
    margin-top: 0px;
}
.markdown-body dl dt>:last-child {
    margin-bottom: 0px;
}
.markdown-body dl dd {
    margin: 0 0 15px;
    padding: 0 15px;
}
.markdown-body dl dd>:first-child {
    margin-top: 0px;
}
.markdown-body dl dd>:last-child {
    margin-bottom: 0px;
}
.markdown-body blockquote {
    border-left: 4px solid #DDD;
    padding: 0 15px;
    color: #777;
}
.markdown-body blockquote>:first-child {
    margin-top: 0px;
}
.markdown-body blockquote>:last-child {
    margin-bottom: 0px;
}
.markdown-body table th {
    font-weight: bold;
}
.markdown-body table th, .markdown-body table td {
    border: 1px solid #ccc;
    padding: 6px 13px;
}
.markdown-body table tr {
    border-top: 1px solid #ccc;
    background-color: #fff;
}
.markdown-body table tr:nth-child(2n) {
    background-color: #f8f8f8;
}
.markdown-body img {
    max-width: 100%;
    -moz-box-sizing: border-box;
    box-sizing: border-box;
}
.markdown-body span.frame {
    display: block;
    overflow: hidden;
}
.markdown-body span.frame>span {
    border: 1px solid #ddd;
    display: block;
    float: left;
    overflow: hidden;
    margin: 13px 0 0;
    padding: 7px;
    width: auto;
}
.markdown-body span.frame span img {
    display: block;
    float: left;
}
.markdown-body span.frame span span {
    clear: both;
    color: #333;
    display: block;
    padding: 5px 0 0;
}
.markdown-body span.align-center {
    display: block;
    overflow: hidden;
    clear: both;
}
.markdown-body span.align-center>span {
    display: block;
    overflow: hidden;
    margin: 13px auto 0;
    text-align: center;
}
.markdown-body span.align-center span img {
    margin: 0 auto;
    text-align: center;
}
.markdown-body span.align-right {
    display: block;
    overflow: hidden;
    clear: both;
}
.markdown-body span.align-right>span {
    display: block;
    overflow: hidden;
    margin: 13px 0 0;
    text-align: right;
}
.markdown-body span.align-right span img {
    margin: 0;
    text-align: right;
}
.markdown-body span.float-left {
    display: block;
    margin-right: 13px;
    overflow: hidden;
    float: left;
}
.markdown-body span.float-left span {
    margin: 13px 0 0;
}
.markdown-body span.float-right {
    display: block;
    margin-left: 13px;
    overflow: hidden;
    float: right;
}
.markdown-body span.float-right>span {
    display: block;
    overflow: hidden;
    margin: 13px auto 0;
    text-align: right;
}
.markdown-body code, .markdown-body tt {
    margin: 0 2px;
    padding: 0px 5px;
    border: 1px solid #eaeaea;
    background-color: #f8f8f8;
    border-radius: 3px;
}
.markdown-body code {
    white-space: nowrap;
}
.markdown-body pre>code {
    margin: 0;
    padding: 0;
    white-space: pre;
    border: none;
    background: transparent;
}
.markdown-body .highlight pre, .markdown-body pre {
    background-color: #f8f8f8;
    border: 1px solid #ccc;
    font-size: 13px;
    line-height: 19px;
    overflow: auto;
    padding: 6px 10px;
    border-radius: 3px;
}
.markdown-body pre code, .markdown-body pre tt {
    margin: 0;
    padding: 0;
    background-color: transparent;
    border: none;
}
''')
sys.stdout.write(HtmlFormatter(style='pastie').get_style_defs('.highlight'))
sys.stdout.write('''
</style>   
''')
sys.stdout.write("<div class='markdown-body'>")
sys.stdout.flush()

extensions = [
    "markdown.extensions.fenced_code",
    "markdown.extensions.codehilite",
    "markdown.extensions.tables"
]
extension_configs = {
    "markdown.extensions.codehilite":{"css_class":"highlight"}
}

if len(sys.argv) > 2:
    extensions.append(AssetMappingExtension(asset_prefix=sys.argv[2]))

# Note: you may want to run this through bleach for sanitization
markdown.markdownFromFile(output_format="html5", extensions=extensions, extension_configs=extension_configs)
sys.stdout.write("</div>")


^ permalink raw reply	[flat|nested] 140+ messages in thread

* [PATCH 05/11] ui-tree: use render fileters to display content
  2018-06-16 14:26                     ` john
@ 2018-06-16 23:16                       ` andy
  0 siblings, 0 replies; 140+ messages in thread
From: andy @ 2018-06-16 23:16 UTC (permalink / raw)




On 06/16/2018 10:26 PM, John Keeping wrote:
> If you're including these patches in your series, please fix my typo in
> the subject ("fileters" has a stray 'e')  :-)

OK.

> On Wed, Jun 13, 2018 at 10:01:55AM +0800, Andy Green wrote:
>> From: John Keeping <john at keeping.me.uk>
>>
>> This allows applying filters to files in the repository, for example to
>> render Markdown or AsciiDoc as HTML.
>>
>> Signed-off-by: John Keeping <john at keeping.me.uk>


^ permalink raw reply	[flat|nested] 140+ messages in thread

* [PATCH 07/11] ui-blame: free read_sha1_file() buffer after use
  2018-06-16 14:23                     ` john
@ 2018-06-16 23:17                       ` andy
  0 siblings, 0 replies; 140+ messages in thread
From: andy @ 2018-06-16 23:17 UTC (permalink / raw)




On 06/16/2018 10:23 PM, John Keeping wrote:
> On Wed, Jun 13, 2018 at 10:02:05AM +0800, Andy Green wrote:
>> Signed-off-by: Andy Green <andy at warmcat.com>
>> ---
>>   ui-blame.c |    3 +++
>>   1 file changed, 3 insertions(+)
>>
>> diff --git a/ui-blame.c b/ui-blame.c
>> index 17e2d60..a5c7d69 100644
>> --- a/ui-blame.c
>> +++ b/ui-blame.c
>> @@ -206,6 +206,9 @@ static void print_object(const unsigned char *sha1, const char *path,
> 
> There's an early return above here after allocating buf, I'm not sure if
> we care about freeing buf on that path as well.
> 
> If we do, I guess we push free(buf) to the end and add a free_buf label
> for the error path to jump to.

Yes, I missed it thanks.  I adapted it with the label.

>>   	} else {
>>   		html_txt(buf);
>>   	}
>> +
>> +	free(buf);
>> +
>>   	html("</code></pre>");
>>   
>>   	html("</div></td>\n");
>>


^ permalink raw reply	[flat|nested] 140+ messages in thread

* Rendering of README.md inline with inner tree view dirs
  2018-06-16 17:35                   ` john
@ 2018-06-18  2:22                     ` andy
  0 siblings, 0 replies; 140+ messages in thread
From: andy @ 2018-06-18  2:22 UTC (permalink / raw)




On 06/17/2018 01:35 AM, John Keeping wrote:
> On Sat, Jun 16, 2018 at 03:12:09PM +0100, John Keeping wrote:

>> However, I'm not sure how to handle relative links: do we need to pass
>> additional parameters for this?  Or can we rely on a render filter doing
>> the right thing?
> 
> Modifying md2html to use the extension API is reasonably
> straightforward.  Below is a modified version which remaps the "src"
> attribute on <img> elements according to a second command line argument,
> you can try it out with:
> 
> 	md2html <README.md README.md /path/to/plain/directory/
> 
> The trailing "/" is important.
> 
> The differences are the AssetMapping classes at the top and the
> extension setup at the bottom; the rest is unchanged from the version in
> CGit's source tree.
> 
> -- >8 --
> #!/usr/bin/env python3
> import markdown
> import sys

Thanks a lot for that... I patchified it under your name / email and 
added your signed-off-by on it.

It works, but it's missing a trick, cgit URLs may have a postfix like 
?h=branch which controls the context shown.

I added a patch-on-top of the python and another on the C to generate 
and use prefix and postfix args.

Now it can show completely relative markdown assets in the correct 
context seamlessly, served from git... so you can see easily the picture 
in the v3.0-stable branch git

https://libwebsockets.org/git/libwebsockets/tree/README.md?h=v3.0-stable

has been updated in master

https://libwebsockets.org/git/libwebsockets/tree/README.md

...even though in both cases the markdown is

![lws-overview](./doc-assets/lws-overview.png)

...ie, is not contaminated with any virtual path, versioning or url 
info... this is pretty nice!

-Andy


^ permalink raw reply	[flat|nested] 140+ messages in thread

* [PATCH v2 00/15] Render READMEs inline in tree view
  2018-06-12  9:31             ` john
  2018-06-13  1:47               ` andy
@ 2018-06-18  2:56               ` andy
  2018-06-18  2:57                 ` [PATCH v2 01/15] manpage: fix sorting order andy
                                   ` (14 more replies)
  1 sibling, 15 replies; 140+ messages in thread
From: andy @ 2018-06-18  2:56 UTC (permalink / raw)


The following series adds config to allow rendering of
selected READMEs inline after the tree view, where
present in the directory being viewed.

Particularly you can use completely relative markdown to
inline pictures served from the current repo rev context,
eg,

![overview](./doc-assets/overview.png)

will "just work" showing the png from the current view
rev context; this format also works in github.

It builds on John Keeping's RENDER mode series from 2016.

Typical config to enable it, if you have a README.md
looks like

inline-readme=README.md
render.md=/usr/libexec/cgit/filters/html-converters/md2html

You can see examples of it in operation at

https://libwebsockets.org/git/libwebsockets/tree
https://libwebsockets.org/git/libwebsockets/tree/?h=v3.0-stable
https://warmcat.com/git/cgit/tree/

The expected basis these apply on top of is

 - jk/for-jason
 - ch/git-2-18-0-rc2

You can find these patches on top of the expected basis here

https://warmcat.com/git/cgit/log/

The series is adapted for many comments on the list, including
one-shot inline rather than a list, repo config override,
dropping one patch of gcc8.1 fixes, integrating John's md2html
changes etc.

There's a new patch about tidying the manpage... the couple
of alphabetically-ordered lists in there had things that
were out of order.

---

Andy Green (9):
      manpage: fix sorting order
      gcc8.1: fix strncat warning
      ui-blame: free read_sha1_file() buffer after use
      ui-tree: ls_tail: add walk table param
      config: add global inline-readme list
      config: add repo inline-readme list
      ui-tree: render any matching README file in tree view
      md2html-add-asset-postfix-arg
      render: adapt for providing extra filter args for plain

John Keeping (6):
      Use string list strdup_strings for mimetypes
      Add source page
      Parse render filters from the config
      ui-tree: split out buffer printing
      ui-tree: use render filters to display content
      md2html: add asset mapping


 cgit.c                          |   34 +++++-
 cgit.css                        |    5 +
 cgit.h                          |    6 +
 cgitrc.5.txt                    |  210 +++++++++++++++++++++++----------------
 cmd.c                           |    8 +
 filter.c                        |    4 +
 filters/html-converters/md2html |   55 ++++++++++
 shared.c                        |   21 ++++
 ui-blame.c                      |    6 +
 ui-shared.c                     |   10 ++
 ui-shared.h                     |    3 +
 ui-ssdiff.c                     |   12 ++
 ui-tree.c                       |  199 ++++++++++++++++++++++++++++++++++---
 ui-tree.h                       |    2 
 14 files changed, 458 insertions(+), 117 deletions(-)

--
Signature


^ permalink raw reply	[flat|nested] 140+ messages in thread

* [PATCH v2 01/15] manpage: fix sorting order
  2018-06-18  2:56               ` [PATCH v2 00/15] Render READMEs inline in tree view andy
@ 2018-06-18  2:57                 ` andy
  2018-06-18  2:57                 ` [PATCH v2 02/15] gcc8.1: fix strncat warning andy
                                   ` (13 subsequent siblings)
  14 siblings, 0 replies; 140+ messages in thread
From: andy @ 2018-06-18  2:57 UTC (permalink / raw)


You maybe didn't know you had OCD until you saw an
alpha sorted list that has stuff out of order in it.

Signed-off-by: Andy Green <andy at warmcat.com>
---
 cgitrc.5.txt |  174 +++++++++++++++++++++++++++++-----------------------------
 1 file changed, 87 insertions(+), 87 deletions(-)

diff --git a/cgitrc.5.txt b/cgitrc.5.txt
index 4da166c..2c702b7 100644
--- a/cgitrc.5.txt
+++ b/cgitrc.5.txt
@@ -54,14 +54,10 @@ branch-sort::
 	list, and when set to "name" enables ordering by branch name. Default
 	value: "name".
 
-cache-root::
-	Path used to store the cgit cache entries. Default value:
-	"/var/cache/cgit". See also: "MACRO EXPANSION".
-
-cache-static-ttl::
+cache-about-ttl::
 	Number which specifies the time-to-live, in minutes, for the cached
-	version of repository pages accessed with a fixed SHA1. See also:
-	"CACHE". Default value: -1".
+	version of the repository about page. See also: "CACHE". Default
+	value: "15".
 
 cache-dynamic-ttl::
 	Number which specifies the time-to-live, in minutes, for the cached
@@ -73,6 +69,10 @@ cache-repo-ttl::
 	version of the repository summary page. See also: "CACHE". Default
 	value: "5".
 
+cache-root::
+	Path used to store the cgit cache entries. Default value:
+	"/var/cache/cgit". See also: "MACRO EXPANSION".
+
 cache-root-ttl::
 	Number which specifies the time-to-live, in minutes, for the cached
 	version of the repository index page. See also: "CACHE". Default
@@ -83,22 +83,22 @@ cache-scanrc-ttl::
 	of scanning a path for git repositories. See also: "CACHE". Default
 	value: "15".
 
-cache-about-ttl::
-	Number which specifies the time-to-live, in minutes, for the cached
-	version of the repository about page. See also: "CACHE". Default
-	value: "15".
-
-cache-snapshot-ttl::
-	Number which specifies the time-to-live, in minutes, for the cached
-	version of snapshots. See also: "CACHE". Default value: "5".
+case-sensitive-sort::
+	Sort items in the repo list case sensitively. Default value: "1".
+	See also: repository-sort, section-sort.
 
 cache-size::
 	The maximum number of entries in the cgit cache. When set to "0",
 	caching is disabled. See also: "CACHE". Default value: "0"
 
-case-sensitive-sort::
-	Sort items in the repo list case sensitively. Default value: "1".
-	See also: repository-sort, section-sort.
+cache-snapshot-ttl::
+	Number which specifies the time-to-live, in minutes, for the cached
+	version of snapshots. See also: "CACHE". Default value: "5".
+
+cache-static-ttl::
+	Number which specifies the time-to-live, in minutes, for the cached
+	version of repository pages accessed with a fixed SHA1. See also:
+	"CACHE". Default value: -1".
 
 clone-prefix::
 	Space-separated list of common prefixes which, when combined with a
@@ -159,12 +159,29 @@ enable-follow-links::
 	Flag which, when set to "1", allows users to follow a file in the log
 	view.  Default value: "0".
 
+enable-git-config::
+	Flag which, when set to "1", will allow cgit to use git config to set
+	any repo specific settings. This option is used in conjunction with
+	"scan-path", and must be defined prior, to augment repo-specific
+	settings. The keys gitweb.owner, gitweb.category, gitweb.description,
+	and gitweb.homepage will map to the cgit keys repo.owner, repo.section,
+	repo.desc, and repo.homepage respectively. All git config keys that begin
+	with "cgit." will be mapped to the corresponding "repo." key in cgit.
+	Default value: "0". See also: scan-path, section-from-path.
+
 enable-http-clone::
 	If set to "1", cgit will act as an dumb HTTP endpoint for git clones.
 	You can add "http://$HTTP_HOST$SCRIPT_NAME/$CGIT_REPO_URL" to clone-url
 	to expose this feature. If you use an alternate way of serving git
 	repositories, you may wish to disable this. Default value: "1".
 
+enable-html-serving::
+	Flag which, when set to "1", will allow the /plain handler to serve
+	mimetype headers that result in the file being treated as HTML by the
+	browser. When set to "0", such file types are returned instead as
+	text/plain or application/octet-stream. Default value: "0". See also:
+	"repo.enable-html-serving".
+
 enable-index-links::
 	Flag which, when set to "1", will make cgit generate extra links for
 	each repo in the repository index (specifically, to the "summary",
@@ -195,27 +212,10 @@ enable-subject-links::
 	in commit view. Default value: "0". See also:
 	"repo.enable-subject-links".
 
-enable-html-serving::
-	Flag which, when set to "1", will allow the /plain handler to serve
-	mimetype headers that result in the file being treated as HTML by the
-	browser. When set to "0", such file types are returned instead as
-	text/plain or application/octet-stream. Default value: "0". See also:
-	"repo.enable-html-serving".
-
 enable-tree-linenumbers::
 	Flag which, when set to "1", will make cgit generate linenumber links
 	for plaintext blobs printed in the tree view. Default value: "1".
 
-enable-git-config::
-	Flag which, when set to "1", will allow cgit to use git config to set
-	any repo specific settings. This option is used in conjunction with
-	"scan-path", and must be defined prior, to augment repo-specific
-	settings. The keys gitweb.owner, gitweb.category, gitweb.description,
-	and gitweb.homepage will map to the cgit keys repo.owner, repo.section,
-	repo.desc, and repo.homepage respectively. All git config keys that begin
-	with "cgit." will be mapped to the corresponding "repo." key in cgit.
-	Default value: "0". See also: scan-path, section-from-path.
-
 favicon::
 	Url used as link to a shortcut icon for cgit. It is suggested to use
 	the value "/favicon.ico" since certain browsers will ignore other
@@ -263,19 +263,14 @@ logo-link::
 	calculated url of the repository index page will be used. Default
 	value: none.
 
-owner-filter::
-	Specifies a command which will be invoked to format the Owner
-	column of the main page.  The command will get the owner on STDIN,
-	and the STDOUT from the command will be included verbatim in the
-	table.  This can be used to link to additional context such as an
-	owners home page.  When active this filter is used instead of the
-	default owner query url.  Default value: none.
-	See also: "FILTER API".
-
 max-atom-items::
 	Specifies the number of items to display in atom feeds view. Default
 	value: "10".
 
+max-blob-size::
+	Specifies the maximum size of a blob to display HTML for in KBytes.
+	Default value: "0" (limit disabled).
+
 max-commit-count::
 	Specifies the number of entries to list per page in "log" view. Default
 	value: "50".
@@ -292,10 +287,6 @@ max-repodesc-length::
 	Specifies the maximum number of repo description characters to display
 	on the repository index page. Default value: "80".
 
-max-blob-size::
-	Specifies the maximum size of a blob to display HTML for in KBytes.
-	Default value: "0" (limit disabled).
-
 max-stats::
 	Set the default maximum statistics period. Valid values are "week",
 	"month", "quarter" and "year". If unspecified, statistics are
@@ -336,6 +327,15 @@ noheader::
 	Flag which, when set to "1", will make cgit omit the standard header
 	on all pages. Default value: none. See also: "embedded".
 
+owner-filter::
+	Specifies a command which will be invoked to format the Owner
+	column of the main page.  The command will get the owner on STDIN,
+	and the STDOUT from the command will be included verbatim in the
+	table.  This can be used to link to additional context such as an
+	owners home page.  When active this filter is used instead of the
+	default owner query url.  Default value: none.
+	See also: "FILTER API".
+
 project-list::
 	A list of subdirectories inside of scan-path, relative to it, that
 	should loaded as git repositories. This must be defined prior to
@@ -501,9 +501,6 @@ repo.defbranch::
 repo.desc::
 	The value to show as repository description. Default value: none.
 
-repo.homepage::
-	The value to show as repository homepage. Default value: none.
-
 repo.email-filter::
 	Override the default email-filter. Default value: none. See also:
 	"enable-filter-overrides". See also: "FILTER API".
@@ -512,6 +509,10 @@ repo.enable-commit-graph::
 	A flag which can be used to disable the global setting
 	`enable-commit-graph'. Default value: none.
 
+repo.enable-html-serving::
+	A flag which can be used to override the global setting
+	`enable-html-serving`. Default value: none.
+
 repo.enable-log-filecount::
 	A flag which can be used to disable the global setting
 	`enable-log-filecount'. Default value: none.
@@ -528,15 +529,14 @@ repo.enable-subject-links::
 	A flag which can be used to override the global setting
 	`enable-subject-links'. Default value: none.
 
-repo.enable-html-serving::
-	A flag which can be used to override the global setting
-	`enable-html-serving`. Default value: none.
-
 repo.hide::
 	Flag which, when set to "1", hides the repository from the repository
 	index. The repository can still be accessed by providing a direct path.
 	Default value: "0". See also: "repo.ignore".
 
+repo.homepage::
+	The value to show as repository homepage. Default value: none.
+
 repo.ignore::
 	Flag which, when set to "1", ignores the repository. The repository
 	is not shown in the index and cannot be accessed by providing a direct
@@ -551,10 +551,6 @@ repo.logo-link::
 	calculated url of the repository index page will be used. Default
 	value: global logo-link.
 
-repo.owner-filter::
-	Override the default owner-filter. Default value: none. See also:
-	"enable-filter-overrides". See also: "FILTER API".
-
 repo.module-link::
 	Text which will be used as the formatstring for a hyperlink when a
 	submodule is printed in a directory listing. The arguments for the
@@ -579,6 +575,10 @@ repo.owner::
 	A value used to identify the owner of the repository. Default value:
 	none.
 
+repo.owner-filter::
+	Override the default owner-filter. Default value: none. See also:
+	"enable-filter-overrides". See also: "FILTER API".
+
 repo.path::
 	An absolute path to the repository directory. For non-bare repositories
 	this is the .git-directory. Default value: none.
@@ -594,15 +594,15 @@ repo.readme::
 	are no non-public files located in the same directory as the readme
 	file. Default value: <readme>.
 
+repo.section::
+	Override the current section name for this repository. Default value:
+	none.
+
 repo.snapshots::
 	A mask of snapshot formats for this repo that cgit generates links for,
 	restricted by the global "snapshots" setting. Default value:
 	<snapshots>.
 
-repo.section::
-	Override the current section name for this repository. Default value:
-	none.
-
 repo.source-filter::
 	Override the default source-filter. Default value: none. See also:
 	"enable-filter-overrides". See also: "FILTER API".
@@ -675,30 +675,6 @@ about filter::
 	The about text that is to be filtered is available on standard input
 	and the filtered text is expected on standard output.
 
-commit filter::
-	This filter is given no arguments. The commit message text that is to
-	be filtered is available on standard input and the filtered text is
-	expected on standard output.
-
-email filter::
-	This filter is given two parameters: the email address of the relevant
-	author and a string indicating the originating page. The filter will
-	then receive the text string to format on standard input and is
-	expected to write to standard output the formatted text to be included
-	in the page.
-
-owner filter::
-	This filter is given no arguments.  The owner text is available on
-	standard input and the filter is expected to write to standard
-	output.  The output is included in the Owner column.
-
-source filter::
-	This filter is given a single parameter: the filename of the source
-	file to filter. The filter can use the filename to determine (for
-	example) the syntax highlighting mode. The contents of the source
-	file that is to be filtered is available on standard input and the
-	filtered contents is expected on standard output.
-
 auth filter::
 	The authentication filter receives 12 parameters:
 	  - filter action, explained below, which specifies which action the
@@ -725,6 +701,30 @@ auth filter::
 	Please see `filters/simple-authentication.lua` for a clear example
 	script that may be modified.
 
+commit filter::
+	This filter is given no arguments. The commit message text that is to
+	be filtered is available on standard input and the filtered text is
+	expected on standard output.
+
+email filter::
+	This filter is given two parameters: the email address of the relevant
+	author and a string indicating the originating page. The filter will
+	then receive the text string to format on standard input and is
+	expected to write to standard output the formatted text to be included
+	in the page.
+
+owner filter::
+	This filter is given no arguments.  The owner text is available on
+	standard input and the filter is expected to write to standard
+	output.  The output is included in the Owner column.
+
+source filter::
+	This filter is given a single parameter: the filename of the source
+	file to filter. The filter can use the filename to determine (for
+	example) the syntax highlighting mode. The contents of the source
+	file that is to be filtered is available on standard input and the
+	filtered contents is expected on standard output.
+
 
 All filters are handed the following environment variables:
 



^ permalink raw reply	[flat|nested] 140+ messages in thread

* [PATCH v2 02/15] gcc8.1: fix strncat warning
  2018-06-18  2:56               ` [PATCH v2 00/15] Render READMEs inline in tree view andy
  2018-06-18  2:57                 ` [PATCH v2 01/15] manpage: fix sorting order andy
@ 2018-06-18  2:57                 ` andy
  2018-07-03 23:45                   ` Jason
  2018-06-18  2:57                 ` [PATCH v2 03/15] Use string list strdup_strings for mimetypes andy
                                   ` (12 subsequent siblings)
  14 siblings, 1 reply; 140+ messages in thread
From: andy @ 2018-06-18  2:57 UTC (permalink / raw)


../ui-ssdiff.c: In function ?replace_tabs?:
../ui-ssdiff.c:142:4: warning: ?strncat? output truncated copying between 1 and 8 bytes from a string of length 8 [-Wstringop-truncation]
    strncat(result, spaces, 8 - (strlen(result) % 8));
    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Actually the strncat that was there before intends that its
stock of spaces gets truncated, and it's not a problem.

However gcc8.1 is also right, normally truncation is undesirable.

Make the code do the padding explicitly.

Signed-off-by: Andy Green <andy at warmcat.com>
---
 ui-ssdiff.c |   12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/ui-ssdiff.c b/ui-ssdiff.c
index 7f261ed..e520b95 100644
--- a/ui-ssdiff.c
+++ b/ui-ssdiff.c
@@ -118,7 +118,6 @@ static char *replace_tabs(char *line)
 	int n_tabs = 0;
 	int i;
 	char *result;
-	char *spaces = "        ";
 
 	if (linelen == 0) {
 		result = xmalloc(1);
@@ -138,8 +137,17 @@ static char *replace_tabs(char *line)
 			strcat(result, prev_buf);
 			break;
 		} else {
+			char *p;
+			int n;
+
 			strncat(result, prev_buf, cur_buf - prev_buf);
-			strncat(result, spaces, 8 - (strlen(result) % 8));
+
+			n = strlen(result);
+			p = result + n;
+			n = 8 - (n % 8);
+			while (n--)
+				*p++ = ' ';
+			*p = '\0';
 		}
 		prev_buf = cur_buf + 1;
 	}



^ permalink raw reply	[flat|nested] 140+ messages in thread

* [PATCH v2 03/15] Use string list strdup_strings for mimetypes
  2018-06-18  2:56               ` [PATCH v2 00/15] Render READMEs inline in tree view andy
  2018-06-18  2:57                 ` [PATCH v2 01/15] manpage: fix sorting order andy
  2018-06-18  2:57                 ` [PATCH v2 02/15] gcc8.1: fix strncat warning andy
@ 2018-06-18  2:57                 ` andy
  2018-06-18  2:57                 ` [PATCH v2 04/15] Add source page andy
                                   ` (11 subsequent siblings)
  14 siblings, 0 replies; 140+ messages in thread
From: andy @ 2018-06-18  2:57 UTC (permalink / raw)


From: John Keeping <john at keeping.me.uk>

There's no need to do this manually with the string list API will do it
for us.

Signed-off-by: John Keeping <john at keeping.me.uk>
---
 cgit.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/cgit.c b/cgit.c
index bd9cb3f..b37d3e0 100644
--- a/cgit.c
+++ b/cgit.c
@@ -23,7 +23,7 @@ static void add_mimetype(const char *name, const char *value)
 {
 	struct string_list_item *item;
 
-	item = string_list_insert(&ctx.cfg.mimetypes, xstrdup(name));
+	item = string_list_insert(&ctx.cfg.mimetypes, name);
 	item->util = xstrdup(value);
 }
 
@@ -419,7 +419,7 @@ static void prepare_context(void)
 	ctx.page.modified = time(NULL);
 	ctx.page.expires = ctx.page.modified;
 	ctx.page.etag = NULL;
-	memset(&ctx.cfg.mimetypes, 0, sizeof(struct string_list));
+	string_list_init(&ctx.cfg.mimetypes, 1);
 	if (ctx.env.script_name)
 		ctx.cfg.script_name = xstrdup(ctx.env.script_name);
 	if (ctx.env.query_string)



^ permalink raw reply	[flat|nested] 140+ messages in thread

* [PATCH v2 04/15] Add source page
  2018-06-18  2:56               ` [PATCH v2 00/15] Render READMEs inline in tree view andy
                                   ` (2 preceding siblings ...)
  2018-06-18  2:57                 ` [PATCH v2 03/15] Use string list strdup_strings for mimetypes andy
@ 2018-06-18  2:57                 ` andy
  2018-06-18 19:08                   ` john
  2018-06-18  2:57                 ` [PATCH v2 05/15] Parse render filters from the config andy
                                   ` (10 subsequent siblings)
  14 siblings, 1 reply; 140+ messages in thread
From: andy @ 2018-06-18  2:57 UTC (permalink / raw)


From: John Keeping <john at keeping.me.uk>

We are about to introduce rendering of content for the tree view.  This
source page will allow bypassing the renderer and accessing the content
of the current tree view.

Signed-off-by: John Keeping <john at keeping.me.uk>
---
 cmd.c       |    6 ++++++
 ui-shared.c |   10 ++++++++++
 ui-shared.h |    3 +++
 3 files changed, 19 insertions(+)

diff --git a/cmd.c b/cmd.c
index 63f0ae5..56e21df 100644
--- a/cmd.c
+++ b/cmd.c
@@ -138,6 +138,11 @@ static void refs_fn(void)
 	cgit_print_refs();
 }
 
+static void source_fn(void)
+{
+	cgit_print_tree(ctx.qry.sha1, ctx.qry.path);
+}
+
 static void snapshot_fn(void)
 {
 	cgit_print_snapshot(ctx.qry.head, ctx.qry.sha1, ctx.qry.path,
@@ -187,6 +192,7 @@ struct cgit_cmd *cgit_get_cmd(void)
 		def_cmd(refs, 1, 0, 0),
 		def_cmd(repolist, 0, 0, 0),
 		def_cmd(snapshot, 1, 0, 0),
+		def_cmd(source, 1, 1, 0),
 		def_cmd(stats, 1, 1, 0),
 		def_cmd(summary, 1, 0, 0),
 		def_cmd(tag, 1, 0, 0),
diff --git a/ui-shared.c b/ui-shared.c
index ce806f6..2ff9329 100644
--- a/ui-shared.c
+++ b/ui-shared.c
@@ -298,6 +298,12 @@ void cgit_tree_link(const char *name, const char *title, const char *class,
 	reporevlink("tree", name, title, class, head, rev, path);
 }
 
+void cgit_source_link(const char *name, const char *title, const char *class,
+		    const char *head, const char *rev, const char *path)
+{
+	reporevlink("source", name, title, class, head, rev, path);
+}
+
 void cgit_plain_link(const char *name, const char *title, const char *class,
 		     const char *head, const char *rev, const char *path)
 {
@@ -480,6 +486,10 @@ static void cgit_self_link(char *name, const char *title, const char *class)
 		cgit_tree_link(name, title, class, ctx.qry.head,
 			       ctx.qry.has_sha1 ? ctx.qry.sha1 : NULL,
 			       ctx.qry.path);
+	else if (!strcmp(ctx.qry.page, "source"))
+		cgit_source_link(name, title, class, ctx.qry.head,
+				 ctx.qry.has_sha1 ? ctx.qry.sha1 : NULL,
+				 ctx.qry.path);
 	else if (!strcmp(ctx.qry.page, "plain"))
 		cgit_plain_link(name, title, class, ctx.qry.head,
 				ctx.qry.has_sha1 ? ctx.qry.sha1 : NULL,
diff --git a/ui-shared.h b/ui-shared.h
index b760a17..5923aaf 100644
--- a/ui-shared.h
+++ b/ui-shared.h
@@ -23,6 +23,9 @@ extern void cgit_tag_link(const char *name, const char *title,
 extern void cgit_tree_link(const char *name, const char *title,
 			   const char *class, const char *head,
 			   const char *rev, const char *path);
+extern void cgit_source_link(const char *name, const char *title,
+			     const char *class, const char *head,
+			     const char *rev, const char *path);
 extern void cgit_plain_link(const char *name, const char *title,
 			    const char *class, const char *head,
 			    const char *rev, const char *path);



^ permalink raw reply	[flat|nested] 140+ messages in thread

* [PATCH v2 05/15] Parse render filters from the config
  2018-06-18  2:56               ` [PATCH v2 00/15] Render READMEs inline in tree view andy
                                   ` (3 preceding siblings ...)
  2018-06-18  2:57                 ` [PATCH v2 04/15] Add source page andy
@ 2018-06-18  2:57                 ` andy
  2018-06-18  2:57                 ` [PATCH v2 06/15] ui-tree: split out buffer printing andy
                                   ` (9 subsequent siblings)
  14 siblings, 0 replies; 140+ messages in thread
From: andy @ 2018-06-18  2:57 UTC (permalink / raw)


From: John Keeping <john at keeping.me.uk>

Render filters will be used to present rendered content in the tree
view, for example to display Markdown source rendered as HTML.

We will add support for using these from the tree view in the following
commits.

AG: adapted so render.= can be used to specify the filter for files
without any suffix

Signed-off-by: John Keeping <john at keeping.me.uk>
Signed-off-by: Andy Green <andy at warmcat.com>
---
 cgit.c       |   19 +++++++++++++++++--
 cgit.h       |    4 +++-
 cgitrc.5.txt |   19 +++++++++++++++++++
 filter.c     |    1 +
 shared.c     |   19 +++++++++++++++++++
 5 files changed, 59 insertions(+), 3 deletions(-)

diff --git a/cgit.c b/cgit.c
index b37d3e0..975e573 100644
--- a/cgit.c
+++ b/cgit.c
@@ -27,6 +27,18 @@ static void add_mimetype(const char *name, const char *value)
 	item->util = xstrdup(value);
 }
 
+static void add_render_filter(const char *name, const char *cmd)
+{
+	struct string_list_item *item;
+	struct cgit_filter *filter = cgit_new_filter(cmd, RENDER);
+
+	if (!filter)
+		return;
+
+	item = string_list_insert(&ctx.cfg.render_filters, name);
+	item->util = filter;
+}
+
 static void process_cached_repolist(const char *path);
 
 static void repo_config(struct cgit_repo *repo, const char *name, const char *value)
@@ -285,8 +297,10 @@ static void config_cb(const char *name, const char *value)
 			ctx.cfg.branch_sort = 1;
 		if (!strcmp(value, "name"))
 			ctx.cfg.branch_sort = 0;
-	} else if (skip_prefix(name, "mimetype.", &arg))
-		add_mimetype(arg, value);
+	} else if (starts_with(name, "mimetype."))
+		add_mimetype(name + 9, value);
+	else if (starts_with(name, "render."))
+		add_render_filter(name + 7, value);
 	else if (!strcmp(name, "include"))
 		parse_configfile(expand_macros(value), config_cb);
 }
@@ -420,6 +434,7 @@ static void prepare_context(void)
 	ctx.page.expires = ctx.page.modified;
 	ctx.page.etag = NULL;
 	string_list_init(&ctx.cfg.mimetypes, 1);
+	string_list_init(&ctx.cfg.render_filters, 1);
 	if (ctx.env.script_name)
 		ctx.cfg.script_name = xstrdup(ctx.env.script_name);
 	if (ctx.env.query_string)
diff --git a/cgit.h b/cgit.h
index 005ae63..a19742f 100644
--- a/cgit.h
+++ b/cgit.h
@@ -55,7 +55,7 @@ typedef enum {
 } diff_type;
 
 typedef enum {
-	ABOUT, COMMIT, SOURCE, EMAIL, AUTH, OWNER
+	ABOUT, COMMIT, SOURCE, EMAIL, AUTH, OWNER, RENDER
 } filter_type;
 
 struct cgit_filter {
@@ -261,6 +261,7 @@ struct cgit_config {
 	int branch_sort;
 	int commit_sort;
 	struct string_list mimetypes;
+	struct string_list render_filters;
 	struct cgit_filter *about_filter;
 	struct cgit_filter *commit_filter;
 	struct cgit_filter *source_filter;
@@ -389,5 +390,6 @@ extern int readfile(const char *path, char **buf, size_t *size);
 extern char *expand_macros(const char *txt);
 
 extern char *get_mimetype_for_filename(const char *filename);
+extern struct cgit_filter *get_render_for_filename(const char *filename);
 
 #endif /* CGIT_H */
diff --git a/cgitrc.5.txt b/cgitrc.5.txt
index 2c702b7..a1560eb 100644
--- a/cgitrc.5.txt
+++ b/cgitrc.5.txt
@@ -359,6 +359,18 @@ renamelimit::
 	 "-1" uses the compiletime value in git (for further info, look at
 	  `man git-diff`). Default value: "-1".
 
+render.<ext>::
+	Specifies a command which will be invoked to render files with the
+	extension `.<ext>`. The command will get the blob content on its STDIN
+	and the name of the blob as its only command line argument. The STDOUT
+	from the command will be included verbatim in the page content. If no
+	render filter is available for a given file extension but the mimetype
+	is specified then the content will be included as an iframe, otherwise
+	the normal source rendering will be used.  Note <ext> may be empty, in
+	which case the render filter is used on files with no suffix.
++
+Default value: none. See also: "FILTER API".
+
 repo.group::
 	Legacy alias for "section". This option is deprecated and will not be
 	supported in cgit-1.0.
@@ -718,6 +730,13 @@ owner filter::
 	standard input and the filter is expected to write to standard
 	output.  The output is included in the Owner column.
 
+render filter::
+	This filter is given a single parameter: the filename of the source
+	file to render. The filter can use the filename to determine (for
+	example) the syntax highlighting mode. The contents of the file that
+	is to be rendered is available on standard input and the rendered
+	content is expected on standard output.
+
 source filter::
 	This filter is given a single parameter: the filename of the source
 	file to filter. The filter can use the filename to determine (for
diff --git a/filter.c b/filter.c
index 70f5b74..4ae4aaa 100644
--- a/filter.c
+++ b/filter.c
@@ -434,6 +434,7 @@ struct cgit_filter *cgit_new_filter(const char *cmd, filter_type filtertype)
 
 		case SOURCE:
 		case ABOUT:
+		case RENDER:
 			argument_count = 1;
 			break;
 
diff --git a/shared.c b/shared.c
index ff1dc29..26a9266 100644
--- a/shared.c
+++ b/shared.c
@@ -571,3 +571,22 @@ char *get_mimetype_for_filename(const char *filename)
 	fclose(file);
 	return NULL;
 }
+
+struct cgit_filter *get_render_for_filename(const char *filename)
+{
+	char *ext;
+	struct string_list_item *item;
+
+	if (!filename)
+		return NULL;
+
+	ext = strrchr(filename, '.');
+	if (!ext)
+		ext = ".";
+	++ext;
+	item = string_list_lookup(&ctx.cfg.render_filters, ext);
+	if (item)
+		return item->util;
+
+	return NULL;
+}



^ permalink raw reply	[flat|nested] 140+ messages in thread

* [PATCH v2 06/15] ui-tree: split out buffer printing
  2018-06-18  2:56               ` [PATCH v2 00/15] Render READMEs inline in tree view andy
                                   ` (4 preceding siblings ...)
  2018-06-18  2:57                 ` [PATCH v2 05/15] Parse render filters from the config andy
@ 2018-06-18  2:57                 ` andy
  2018-06-18  2:57                 ` [PATCH v2 07/15] ui-tree: use render filters to display content andy
                                   ` (8 subsequent siblings)
  14 siblings, 0 replies; 140+ messages in thread
From: andy @ 2018-06-18  2:57 UTC (permalink / raw)


From: John Keeping <john at keeping.me.uk>

Signed-off-by: John Keeping <john at keeping.me.uk>
---
 ui-tree.c |   25 +++++++++++++++----------
 1 file changed, 15 insertions(+), 10 deletions(-)

diff --git a/ui-tree.c b/ui-tree.c
index e6b3074..d26e35e 100644
--- a/ui-tree.c
+++ b/ui-tree.c
@@ -84,6 +84,20 @@ static void print_binary_buffer(char *buf, unsigned long size)
 	html("</table>\n");
 }
 
+static void print_buffer(const char *basename, char *buf, unsigned long size)
+{
+	if (ctx.cfg.max_blob_size && size / 1024 > ctx.cfg.max_blob_size) {
+		htmlf("<div class='error'>blob size (%ldKB) exceeds display size limit (%dKB).</div>",
+				size / 1024, ctx.cfg.max_blob_size);
+		return;
+	}
+
+	if (buffer_is_binary(buf, size))
+		print_binary_buffer(buf, size);
+	else
+		print_text_buffer(basename, buf, size);
+}
+
 static void print_object(const struct object_id *oid, char *path, const char *basename, const char *rev)
 {
 	enum object_type type;
@@ -117,16 +131,7 @@ static void print_object(const struct object_id *oid, char *path, const char *ba
 	}
 	html(")\n");
 
-	if (ctx.cfg.max_blob_size && size / 1024 > ctx.cfg.max_blob_size) {
-		htmlf("<div class='error'>blob size (%ldKB) exceeds display size limit (%dKB).</div>",
-				size / 1024, ctx.cfg.max_blob_size);
-		return;
-	}
-
-	if (buffer_is_binary(buf, size))
-		print_binary_buffer(buf, size);
-	else
-		print_text_buffer(basename, buf, size);
+	print_buffer(basename, buf, size);
 
 	free(buf);
 }



^ permalink raw reply	[flat|nested] 140+ messages in thread

* [PATCH v2 07/15] ui-tree: use render filters to display content
  2018-06-18  2:56               ` [PATCH v2 00/15] Render READMEs inline in tree view andy
                                   ` (5 preceding siblings ...)
  2018-06-18  2:57                 ` [PATCH v2 06/15] ui-tree: split out buffer printing andy
@ 2018-06-18  2:57                 ` andy
  2018-06-18  2:57                 ` [PATCH v2 08/15] ui-blame: free read_sha1_file() buffer after use andy
                                   ` (7 subsequent siblings)
  14 siblings, 0 replies; 140+ messages in thread
From: andy @ 2018-06-18  2:57 UTC (permalink / raw)


From: John Keeping <john at keeping.me.uk>

This allows applying filters to files in the repository, for example to
render Markdown or AsciiDoc as HTML.

Signed-off-by: John Keeping <john at keeping.me.uk>
---
 cgit.css  |    5 +++
 cmd.c     |    4 +-
 ui-tree.c |  103 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++----
 ui-tree.h |    2 +
 4 files changed, 105 insertions(+), 9 deletions(-)

diff --git a/cgit.css b/cgit.css
index 217a05a..da8d9b0 100644
--- a/cgit.css
+++ b/cgit.css
@@ -274,6 +274,11 @@ div#cgit div#blob {
 	border: solid 1px black;
 }
 
+div#cgit iframe {
+	width: 100%;
+	height: 40em;
+}
+
 div#cgit div.error {
 	color: red;
 	font-weight: bold;
diff --git a/cmd.c b/cmd.c
index 56e21df..ca48b2f 100644
--- a/cmd.c
+++ b/cmd.c
@@ -140,7 +140,7 @@ static void refs_fn(void)
 
 static void source_fn(void)
 {
-	cgit_print_tree(ctx.qry.sha1, ctx.qry.path);
+	cgit_print_tree(ctx.qry.sha1, ctx.qry.path, false);
 }
 
 static void snapshot_fn(void)
@@ -166,7 +166,7 @@ static void tag_fn(void)
 
 static void tree_fn(void)
 {
-	cgit_print_tree(ctx.qry.sha1, ctx.qry.path);
+	cgit_print_tree(ctx.qry.sha1, ctx.qry.path, true);
 }
 
 #define def_cmd(name, want_repo, want_vpath, is_clone) \
diff --git a/ui-tree.c b/ui-tree.c
index d26e35e..51537f0 100644
--- a/ui-tree.c
+++ b/ui-tree.c
@@ -15,6 +15,7 @@ struct walk_tree_context {
 	char *curr_rev;
 	char *match_path;
 	int state;
+	bool use_render;
 };
 
 static void print_text_buffer(const char *name, char *buf, unsigned long size)
@@ -98,10 +99,69 @@ static void print_buffer(const char *basename, char *buf, unsigned long size)
 		print_text_buffer(basename, buf, size);
 }
 
-static void print_object(const struct object_id *oid, char *path, const char *basename, const char *rev)
+static void render_buffer(struct cgit_filter *render, const char *name,
+		char *buf, unsigned long size)
+{
+	char *filter_arg = xstrdup(name);
+
+	html("<div class='blob'>");
+	cgit_open_filter(render, filter_arg);
+	html_raw(buf, size);
+	cgit_close_filter(render);
+	html("</div>");
+
+	free(filter_arg);
+}
+
+static void include_file(const char *path, const char *mimetype)
+{
+	const char *delim = "?";
+
+	html("<div class='blob'>");
+
+	if (!strncmp(mimetype, "image/", 6)) {
+		html("<img alt='");
+		html_attr(path);
+		html("' src='");
+	} else {
+		html("<iframe sandbox='allow-scripts' src='");
+	}
+
+	if (ctx.cfg.virtual_root) {
+		html_url_path(ctx.cfg.virtual_root);
+		html_url_path(ctx.repo->url);
+		if (ctx.repo->url[strlen(ctx.repo->url) - 1] != '/')
+			html("/");
+		html("plain/");
+		html_url_path(path);
+	} else {
+		html_url_path(ctx.cfg.script_name);
+		html("?url=");
+		html_url_arg(ctx.repo->url);
+		if (ctx.repo->url[strlen(ctx.repo->url) - 1] != '/')
+			html("/");
+		html("plain/");
+		if (path)
+			html_url_arg(path);
+		delim = "&";
+	}
+	if (ctx.qry.head && ctx.repo->defbranch &&
+	    strcmp(ctx.qry.head, ctx.repo->defbranch)) {
+		html(delim);
+		html("h=");
+		html_url_arg(ctx.qry.head);
+		delim = "&";
+	}
+
+	html("'></div>");
+}
+
+static void print_object(const struct object_id *oid, char *path, const char *basename,
+			 const char *rev, bool use_render)
 {
 	enum object_type type;
-	char *buf;
+	struct cgit_filter *render;
+	char *buf, *mimetype;
 	unsigned long size;
 
 	type = oid_object_info(the_repository, oid, &size);
@@ -118,22 +178,50 @@ static void print_object(const struct object_id *oid, char *path, const char *ba
 		return;
 	}
 
+	render = get_render_for_filename(path);
+	mimetype = render ? NULL : get_mimetype_for_filename(path);
+
 	cgit_set_title_from_path(path);
 
+	/*
+	 * If we don't have a render filter or a mimetype, we won't include the
+	 * file in the page.
+	 */
+	if (!render && !mimetype)
+		use_render = false;
+
 	cgit_print_layout_start();
 	htmlf("blob: %s (", oid_to_hex(oid));
 	cgit_plain_link("plain", NULL, NULL, ctx.qry.head,
 		        rev, path);
+
 	if (ctx.cfg.enable_blame) {
 		html(") (");
 		cgit_blame_link("blame", NULL, NULL, ctx.qry.head,
 			        rev, path);
 	}
+	if (use_render) {
+		html(", ");
+		cgit_source_link("source", NULL, NULL, ctx.qry.head,
+				rev, path);
+	} else if (render || mimetype) {
+		html(", ");
+		cgit_tree_link("render", NULL, NULL, ctx.qry.head,
+			       rev, path);
+	}
 	html(")\n");
 
-	print_buffer(basename, buf, size);
+	if (use_render) {
+		if (render)
+			render_buffer(render, basename, buf, size);
+		else
+			include_file(path, mimetype);
+	} else {
+		print_buffer(basename, buf, size);
+	}
 
 	free(buf);
+	free(mimetype);
 }
 
 struct single_tree_ctx {
@@ -325,8 +413,10 @@ static int walk_tree(const struct object_id *oid, struct strbuf *base,
 			return READ_TREE_RECURSIVE;
 		} else {
 			walk_tree_ctx->state = 2;
-			print_object(oid, buffer.buf, pathname, walk_tree_ctx->curr_rev);
+			print_object(oid, buffer.buf, pathname, walk_tree_ctx->curr_rev,
+				     walk_tree_ctx->use_render);
 			strbuf_release(&buffer);
+
 			return 0;
 		}
 	}
@@ -339,7 +429,7 @@ static int walk_tree(const struct object_id *oid, struct strbuf *base,
  *   rev:  the commit pointing at the root tree object
  *   path: path to tree or blob
  */
-void cgit_print_tree(const char *rev, char *path)
+void cgit_print_tree(const char *rev, char *path, bool use_render)
 {
 	struct object_id oid;
 	struct commit *commit;
@@ -353,7 +443,8 @@ void cgit_print_tree(const char *rev, char *path)
 	};
 	struct walk_tree_context walk_tree_ctx = {
 		.match_path = path,
-		.state = 0
+		.state = 0,
+		.use_render = use_render,
 	};
 
 	if (!rev)
diff --git a/ui-tree.h b/ui-tree.h
index bbd34e3..a0fc8e2 100644
--- a/ui-tree.h
+++ b/ui-tree.h
@@ -1,6 +1,6 @@
 #ifndef UI_TREE_H
 #define UI_TREE_H
 
-extern void cgit_print_tree(const char *rev, char *path);
+extern void cgit_print_tree(const char *rev, char *path, bool use_render);
 
 #endif /* UI_TREE_H */



^ permalink raw reply	[flat|nested] 140+ messages in thread

* [PATCH v2 08/15] ui-blame: free read_sha1_file() buffer after use
  2018-06-18  2:56               ` [PATCH v2 00/15] Render READMEs inline in tree view andy
                                   ` (6 preceding siblings ...)
  2018-06-18  2:57                 ` [PATCH v2 07/15] ui-tree: use render filters to display content andy
@ 2018-06-18  2:57                 ` andy
  2018-06-18  2:58                 ` [PATCH v2 09/15] ui-tree: ls_tail: add walk table param andy
                                   ` (6 subsequent siblings)
  14 siblings, 0 replies; 140+ messages in thread
From: andy @ 2018-06-18  2:57 UTC (permalink / raw)


Signed-off-by: Andy Green <andy at warmcat.com>
---
 ui-blame.c |    6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/ui-blame.c b/ui-blame.c
index daa7e2b..6e23f0b 100644
--- a/ui-blame.c
+++ b/ui-blame.c
@@ -154,7 +154,7 @@ static void print_object(const struct object_id *oid, const char *path,
 		htmlf("<div class='error'>blob size (%ldKB)"
 		      " exceeds display size limit (%dKB).</div>",
 		      size / 1024, ctx.cfg.max_blob_size);
-		return;
+		goto cleanup;
 	}
 
 	html("<table class='blame blob'>\n<tr>\n");
@@ -206,6 +206,7 @@ static void print_object(const struct object_id *oid, const char *path,
 	} else {
 		html_txt(buf);
 	}
+
 	html("</code></pre>");
 
 	html("</div></td>\n");
@@ -213,6 +214,9 @@ static void print_object(const struct object_id *oid, const char *path,
 	html("</tr>\n</table>\n");
 
 	cgit_print_layout_end();
+
+cleanup:
+	free(buf);
 }
 
 static int walk_tree(const struct object_id *oid, struct strbuf *base,



^ permalink raw reply	[flat|nested] 140+ messages in thread

* [PATCH v2 09/15] ui-tree: ls_tail: add walk table param
  2018-06-18  2:56               ` [PATCH v2 00/15] Render READMEs inline in tree view andy
                                   ` (7 preceding siblings ...)
  2018-06-18  2:57                 ` [PATCH v2 08/15] ui-blame: free read_sha1_file() buffer after use andy
@ 2018-06-18  2:58                 ` andy
  2018-06-18  2:58                 ` [PATCH v2 10/15] config: add global inline-readme list andy
                                   ` (5 subsequent siblings)
  14 siblings, 0 replies; 140+ messages in thread
From: andy @ 2018-06-18  2:58 UTC (permalink / raw)


Arrange that walk_tree_ctx is available in ls_tail, we
will make use of it shortly.

Signed-off-by: Andy Green <andy at warmcat.com>
---
 ui-tree.c |    6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/ui-tree.c b/ui-tree.c
index 51537f0..368cdc5 100644
--- a/ui-tree.c
+++ b/ui-tree.c
@@ -366,7 +366,7 @@ static void ls_head(void)
 	html("</tr>\n");
 }
 
-static void ls_tail(void)
+static void ls_tail(struct walk_tree_context *walk_tree_ctx)
 {
 	html("</table>\n");
 	cgit_print_layout_end();
@@ -388,7 +388,7 @@ static void ls_tree(const struct object_id *oid, char *path, struct walk_tree_co
 
 	ls_head();
 	read_tree_recursive(tree, "", 0, 1, &paths, ls_item, walk_tree_ctx);
-	ls_tail();
+	ls_tail(walk_tree_ctx);
 }
 
 
@@ -471,7 +471,7 @@ void cgit_print_tree(const char *rev, char *path, bool use_render)
 
 	read_tree_recursive(commit->maybe_tree, "", 0, 0, &paths, walk_tree, &walk_tree_ctx);
 	if (walk_tree_ctx.state == 1)
-		ls_tail();
+		ls_tail(&walk_tree_ctx);
 	else if (walk_tree_ctx.state == 2)
 		cgit_print_layout_end();
 	else



^ permalink raw reply	[flat|nested] 140+ messages in thread

* [PATCH v2 10/15] config: add global inline-readme list
  2018-06-18  2:56               ` [PATCH v2 00/15] Render READMEs inline in tree view andy
                                   ` (8 preceding siblings ...)
  2018-06-18  2:58                 ` [PATCH v2 09/15] ui-tree: ls_tail: add walk table param andy
@ 2018-06-18  2:58                 ` andy
  2018-06-18 19:32                   ` john
  2018-06-18  2:58                 ` [PATCH v2 11/15] config: add repo " andy
                                   ` (4 subsequent siblings)
  14 siblings, 1 reply; 140+ messages in thread
From: andy @ 2018-06-18  2:58 UTC (permalink / raw)


Allows the user to specify a list of filenames that should be
rendered inline with tree view, if present in the directory.

Signed-off-by: Andy Green <andy at warmcat.com>
---
 cgit.c       |    5 ++++-
 cgit.h       |    1 +
 cgitrc.5.txt |    7 +++++++
 3 files changed, 12 insertions(+), 1 deletion(-)

diff --git a/cgit.c b/cgit.c
index 975e573..4ffd61f 100644
--- a/cgit.c
+++ b/cgit.c
@@ -1,6 +1,6 @@
 /* cgit.c: cgi for the git scm
  *
- * Copyright (C) 2006-2014 cgit Development Team <cgit at lists.zx2c4.com>
+ * Copyright (C) 2006-2018 cgit Development Team <cgit at lists.zx2c4.com>
  *
  * Licensed under GNU General Public License v2
  *   (see COPYING for full license text)
@@ -301,6 +301,8 @@ static void config_cb(const char *name, const char *value)
 		add_mimetype(name + 9, value);
 	else if (starts_with(name, "render."))
 		add_render_filter(name + 7, value);
+	else if (!strcmp(name, "inline-readme"))
+		string_list_insert(&ctx.cfg.inline_readme, value);
 	else if (!strcmp(name, "include"))
 		parse_configfile(expand_macros(value), config_cb);
 }
@@ -435,6 +437,7 @@ static void prepare_context(void)
 	ctx.page.etag = NULL;
 	string_list_init(&ctx.cfg.mimetypes, 1);
 	string_list_init(&ctx.cfg.render_filters, 1);
+	string_list_init(&ctx.cfg.inline_readme, 1);
 	if (ctx.env.script_name)
 		ctx.cfg.script_name = xstrdup(ctx.env.script_name);
 	if (ctx.env.query_string)
diff --git a/cgit.h b/cgit.h
index a19742f..664f003 100644
--- a/cgit.h
+++ b/cgit.h
@@ -261,6 +261,7 @@ struct cgit_config {
 	int branch_sort;
 	int commit_sort;
 	struct string_list mimetypes;
+	struct string_list inline_readme;
 	struct string_list render_filters;
 	struct cgit_filter *about_filter;
 	struct cgit_filter *commit_filter;
diff --git a/cgitrc.5.txt b/cgitrc.5.txt
index a1560eb..37858af 100644
--- a/cgitrc.5.txt
+++ b/cgitrc.5.txt
@@ -250,6 +250,13 @@ index-info::
 	is deprecated, and will not be supported by cgit-1.0 (use root-desc
 	instead). Default value: none.
 
+inline-readme::
+	Append given filename to the list of filenames to be rendered after the
+	tree navigation in tree view, if present in the directory being viewed.  Eg,
+	'inline-readme=README.md'.  You may also want a corresponding render.
+	entry for the readme suffix, eg,
+	'render.md=/usr/libexec/cgit/filters/html-converters/md2html'
+
 local-time::
 	Flag which, if set to "1", makes cgit print commit and tag times in the
 	servers timezone. Default value: "0".



^ permalink raw reply	[flat|nested] 140+ messages in thread

* [PATCH v2 11/15] config: add repo inline-readme list
  2018-06-18  2:56               ` [PATCH v2 00/15] Render READMEs inline in tree view andy
                                   ` (9 preceding siblings ...)
  2018-06-18  2:58                 ` [PATCH v2 10/15] config: add global inline-readme list andy
@ 2018-06-18  2:58                 ` andy
  2018-06-18 19:30                   ` john
  2018-06-18  2:58                 ` [PATCH v2 12/15] ui-tree: render any matching README file in tree view andy
                                   ` (3 subsequent siblings)
  14 siblings, 1 reply; 140+ messages in thread
From: andy @ 2018-06-18  2:58 UTC (permalink / raw)


This allows the user to choose to override any global
inline-readme list for a specific repo, using the
same kind of semantics as the other repo overrides.

Signed-off-by: Andy Green <andy at warmcat.com>
---
 cgit.c       |    6 ++++++
 cgit.h       |    1 +
 cgitrc.5.txt |   10 ++++++++++
 shared.c     |    2 ++
 4 files changed, 19 insertions(+)

diff --git a/cgit.c b/cgit.c
index 4ffd61f..7c13327 100644
--- a/cgit.c
+++ b/cgit.c
@@ -103,6 +103,12 @@ static void repo_config(struct cgit_repo *repo, const char *name, const char *va
 		repo->hide = atoi(value);
 	else if (!strcmp(name, "ignore"))
 		repo->ignore = atoi(value);
+	else if (!strcmp(name, "inline-readme")) {
+		if (repo->inline_readme.items == ctx.cfg.inline_readme.items)
+			string_list_init(&repo->inline_readme, 1);
+
+		string_list_append(&repo->inline_readme, value);
+	}
 	else if (ctx.cfg.enable_filter_overrides) {
 		if (!strcmp(name, "about-filter"))
 			repo->about_filter = cgit_new_filter(value, ABOUT);
diff --git a/cgit.h b/cgit.h
index 664f003..0aebeba 100644
--- a/cgit.h
+++ b/cgit.h
@@ -84,6 +84,7 @@ struct cgit_repo {
 	char *defbranch;
 	char *module_link;
 	struct string_list readme;
+	struct string_list inline_readme;
 	char *section;
 	char *clone_url;
 	char *logo;
diff --git a/cgitrc.5.txt b/cgitrc.5.txt
index 37858af..3f493cb 100644
--- a/cgitrc.5.txt
+++ b/cgitrc.5.txt
@@ -561,6 +561,16 @@ repo.ignore::
 	is not shown in the index and cannot be accessed by providing a direct
 	path. Default value: "0". See also: "repo.hide".
 
+repo.inline-readme::
+	Append given filename to the list of filenames to be rendered after the
+	tree navigation in tree view, if present in the directory being viewed.  Eg,
+	'repo.inline-readme=README.md'.  You may also want a corresponding render.
+	entry for the readme suffix, eg,
+	'render.md=/usr/libexec/cgit/filters/html-converters/md2html'.
+	If not given, the repo will use any global 'inline-readme=' configuration;
+	if any 'repo.inline-readme' are given only they are used for that repo,
+	and the global 'inline-readme=' list is ignored for that repo.
+
 repo.logo::
 	Url which specifies the source of an image which will be used as a logo
 	on this repo's pages. Default value: global logo.
diff --git a/shared.c b/shared.c
index 26a9266..8fe5c1b 100644
--- a/shared.c
+++ b/shared.c
@@ -77,6 +77,8 @@ struct cgit_repo *cgit_add_repo(const char *url)
 	ret->clone_url = ctx.cfg.clone_url;
 	ret->submodules.strdup_strings = 1;
 	ret->hide = ret->ignore = 0;
+	ret->inline_readme = ctx.cfg.inline_readme;
+
 	return ret;
 }
 



^ permalink raw reply	[flat|nested] 140+ messages in thread

* [PATCH v2 12/15] ui-tree: render any matching README file in tree view
  2018-06-18  2:56               ` [PATCH v2 00/15] Render READMEs inline in tree view andy
                                   ` (10 preceding siblings ...)
  2018-06-18  2:58                 ` [PATCH v2 11/15] config: add repo " andy
@ 2018-06-18  2:58                 ` andy
  2018-06-18 19:36                   ` john
  2018-06-18  2:58                 ` [PATCH v2 13/15] md2html: add asset mapping andy
                                   ` (2 subsequent siblings)
  14 siblings, 1 reply; 140+ messages in thread
From: andy @ 2018-06-18  2:58 UTC (permalink / raw)


While listing the items in tree view, we collect a list
of any filenames that match any tree-readme entries from the
config file.

After the tree view has been shown, we iterate through any
collected readme files rendering them inline.

Signed-off-by: Andy Green <andy at warmcat.com>
---
 ui-tree.c |   60 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 59 insertions(+), 1 deletion(-)

diff --git a/ui-tree.c b/ui-tree.c
index 368cdc5..9f59d18 100644
--- a/ui-tree.c
+++ b/ui-tree.c
@@ -1,6 +1,6 @@
 /* ui-tree.c: functions for tree output
  *
- * Copyright (C) 2006-2017 cgit Development Team <cgit at lists.zx2c4.com>
+ * Copyright (C) 2006-2018 cgit Development Team <cgit at lists.zx2c4.com>
  *
  * Licensed under GNU General Public License v2
  *   (see COPYING for full license text)
@@ -12,8 +12,10 @@
 #include "ui-shared.h"
 
 struct walk_tree_context {
+	struct object_id inline_oid;
 	char *curr_rev;
 	char *match_path;
+	char *inline_path;
 	int state;
 	bool use_render;
 };
@@ -326,11 +328,19 @@ static int ls_item(const struct object_id *oid, struct strbuf *base,
 				&fullpath);
 	} else {
 		char *ext = strrchr(name, '.');
+
 		strbuf_addstr(&class, "ls-blob");
 		if (ext)
 			strbuf_addf(&class, " %s", ext + 1);
+
 		cgit_tree_link(name, NULL, class.buf, ctx.qry.head,
 			       walk_tree_ctx->curr_rev, fullpath.buf);
+
+		if (!walk_tree_ctx->inline_path &&
+		    string_list_has_string(&ctx.repo->inline_readme, name)) {
+			walk_tree_ctx->inline_path = xstrdup(pathname);
+			oidcpy(&walk_tree_ctx->inline_oid, oid);
+		}
 	}
 	htmlf("</td><td class='ls-size'>%li</td>", size);
 
@@ -368,7 +378,53 @@ static void ls_head(void)
 
 static void ls_tail(struct walk_tree_context *walk_tree_ctx)
 {
+	struct cgit_filter *render;
+	enum object_type type;
+	char *buf, *mimetype, *name;
+	unsigned long size;
+
 	html("</table>\n");
+
+	if (!walk_tree_ctx->inline_path)
+		goto done;
+
+	type = oid_object_info(the_repository, &walk_tree_ctx->inline_oid, &size);
+	if (type == OBJ_BAD)
+		goto done;
+
+	buf = read_object_file(&walk_tree_ctx->inline_oid, &type, &size);
+	if (!buf)
+		goto done;
+
+	/* create a vertical gap between tree nav / inline */
+	html("<table class=\"tabs\"><tr><td></td></tr></table>");
+
+	render = get_render_for_filename(walk_tree_ctx->inline_path);
+	mimetype = render ? NULL : get_mimetype_for_filename(
+				walk_tree_ctx->inline_path);
+
+	name = strrchr(walk_tree_ctx->inline_path, '/');
+	if (name)
+		name++;
+	else
+		name = walk_tree_ctx->inline_path;
+
+	htmlf("<h2>%s</h2>", name);
+	html("<div class=blob>&nbsp;</div>\n");
+
+	if (render || mimetype) {
+		if (render)
+			render_buffer(render, name, buf, size);
+		else
+			include_file(walk_tree_ctx->inline_path, mimetype);
+	} else {
+		print_buffer(name, buf, size);
+	}
+
+	free(mimetype);
+	free(buf);
+
+done:
 	cgit_print_layout_end();
 }
 
@@ -479,4 +535,6 @@ void cgit_print_tree(const char *rev, char *path, bool use_render)
 
 cleanup:
 	free(walk_tree_ctx.curr_rev);
+	if (walk_tree_ctx.inline_path)
+		free(walk_tree_ctx.inline_path);
 }



^ permalink raw reply	[flat|nested] 140+ messages in thread

* [PATCH v2 13/15] md2html: add asset mapping
  2018-06-18  2:56               ` [PATCH v2 00/15] Render READMEs inline in tree view andy
                                   ` (11 preceding siblings ...)
  2018-06-18  2:58                 ` [PATCH v2 12/15] ui-tree: render any matching README file in tree view andy
@ 2018-06-18  2:58                 ` andy
  2018-06-18  2:58                 ` [PATCH v2 14/15] md2html-add-asset-postfix-arg andy
  2018-06-18  2:58                 ` [PATCH v2 15/15] render: adapt for providing extra filter args for plain andy
  14 siblings, 0 replies; 140+ messages in thread
From: andy @ 2018-06-18  2:58 UTC (permalink / raw)


From: John Keeping <john at keeping.me.uk>

This remaps the "src" attribute on <img> elements according to a second
command line argument, you can try it out with:

	md2html <README.md README.md /path/to/plain/directory/

The trailing "/" is important.

This is useful when serving relative URLs from the repo in a readme.

Signed-off-by: John Keeping <john at keeping.me.uk>
---
 filters/html-converters/md2html |   50 ++++++++++++++++++++++++++++++++++++++-
 1 file changed, 49 insertions(+), 1 deletion(-)

diff --git a/filters/html-converters/md2html b/filters/html-converters/md2html
index ebf3856..eb5d977 100755
--- a/filters/html-converters/md2html
+++ b/filters/html-converters/md2html
@@ -2,7 +2,41 @@
 import markdown
 import sys
 import io
+from markdown.util import etree
 from pygments.formatters import HtmlFormatter
+from urllib.parse import urljoin
+
+
+class AssetMappingProcessor(markdown.treeprocessors.Treeprocessor):
+
+    def __init__(self, asset_prefix):
+        self.asset_prefix = asset_prefix
+
+    def run(self, root):
+        asset_prefix = self.asset_prefix
+        for img in root.iter('img'):
+            src = img.get('src')
+            if src is None:
+                continue
+            img.set('src', urljoin(asset_prefix, src))
+
+
+class AssetMappingExtension(markdown.extensions.Extension):
+
+    def __init__(self, **kwargs):
+        self.config = {'asset_prefix': ['', 'prefix for relative asset URLs']}
+        super(AssetMappingExtension, self).__init__(**kwargs)
+
+    def extendMarkdown(self, md, md_globals):
+        asset_prefix = self.getConfig('asset_prefix')
+        if not asset_prefix:
+            return
+
+        md.treeprocessors.add('asset_mapping',
+                              AssetMappingProcessor(asset_prefix),
+                              '_end')
+
+
 sys.stdin = io.TextIOWrapper(sys.stdin.buffer, encoding='utf-8')
 sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')
 sys.stdout.write('''
@@ -289,6 +323,20 @@ sys.stdout.write('''
 ''')
 sys.stdout.write("<div class='markdown-body'>")
 sys.stdout.flush()
+
+extensions = [
+    "markdown.extensions.fenced_code",
+    "markdown.extensions.codehilite",
+    "markdown.extensions.tables"
+]
+extension_configs = {
+    "markdown.extensions.codehilite":{"css_class":"highlight"}
+}
+
+if len(sys.argv) > 2:
+    extensions.append(AssetMappingExtension(asset_prefix=sys.argv[2]))
+
 # Note: you may want to run this through bleach for sanitization
-markdown.markdownFromFile(output_format="html5", extensions=["markdown.extensions.fenced_code", "markdown.extensions.codehilite", "markdown.extensions.tables"], extension_configs={"markdown.extensions.codehilite":{"css_class":"highlight"}})
+markdown.markdownFromFile(output_format="html5", extensions=extensions, extension_configs=extension_configs)
 sys.stdout.write("</div>")
+



^ permalink raw reply	[flat|nested] 140+ messages in thread

* [PATCH v2 14/15] md2html-add-asset-postfix-arg
  2018-06-18  2:56               ` [PATCH v2 00/15] Render READMEs inline in tree view andy
                                   ` (12 preceding siblings ...)
  2018-06-18  2:58                 ` [PATCH v2 13/15] md2html: add asset mapping andy
@ 2018-06-18  2:58                 ` andy
  2018-06-18 19:21                   ` john
  2018-06-18  2:58                 ` [PATCH v2 15/15] render: adapt for providing extra filter args for plain andy
  14 siblings, 1 reply; 140+ messages in thread
From: andy @ 2018-06-18  2:58 UTC (permalink / raw)


Extend md2html with a third argument for URL postfix, like "?h=mybranch"

Signed-off-by: Andy Green <andy at warmcat.com>
---
 filters/html-converters/md2html |   17 +++++++++++------
 1 file changed, 11 insertions(+), 6 deletions(-)

diff --git a/filters/html-converters/md2html b/filters/html-converters/md2html
index eb5d977..128a61b 100755
--- a/filters/html-converters/md2html
+++ b/filters/html-converters/md2html
@@ -9,31 +9,36 @@ from urllib.parse import urljoin
 
 class AssetMappingProcessor(markdown.treeprocessors.Treeprocessor):
 
-    def __init__(self, asset_prefix):
+    def __init__(self, asset_prefix, asset_postfix):
         self.asset_prefix = asset_prefix
+        self.asset_postfix = asset_postfix
 
     def run(self, root):
         asset_prefix = self.asset_prefix
+        asset_postfix = self.asset_postfix
         for img in root.iter('img'):
             src = img.get('src')
             if src is None:
                 continue
-            img.set('src', urljoin(asset_prefix, src))
+            img.set('src', urljoin(urljoin(asset_prefix, src), asset_postfix))
 
 
 class AssetMappingExtension(markdown.extensions.Extension):
 
     def __init__(self, **kwargs):
-        self.config = {'asset_prefix': ['', 'prefix for relative asset URLs']}
+        self.config = {'asset_prefix': ['', 'prefix for relative asset URLs'], 'asset_postfix': ['', 'postfix for relative asset URLs']}
         super(AssetMappingExtension, self).__init__(**kwargs)
 
     def extendMarkdown(self, md, md_globals):
         asset_prefix = self.getConfig('asset_prefix')
         if not asset_prefix:
             return
+        asset_postfix = self.getConfig('asset_postfix')
+        if not asset_postfix:
+            return
 
         md.treeprocessors.add('asset_mapping',
-                              AssetMappingProcessor(asset_prefix),
+                              AssetMappingProcessor(asset_prefix, asset_postfix),
                               '_end')
 
 
@@ -333,8 +338,8 @@ extension_configs = {
     "markdown.extensions.codehilite":{"css_class":"highlight"}
 }
 
-if len(sys.argv) > 2:
-    extensions.append(AssetMappingExtension(asset_prefix=sys.argv[2]))
+if len(sys.argv) > 3:
+    extensions.append(AssetMappingExtension(asset_prefix=sys.argv[2],asset_postfix=sys.argv[3]))
 
 # Note: you may want to run this through bleach for sanitization
 markdown.markdownFromFile(output_format="html5", extensions=extensions, extension_configs=extension_configs)



^ permalink raw reply	[flat|nested] 140+ messages in thread

* [PATCH v2 15/15] render: adapt for providing extra filter args for plain
  2018-06-18  2:56               ` [PATCH v2 00/15] Render READMEs inline in tree view andy
                                   ` (13 preceding siblings ...)
  2018-06-18  2:58                 ` [PATCH v2 14/15] md2html-add-asset-postfix-arg andy
@ 2018-06-18  2:58                 ` andy
  2018-06-18 19:25                   ` john
  14 siblings, 1 reply; 140+ messages in thread
From: andy @ 2018-06-18  2:58 UTC (permalink / raw)


This changes the render filter exec part to provide a second
and third argument, which are used by md2html to fix up the url
path for "plain" for the repo, eg, "/cgit/plain/" and
"?h=mybranch", as required by the modifications to md2html in
the previous patches.

The combination means cgit becomes able to serve assets using
markdown urls starting from the repo root dir, without mentioning
any virtual url part specific to a cgit or other web rendering
instance, while respecting the version context.

Eg, continuing the example of the arguments being
"/cgit/plain/" and "?h=mybranch" from above, if the markdown has

![overview](./doc-assets/overview.png)

the img src will be fixed up to

"/cgit/plain/doc-assets/overview.png?h=mybranch"

If the same document is viewed from a different rev in cgit, the
processed markdown url will change to match the cgit context, even
though the markdown relative URL is the same for all versions.

Signed-off-by: Andy Green <andy at warmcat.com>
---
 filter.c  |    5 ++++-
 ui-tree.c |   13 +++++++++++--
 2 files changed, 15 insertions(+), 3 deletions(-)

diff --git a/filter.c b/filter.c
index 4ae4aaa..7c1f188 100644
--- a/filter.c
+++ b/filter.c
@@ -424,6 +424,10 @@ struct cgit_filter *cgit_new_filter(const char *cmd, filter_type filtertype)
 			argument_count = 12;
 			break;
 
+		case RENDER:
+			argument_count = 3;
+			break;
+
 		case EMAIL:
 			argument_count = 2;
 			break;
@@ -434,7 +438,6 @@ struct cgit_filter *cgit_new_filter(const char *cmd, filter_type filtertype)
 
 		case SOURCE:
 		case ABOUT:
-		case RENDER:
 			argument_count = 1;
 			break;
 
diff --git a/ui-tree.c b/ui-tree.c
index 9f59d18..5bbe30d 100644
--- a/ui-tree.c
+++ b/ui-tree.c
@@ -102,16 +102,25 @@ static void print_buffer(const char *basename, char *buf, unsigned long size)
 }
 
 static void render_buffer(struct cgit_filter *render, const char *name,
-		char *buf, unsigned long size)
+			  char *buf, unsigned long size)
 {
 	char *filter_arg = xstrdup(name);
+	char *repo_url = cgit_repourl(ctx.repo->url);
+	struct strbuf sb_plain = STRBUF_INIT, sb_postfix = STRBUF_INIT;
+
+	strbuf_addf(&sb_plain, "%splain/", repo_url);
+	if (ctx.qry.head)
+		strbuf_addf(&sb_postfix, "?h=%s", ctx.qry.head);
+	free(repo_url);
 
 	html("<div class='blob'>");
-	cgit_open_filter(render, filter_arg);
+	cgit_open_filter(render, filter_arg, sb_plain.buf, sb_postfix.buf);
 	html_raw(buf, size);
 	cgit_close_filter(render);
 	html("</div>");
 
+	strbuf_release(&sb_plain);
+	strbuf_release(&sb_postfix);
 	free(filter_arg);
 }
 



^ permalink raw reply	[flat|nested] 140+ messages in thread

* [PATCH v2 04/15] Add source page
  2018-06-18  2:57                 ` [PATCH v2 04/15] Add source page andy
@ 2018-06-18 19:08                   ` john
  2018-06-18 19:27                     ` andy
  0 siblings, 1 reply; 140+ messages in thread
From: john @ 2018-06-18 19:08 UTC (permalink / raw)


On Mon, Jun 18, 2018 at 10:57:35AM +0800, Andy Green wrote:
> From: John Keeping <john at keeping.me.uk>
> 
> We are about to introduce rendering of content for the tree view.  This
> source page will allow bypassing the renderer and accessing the content
> of the current tree view.
> 
> Signed-off-by: John Keeping <john at keeping.me.uk>
> ---

While testing this series, I noticed a slight deficiency in the source
view in that nothing in the header is highlighted.

The following fixup seems like the right thing to do.  What do you
think?

-- >8 --
Subject: [PATCH] fixup! Add source page

Signed-off-by: John Keeping <john at keeping.me.uk>
---
 ui-shared.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/ui-shared.c b/ui-shared.c
index f358a68..c769ff8 100644
--- a/ui-shared.c
+++ b/ui-shared.c
@@ -1006,6 +1006,10 @@ void cgit_print_pageheader(void)
 		if (ctx.qry.page && !strcmp(ctx.qry.page, "blame"))
 			cgit_blame_link("blame", NULL, hc("blame"), ctx.qry.head,
 				        ctx.qry.sha1, ctx.qry.vpath);
+		else if (ctx.qry.page && !strcmp(ctx.qry.page, "source"))
+			cgit_source_link("tree", NULL, hc("source"),
+					 ctx.qry.head, ctx.qry.sha1,
+					 ctx.qry.vpath);
 		else
 			cgit_tree_link("tree", NULL, hc("tree"), ctx.qry.head,
 				       ctx.qry.sha1, ctx.qry.vpath);
-- 
2.17.1



^ permalink raw reply	[flat|nested] 140+ messages in thread

* [PATCH v2 14/15] md2html-add-asset-postfix-arg
  2018-06-18  2:58                 ` [PATCH v2 14/15] md2html-add-asset-postfix-arg andy
@ 2018-06-18 19:21                   ` john
  2018-06-19  3:55                     ` andy
  0 siblings, 1 reply; 140+ messages in thread
From: john @ 2018-06-18 19:21 UTC (permalink / raw)


On Mon, Jun 18, 2018 at 10:58:26AM +0800, Andy Green wrote:
> Extend md2html with a third argument for URL postfix, like "?h=mybranch"
> 
> Signed-off-by: Andy Green <andy at warmcat.com>
> ---
>  filters/html-converters/md2html |   17 +++++++++++------
>  1 file changed, 11 insertions(+), 6 deletions(-)
> 
> diff --git a/filters/html-converters/md2html b/filters/html-converters/md2html
> index eb5d977..128a61b 100755
> --- a/filters/html-converters/md2html
> +++ b/filters/html-converters/md2html
> @@ -9,31 +9,36 @@ from urllib.parse import urljoin
>  
>  class AssetMappingProcessor(markdown.treeprocessors.Treeprocessor):
>  
> -    def __init__(self, asset_prefix):
> +    def __init__(self, asset_prefix, asset_postfix):
>          self.asset_prefix = asset_prefix
> +        self.asset_postfix = asset_postfix
>  
>      def run(self, root):
>          asset_prefix = self.asset_prefix
> +        asset_postfix = self.asset_postfix
>          for img in root.iter('img'):
>              src = img.get('src')
>              if src is None:
>                  continue
> -            img.set('src', urljoin(asset_prefix, src))
> +            img.set('src', urljoin(urljoin(asset_prefix, src), asset_postfix))
>  
>  
>  class AssetMappingExtension(markdown.extensions.Extension):
>  
>      def __init__(self, **kwargs):
> -        self.config = {'asset_prefix': ['', 'prefix for relative asset URLs']}
> +        self.config = {'asset_prefix': ['', 'prefix for relative asset URLs'], 'asset_postfix': ['', 'postfix for relative asset URLs']}

For style it would be nice to align this under asset_prefix.

>          super(AssetMappingExtension, self).__init__(**kwargs)
>  
>      def extendMarkdown(self, md, md_globals):
>          asset_prefix = self.getConfig('asset_prefix')
>          if not asset_prefix:
>              return
> +        asset_postfix = self.getConfig('asset_postfix')
> +        if not asset_postfix:
> +            return

Is this right?  Should we allow one of these to be empty and still
process the other one?  In other words, shouldn't the bail out condition
be:

    if not (asset_prefix or asset_postfix):
        return

I don't think any change to AssetMappingProcessor is required because
urljoin already does the right thing when handed the empty string and
the config assure that if no value is specified then that is what we
get.

>  
>          md.treeprocessors.add('asset_mapping',
> -                              AssetMappingProcessor(asset_prefix),
> +                              AssetMappingProcessor(asset_prefix, asset_postfix),
>                                '_end')
>  
>  
> @@ -333,8 +338,8 @@ extension_configs = {
>      "markdown.extensions.codehilite":{"css_class":"highlight"}
>  }
>  
> -if len(sys.argv) > 2:
> -    extensions.append(AssetMappingExtension(asset_prefix=sys.argv[2]))
> +if len(sys.argv) > 3:
> +    extensions.append(AssetMappingExtension(asset_prefix=sys.argv[2],asset_postfix=sys.argv[3]))

Can we allow specifying only the prefix here?  Something like:

    if len(sys.argv) > 2:
        args = {'asset_prefix': sys.argv[2]}
        if len(sys.argv) > 3:
            args['asset_postfix'] = sys.argv[3]
        extensions.append(AssetMappingExtension(**args))

>  
>  # Note: you may want to run this through bleach for sanitization
>  markdown.markdownFromFile(output_format="html5", extensions=extensions, extension_configs=extension_configs)
> 


^ permalink raw reply	[flat|nested] 140+ messages in thread

* [PATCH v2 15/15] render: adapt for providing extra filter args for plain
  2018-06-18  2:58                 ` [PATCH v2 15/15] render: adapt for providing extra filter args for plain andy
@ 2018-06-18 19:25                   ` john
  2018-06-19  3:34                     ` andy
  0 siblings, 1 reply; 140+ messages in thread
From: john @ 2018-06-18 19:25 UTC (permalink / raw)


On Mon, Jun 18, 2018 at 10:58:31AM +0800, Andy Green wrote:
> This changes the render filter exec part to provide a second
> and third argument, which are used by md2html to fix up the url
> path for "plain" for the repo, eg, "/cgit/plain/" and
> "?h=mybranch", as required by the modifications to md2html in
> the previous patches.
> 
> The combination means cgit becomes able to serve assets using
> markdown urls starting from the repo root dir, without mentioning
> any virtual url part specific to a cgit or other web rendering
> instance, while respecting the version context.
> 
> Eg, continuing the example of the arguments being
> "/cgit/plain/" and "?h=mybranch" from above, if the markdown has
> 
> ![overview](./doc-assets/overview.png)
> 
> the img src will be fixed up to
> 
> "/cgit/plain/doc-assets/overview.png?h=mybranch"
> 
> If the same document is viewed from a different rev in cgit, the
> processed markdown url will change to match the cgit context, even
> though the markdown relative URL is the same for all versions.
> 
> Signed-off-by: Andy Green <andy at warmcat.com>
> ---
>  filter.c  |    5 ++++-
>  ui-tree.c |   13 +++++++++++--
>  2 files changed, 15 insertions(+), 3 deletions(-)
> 
> diff --git a/filter.c b/filter.c
> index 4ae4aaa..7c1f188 100644
> --- a/filter.c
> +++ b/filter.c
> @@ -424,6 +424,10 @@ struct cgit_filter *cgit_new_filter(const char *cmd, filter_type filtertype)
>  			argument_count = 12;
>  			break;
>  
> +		case RENDER:
> +			argument_count = 3;
> +			break;
> +
>  		case EMAIL:
>  			argument_count = 2;
>  			break;
> @@ -434,7 +438,6 @@ struct cgit_filter *cgit_new_filter(const char *cmd, filter_type filtertype)
>  
>  		case SOURCE:
>  		case ABOUT:
> -		case RENDER:
>  			argument_count = 1;
>  			break;
>  
> diff --git a/ui-tree.c b/ui-tree.c
> index 9f59d18..5bbe30d 100644
> --- a/ui-tree.c
> +++ b/ui-tree.c
> @@ -102,16 +102,25 @@ static void print_buffer(const char *basename, char *buf, unsigned long size)
>  }
>  
>  static void render_buffer(struct cgit_filter *render, const char *name,
> -		char *buf, unsigned long size)
> +			  char *buf, unsigned long size)
>  {
>  	char *filter_arg = xstrdup(name);
> +	char *repo_url = cgit_repourl(ctx.repo->url);
> +	struct strbuf sb_plain = STRBUF_INIT, sb_postfix = STRBUF_INIT;
> +
> +	strbuf_addf(&sb_plain, "%splain/", repo_url);

This doesn't always work (if we don't have cfg.virtual_root set it's
wrong).

The logic in ui-shared.c::reporevlink() does the right thing, and it
might be possible to extract a helper function but we may just have to
replicate it since that version generates the URL as an HTML attribute
value.

> +	if (ctx.qry.head)
> +		strbuf_addf(&sb_postfix, "?h=%s", ctx.qry.head);
> +	free(repo_url);
>  
>  	html("<div class='blob'>");
> -	cgit_open_filter(render, filter_arg);
> +	cgit_open_filter(render, filter_arg, sb_plain.buf, sb_postfix.buf);
>  	html_raw(buf, size);
>  	cgit_close_filter(render);
>  	html("</div>");
>  
> +	strbuf_release(&sb_plain);
> +	strbuf_release(&sb_postfix);
>  	free(filter_arg);
>  }
>  


^ permalink raw reply	[flat|nested] 140+ messages in thread

* [PATCH v2 04/15] Add source page
  2018-06-18 19:08                   ` john
@ 2018-06-18 19:27                     ` andy
  0 siblings, 0 replies; 140+ messages in thread
From: andy @ 2018-06-18 19:27 UTC (permalink / raw)




On June 19, 2018 3:08:16 AM GMT+08:00, John Keeping <john at keeping.me.uk> wrote:
>On Mon, Jun 18, 2018 at 10:57:35AM +0800, Andy Green wrote:
>> From: John Keeping <john at keeping.me.uk>
>> 
>> We are about to introduce rendering of content for the tree view. 
>This
>> source page will allow bypassing the renderer and accessing the
>content
>> of the current tree view.
>> 
>> Signed-off-by: John Keeping <john at keeping.me.uk>
>> ---
>
>While testing this series, I noticed a slight deficiency in the source
>view in that nothing in the header is highlighted.
>
>The following fixup seems like the right thing to do.  What do you
>think?

OK thanks I'll squash it in.

-Andy

>-- >8 --
>Subject: [PATCH] fixup! Add source page
>
>Signed-off-by: John Keeping <john at keeping.me.uk>
>---
> ui-shared.c | 4 ++++
> 1 file changed, 4 insertions(+)
>
>diff --git a/ui-shared.c b/ui-shared.c
>index f358a68..c769ff8 100644
>--- a/ui-shared.c
>+++ b/ui-shared.c
>@@ -1006,6 +1006,10 @@ void cgit_print_pageheader(void)
> 		if (ctx.qry.page && !strcmp(ctx.qry.page, "blame"))
> 			cgit_blame_link("blame", NULL, hc("blame"), ctx.qry.head,
> 				        ctx.qry.sha1, ctx.qry.vpath);
>+		else if (ctx.qry.page && !strcmp(ctx.qry.page, "source"))
>+			cgit_source_link("tree", NULL, hc("source"),
>+					 ctx.qry.head, ctx.qry.sha1,
>+					 ctx.qry.vpath);
> 		else
> 			cgit_tree_link("tree", NULL, hc("tree"), ctx.qry.head,
> 				       ctx.qry.sha1, ctx.qry.vpath);


^ permalink raw reply	[flat|nested] 140+ messages in thread

* [PATCH v2 11/15] config: add repo inline-readme list
  2018-06-18  2:58                 ` [PATCH v2 11/15] config: add repo " andy
@ 2018-06-18 19:30                   ` john
  0 siblings, 0 replies; 140+ messages in thread
From: john @ 2018-06-18 19:30 UTC (permalink / raw)


On Mon, Jun 18, 2018 at 10:58:10AM +0800, Andy Green wrote:
> This allows the user to choose to override any global
> inline-readme list for a specific repo, using the
> same kind of semantics as the other repo overrides.
> 
> Signed-off-by: Andy Green <andy at warmcat.com>

One small style nit below, but other than that this looks good.

Reviewed-by: John Keeping <john at keeping.me.uk>

> ---
>  cgit.c       |    6 ++++++
>  cgit.h       |    1 +
>  cgitrc.5.txt |   10 ++++++++++
>  shared.c     |    2 ++
>  4 files changed, 19 insertions(+)
> 
> diff --git a/cgit.c b/cgit.c
> index 4ffd61f..7c13327 100644
> --- a/cgit.c
> +++ b/cgit.c
> @@ -103,6 +103,12 @@ static void repo_config(struct cgit_repo *repo, const char *name, const char *va
>  		repo->hide = atoi(value);
>  	else if (!strcmp(name, "ignore"))
>  		repo->ignore = atoi(value);
> +	else if (!strcmp(name, "inline-readme")) {
> +		if (repo->inline_readme.items == ctx.cfg.inline_readme.items)
> +			string_list_init(&repo->inline_readme, 1);
> +
> +		string_list_append(&repo->inline_readme, value);
> +	}
>  	else if (ctx.cfg.enable_filter_overrides) {

The else if should be on the same line as the closing } here.

>  		if (!strcmp(name, "about-filter"))
>  			repo->about_filter = cgit_new_filter(value, ABOUT);
> diff --git a/cgit.h b/cgit.h
> index 664f003..0aebeba 100644
> --- a/cgit.h
> +++ b/cgit.h
> @@ -84,6 +84,7 @@ struct cgit_repo {
>  	char *defbranch;
>  	char *module_link;
>  	struct string_list readme;
> +	struct string_list inline_readme;
>  	char *section;
>  	char *clone_url;
>  	char *logo;
> diff --git a/cgitrc.5.txt b/cgitrc.5.txt
> index 37858af..3f493cb 100644
> --- a/cgitrc.5.txt
> +++ b/cgitrc.5.txt
> @@ -561,6 +561,16 @@ repo.ignore::
>  	is not shown in the index and cannot be accessed by providing a direct
>  	path. Default value: "0". See also: "repo.hide".
>  
> +repo.inline-readme::
> +	Append given filename to the list of filenames to be rendered after the
> +	tree navigation in tree view, if present in the directory being viewed.  Eg,
> +	'repo.inline-readme=README.md'.  You may also want a corresponding render.
> +	entry for the readme suffix, eg,
> +	'render.md=/usr/libexec/cgit/filters/html-converters/md2html'.
> +	If not given, the repo will use any global 'inline-readme=' configuration;
> +	if any 'repo.inline-readme' are given only they are used for that repo,
> +	and the global 'inline-readme=' list is ignored for that repo.
> +
>  repo.logo::
>  	Url which specifies the source of an image which will be used as a logo
>  	on this repo's pages. Default value: global logo.
> diff --git a/shared.c b/shared.c
> index 26a9266..8fe5c1b 100644
> --- a/shared.c
> +++ b/shared.c
> @@ -77,6 +77,8 @@ struct cgit_repo *cgit_add_repo(const char *url)
>  	ret->clone_url = ctx.cfg.clone_url;
>  	ret->submodules.strdup_strings = 1;
>  	ret->hide = ret->ignore = 0;
> +	ret->inline_readme = ctx.cfg.inline_readme;
> +
>  	return ret;
>  }
>  


^ permalink raw reply	[flat|nested] 140+ messages in thread

* [PATCH v2 10/15] config: add global inline-readme list
  2018-06-18  2:58                 ` [PATCH v2 10/15] config: add global inline-readme list andy
@ 2018-06-18 19:32                   ` john
  0 siblings, 0 replies; 140+ messages in thread
From: john @ 2018-06-18 19:32 UTC (permalink / raw)


On Mon, Jun 18, 2018 at 10:58:05AM +0800, Andy Green wrote:
> Allows the user to specify a list of filenames that should be
> rendered inline with tree view, if present in the directory.
> 
> Signed-off-by: Andy Green <andy at warmcat.com>
> ---
> diff --git a/cgitrc.5.txt b/cgitrc.5.txt
> index a1560eb..37858af 100644
> --- a/cgitrc.5.txt
> +++ b/cgitrc.5.txt
> @@ -250,6 +250,13 @@ index-info::
>  	is deprecated, and will not be supported by cgit-1.0 (use root-desc
>  	instead). Default value: none.
>  
> +inline-readme::
> +	Append given filename to the list of filenames to be rendered after the
> +	tree navigation in tree view, if present in the directory being viewed.  Eg,
> +	'inline-readme=README.md'.  You may also want a corresponding render.
> +	entry for the readme suffix, eg,
> +	'render.md=/usr/libexec/cgit/filters/html-converters/md2html'

The documentation in the following patch is a bit more descriptive than
this.  I wonder if it makes sense to follow the pattern we use for the
"readme" option and say that this defines the default value for
repo.inline-readme.


^ permalink raw reply	[flat|nested] 140+ messages in thread

* [PATCH v2 12/15] ui-tree: render any matching README file in tree view
  2018-06-18  2:58                 ` [PATCH v2 12/15] ui-tree: render any matching README file in tree view andy
@ 2018-06-18 19:36                   ` john
  2018-06-19  1:55                     ` andy
  0 siblings, 1 reply; 140+ messages in thread
From: john @ 2018-06-18 19:36 UTC (permalink / raw)


On Mon, Jun 18, 2018 at 10:58:15AM +0800, Andy Green wrote:
> While listing the items in tree view, we collect a list
> of any filenames that match any tree-readme entries from the
> config file.
> 
> After the tree view has been shown, we iterate through any
> collected readme files rendering them inline.
> 
> Signed-off-by: Andy Green <andy at warmcat.com>

A couple of minor style points below, but this looks good.  With or
without the style changes:

Reviewed-by: John Keeping <john at keeping.me.uk>

> ---
>  ui-tree.c |   60 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
>  1 file changed, 59 insertions(+), 1 deletion(-)
> 
> diff --git a/ui-tree.c b/ui-tree.c
> index 368cdc5..9f59d18 100644
> --- a/ui-tree.c
> +++ b/ui-tree.c
> @@ -1,6 +1,6 @@
>  /* ui-tree.c: functions for tree output
>   *
> - * Copyright (C) 2006-2017 cgit Development Team <cgit at lists.zx2c4.com>
> + * Copyright (C) 2006-2018 cgit Development Team <cgit at lists.zx2c4.com>
>   *
>   * Licensed under GNU General Public License v2
>   *   (see COPYING for full license text)
> @@ -12,8 +12,10 @@
>  #include "ui-shared.h"
>  
>  struct walk_tree_context {
> +	struct object_id inline_oid;
>  	char *curr_rev;
>  	char *match_path;
> +	char *inline_path;
>  	int state;
>  	bool use_render;
>  };
> @@ -326,11 +328,19 @@ static int ls_item(const struct object_id *oid, struct strbuf *base,
>  				&fullpath);
>  	} else {
>  		char *ext = strrchr(name, '.');
> +
>  		strbuf_addstr(&class, "ls-blob");
>  		if (ext)
>  			strbuf_addf(&class, " %s", ext + 1);
> +
>  		cgit_tree_link(name, NULL, class.buf, ctx.qry.head,
>  			       walk_tree_ctx->curr_rev, fullpath.buf);
> +
> +		if (!walk_tree_ctx->inline_path &&
> +		    string_list_has_string(&ctx.repo->inline_readme, name)) {
> +			walk_tree_ctx->inline_path = xstrdup(pathname);
> +			oidcpy(&walk_tree_ctx->inline_oid, oid);
> +		}
>  	}
>  	htmlf("</td><td class='ls-size'>%li</td>", size);
>  
> @@ -368,7 +378,53 @@ static void ls_head(void)
>  
>  static void ls_tail(struct walk_tree_context *walk_tree_ctx)
>  {
> +	struct cgit_filter *render;
> +	enum object_type type;
> +	char *buf, *mimetype, *name;
> +	unsigned long size;
> +
>  	html("</table>\n");
> +
> +	if (!walk_tree_ctx->inline_path)
> +		goto done;
> +
> +	type = oid_object_info(the_repository, &walk_tree_ctx->inline_oid, &size);
> +	if (type == OBJ_BAD)
> +		goto done;
> +
> +	buf = read_object_file(&walk_tree_ctx->inline_oid, &type, &size);
> +	if (!buf)
> +		goto done;
> +
> +	/* create a vertical gap between tree nav / inline */
> +	html("<table class=\"tabs\"><tr><td></td></tr></table>");
> +
> +	render = get_render_for_filename(walk_tree_ctx->inline_path);
> +	mimetype = render ? NULL : get_mimetype_for_filename(
> +				walk_tree_ctx->inline_path);
> +
> +	name = strrchr(walk_tree_ctx->inline_path, '/');

Isn't this impossible?   inline_path is a filename at a single level of
the tree and Git forbids directory separators there.

> +	if (name)
> +		name++;
> +	else
> +		name = walk_tree_ctx->inline_path;
> +
> +	htmlf("<h2>%s</h2>", name);
> +	html("<div class=blob>&nbsp;</div>\n");
> +
> +	if (render || mimetype) {
> +		if (render)
> +			render_buffer(render, name, buf, size);
> +		else
> +			include_file(walk_tree_ctx->inline_path, mimetype);

We can lose a level of indentation here by writing it as:

	if (render)
		...
	else if (mimetype)
		...
	else
		...

> +	} else {
> +		print_buffer(name, buf, size);
> +	}
> +
> +	free(mimetype);
> +	free(buf);
> +
> +done:
>  	cgit_print_layout_end();
>  }
>  
> @@ -479,4 +535,6 @@ void cgit_print_tree(const char *rev, char *path, bool use_render)
>  
>  cleanup:
>  	free(walk_tree_ctx.curr_rev);
> +	if (walk_tree_ctx.inline_path)
> +		free(walk_tree_ctx.inline_path);
>  }


^ permalink raw reply	[flat|nested] 140+ messages in thread

* [PATCH v2 12/15] ui-tree: render any matching README file in tree view
  2018-06-18 19:36                   ` john
@ 2018-06-19  1:55                     ` andy
  2018-06-19  8:31                       ` john
  0 siblings, 1 reply; 140+ messages in thread
From: andy @ 2018-06-19  1:55 UTC (permalink / raw)




On 06/19/2018 03:36 AM, John Keeping wrote:
> On Mon, Jun 18, 2018 at 10:58:15AM +0800, Andy Green wrote:
>> While listing the items in tree view, we collect a list
>> of any filenames that match any tree-readme entries from the
>> config file.
>>
>> After the tree view has been shown, we iterate through any
>> collected readme files rendering them inline.
>>
>> Signed-off-by: Andy Green <andy at warmcat.com>
> 
> A couple of minor style points below, but this looks good.  With or
> without the style changes:
> 
> Reviewed-by: John Keeping <john at keeping.me.uk>

>> +	render = get_render_for_filename(walk_tree_ctx->inline_path);
>> +	mimetype = render ? NULL : get_mimetype_for_filename(
>> +				walk_tree_ctx->inline_path);
>> +
>> +	name = strrchr(walk_tree_ctx->inline_path, '/');
> 
> Isn't this impossible?   inline_path is a filename at a single level of
> the tree and Git forbids directory separators there.

Yes... it gets copied from a var "pathname"... I changed the name to 
inline_filename to remove this confusion in the new code anyway.  And I 
removed name here and just use walk_tree_ctx->inline_filename.

>> +	if (name)
>> +		name++;
>> +	else
>> +		name = walk_tree_ctx->inline_path;
>> +
>> +	htmlf("<h2>%s</h2>", name);
>> +	html("<div class=blob>&nbsp;</div>\n");
>> +
>> +	if (render || mimetype) {
>> +		if (render)
>> +			render_buffer(render, name, buf, size);
>> +		else
>> +			include_file(walk_tree_ctx->inline_path, mimetype);
> 
> We can lose a level of indentation here by writing it as:
> 
> 	if (render)
> 		...
> 	else if (mimetype)
> 		...
> 	else
> 		...

OK.  Actually this was a modified cut-n-paste from your patch's 
implementation in print_object().  So I also changed that code to follow 
this scheme.

	if (use_render) {
		if (render)
			render_buffer(render, basename, buf, size);
		else
			include_file(path, mimetype);
	} else {
		print_buffer(basename, buf, size);
	}

became

         if (!use_render)
                 print_buffer(basename, buf, size);
         else if (render)
                 render_buffer(render, basename, buf, size);
         else
                 include_file(path, mimetype);

-Andy


^ permalink raw reply	[flat|nested] 140+ messages in thread

* [PATCH v2 15/15] render: adapt for providing extra filter args for plain
  2018-06-18 19:25                   ` john
@ 2018-06-19  3:34                     ` andy
  0 siblings, 0 replies; 140+ messages in thread
From: andy @ 2018-06-19  3:34 UTC (permalink / raw)




On 06/19/2018 03:25 AM, John Keeping wrote:
> On Mon, Jun 18, 2018 at 10:58:31AM +0800, Andy Green wrote:
>> This changes the render filter exec part to provide a second
>> and third argument, which are used by md2html to fix up the url
>> path for "plain" for the repo, eg, "/cgit/plain/" and
>> "?h=mybranch", as required by the modifications to md2html in
>> the previous patches.

>>   static void render_buffer(struct cgit_filter *render, const char *name,
>> -		char *buf, unsigned long size)
>> +			  char *buf, unsigned long size)
>>   {
>>   	char *filter_arg = xstrdup(name);
>> +	char *repo_url = cgit_repourl(ctx.repo->url);
>> +	struct strbuf sb_plain = STRBUF_INIT, sb_postfix = STRBUF_INIT;
>> +
>> +	strbuf_addf(&sb_plain, "%splain/", repo_url);
> 
> This doesn't always work (if we don't have cfg.virtual_root set it's
> wrong).

I see, thanks.

> The logic in ui-shared.c::reporevlink() does the right thing, and it
> might be possible to extract a helper function but we may just have to
> replicate it since that version generates the URL as an HTML attribute
> value.

OK... I studied it... first what's in repolink has some duplication of 
code that I added a patch to clean out.

In a second patch I added a helper cgit_repo_create_url() that does the 
core function without urlencode into a pair of strbufs, one for before 
any ? and one including the ? and anything after.  They can point to the 
same strbuf if the caller doesn't care.

-Andy


^ permalink raw reply	[flat|nested] 140+ messages in thread

* [PATCH v2 14/15] md2html-add-asset-postfix-arg
  2018-06-18 19:21                   ` john
@ 2018-06-19  3:55                     ` andy
  2018-06-19  8:34                       ` john
  0 siblings, 1 reply; 140+ messages in thread
From: andy @ 2018-06-19  3:55 UTC (permalink / raw)




On 06/19/2018 03:21 AM, John Keeping wrote:
> On Mon, Jun 18, 2018 at 10:58:26AM +0800, Andy Green wrote:

>>   class AssetMappingExtension(markdown.extensions.Extension):
>>   
>>       def __init__(self, **kwargs):
>> -        self.config = {'asset_prefix': ['', 'prefix for relative asset URLs']}
>> +        self.config = {'asset_prefix': ['', 'prefix for relative asset URLs'], 'asset_postfix': ['', 'postfix for relative asset URLs']}
> 
> For style it would be nice to align this under asset_prefix.

Just worried to upset the python indent monster... it seems to work 
intended I guess it only cares at the start of statements.

>>           super(AssetMappingExtension, self).__init__(**kwargs)
>>   
>>       def extendMarkdown(self, md, md_globals):
>>           asset_prefix = self.getConfig('asset_prefix')
>>           if not asset_prefix:
>>               return
>> +        asset_postfix = self.getConfig('asset_postfix')
>> +        if not asset_postfix:
>> +            return
> 
> Is this right?  Should we allow one of these to be empty and still
> process the other one?  In other words, shouldn't the bail out condition
> be:
> 
>      if not (asset_prefix or asset_postfix):
>          return

Yeah... the original code that generated the args always generated a 
postfix, so there was "no problem".

However the improved code snips ?h=defaultbranch and can be an empty 
string.  So I changed this as you suggested.

> I don't think any change to AssetMappingProcessor is required because
> urljoin already does the right thing when handed the empty string and
> the config assure that if no value is specified then that is what we
> get.

I am not certain of your meaning here... you mean change from what this 
patch already does for the reason above?  It must change 
AssetMappingProcessor generally to do what it's trying to do.

>> -if len(sys.argv) > 2:
>> -    extensions.append(AssetMappingExtension(asset_prefix=sys.argv[2]))
>> +if len(sys.argv) > 3:
>> +    extensions.append(AssetMappingExtension(asset_prefix=sys.argv[2],asset_postfix=sys.argv[3]))
> 
> Can we allow specifying only the prefix here?  Something like:
> 
>      if len(sys.argv) > 2:
>          args = {'asset_prefix': sys.argv[2]}
>          if len(sys.argv) > 3:
>              args['asset_postfix'] = sys.argv[3]
>          extensions.append(AssetMappingExtension(**args))

OK.

-Andy


^ permalink raw reply	[flat|nested] 140+ messages in thread

* [PATCH v2 12/15] ui-tree: render any matching README file in tree view
  2018-06-19  1:55                     ` andy
@ 2018-06-19  8:31                       ` john
  2018-06-19  8:38                         ` andy
  0 siblings, 1 reply; 140+ messages in thread
From: john @ 2018-06-19  8:31 UTC (permalink / raw)


On Tue, Jun 19, 2018 at 09:55:18AM +0800, Andy Green wrote:
> 
> 
> On 06/19/2018 03:36 AM, John Keeping wrote:
> > On Mon, Jun 18, 2018 at 10:58:15AM +0800, Andy Green wrote:
> >> While listing the items in tree view, we collect a list
> >> of any filenames that match any tree-readme entries from the
> >> config file.
> >>
> >> After the tree view has been shown, we iterate through any
> >> collected readme files rendering them inline.
> >>
> >> Signed-off-by: Andy Green <andy at warmcat.com>
> > 
> > A couple of minor style points below, but this looks good.  With or
> > without the style changes:
> > 
> > Reviewed-by: John Keeping <john at keeping.me.uk>
> 
> >> +	render = get_render_for_filename(walk_tree_ctx->inline_path);
> >> +	mimetype = render ? NULL : get_mimetype_for_filename(
> >> +				walk_tree_ctx->inline_path);
> >> +
> >> +	name = strrchr(walk_tree_ctx->inline_path, '/');
> > 
> > Isn't this impossible?   inline_path is a filename at a single level of
> > the tree and Git forbids directory separators there.
> 
> Yes... it gets copied from a var "pathname"... I changed the name to 
> inline_filename to remove this confusion in the new code anyway.  And I 
> removed name here and just use walk_tree_ctx->inline_filename.
> 
> >> +	if (name)
> >> +		name++;
> >> +	else
> >> +		name = walk_tree_ctx->inline_path;
> >> +
> >> +	htmlf("<h2>%s</h2>", name);
> >> +	html("<div class=blob>&nbsp;</div>\n");
> >> +
> >> +	if (render || mimetype) {
> >> +		if (render)
> >> +			render_buffer(render, name, buf, size);
> >> +		else
> >> +			include_file(walk_tree_ctx->inline_path, mimetype);
> > 
> > We can lose a level of indentation here by writing it as:
> > 
> > 	if (render)
> > 		...
> > 	else if (mimetype)
> > 		...
> > 	else
> > 		...
> 
> OK.  Actually this was a modified cut-n-paste from your patch's 
> implementation in print_object().  So I also changed that code to follow 
> this scheme.
> 
> 	if (use_render) {
> 		if (render)
> 			render_buffer(render, basename, buf, size);
> 		else
> 			include_file(path, mimetype);
> 	} else {
> 		print_buffer(basename, buf, size);
> 	}
> 
> became
> 
>          if (!use_render)
>                  print_buffer(basename, buf, size);
>          else if (render)
>                  render_buffer(render, basename, buf, size);
>          else
>                  include_file(path, mimetype);

I think the point is that the logic is different, in that this version
effectively has use_render always true, whereas the version in
print_object() must allow the caller to disable render/mimetype handling
even if those variables are non-null.

It's personal taste, but I think the positive logic is clearer to read.


^ permalink raw reply	[flat|nested] 140+ messages in thread

* [PATCH v2 14/15] md2html-add-asset-postfix-arg
  2018-06-19  3:55                     ` andy
@ 2018-06-19  8:34                       ` john
  0 siblings, 0 replies; 140+ messages in thread
From: john @ 2018-06-19  8:34 UTC (permalink / raw)


On Tue, Jun 19, 2018 at 11:55:35AM +0800, Andy Green wrote:
> 
> 
> On 06/19/2018 03:21 AM, John Keeping wrote:
> > On Mon, Jun 18, 2018 at 10:58:26AM +0800, Andy Green wrote:
> 
> >>   class AssetMappingExtension(markdown.extensions.Extension):
> >>   
> >>       def __init__(self, **kwargs):
> >> -        self.config = {'asset_prefix': ['', 'prefix for relative asset URLs']}
> >> +        self.config = {'asset_prefix': ['', 'prefix for relative asset URLs'], 'asset_postfix': ['', 'postfix for relative asset URLs']}
> > 
> > For style it would be nice to align this under asset_prefix.
> 
> Just worried to upset the python indent monster... it seems to work 
> intended I guess it only cares at the start of statements.

Yeah, if you're inside braces of any kind you can pretty much do what
you want.

> >>           super(AssetMappingExtension, self).__init__(**kwargs)
> >>   
> >>       def extendMarkdown(self, md, md_globals):
> >>           asset_prefix = self.getConfig('asset_prefix')
> >>           if not asset_prefix:
> >>               return
> >> +        asset_postfix = self.getConfig('asset_postfix')
> >> +        if not asset_postfix:
> >> +            return
> > 
> > Is this right?  Should we allow one of these to be empty and still
> > process the other one?  In other words, shouldn't the bail out condition
> > be:
> > 
> >      if not (asset_prefix or asset_postfix):
> >          return
> 
> Yeah... the original code that generated the args always generated a 
> postfix, so there was "no problem".
> 
> However the improved code snips ?h=defaultbranch and can be an empty 
> string.  So I changed this as you suggested.
> 
> > I don't think any change to AssetMappingProcessor is required because
> > urljoin already does the right thing when handed the empty string and
> > the config assure that if no value is specified then that is what we
> > get.
> 
> I am not certain of your meaning here... you mean change from what this 
> patch already does for the reason above?  It must change 
> AssetMappingProcessor generally to do what it's trying to do.

I mean that changing the code here will allow empty strings to be passed
to AssetMappingProcessor.run() which previously was blocked by these
conditions.  But no change is required there because it already does the
right thing when handed an empty string as one of prefix/postfix.


^ permalink raw reply	[flat|nested] 140+ messages in thread

* [PATCH v2 12/15] ui-tree: render any matching README file in tree view
  2018-06-19  8:31                       ` john
@ 2018-06-19  8:38                         ` andy
  0 siblings, 0 replies; 140+ messages in thread
From: andy @ 2018-06-19  8:38 UTC (permalink / raw)




On 06/19/2018 04:31 PM, John Keeping wrote:

>>> We can lose a level of indentation here by writing it as:
>>>
>>> 	if (render)
>>> 		...
>>> 	else if (mimetype)
>>> 		...
>>> 	else
>>> 		...
>>
>> OK.  Actually this was a modified cut-n-paste from your patch's
>> implementation in print_object().  So I also changed that code to follow
>> this scheme.
>>
>> 	if (use_render) {
>> 		if (render)
>> 			render_buffer(render, basename, buf, size);
>> 		else
>> 			include_file(path, mimetype);
>> 	} else {
>> 		print_buffer(basename, buf, size);
>> 	}
>>
>> became
>>
>>           if (!use_render)
>>                   print_buffer(basename, buf, size);
>>           else if (render)
>>                   render_buffer(render, basename, buf, size);
>>           else
>>                   include_file(path, mimetype);
> 
> I think the point is that the logic is different, in that this version
> effectively has use_render always true, whereas the version in
> print_object() must allow the caller to disable render/mimetype handling
> even if those variables are non-null.
> 
> It's personal taste, but I think the positive logic is clearer to read.

OK...

-Andy


^ permalink raw reply	[flat|nested] 140+ messages in thread

* [PATCH v3 00/17] Render READMEs inline in tree view
  2018-06-13  2:01                 ` [PATCH 00/11] Render READMEs inline in tree view andy
                                     ` (11 preceding siblings ...)
  2018-06-14  3:47                   ` [PATCH 00/11] Render READMEs inline " andy
@ 2018-06-19  9:01                   ` andy
  2018-06-19  9:01                     ` [PATCH v3 01/17] manpage: fix sorting order andy
                                       ` (16 more replies)
  2018-06-20 10:11                   ` [PATCH v4 00/16] Render READMEs inline in tree view andy
  13 siblings, 17 replies; 140+ messages in thread
From: andy @ 2018-06-19  9:01 UTC (permalink / raw)


The following series adds config to allow rendering of
selected READMEs inline after the tree view, where
present in the directory being viewed.

Particularly you can use completely relative markdown to
inline pictures served from the current repo rev context,
eg,

![overview](./doc-assets/overview.png)

will "just work" showing the png from the current view
rev context; this format also works in github.

It builds on John Keeping's RENDER mode series from 2016.

Typical config to enable it, if you have a README.md
looks like

inline-readme=README.md
render.md=/usr/libexec/cgit/filters/html-converters/md2html

You can see examples of it in operation at

https://libwebsockets.org/git/libwebsockets/tree
https://libwebsockets.org/git/libwebsockets/tree/?h=v3.0-stable
https://warmcat.com/git/cgit/tree/

The expected basis these apply on top of is

 - jk/for-jason
 - ch/for-jason

You can find these patches on top of the expected basis here

https://warmcat.com/git/cgit/log/

v3 deals with more comment from after v2

---

Andy Green (11):
      manpage: fix sorting order
      blame: css: make blame highlight div absolute and at parent top
      ui-blame: free read_sha1_file() buffer after use
      ui-tree: ls_tail: add walk table param
      config: add global inline-readme list
      config: add repo inline-readme list
      ui-tree: render any matching README file in tree view
      md2html-add-asset-postfix-arg
      ui-shared: deduplicate some code in repolink
      ui-shared: add helper for generating non-urlencoded links
      render: adapt for providing extra filter args for plain

John Keeping (6):
      Use string list strdup_strings for mimetypes
      Add source page
      Parse render filters from the config
      ui-tree: split out buffer printing
      ui-tree: use render filters to display content
      md2html: add asset mapping


 cgit.c                          |   35 +++++-
 cgit.css                        |    7 +
 cgit.h                          |    6 +
 cgitrc.5.txt                    |  215 +++++++++++++++++++++++----------------
 cmd.c                           |    8 +
 filter.c                        |    4 +
 filters/html-converters/md2html |   57 ++++++++++
 shared.c                        |   21 ++++
 ui-blame.c                      |    9 +-
 ui-shared.c                     |   70 ++++++++++---
 ui-shared.h                     |    6 +
 ui-tree.c                       |  193 +++++++++++++++++++++++++++++++----
 ui-tree.h                       |    2 
 13 files changed, 496 insertions(+), 137 deletions(-)

--
Signature


^ permalink raw reply	[flat|nested] 140+ messages in thread

* [PATCH v3 01/17] manpage: fix sorting order
  2018-06-19  9:01                   ` [PATCH v3 00/17] " andy
@ 2018-06-19  9:01                     ` andy
  2018-06-19 21:35                       ` john
  2018-06-19  9:01                     ` [PATCH v3 02/17] blame: css: make blame highlight div absolute and at parent top andy
                                       ` (15 subsequent siblings)
  16 siblings, 1 reply; 140+ messages in thread
From: andy @ 2018-06-19  9:01 UTC (permalink / raw)


You maybe didn't know you had OCD until you saw an
alpha sorted list that has stuff out of order in it.

Signed-off-by: Andy Green <andy at warmcat.com>
---
 cgitrc.5.txt |  176 +++++++++++++++++++++++++++++-----------------------------
 1 file changed, 88 insertions(+), 88 deletions(-)

diff --git a/cgitrc.5.txt b/cgitrc.5.txt
index acfae91..f6f6502 100644
--- a/cgitrc.5.txt
+++ b/cgitrc.5.txt
@@ -54,14 +54,10 @@ branch-sort::
 	list, and when set to "name" enables ordering by branch name. Default
 	value: "name".
 
-cache-root::
-	Path used to store the cgit cache entries. Default value:
-	"/var/cache/cgit". See also: "MACRO EXPANSION".
-
-cache-static-ttl::
+cache-about-ttl::
 	Number which specifies the time-to-live, in minutes, for the cached
-	version of repository pages accessed with a fixed SHA1. See also:
-	"CACHE". Default value: -1".
+	version of the repository about page. See also: "CACHE". Default
+	value: "15".
 
 cache-dynamic-ttl::
 	Number which specifies the time-to-live, in minutes, for the cached
@@ -73,6 +69,10 @@ cache-repo-ttl::
 	version of the repository summary page. See also: "CACHE". Default
 	value: "5".
 
+cache-root::
+	Path used to store the cgit cache entries. Default value:
+	"/var/cache/cgit". See also: "MACRO EXPANSION".
+
 cache-root-ttl::
 	Number which specifies the time-to-live, in minutes, for the cached
 	version of the repository index page. See also: "CACHE". Default
@@ -83,22 +83,22 @@ cache-scanrc-ttl::
 	of scanning a path for git repositories. See also: "CACHE". Default
 	value: "15".
 
-cache-about-ttl::
-	Number which specifies the time-to-live, in minutes, for the cached
-	version of the repository about page. See also: "CACHE". Default
-	value: "15".
-
-cache-snapshot-ttl::
-	Number which specifies the time-to-live, in minutes, for the cached
-	version of snapshots. See also: "CACHE". Default value: "5".
+case-sensitive-sort::
+	Sort items in the repo list case sensitively. Default value: "1".
+	See also: repository-sort, section-sort.
 
 cache-size::
 	The maximum number of entries in the cgit cache. When set to "0",
 	caching is disabled. See also: "CACHE". Default value: "0"
 
-case-sensitive-sort::
-	Sort items in the repo list case sensitively. Default value: "1".
-	See also: repository-sort, section-sort.
+cache-snapshot-ttl::
+	Number which specifies the time-to-live, in minutes, for the cached
+	version of snapshots. See also: "CACHE". Default value: "5".
+
+cache-static-ttl::
+	Number which specifies the time-to-live, in minutes, for the cached
+	version of repository pages accessed with a fixed SHA1. See also:
+	"CACHE". Default value: -1".
 
 clone-prefix::
 	Space-separated list of common prefixes which, when combined with a
@@ -159,12 +159,29 @@ enable-follow-links::
 	Flag which, when set to "1", allows users to follow a file in the log
 	view.  Default value: "0".
 
+enable-git-config::
+	Flag which, when set to "1", will allow cgit to use git config to set
+	any repo specific settings. This option is used in conjunction with
+	"scan-path", and must be defined prior, to augment repo-specific
+	settings. The keys gitweb.owner, gitweb.category, gitweb.description,
+	and gitweb.homepage will map to the cgit keys repo.owner, repo.section,
+	repo.desc, and repo.homepage respectively. All git config keys that begin
+	with "cgit." will be mapped to the corresponding "repo." key in cgit.
+	Default value: "0". See also: scan-path, section-from-path.
+
 enable-http-clone::
-	If set to "1", cgit will act as an dumb HTTP endpoint for git clones.
+	If set to "1", cgit will act as a dumb HTTP endpoint for git clones.
 	You can add "http://$HTTP_HOST$SCRIPT_NAME/$CGIT_REPO_URL" to clone-url
 	to expose this feature. If you use an alternate way of serving git
 	repositories, you may wish to disable this. Default value: "1".
 
+enable-html-serving::
+	Flag which, when set to "1", will allow the /plain handler to serve
+	mimetype headers that result in the file being treated as HTML by the
+	browser. When set to "0", such file types are returned instead as
+	text/plain or application/octet-stream. Default value: "0". See also:
+	"repo.enable-html-serving".
+
 enable-index-links::
 	Flag which, when set to "1", will make cgit generate extra links for
 	each repo in the repository index (specifically, to the "summary",
@@ -195,27 +212,10 @@ enable-subject-links::
 	in commit view. Default value: "0". See also:
 	"repo.enable-subject-links".
 
-enable-html-serving::
-	Flag which, when set to "1", will allow the /plain handler to serve
-	mimetype headers that result in the file being treated as HTML by the
-	browser. When set to "0", such file types are returned instead as
-	text/plain or application/octet-stream. Default value: "0". See also:
-	"repo.enable-html-serving".
-
 enable-tree-linenumbers::
 	Flag which, when set to "1", will make cgit generate linenumber links
 	for plaintext blobs printed in the tree view. Default value: "1".
 
-enable-git-config::
-	Flag which, when set to "1", will allow cgit to use git config to set
-	any repo specific settings. This option is used in conjunction with
-	"scan-path", and must be defined prior, to augment repo-specific
-	settings. The keys gitweb.owner, gitweb.category, gitweb.description,
-	and gitweb.homepage will map to the cgit keys repo.owner, repo.section,
-	repo.desc, and repo.homepage respectively. All git config keys that begin
-	with "cgit." will be mapped to the corresponding "repo." key in cgit.
-	Default value: "0". See also: scan-path, section-from-path.
-
 favicon::
 	Url used as link to a shortcut icon for cgit. It is suggested to use
 	the value "/favicon.ico" since certain browsers will ignore other
@@ -251,19 +251,14 @@ logo-link::
 	calculated url of the repository index page will be used. Default
 	value: none.
 
-owner-filter::
-	Specifies a command which will be invoked to format the Owner
-	column of the main page.  The command will get the owner on STDIN,
-	and the STDOUT from the command will be included verbatim in the
-	table.  This can be used to link to additional context such as an
-	owners home page.  When active this filter is used instead of the
-	default owner query url.  Default value: none.
-	See also: "FILTER API".
-
 max-atom-items::
 	Specifies the number of items to display in atom feeds view. Default
 	value: "10".
 
+max-blob-size::
+	Specifies the maximum size of a blob to display HTML for in KBytes.
+	Default value: "0" (limit disabled).
+
 max-commit-count::
 	Specifies the number of entries to list per page in "log" view. Default
 	value: "50".
@@ -280,10 +275,6 @@ max-repodesc-length::
 	Specifies the maximum number of repo description characters to display
 	on the repository index page. Default value: "80".
 
-max-blob-size::
-	Specifies the maximum size of a blob to display HTML for in KBytes.
-	Default value: "0" (limit disabled).
-
 max-stats::
 	Set the default maximum statistics period. Valid values are "week",
 	"month", "quarter" and "year". If unspecified, statistics are
@@ -319,6 +310,15 @@ noheader::
 	Flag which, when set to "1", will make cgit omit the standard header
 	on all pages. Default value: none. See also: "embedded".
 
+owner-filter::
+	Specifies a command which will be invoked to format the Owner
+	column of the main page.  The command will get the owner on STDIN,
+	and the STDOUT from the command will be included verbatim in the
+	table.  This can be used to link to additional context such as an
+	owners home page.  When active this filter is used instead of the
+	default owner query url.  Default value: none.
+	See also: "FILTER API".
+
 project-list::
 	A list of subdirectories inside of scan-path, relative to it, that
 	should loaded as git repositories. This must be defined prior to
@@ -481,9 +481,6 @@ repo.defbranch::
 repo.desc::
 	The value to show as repository description. Default value: none.
 
-repo.homepage::
-	The value to show as repository homepage. Default value: none.
-
 repo.email-filter::
 	Override the default email-filter. Default value: none. See also:
 	"enable-filter-overrides". See also: "FILTER API".
@@ -492,6 +489,10 @@ repo.enable-commit-graph::
 	A flag which can be used to disable the global setting
 	`enable-commit-graph'. Default value: none.
 
+repo.enable-html-serving::
+	A flag which can be used to override the global setting
+	`enable-html-serving`. Default value: none.
+
 repo.enable-log-filecount::
 	A flag which can be used to disable the global setting
 	`enable-log-filecount'. Default value: none.
@@ -508,15 +509,14 @@ repo.enable-subject-links::
 	A flag which can be used to override the global setting
 	`enable-subject-links'. Default value: none.
 
-repo.enable-html-serving::
-	A flag which can be used to override the global setting
-	`enable-html-serving`. Default value: none.
-
 repo.hide::
 	Flag which, when set to "1", hides the repository from the repository
 	index. The repository can still be accessed by providing a direct path.
 	Default value: "0". See also: "repo.ignore".
 
+repo.homepage::
+	The value to show as repository homepage. Default value: none.
+
 repo.ignore::
 	Flag which, when set to "1", ignores the repository. The repository
 	is not shown in the index and cannot be accessed by providing a direct
@@ -531,10 +531,6 @@ repo.logo-link::
 	calculated url of the repository index page will be used. Default
 	value: global logo-link.
 
-repo.owner-filter::
-	Override the default owner-filter. Default value: none. See also:
-	"enable-filter-overrides". See also: "FILTER API".
-
 repo.module-link::
 	Text which will be used as the formatstring for a hyperlink when a
 	submodule is printed in a directory listing. The arguments for the
@@ -559,6 +555,10 @@ repo.owner::
 	A value used to identify the owner of the repository. Default value:
 	none.
 
+repo.owner-filter::
+	Override the default owner-filter. Default value: none. See also:
+	"enable-filter-overrides". See also: "FILTER API".
+
 repo.path::
 	An absolute path to the repository directory. For non-bare repositories
 	this is the .git-directory. Default value: none.
@@ -574,6 +574,10 @@ repo.readme::
 	are no non-public files located in the same directory as the readme
 	file. Default value: <readme>.
 
+repo.section::
+	Override the current section name for this repository. Default value:
+	none.
+
 repo.snapshots::
 	A mask of snapshot formats for this repo that cgit generates links for,
 	restricted by the global "snapshots" setting. Default value:
@@ -586,10 +590,6 @@ repo.snapshot-prefix::
 	of "linux-stable-3.15.4".  Default value: <empty> meaning to use
 	the repository basename.
 
-repo.section::
-	Override the current section name for this repository. Default value:
-	none.
-
 repo.source-filter::
 	Override the default source-filter. Default value: none. See also:
 	"enable-filter-overrides". See also: "FILTER API".
@@ -662,30 +662,6 @@ about filter::
 	The about text that is to be filtered is available on standard input
 	and the filtered text is expected on standard output.
 
-commit filter::
-	This filter is given no arguments. The commit message text that is to
-	be filtered is available on standard input and the filtered text is
-	expected on standard output.
-
-email filter::
-	This filter is given two parameters: the email address of the relevant
-	author and a string indicating the originating page. The filter will
-	then receive the text string to format on standard input and is
-	expected to write to standard output the formatted text to be included
-	in the page.
-
-owner filter::
-	This filter is given no arguments.  The owner text is available on
-	standard input and the filter is expected to write to standard
-	output.  The output is included in the Owner column.
-
-source filter::
-	This filter is given a single parameter: the filename of the source
-	file to filter. The filter can use the filename to determine (for
-	example) the syntax highlighting mode. The contents of the source
-	file that is to be filtered is available on standard input and the
-	filtered contents is expected on standard output.
-
 auth filter::
 	The authentication filter receives 12 parameters:
 	  - filter action, explained below, which specifies which action the
@@ -712,6 +688,30 @@ auth filter::
 	Please see `filters/simple-authentication.lua` for a clear example
 	script that may be modified.
 
+commit filter::
+	This filter is given no arguments. The commit message text that is to
+	be filtered is available on standard input and the filtered text is
+	expected on standard output.
+
+email filter::
+	This filter is given two parameters: the email address of the relevant
+	author and a string indicating the originating page. The filter will
+	then receive the text string to format on standard input and is
+	expected to write to standard output the formatted text to be included
+	in the page.
+
+owner filter::
+	This filter is given no arguments.  The owner text is available on
+	standard input and the filter is expected to write to standard
+	output.  The output is included in the Owner column.
+
+source filter::
+	This filter is given a single parameter: the filename of the source
+	file to filter. The filter can use the filename to determine (for
+	example) the syntax highlighting mode. The contents of the source
+	file that is to be filtered is available on standard input and the
+	filtered contents is expected on standard output.
+
 
 All filters are handed the following environment variables:
 



^ permalink raw reply	[flat|nested] 140+ messages in thread

* [PATCH v3 02/17] blame: css: make blame highlight div absolute and at parent top
  2018-06-19  9:01                   ` [PATCH v3 00/17] " andy
  2018-06-19  9:01                     ` [PATCH v3 01/17] manpage: fix sorting order andy
@ 2018-06-19  9:01                     ` andy
  2018-06-19  9:01                     ` [PATCH v3 03/17] Use string list strdup_strings for mimetypes andy
                                       ` (14 subsequent siblings)
  16 siblings, 0 replies; 140+ messages in thread
From: andy @ 2018-06-19  9:01 UTC (permalink / raw)


Normal operation of blame view requires div.highlight to
have absolute position and set to its parent's top for me.

Otherwise the grey background boxes indicating the extent of
the patch in the lines td displace the highlit sources, they
start at the bottom of the td.

This patch makes the blame highlight div start back up the top of
its parent area and render on top of the grey boxes.

Checked on Linux Firefox 60 and Linux Chrome 69.

"highlight" div class name is also used in md2html rendering
output.  So this patch solves it by introducing a wrapper
div and new "blame_highlight" css class.

Signed-off-by: Andy Green <andy at warmcat.com>
---
 cgit.css   |    2 ++
 ui-blame.c |    4 ++--
 2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/cgit.css b/cgit.css
index 43f6a5a..fb3cc70 100644
--- a/cgit.css
+++ b/cgit.css
@@ -162,6 +162,8 @@ div#cgit table.list tr.nohover-highlight:hover:nth-child(odd) {
 	background: white;
 }
 
+div#cgit div.blame_highlight { position: absolute; top: 0; }
+
 div#cgit table.list th {
 	font-weight: bold;
 	/* color: #888;
diff --git a/ui-blame.c b/ui-blame.c
index daa7e2b..8b56554 100644
--- a/ui-blame.c
+++ b/ui-blame.c
@@ -196,7 +196,7 @@ static void print_object(const struct object_id *oid, const char *path,
 	free((void *)sb.final_buf);
 
 	/* Lines */
-	html("<pre><code>");
+	html("<div class=\"blame_highlight\"> <pre><code>");
 	if (ctx.repo->source_filter) {
 		char *filter_arg = xstrdup(basename);
 		cgit_open_filter(ctx.repo->source_filter, filter_arg);
@@ -206,7 +206,7 @@ static void print_object(const struct object_id *oid, const char *path,
 	} else {
 		html_txt(buf);
 	}
-	html("</code></pre>");
+	html("</code></pre></div>");
 
 	html("</div></td>\n");
 



^ permalink raw reply	[flat|nested] 140+ messages in thread

* [PATCH v3 03/17] Use string list strdup_strings for mimetypes
  2018-06-19  9:01                   ` [PATCH v3 00/17] " andy
  2018-06-19  9:01                     ` [PATCH v3 01/17] manpage: fix sorting order andy
  2018-06-19  9:01                     ` [PATCH v3 02/17] blame: css: make blame highlight div absolute and at parent top andy
@ 2018-06-19  9:01                     ` andy
  2018-06-19  9:01                     ` [PATCH v3 04/17] Add source page andy
                                       ` (13 subsequent siblings)
  16 siblings, 0 replies; 140+ messages in thread
From: andy @ 2018-06-19  9:01 UTC (permalink / raw)


From: John Keeping <john at keeping.me.uk>

There's no need to do this manually with the string list API will do it
for us.

Signed-off-by: John Keeping <john at keeping.me.uk>
---
 cgit.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/cgit.c b/cgit.c
index 223dfc8..0c9f3e9 100644
--- a/cgit.c
+++ b/cgit.c
@@ -23,7 +23,7 @@ static void add_mimetype(const char *name, const char *value)
 {
 	struct string_list_item *item;
 
-	item = string_list_insert(&ctx.cfg.mimetypes, xstrdup(name));
+	item = string_list_insert(&ctx.cfg.mimetypes, name);
 	item->util = xstrdup(value);
 }
 
@@ -414,7 +414,7 @@ static void prepare_context(void)
 	ctx.page.modified = time(NULL);
 	ctx.page.expires = ctx.page.modified;
 	ctx.page.etag = NULL;
-	memset(&ctx.cfg.mimetypes, 0, sizeof(struct string_list));
+	string_list_init(&ctx.cfg.mimetypes, 1);
 	if (ctx.env.script_name)
 		ctx.cfg.script_name = xstrdup(ctx.env.script_name);
 	if (ctx.env.query_string)



^ permalink raw reply	[flat|nested] 140+ messages in thread

* [PATCH v3 04/17] Add source page
  2018-06-19  9:01                   ` [PATCH v3 00/17] " andy
                                       ` (2 preceding siblings ...)
  2018-06-19  9:01                     ` [PATCH v3 03/17] Use string list strdup_strings for mimetypes andy
@ 2018-06-19  9:01                     ` andy
  2018-06-19  9:01                     ` [PATCH v3 05/17] Parse render filters from the config andy
                                       ` (12 subsequent siblings)
  16 siblings, 0 replies; 140+ messages in thread
From: andy @ 2018-06-19  9:01 UTC (permalink / raw)


From: John Keeping <john at keeping.me.uk>

We are about to introduce rendering of content for the tree view.  This
source page will allow bypassing the renderer and accessing the content
of the current tree view.

Signed-off-by: John Keeping <john at keeping.me.uk>
---
 cmd.c       |    6 ++++++
 ui-shared.c |   14 ++++++++++++++
 ui-shared.h |    3 +++
 3 files changed, 23 insertions(+)

diff --git a/cmd.c b/cmd.c
index 63f0ae5..56e21df 100644
--- a/cmd.c
+++ b/cmd.c
@@ -138,6 +138,11 @@ static void refs_fn(void)
 	cgit_print_refs();
 }
 
+static void source_fn(void)
+{
+	cgit_print_tree(ctx.qry.sha1, ctx.qry.path);
+}
+
 static void snapshot_fn(void)
 {
 	cgit_print_snapshot(ctx.qry.head, ctx.qry.sha1, ctx.qry.path,
@@ -187,6 +192,7 @@ struct cgit_cmd *cgit_get_cmd(void)
 		def_cmd(refs, 1, 0, 0),
 		def_cmd(repolist, 0, 0, 0),
 		def_cmd(snapshot, 1, 0, 0),
+		def_cmd(source, 1, 1, 0),
 		def_cmd(stats, 1, 1, 0),
 		def_cmd(summary, 1, 0, 0),
 		def_cmd(tag, 1, 0, 0),
diff --git a/ui-shared.c b/ui-shared.c
index ba88106..d2985c8 100644
--- a/ui-shared.c
+++ b/ui-shared.c
@@ -307,6 +307,12 @@ void cgit_tree_link(const char *name, const char *title, const char *class,
 	reporevlink("tree", name, title, class, head, rev, path);
 }
 
+void cgit_source_link(const char *name, const char *title, const char *class,
+		    const char *head, const char *rev, const char *path)
+{
+	reporevlink("source", name, title, class, head, rev, path);
+}
+
 void cgit_plain_link(const char *name, const char *title, const char *class,
 		     const char *head, const char *rev, const char *path)
 {
@@ -489,6 +495,10 @@ static void cgit_self_link(char *name, const char *title, const char *class)
 		cgit_tree_link(name, title, class, ctx.qry.head,
 			       ctx.qry.has_sha1 ? ctx.qry.sha1 : NULL,
 			       ctx.qry.path);
+	else if (!strcmp(ctx.qry.page, "source"))
+		cgit_source_link(name, title, class, ctx.qry.head,
+				 ctx.qry.has_sha1 ? ctx.qry.sha1 : NULL,
+				 ctx.qry.path);
 	else if (!strcmp(ctx.qry.page, "plain"))
 		cgit_plain_link(name, title, class, ctx.qry.head,
 				ctx.qry.has_sha1 ? ctx.qry.sha1 : NULL,
@@ -1003,6 +1013,10 @@ void cgit_print_pageheader(void)
 		if (ctx.qry.page && !strcmp(ctx.qry.page, "blame"))
 			cgit_blame_link("blame", NULL, hc("blame"), ctx.qry.head,
 				        ctx.qry.sha1, ctx.qry.vpath);
+		else if (ctx.qry.page && !strcmp(ctx.qry.page, "source"))
+			cgit_source_link("tree", NULL, hc("source"),
+					 ctx.qry.head, ctx.qry.sha1,
+					 ctx.qry.vpath);
 		else
 			cgit_tree_link("tree", NULL, hc("tree"), ctx.qry.head,
 				       ctx.qry.sha1, ctx.qry.vpath);
diff --git a/ui-shared.h b/ui-shared.h
index 4d5978b..c105b3b 100644
--- a/ui-shared.h
+++ b/ui-shared.h
@@ -23,6 +23,9 @@ extern void cgit_tag_link(const char *name, const char *title,
 extern void cgit_tree_link(const char *name, const char *title,
 			   const char *class, const char *head,
 			   const char *rev, const char *path);
+extern void cgit_source_link(const char *name, const char *title,
+			     const char *class, const char *head,
+			     const char *rev, const char *path);
 extern void cgit_plain_link(const char *name, const char *title,
 			    const char *class, const char *head,
 			    const char *rev, const char *path);



^ permalink raw reply	[flat|nested] 140+ messages in thread

* [PATCH v3 05/17] Parse render filters from the config
  2018-06-19  9:01                   ` [PATCH v3 00/17] " andy
                                       ` (3 preceding siblings ...)
  2018-06-19  9:01                     ` [PATCH v3 04/17] Add source page andy
@ 2018-06-19  9:01                     ` andy
  2018-06-19 21:37                       ` john
  2018-06-19  9:01                     ` [PATCH v3 06/17] ui-tree: split out buffer printing andy
                                       ` (11 subsequent siblings)
  16 siblings, 1 reply; 140+ messages in thread
From: andy @ 2018-06-19  9:01 UTC (permalink / raw)


From: John Keeping <john at keeping.me.uk>

Render filters will be used to present rendered content in the tree
view, for example to display Markdown source rendered as HTML.

We will add support for using these from the tree view in the following
commits.

AG: adapted so render.= can be used to specify the filter for files
without any suffix

Signed-off-by: John Keeping <john at keeping.me.uk>
Signed-off-by: Andy Green <andy at warmcat.com>
---
 cgit.c       |   19 +++++++++++++++++--
 cgit.h       |    4 +++-
 cgitrc.5.txt |   19 +++++++++++++++++++
 filter.c     |    1 +
 shared.c     |   19 +++++++++++++++++++
 5 files changed, 59 insertions(+), 3 deletions(-)

diff --git a/cgit.c b/cgit.c
index 0c9f3e9..e0e94d5 100644
--- a/cgit.c
+++ b/cgit.c
@@ -27,6 +27,18 @@ static void add_mimetype(const char *name, const char *value)
 	item->util = xstrdup(value);
 }
 
+static void add_render_filter(const char *name, const char *cmd)
+{
+	struct string_list_item *item;
+	struct cgit_filter *filter = cgit_new_filter(cmd, RENDER);
+
+	if (!filter)
+		return;
+
+	item = string_list_insert(&ctx.cfg.render_filters, name);
+	item->util = filter;
+}
+
 static void process_cached_repolist(const char *path);
 
 static void repo_config(struct cgit_repo *repo, const char *name, const char *value)
@@ -281,8 +293,10 @@ static void config_cb(const char *name, const char *value)
 			ctx.cfg.branch_sort = 1;
 		if (!strcmp(value, "name"))
 			ctx.cfg.branch_sort = 0;
-	} else if (skip_prefix(name, "mimetype.", &arg))
-		add_mimetype(arg, value);
+	} else if (starts_with(name, "mimetype."))
+		add_mimetype(name + 9, value);
+	else if (starts_with(name, "render."))
+		add_render_filter(name + 7, value);
 	else if (!strcmp(name, "include"))
 		parse_configfile(expand_macros(value), config_cb);
 }
@@ -415,6 +429,7 @@ static void prepare_context(void)
 	ctx.page.expires = ctx.page.modified;
 	ctx.page.etag = NULL;
 	string_list_init(&ctx.cfg.mimetypes, 1);
+	string_list_init(&ctx.cfg.render_filters, 1);
 	if (ctx.env.script_name)
 		ctx.cfg.script_name = xstrdup(ctx.env.script_name);
 	if (ctx.env.query_string)
diff --git a/cgit.h b/cgit.h
index 6feca68..3149946 100644
--- a/cgit.h
+++ b/cgit.h
@@ -57,7 +57,7 @@ typedef enum {
 } diff_type;
 
 typedef enum {
-	ABOUT, COMMIT, SOURCE, EMAIL, AUTH, OWNER
+	ABOUT, COMMIT, SOURCE, EMAIL, AUTH, OWNER, RENDER
 } filter_type;
 
 struct cgit_filter {
@@ -261,6 +261,7 @@ struct cgit_config {
 	int branch_sort;
 	int commit_sort;
 	struct string_list mimetypes;
+	struct string_list render_filters;
 	struct cgit_filter *about_filter;
 	struct cgit_filter *commit_filter;
 	struct cgit_filter *source_filter;
@@ -391,5 +392,6 @@ extern int readfile(const char *path, char **buf, size_t *size);
 extern char *expand_macros(const char *txt);
 
 extern char *get_mimetype_for_filename(const char *filename);
+extern struct cgit_filter *get_render_for_filename(const char *filename);
 
 #endif /* CGIT_H */
diff --git a/cgitrc.5.txt b/cgitrc.5.txt
index f6f6502..34b6186 100644
--- a/cgitrc.5.txt
+++ b/cgitrc.5.txt
@@ -342,6 +342,18 @@ renamelimit::
 	 "-1" uses the compiletime value in git (for further info, look at
 	  `man git-diff`). Default value: "-1".
 
+render.<ext>::
+	Specifies a command which will be invoked to render files with the
+	extension `.<ext>`. The command will get the blob content on its STDIN
+	and the name of the blob as its only command line argument. The STDOUT
+	from the command will be included verbatim in the page content. If no
+	render filter is available for a given file extension but the mimetype
+	is specified then the content will be included as an iframe, otherwise
+	the normal source rendering will be used.  Note <ext> may be empty, in
+	which case the render filter is used on files with no suffix.
++
+Default value: none. See also: "FILTER API".
+
 repository-sort::
 	The way in which repositories in each section are sorted. Valid values
 	are "name" for sorting by the repo name or "age" for sorting by the
@@ -705,6 +717,13 @@ owner filter::
 	standard input and the filter is expected to write to standard
 	output.  The output is included in the Owner column.
 
+render filter::
+	This filter is given a single parameter: the filename of the source
+	file to render. The filter can use the filename to determine (for
+	example) the syntax highlighting mode. The contents of the file that
+	is to be rendered is available on standard input and the rendered
+	content is expected on standard output.
+
 source filter::
 	This filter is given a single parameter: the filename of the source
 	file to filter. The filter can use the filename to determine (for
diff --git a/filter.c b/filter.c
index 70f5b74..4ae4aaa 100644
--- a/filter.c
+++ b/filter.c
@@ -434,6 +434,7 @@ struct cgit_filter *cgit_new_filter(const char *cmd, filter_type filtertype)
 
 		case SOURCE:
 		case ABOUT:
+		case RENDER:
 			argument_count = 1;
 			break;
 
diff --git a/shared.c b/shared.c
index d7c7636..665f8ed 100644
--- a/shared.c
+++ b/shared.c
@@ -574,3 +574,22 @@ char *get_mimetype_for_filename(const char *filename)
 	fclose(file);
 	return NULL;
 }
+
+struct cgit_filter *get_render_for_filename(const char *filename)
+{
+	char *ext;
+	struct string_list_item *item;
+
+	if (!filename)
+		return NULL;
+
+	ext = strrchr(filename, '.');
+	if (!ext)
+		ext = ".";
+	++ext;
+	item = string_list_lookup(&ctx.cfg.render_filters, ext);
+	if (item)
+		return item->util;
+
+	return NULL;
+}



^ permalink raw reply	[flat|nested] 140+ messages in thread

* [PATCH v3 06/17] ui-tree: split out buffer printing
  2018-06-19  9:01                   ` [PATCH v3 00/17] " andy
                                       ` (4 preceding siblings ...)
  2018-06-19  9:01                     ` [PATCH v3 05/17] Parse render filters from the config andy
@ 2018-06-19  9:01                     ` andy
  2018-06-19  9:02                     ` [PATCH v3 07/17] ui-tree: use render filters to display content andy
                                       ` (10 subsequent siblings)
  16 siblings, 0 replies; 140+ messages in thread
From: andy @ 2018-06-19  9:01 UTC (permalink / raw)


From: John Keeping <john at keeping.me.uk>

Signed-off-by: John Keeping <john at keeping.me.uk>
---
 ui-tree.c |   25 +++++++++++++++----------
 1 file changed, 15 insertions(+), 10 deletions(-)

diff --git a/ui-tree.c b/ui-tree.c
index e6b3074..d26e35e 100644
--- a/ui-tree.c
+++ b/ui-tree.c
@@ -84,6 +84,20 @@ static void print_binary_buffer(char *buf, unsigned long size)
 	html("</table>\n");
 }
 
+static void print_buffer(const char *basename, char *buf, unsigned long size)
+{
+	if (ctx.cfg.max_blob_size && size / 1024 > ctx.cfg.max_blob_size) {
+		htmlf("<div class='error'>blob size (%ldKB) exceeds display size limit (%dKB).</div>",
+				size / 1024, ctx.cfg.max_blob_size);
+		return;
+	}
+
+	if (buffer_is_binary(buf, size))
+		print_binary_buffer(buf, size);
+	else
+		print_text_buffer(basename, buf, size);
+}
+
 static void print_object(const struct object_id *oid, char *path, const char *basename, const char *rev)
 {
 	enum object_type type;
@@ -117,16 +131,7 @@ static void print_object(const struct object_id *oid, char *path, const char *ba
 	}
 	html(")\n");
 
-	if (ctx.cfg.max_blob_size && size / 1024 > ctx.cfg.max_blob_size) {
-		htmlf("<div class='error'>blob size (%ldKB) exceeds display size limit (%dKB).</div>",
-				size / 1024, ctx.cfg.max_blob_size);
-		return;
-	}
-
-	if (buffer_is_binary(buf, size))
-		print_binary_buffer(buf, size);
-	else
-		print_text_buffer(basename, buf, size);
+	print_buffer(basename, buf, size);
 
 	free(buf);
 }



^ permalink raw reply	[flat|nested] 140+ messages in thread

* [PATCH v3 07/17] ui-tree: use render filters to display content
  2018-06-19  9:01                   ` [PATCH v3 00/17] " andy
                                       ` (5 preceding siblings ...)
  2018-06-19  9:01                     ` [PATCH v3 06/17] ui-tree: split out buffer printing andy
@ 2018-06-19  9:02                     ` andy
  2018-06-19  9:02                     ` [PATCH v3 08/17] ui-blame: free read_sha1_file() buffer after use andy
                                       ` (9 subsequent siblings)
  16 siblings, 0 replies; 140+ messages in thread
From: andy @ 2018-06-19  9:02 UTC (permalink / raw)


From: John Keeping <john at keeping.me.uk>

This allows applying filters to files in the repository, for example to
render Markdown or AsciiDoc as HTML.

Signed-off-by: John Keeping <john at keeping.me.uk>
---
 cgit.css  |    5 +++
 cmd.c     |    4 +-
 ui-tree.c |  104 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++----
 ui-tree.h |    2 +
 4 files changed, 105 insertions(+), 10 deletions(-)

diff --git a/cgit.css b/cgit.css
index fb3cc70..1ac3a93 100644
--- a/cgit.css
+++ b/cgit.css
@@ -276,6 +276,11 @@ div#cgit div#blob {
 	border: solid 1px black;
 }
 
+div#cgit iframe {
+	width: 100%;
+	height: 40em;
+}
+
 div#cgit div.error {
 	color: red;
 	font-weight: bold;
diff --git a/cmd.c b/cmd.c
index 56e21df..ca48b2f 100644
--- a/cmd.c
+++ b/cmd.c
@@ -140,7 +140,7 @@ static void refs_fn(void)
 
 static void source_fn(void)
 {
-	cgit_print_tree(ctx.qry.sha1, ctx.qry.path);
+	cgit_print_tree(ctx.qry.sha1, ctx.qry.path, false);
 }
 
 static void snapshot_fn(void)
@@ -166,7 +166,7 @@ static void tag_fn(void)
 
 static void tree_fn(void)
 {
-	cgit_print_tree(ctx.qry.sha1, ctx.qry.path);
+	cgit_print_tree(ctx.qry.sha1, ctx.qry.path, true);
 }
 
 #define def_cmd(name, want_repo, want_vpath, is_clone) \
diff --git a/ui-tree.c b/ui-tree.c
index d26e35e..721c812 100644
--- a/ui-tree.c
+++ b/ui-tree.c
@@ -15,6 +15,7 @@ struct walk_tree_context {
 	char *curr_rev;
 	char *match_path;
 	int state;
+	bool use_render;
 };
 
 static void print_text_buffer(const char *name, char *buf, unsigned long size)
@@ -98,10 +99,69 @@ static void print_buffer(const char *basename, char *buf, unsigned long size)
 		print_text_buffer(basename, buf, size);
 }
 
-static void print_object(const struct object_id *oid, char *path, const char *basename, const char *rev)
+static void render_buffer(struct cgit_filter *render, const char *name,
+		char *buf, unsigned long size)
+{
+	char *filter_arg = xstrdup(name);
+
+	html("<div class='blob'>");
+	cgit_open_filter(render, filter_arg);
+	html_raw(buf, size);
+	cgit_close_filter(render);
+	html("</div>");
+
+	free(filter_arg);
+}
+
+static void include_file(const char *path, const char *mimetype)
+{
+	const char *delim = "?";
+
+	html("<div class='blob'>");
+
+	if (!strncmp(mimetype, "image/", 6)) {
+		html("<img alt='");
+		html_attr(path);
+		html("' src='");
+	} else {
+		html("<iframe sandbox='allow-scripts' src='");
+	}
+
+	if (ctx.cfg.virtual_root) {
+		html_url_path(ctx.cfg.virtual_root);
+		html_url_path(ctx.repo->url);
+		if (ctx.repo->url[strlen(ctx.repo->url) - 1] != '/')
+			html("/");
+		html("plain/");
+		html_url_path(path);
+	} else {
+		html_url_path(ctx.cfg.script_name);
+		html("?url=");
+		html_url_arg(ctx.repo->url);
+		if (ctx.repo->url[strlen(ctx.repo->url) - 1] != '/')
+			html("/");
+		html("plain/");
+		if (path)
+			html_url_arg(path);
+		delim = "&";
+	}
+	if (ctx.qry.head && ctx.repo->defbranch &&
+	    strcmp(ctx.qry.head, ctx.repo->defbranch)) {
+		html(delim);
+		html("h=");
+		html_url_arg(ctx.qry.head);
+		delim = "&";
+	}
+
+	html("'></div>");
+}
+
+static void print_object(const struct object_id *oid, char *path, const char *basename,
+			 const char *rev, bool use_render)
 {
 	enum object_type type;
-	char *buf;
+	struct cgit_filter *render;
+	char *buf, *mimetype;
 	unsigned long size;
 
 	type = oid_object_info(the_repository, oid, &size);
@@ -118,22 +178,49 @@ static void print_object(const struct object_id *oid, char *path, const char *ba
 		return;
 	}
 
+	render = get_render_for_filename(path);
+	mimetype = render ? NULL : get_mimetype_for_filename(path);
+
 	cgit_set_title_from_path(path);
 
+	/*
+	 * If we don't have a render filter or a mimetype, we won't include the
+	 * file in the page.
+	 */
+	if (!render && !mimetype)
+		use_render = false;
+
 	cgit_print_layout_start();
 	htmlf("blob: %s (", oid_to_hex(oid));
 	cgit_plain_link("plain", NULL, NULL, ctx.qry.head,
 		        rev, path);
+
 	if (ctx.cfg.enable_blame) {
 		html(") (");
 		cgit_blame_link("blame", NULL, NULL, ctx.qry.head,
 			        rev, path);
 	}
+	if (use_render) {
+		html(", ");
+		cgit_source_link("source", NULL, NULL, ctx.qry.head,
+				rev, path);
+	} else if (render || mimetype) {
+		html(", ");
+		cgit_tree_link("render", NULL, NULL, ctx.qry.head,
+			       rev, path);
+	}
 	html(")\n");
 
-	print_buffer(basename, buf, size);
-
+	if (use_render) {
+		if (render)
+			render_buffer(render, basename, buf, size);
+		else
+			include_file(path, mimetype);
+	} else
+		print_buffer(basename, buf, size);
+ 
 	free(buf);
+	free(mimetype);
 }
 
 struct single_tree_ctx {
@@ -325,8 +412,10 @@ static int walk_tree(const struct object_id *oid, struct strbuf *base,
 			return READ_TREE_RECURSIVE;
 		} else {
 			walk_tree_ctx->state = 2;
-			print_object(oid, buffer.buf, pathname, walk_tree_ctx->curr_rev);
+			print_object(oid, buffer.buf, pathname, walk_tree_ctx->curr_rev,
+				     walk_tree_ctx->use_render);
 			strbuf_release(&buffer);
+
 			return 0;
 		}
 	}
@@ -339,7 +428,7 @@ static int walk_tree(const struct object_id *oid, struct strbuf *base,
  *   rev:  the commit pointing at the root tree object
  *   path: path to tree or blob
  */
-void cgit_print_tree(const char *rev, char *path)
+void cgit_print_tree(const char *rev, char *path, bool use_render)
 {
 	struct object_id oid;
 	struct commit *commit;
@@ -353,7 +442,8 @@ void cgit_print_tree(const char *rev, char *path)
 	};
 	struct walk_tree_context walk_tree_ctx = {
 		.match_path = path,
-		.state = 0
+		.state = 0,
+		.use_render = use_render,
 	};
 
 	if (!rev)
diff --git a/ui-tree.h b/ui-tree.h
index bbd34e3..a0fc8e2 100644
--- a/ui-tree.h
+++ b/ui-tree.h
@@ -1,6 +1,6 @@
 #ifndef UI_TREE_H
 #define UI_TREE_H
 
-extern void cgit_print_tree(const char *rev, char *path);
+extern void cgit_print_tree(const char *rev, char *path, bool use_render);
 
 #endif /* UI_TREE_H */



^ permalink raw reply	[flat|nested] 140+ messages in thread

* [PATCH v3 08/17] ui-blame: free read_sha1_file() buffer after use
  2018-06-19  9:01                   ` [PATCH v3 00/17] " andy
                                       ` (6 preceding siblings ...)
  2018-06-19  9:02                     ` [PATCH v3 07/17] ui-tree: use render filters to display content andy
@ 2018-06-19  9:02                     ` andy
  2018-06-19 21:46                       ` john
  2018-06-19  9:02                     ` [PATCH v3 09/17] ui-tree: ls_tail: add walk table param andy
                                       ` (8 subsequent siblings)
  16 siblings, 1 reply; 140+ messages in thread
From: andy @ 2018-06-19  9:02 UTC (permalink / raw)


Signed-off-by: Andy Green <andy at warmcat.com>
---
 ui-blame.c |    5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/ui-blame.c b/ui-blame.c
index 8b56554..37e2c68 100644
--- a/ui-blame.c
+++ b/ui-blame.c
@@ -154,7 +154,7 @@ static void print_object(const struct object_id *oid, const char *path,
 		htmlf("<div class='error'>blob size (%ldKB)"
 		      " exceeds display size limit (%dKB).</div>",
 		      size / 1024, ctx.cfg.max_blob_size);
-		return;
+		goto cleanup;
 	}
 
 	html("<table class='blame blob'>\n<tr>\n");
@@ -213,6 +213,9 @@ static void print_object(const struct object_id *oid, const char *path,
 	html("</tr>\n</table>\n");
 
 	cgit_print_layout_end();
+
+cleanup:
+	free(buf);
 }
 
 static int walk_tree(const struct object_id *oid, struct strbuf *base,



^ permalink raw reply	[flat|nested] 140+ messages in thread

* [PATCH v3 09/17] ui-tree: ls_tail: add walk table param
  2018-06-19  9:01                   ` [PATCH v3 00/17] " andy
                                       ` (7 preceding siblings ...)
  2018-06-19  9:02                     ` [PATCH v3 08/17] ui-blame: free read_sha1_file() buffer after use andy
@ 2018-06-19  9:02                     ` andy
  2018-06-19  9:02                     ` [PATCH v3 10/17] config: add global inline-readme list andy
                                       ` (7 subsequent siblings)
  16 siblings, 0 replies; 140+ messages in thread
From: andy @ 2018-06-19  9:02 UTC (permalink / raw)


Arrange that walk_tree_ctx is available in ls_tail, we
will make use of it shortly.

Signed-off-by: Andy Green <andy at warmcat.com>
Reviewed-by: John Keeping <john at keeping.me.uk>
---
 ui-tree.c |    6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/ui-tree.c b/ui-tree.c
index 721c812..1ccbb22 100644
--- a/ui-tree.c
+++ b/ui-tree.c
@@ -365,7 +365,7 @@ static void ls_head(void)
 	html("</tr>\n");
 }
 
-static void ls_tail(void)
+static void ls_tail(struct walk_tree_context *walk_tree_ctx)
 {
 	html("</table>\n");
 	cgit_print_layout_end();
@@ -387,7 +387,7 @@ static void ls_tree(const struct object_id *oid, char *path, struct walk_tree_co
 
 	ls_head();
 	read_tree_recursive(tree, "", 0, 1, &paths, ls_item, walk_tree_ctx);
-	ls_tail();
+	ls_tail(walk_tree_ctx);
 }
 
 
@@ -470,7 +470,7 @@ void cgit_print_tree(const char *rev, char *path, bool use_render)
 
 	read_tree_recursive(commit->maybe_tree, "", 0, 0, &paths, walk_tree, &walk_tree_ctx);
 	if (walk_tree_ctx.state == 1)
-		ls_tail();
+		ls_tail(&walk_tree_ctx);
 	else if (walk_tree_ctx.state == 2)
 		cgit_print_layout_end();
 	else



^ permalink raw reply	[flat|nested] 140+ messages in thread

* [PATCH v3 10/17] config: add global inline-readme list
  2018-06-19  9:01                   ` [PATCH v3 00/17] " andy
                                       ` (8 preceding siblings ...)
  2018-06-19  9:02                     ` [PATCH v3 09/17] ui-tree: ls_tail: add walk table param andy
@ 2018-06-19  9:02                     ` andy
  2018-06-19  9:02                     ` [PATCH v3 11/17] config: add repo " andy
                                       ` (6 subsequent siblings)
  16 siblings, 0 replies; 140+ messages in thread
From: andy @ 2018-06-19  9:02 UTC (permalink / raw)


Allows the user to specify a list of filenames that should be
rendered inline with tree view, if present in the directory.

Signed-off-by: Andy Green <andy at warmcat.com>
---
 cgit.c       |    5 ++++-
 cgit.h       |    1 +
 cgitrc.5.txt |   10 ++++++++++
 3 files changed, 15 insertions(+), 1 deletion(-)

diff --git a/cgit.c b/cgit.c
index e0e94d5..bf62199 100644
--- a/cgit.c
+++ b/cgit.c
@@ -1,6 +1,6 @@
 /* cgit.c: cgi for the git scm
  *
- * Copyright (C) 2006-2014 cgit Development Team <cgit at lists.zx2c4.com>
+ * Copyright (C) 2006-2018 cgit Development Team <cgit at lists.zx2c4.com>
  *
  * Licensed under GNU General Public License v2
  *   (see COPYING for full license text)
@@ -297,6 +297,8 @@ static void config_cb(const char *name, const char *value)
 		add_mimetype(name + 9, value);
 	else if (starts_with(name, "render."))
 		add_render_filter(name + 7, value);
+	else if (!strcmp(name, "inline-readme"))
+		string_list_insert(&ctx.cfg.inline_readme, value);
 	else if (!strcmp(name, "include"))
 		parse_configfile(expand_macros(value), config_cb);
 }
@@ -430,6 +432,7 @@ static void prepare_context(void)
 	ctx.page.etag = NULL;
 	string_list_init(&ctx.cfg.mimetypes, 1);
 	string_list_init(&ctx.cfg.render_filters, 1);
+	string_list_init(&ctx.cfg.inline_readme, 1);
 	if (ctx.env.script_name)
 		ctx.cfg.script_name = xstrdup(ctx.env.script_name);
 	if (ctx.env.query_string)
diff --git a/cgit.h b/cgit.h
index 3149946..79605e7 100644
--- a/cgit.h
+++ b/cgit.h
@@ -261,6 +261,7 @@ struct cgit_config {
 	int branch_sort;
 	int commit_sort;
 	struct string_list mimetypes;
+	struct string_list inline_readme;
 	struct string_list render_filters;
 	struct cgit_filter *about_filter;
 	struct cgit_filter *commit_filter;
diff --git a/cgitrc.5.txt b/cgitrc.5.txt
index 34b6186..7ca8de9 100644
--- a/cgitrc.5.txt
+++ b/cgitrc.5.txt
@@ -238,6 +238,16 @@ include::
 	Name of a configfile to include before the rest of the current config-
 	file is parsed. Default value: none. See also: "MACRO EXPANSION".
 
+inline-readme::
+	Append given filename to the list of filenames to be rendered after the
+	tree navigation in tree view, if present in the directory being viewed.  Eg,
+	'inline-readme=README.md'.  You may also want a corresponding render.
+	entry for the readme suffix, eg,
+	'render.md=/usr/libexec/cgit/filters/html-converters/md2html'.  Repos will
+	use the list defined with 'inline-readme' by default, however they can
+	individually also choose to ignore this global list, and create a
+	repo-specific list by using 'repo.inline-readme'.
+
 local-time::
 	Flag which, if set to "1", makes cgit print commit and tag times in the
 	servers timezone. Default value: "0".



^ permalink raw reply	[flat|nested] 140+ messages in thread

* [PATCH v3 11/17] config: add repo inline-readme list
  2018-06-19  9:01                   ` [PATCH v3 00/17] " andy
                                       ` (9 preceding siblings ...)
  2018-06-19  9:02                     ` [PATCH v3 10/17] config: add global inline-readme list andy
@ 2018-06-19  9:02                     ` andy
  2018-06-19  9:02                     ` [PATCH v3 12/17] ui-tree: render any matching README file in tree view andy
                                       ` (5 subsequent siblings)
  16 siblings, 0 replies; 140+ messages in thread
From: andy @ 2018-06-19  9:02 UTC (permalink / raw)


This allows the user to choose to override any global
inline-readme list for a specific repo, using the
same kind of semantics as the other repo overrides.

Signed-off-by: Andy Green <andy at warmcat.com>
---
 cgit.c       |    7 ++++++-
 cgit.h       |    1 +
 cgitrc.5.txt |   10 ++++++++++
 shared.c     |    2 ++
 4 files changed, 19 insertions(+), 1 deletion(-)

diff --git a/cgit.c b/cgit.c
index bf62199..bdb2fad 100644
--- a/cgit.c
+++ b/cgit.c
@@ -105,7 +105,12 @@ static void repo_config(struct cgit_repo *repo, const char *name, const char *va
 		repo->hide = atoi(value);
 	else if (!strcmp(name, "ignore"))
 		repo->ignore = atoi(value);
-	else if (ctx.cfg.enable_filter_overrides) {
+	else if (!strcmp(name, "inline-readme")) {
+		if (repo->inline_readme.items == ctx.cfg.inline_readme.items)
+			string_list_init(&repo->inline_readme, 1);
+
+		string_list_append(&repo->inline_readme, value);
+	} else if (ctx.cfg.enable_filter_overrides) {
 		if (!strcmp(name, "about-filter"))
 			repo->about_filter = cgit_new_filter(value, ABOUT);
 		else if (!strcmp(name, "commit-filter"))
diff --git a/cgit.h b/cgit.h
index 79605e7..99ea7a2 100644
--- a/cgit.h
+++ b/cgit.h
@@ -86,6 +86,7 @@ struct cgit_repo {
 	char *defbranch;
 	char *module_link;
 	struct string_list readme;
+	struct string_list inline_readme;
 	char *section;
 	char *clone_url;
 	char *logo;
diff --git a/cgitrc.5.txt b/cgitrc.5.txt
index 7ca8de9..62d7c2a 100644
--- a/cgitrc.5.txt
+++ b/cgitrc.5.txt
@@ -544,6 +544,16 @@ repo.ignore::
 	is not shown in the index and cannot be accessed by providing a direct
 	path. Default value: "0". See also: "repo.hide".
 
+repo.inline-readme::
+	Append given filename to the list of filenames to be rendered after the
+	tree navigation in tree view, if present in the directory being viewed.  Eg,
+	'repo.inline-readme=README.md'.  You may also want a corresponding render.
+	entry for the readme suffix, eg,
+	'render.md=/usr/libexec/cgit/filters/html-converters/md2html'.
+	If not given, the repo will use any global 'inline-readme=' configuration;
+	if any 'repo.inline-readme' are given only they are used for that repo,
+	and the global 'inline-readme=' list is ignored for that repo.
+
 repo.logo::
 	Url which specifies the source of an image which will be used as a logo
 	on this repo's pages. Default value: global logo.
diff --git a/shared.c b/shared.c
index 665f8ed..cd0782d 100644
--- a/shared.c
+++ b/shared.c
@@ -77,6 +77,8 @@ struct cgit_repo *cgit_add_repo(const char *url)
 	ret->clone_url = ctx.cfg.clone_url;
 	ret->submodules.strdup_strings = 1;
 	ret->hide = ret->ignore = 0;
+	ret->inline_readme = ctx.cfg.inline_readme;
+
 	return ret;
 }
 



^ permalink raw reply	[flat|nested] 140+ messages in thread

* [PATCH v3 12/17] ui-tree: render any matching README file in tree view
  2018-06-19  9:01                   ` [PATCH v3 00/17] " andy
                                       ` (10 preceding siblings ...)
  2018-06-19  9:02                     ` [PATCH v3 11/17] config: add repo " andy
@ 2018-06-19  9:02                     ` andy
  2018-06-19 21:49                       ` john
  2018-06-19  9:02                     ` [PATCH v3 13/17] md2html: add asset mapping andy
                                       ` (4 subsequent siblings)
  16 siblings, 1 reply; 140+ messages in thread
From: andy @ 2018-06-19  9:02 UTC (permalink / raw)


While listing the items in tree view, we collect a list
of any filenames that match any tree-readme entries from the
config file.

After the tree view has been shown, we iterate through any
collected readme files rendering them inline.

Signed-off-by: Andy Green <andy at warmcat.com>
Reviewed-by: John Keeping <john at keeping.me.uk>
---
 ui-tree.c |   53 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 52 insertions(+), 1 deletion(-)

diff --git a/ui-tree.c b/ui-tree.c
index 1ccbb22..6ffd4dd 100644
--- a/ui-tree.c
+++ b/ui-tree.c
@@ -1,6 +1,6 @@
 /* ui-tree.c: functions for tree output
  *
- * Copyright (C) 2006-2017 cgit Development Team <cgit at lists.zx2c4.com>
+ * Copyright (C) 2006-2018 cgit Development Team <cgit at lists.zx2c4.com>
  *
  * Licensed under GNU General Public License v2
  *   (see COPYING for full license text)
@@ -12,8 +12,10 @@
 #include "ui-shared.h"
 
 struct walk_tree_context {
+	struct object_id inline_oid;
 	char *curr_rev;
 	char *match_path;
+	char *inline_filename;
 	int state;
 	bool use_render;
 };
@@ -325,11 +327,19 @@ static int ls_item(const struct object_id *oid, struct strbuf *base,
 				&fullpath);
 	} else {
 		char *ext = strrchr(name, '.');
+
 		strbuf_addstr(&class, "ls-blob");
 		if (ext)
 			strbuf_addf(&class, " %s", ext + 1);
+
 		cgit_tree_link(name, NULL, class.buf, ctx.qry.head,
 			       walk_tree_ctx->curr_rev, fullpath.buf);
+
+		if (!walk_tree_ctx->inline_filename &&
+		    string_list_has_string(&ctx.repo->inline_readme, name)) {
+			walk_tree_ctx->inline_filename = xstrdup(pathname);
+			oidcpy(&walk_tree_ctx->inline_oid, oid);
+		}
 	}
 	htmlf("</td><td class='ls-size'>%li</td>", size);
 
@@ -367,7 +377,46 @@ static void ls_head(void)
 
 static void ls_tail(struct walk_tree_context *walk_tree_ctx)
 {
+	struct cgit_filter *render;
+	enum object_type type;
+	char *buf, *mimetype;
+	unsigned long size;
+
 	html("</table>\n");
+
+	if (!walk_tree_ctx->inline_filename)
+		goto done;
+
+	type = oid_object_info(the_repository, &walk_tree_ctx->inline_oid, &size);
+	if (type == OBJ_BAD)
+		goto done;
+
+	buf = read_object_file(&walk_tree_ctx->inline_oid, &type, &size);
+	if (!buf)
+		goto done;
+
+	/* create a vertical gap between tree nav / inline */
+	html("<table class=\"tabs\"><tr><td></td></tr></table>");
+
+	render = get_render_for_filename(walk_tree_ctx->inline_filename);
+	mimetype = render ? NULL : get_mimetype_for_filename(
+				walk_tree_ctx->inline_filename);
+
+	htmlf("<h2>%s</h2>", walk_tree_ctx->inline_filename);
+	html("<div class=blob>&nbsp;</div>\n");
+
+	if (render)
+		render_buffer(render, walk_tree_ctx->inline_filename,
+			      buf, size);
+	else if (mimetype)
+		include_file(walk_tree_ctx->inline_filename, mimetype);
+	else
+		print_buffer(walk_tree_ctx->inline_filename, buf, size);
+
+	free(mimetype);
+	free(buf);
+
+done:
 	cgit_print_layout_end();
 }
 
@@ -478,4 +527,6 @@ void cgit_print_tree(const char *rev, char *path, bool use_render)
 
 cleanup:
 	free(walk_tree_ctx.curr_rev);
+	if (walk_tree_ctx.inline_filename)
+		free(walk_tree_ctx.inline_filename);
 }



^ permalink raw reply	[flat|nested] 140+ messages in thread

* [PATCH v3 13/17] md2html: add asset mapping
  2018-06-19  9:01                   ` [PATCH v3 00/17] " andy
                                       ` (11 preceding siblings ...)
  2018-06-19  9:02                     ` [PATCH v3 12/17] ui-tree: render any matching README file in tree view andy
@ 2018-06-19  9:02                     ` andy
  2018-06-19  9:02                     ` [PATCH v3 14/17] md2html-add-asset-postfix-arg andy
                                       ` (3 subsequent siblings)
  16 siblings, 0 replies; 140+ messages in thread
From: andy @ 2018-06-19  9:02 UTC (permalink / raw)


From: John Keeping <john at keeping.me.uk>

This remaps the "src" attribute on <img> elements according to a second
command line argument, you can try it out with:

	md2html <README.md README.md /path/to/plain/directory/

The trailing "/" is important.

This is useful when serving relative URLs from the repo in a readme.

Signed-off-by: John Keeping <john at keeping.me.uk>
---
 filters/html-converters/md2html |   50 ++++++++++++++++++++++++++++++++++++++-
 1 file changed, 49 insertions(+), 1 deletion(-)

diff --git a/filters/html-converters/md2html b/filters/html-converters/md2html
index ebf3856..eb5d977 100755
--- a/filters/html-converters/md2html
+++ b/filters/html-converters/md2html
@@ -2,7 +2,41 @@
 import markdown
 import sys
 import io
+from markdown.util import etree
 from pygments.formatters import HtmlFormatter
+from urllib.parse import urljoin
+
+
+class AssetMappingProcessor(markdown.treeprocessors.Treeprocessor):
+
+    def __init__(self, asset_prefix):
+        self.asset_prefix = asset_prefix
+
+    def run(self, root):
+        asset_prefix = self.asset_prefix
+        for img in root.iter('img'):
+            src = img.get('src')
+            if src is None:
+                continue
+            img.set('src', urljoin(asset_prefix, src))
+
+
+class AssetMappingExtension(markdown.extensions.Extension):
+
+    def __init__(self, **kwargs):
+        self.config = {'asset_prefix': ['', 'prefix for relative asset URLs']}
+        super(AssetMappingExtension, self).__init__(**kwargs)
+
+    def extendMarkdown(self, md, md_globals):
+        asset_prefix = self.getConfig('asset_prefix')
+        if not asset_prefix:
+            return
+
+        md.treeprocessors.add('asset_mapping',
+                              AssetMappingProcessor(asset_prefix),
+                              '_end')
+
+
 sys.stdin = io.TextIOWrapper(sys.stdin.buffer, encoding='utf-8')
 sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')
 sys.stdout.write('''
@@ -289,6 +323,20 @@ sys.stdout.write('''
 ''')
 sys.stdout.write("<div class='markdown-body'>")
 sys.stdout.flush()
+
+extensions = [
+    "markdown.extensions.fenced_code",
+    "markdown.extensions.codehilite",
+    "markdown.extensions.tables"
+]
+extension_configs = {
+    "markdown.extensions.codehilite":{"css_class":"highlight"}
+}
+
+if len(sys.argv) > 2:
+    extensions.append(AssetMappingExtension(asset_prefix=sys.argv[2]))
+
 # Note: you may want to run this through bleach for sanitization
-markdown.markdownFromFile(output_format="html5", extensions=["markdown.extensions.fenced_code", "markdown.extensions.codehilite", "markdown.extensions.tables"], extension_configs={"markdown.extensions.codehilite":{"css_class":"highlight"}})
+markdown.markdownFromFile(output_format="html5", extensions=extensions, extension_configs=extension_configs)
 sys.stdout.write("</div>")
+



^ permalink raw reply	[flat|nested] 140+ messages in thread

* [PATCH v3 14/17] md2html-add-asset-postfix-arg
  2018-06-19  9:01                   ` [PATCH v3 00/17] " andy
                                       ` (12 preceding siblings ...)
  2018-06-19  9:02                     ` [PATCH v3 13/17] md2html: add asset mapping andy
@ 2018-06-19  9:02                     ` andy
  2018-06-19  9:02                     ` [PATCH v3 15/17] ui-shared: deduplicate some code in repolink andy
                                       ` (2 subsequent siblings)
  16 siblings, 0 replies; 140+ messages in thread
From: andy @ 2018-06-19  9:02 UTC (permalink / raw)


Extend md2html with a third argument for URL postfix, like "?h=mybranch"

Signed-off-by: Andy Green <andy at warmcat.com>
---
 filters/html-converters/md2html |   19 +++++++++++++------
 1 file changed, 13 insertions(+), 6 deletions(-)

diff --git a/filters/html-converters/md2html b/filters/html-converters/md2html
index eb5d977..6f4f1b3 100755
--- a/filters/html-converters/md2html
+++ b/filters/html-converters/md2html
@@ -9,31 +9,35 @@ from urllib.parse import urljoin
 
 class AssetMappingProcessor(markdown.treeprocessors.Treeprocessor):
 
-    def __init__(self, asset_prefix):
+    def __init__(self, asset_prefix, asset_postfix):
         self.asset_prefix = asset_prefix
+        self.asset_postfix = asset_postfix
 
     def run(self, root):
         asset_prefix = self.asset_prefix
+        asset_postfix = self.asset_postfix
         for img in root.iter('img'):
             src = img.get('src')
             if src is None:
                 continue
-            img.set('src', urljoin(asset_prefix, src))
+            img.set('src', urljoin(urljoin(asset_prefix, src), asset_postfix))
 
 
 class AssetMappingExtension(markdown.extensions.Extension):
 
     def __init__(self, **kwargs):
-        self.config = {'asset_prefix': ['', 'prefix for relative asset URLs']}
+        self.config = {'asset_prefix':  ['', 'prefix for relative asset URLs'],
+                       'asset_postfix': ['', 'postfix for relative asset URLs']}
         super(AssetMappingExtension, self).__init__(**kwargs)
 
     def extendMarkdown(self, md, md_globals):
         asset_prefix = self.getConfig('asset_prefix')
-        if not asset_prefix:
+        asset_postfix = self.getConfig('asset_postfix')
+        if not (asset_prefix or asset_postfix):
             return
 
         md.treeprocessors.add('asset_mapping',
-                              AssetMappingProcessor(asset_prefix),
+                              AssetMappingProcessor(asset_prefix, asset_postfix),
                               '_end')
 
 
@@ -334,7 +338,10 @@ extension_configs = {
 }
 
 if len(sys.argv) > 2:
-    extensions.append(AssetMappingExtension(asset_prefix=sys.argv[2]))
+    args = {'asset_prefix': sys.argv[2]}
+    if len(sys.argv) > 3:
+        args['asset_postfix'] = sys.argv[3]
+    extensions.append(AssetMappingExtension(**args))
 
 # Note: you may want to run this through bleach for sanitization
 markdown.markdownFromFile(output_format="html5", extensions=extensions, extension_configs=extension_configs)



^ permalink raw reply	[flat|nested] 140+ messages in thread

* [PATCH v3 15/17] ui-shared: deduplicate some code in repolink
  2018-06-19  9:01                   ` [PATCH v3 00/17] " andy
                                       ` (13 preceding siblings ...)
  2018-06-19  9:02                     ` [PATCH v3 14/17] md2html-add-asset-postfix-arg andy
@ 2018-06-19  9:02                     ` andy
  2018-06-19 21:48                       ` john
  2018-06-19  9:02                     ` [PATCH v3 16/17] ui-shared: add helper for generating non-urlencoded links andy
  2018-06-19  9:02                     ` [PATCH v3 17/17] render: adapt for providing extra filter args for plain andy
  16 siblings, 1 reply; 140+ messages in thread
From: andy @ 2018-06-19  9:02 UTC (permalink / raw)


8 lines of code are duplicated in repolink, clean it
so the common code appears once

Signed-off-by: Andy Green <andy at warmcat.com>
---
 ui-shared.c |   26 ++++++++++----------------
 1 file changed, 10 insertions(+), 16 deletions(-)

diff --git a/ui-shared.c b/ui-shared.c
index d2985c8..21bbded 100644
--- a/ui-shared.c
+++ b/ui-shared.c
@@ -241,28 +241,22 @@ static char *repolink(const char *title, const char *class, const char *page,
 	if (ctx.cfg.virtual_root) {
 		html_url_path(ctx.cfg.virtual_root);
 		html_url_path(ctx.repo->url);
-		if (ctx.repo->url[strlen(ctx.repo->url) - 1] != '/')
-			html("/");
-		if (page) {
-			html_url_path(page);
-			html("/");
-			if (path)
-				html_url_path(path);
-		}
 	} else {
 		html_url_path(ctx.cfg.script_name);
 		html("?url=");
 		html_url_arg(ctx.repo->url);
-		if (ctx.repo->url[strlen(ctx.repo->url) - 1] != '/')
-			html("/");
-		if (page) {
-			html_url_arg(page);
-			html("/");
-			if (path)
-				html_url_arg(path);
-		}
 		delim = "&amp;";
 	}
+
+	if (ctx.repo->url[strlen(ctx.repo->url) - 1] != '/')
+		html("/");
+	if (page) {
+		html_url_arg(page);
+		html("/");
+		if (path)
+			html_url_arg(path);
+	}
+
 	if (head && ctx.repo->defbranch && strcmp(head, ctx.repo->defbranch)) {
 		html(delim);
 		html("h=");



^ permalink raw reply	[flat|nested] 140+ messages in thread

* [PATCH v3 16/17] ui-shared: add helper for generating non-urlencoded links
  2018-06-19  9:01                   ` [PATCH v3 00/17] " andy
                                       ` (14 preceding siblings ...)
  2018-06-19  9:02                     ` [PATCH v3 15/17] ui-shared: deduplicate some code in repolink andy
@ 2018-06-19  9:02                     ` andy
  2018-06-19 21:55                       ` john
  2018-06-19  9:02                     ` [PATCH v3 17/17] render: adapt for providing extra filter args for plain andy
  16 siblings, 1 reply; 140+ messages in thread
From: andy @ 2018-06-19  9:02 UTC (permalink / raw)


We are going to have to produce plain links in the next patch.
But depending on config, the links are not simple.

Reproduce the logic in repolink() to generate correctly-
formatted links in a strbuf, without urlencoding, in a reusable
helper cgit_repo_create_url().

Signed-off-by: Andy Green <andy at warmcat.com>
---
 ui-shared.c |   30 ++++++++++++++++++++++++++++++
 ui-shared.h |    3 +++
 2 files changed, 33 insertions(+)

diff --git a/ui-shared.c b/ui-shared.c
index 21bbded..79c39a8 100644
--- a/ui-shared.c
+++ b/ui-shared.c
@@ -221,6 +221,36 @@ void cgit_index_link(const char *name, const char *title, const char *class,
 	site_link(NULL, name, title, class, pattern, sort, ofs, always_root);
 }
 
+char *cgit_repo_create_url(struct strbuf *sb_pre, struct strbuf *sb_post,
+			    const char *page, const char *head, const char *path)
+{
+	const char *delim = "?";
+	struct strbuf *sb = sb_pre;
+
+	if (ctx.cfg.virtual_root)
+		strbuf_addf(sb_pre, "%s%s", ctx.cfg.virtual_root, ctx.repo->url);
+	else {
+		strbuf_addstr(sb_pre, ctx.cfg.script_name);
+		strbuf_addf(sb_post, "?url=%s", ctx.repo->url);
+		sb = sb_post;
+		delim = "&amp;";
+	}
+
+	if (ctx.repo->url[strlen(ctx.repo->url) - 1] != '/')
+		strbuf_addch(sb, '/');
+	if (page) {
+		strbuf_addf(sb, "%s/", page);
+		if (path)
+			strbuf_addstr(sb, path);
+	}
+
+	if (head && ctx.repo->defbranch && strcmp(head, ctx.repo->defbranch)) {
+		strbuf_addf(sb_post, "%sh=%s", delim, head);
+		delim = "&amp;";
+	}
+	return fmt("%s", delim);
+}
+
 static char *repolink(const char *title, const char *class, const char *page,
 		      const char *head, const char *path)
 {
diff --git a/ui-shared.h b/ui-shared.h
index c105b3b..679d2f2 100644
--- a/ui-shared.h
+++ b/ui-shared.h
@@ -59,6 +59,9 @@ extern void cgit_object_link(struct object *obj);
 
 extern void cgit_submodule_link(const char *class, char *path,
 				const char *rev);
+extern char *cgit_repo_create_url(struct strbuf *sb_pre, struct strbuf *sb_post,
+				  const char *page, const char *head,
+				  const char *path);
 
 extern void cgit_print_layout_start(void);
 extern void cgit_print_layout_end(void);



^ permalink raw reply	[flat|nested] 140+ messages in thread

* [PATCH v3 17/17] render: adapt for providing extra filter args for plain
  2018-06-19  9:01                   ` [PATCH v3 00/17] " andy
                                       ` (15 preceding siblings ...)
  2018-06-19  9:02                     ` [PATCH v3 16/17] ui-shared: add helper for generating non-urlencoded links andy
@ 2018-06-19  9:02                     ` andy
  2018-06-19 21:56                       ` john
  16 siblings, 1 reply; 140+ messages in thread
From: andy @ 2018-06-19  9:02 UTC (permalink / raw)


This changes the render filter exec part to provide a second
and third argument, which are used by md2html to fix up the url
path for "plain" for the repo, eg, "/cgit/plain/" and
"?h=mybranch", as required by the modifications to md2html in
the previous patches.

The combination means cgit becomes able to serve assets using
markdown urls starting from the repo root dir, without mentioning
any virtual url part specific to a cgit or other web rendering
instance, while respecting the version context.

Eg, continuing the example of the arguments being
"/cgit/plain/" and "?h=mybranch" from above, if the markdown has

![overview](./doc-assets/overview.png)

the img src will be fixed up to

"/cgit/plain/doc-assets/overview.png?h=mybranch"

If the same document is viewed from a different rev in cgit, the
processed markdown url will change to match the cgit context, even
though the markdown relative URL is the same for all versions.

Signed-off-by: Andy Green <andy at warmcat.com>
---
 filter.c  |    5 ++++-
 ui-tree.c |   11 +++++++++--
 2 files changed, 13 insertions(+), 3 deletions(-)

diff --git a/filter.c b/filter.c
index 4ae4aaa..7c1f188 100644
--- a/filter.c
+++ b/filter.c
@@ -424,6 +424,10 @@ struct cgit_filter *cgit_new_filter(const char *cmd, filter_type filtertype)
 			argument_count = 12;
 			break;
 
+		case RENDER:
+			argument_count = 3;
+			break;
+
 		case EMAIL:
 			argument_count = 2;
 			break;
@@ -434,7 +438,6 @@ struct cgit_filter *cgit_new_filter(const char *cmd, filter_type filtertype)
 
 		case SOURCE:
 		case ABOUT:
-		case RENDER:
 			argument_count = 1;
 			break;
 
diff --git a/ui-tree.c b/ui-tree.c
index 6ffd4dd..2e94755 100644
--- a/ui-tree.c
+++ b/ui-tree.c
@@ -102,16 +102,23 @@ static void print_buffer(const char *basename, char *buf, unsigned long size)
 }
 
 static void render_buffer(struct cgit_filter *render, const char *name,
-		char *buf, unsigned long size)
+			  char *buf, unsigned long size)
 {
 	char *filter_arg = xstrdup(name);
+	struct strbuf sb_pre = STRBUF_INIT, sb_post = STRBUF_INIT;
+
+	cgit_repo_create_url(&sb_pre, &sb_post, "plain", ctx.qry.head, NULL);
+
+	fprintf(stderr, "'%s' '%s'\n", sb_pre.buf, sb_post.buf);
 
 	html("<div class='blob'>");
-	cgit_open_filter(render, filter_arg);
+	cgit_open_filter(render, filter_arg, sb_pre.buf, sb_post.buf);
 	html_raw(buf, size);
 	cgit_close_filter(render);
 	html("</div>");
 
+	strbuf_release(&sb_pre);
+	strbuf_release(&sb_post);
 	free(filter_arg);
 }
 



^ permalink raw reply	[flat|nested] 140+ messages in thread

* [PATCH v3 01/17] manpage: fix sorting order
  2018-06-19  9:01                     ` [PATCH v3 01/17] manpage: fix sorting order andy
@ 2018-06-19 21:35                       ` john
  0 siblings, 0 replies; 140+ messages in thread
From: john @ 2018-06-19 21:35 UTC (permalink / raw)


On Tue, Jun 19, 2018 at 05:01:31PM +0800, Andy Green wrote:
> You maybe didn't know you had OCD until you saw an
> alpha sorted list that has stuff out of order in it.
> 
> Signed-off-by: Andy Green <andy at warmcat.com>

Reviewed-by: John Keeping <john at keeping.me.uk>

> ---
>  cgitrc.5.txt |  176 +++++++++++++++++++++++++++++-----------------------------
>  1 file changed, 88 insertions(+), 88 deletions(-)
> 
> diff --git a/cgitrc.5.txt b/cgitrc.5.txt
> index acfae91..f6f6502 100644
> --- a/cgitrc.5.txt
> +++ b/cgitrc.5.txt
> @@ -54,14 +54,10 @@ branch-sort::
>  	list, and when set to "name" enables ordering by branch name. Default
>  	value: "name".
>  
> -cache-root::
> -	Path used to store the cgit cache entries. Default value:
> -	"/var/cache/cgit". See also: "MACRO EXPANSION".
> -
> -cache-static-ttl::
> +cache-about-ttl::
>  	Number which specifies the time-to-live, in minutes, for the cached
> -	version of repository pages accessed with a fixed SHA1. See also:
> -	"CACHE". Default value: -1".
> +	version of the repository about page. See also: "CACHE". Default
> +	value: "15".
>  
>  cache-dynamic-ttl::
>  	Number which specifies the time-to-live, in minutes, for the cached
> @@ -73,6 +69,10 @@ cache-repo-ttl::
>  	version of the repository summary page. See also: "CACHE". Default
>  	value: "5".
>  
> +cache-root::
> +	Path used to store the cgit cache entries. Default value:
> +	"/var/cache/cgit". See also: "MACRO EXPANSION".
> +
>  cache-root-ttl::
>  	Number which specifies the time-to-live, in minutes, for the cached
>  	version of the repository index page. See also: "CACHE". Default
> @@ -83,22 +83,22 @@ cache-scanrc-ttl::
>  	of scanning a path for git repositories. See also: "CACHE". Default
>  	value: "15".
>  
> -cache-about-ttl::
> -	Number which specifies the time-to-live, in minutes, for the cached
> -	version of the repository about page. See also: "CACHE". Default
> -	value: "15".
> -
> -cache-snapshot-ttl::
> -	Number which specifies the time-to-live, in minutes, for the cached
> -	version of snapshots. See also: "CACHE". Default value: "5".
> +case-sensitive-sort::
> +	Sort items in the repo list case sensitively. Default value: "1".
> +	See also: repository-sort, section-sort.
>  
>  cache-size::
>  	The maximum number of entries in the cgit cache. When set to "0",
>  	caching is disabled. See also: "CACHE". Default value: "0"
>  
> -case-sensitive-sort::
> -	Sort items in the repo list case sensitively. Default value: "1".
> -	See also: repository-sort, section-sort.
> +cache-snapshot-ttl::
> +	Number which specifies the time-to-live, in minutes, for the cached
> +	version of snapshots. See also: "CACHE". Default value: "5".
> +
> +cache-static-ttl::
> +	Number which specifies the time-to-live, in minutes, for the cached
> +	version of repository pages accessed with a fixed SHA1. See also:
> +	"CACHE". Default value: -1".
>  
>  clone-prefix::
>  	Space-separated list of common prefixes which, when combined with a
> @@ -159,12 +159,29 @@ enable-follow-links::
>  	Flag which, when set to "1", allows users to follow a file in the log
>  	view.  Default value: "0".
>  
> +enable-git-config::
> +	Flag which, when set to "1", will allow cgit to use git config to set
> +	any repo specific settings. This option is used in conjunction with
> +	"scan-path", and must be defined prior, to augment repo-specific
> +	settings. The keys gitweb.owner, gitweb.category, gitweb.description,
> +	and gitweb.homepage will map to the cgit keys repo.owner, repo.section,
> +	repo.desc, and repo.homepage respectively. All git config keys that begin
> +	with "cgit." will be mapped to the corresponding "repo." key in cgit.
> +	Default value: "0". See also: scan-path, section-from-path.
> +
>  enable-http-clone::
> -	If set to "1", cgit will act as an dumb HTTP endpoint for git clones.
> +	If set to "1", cgit will act as a dumb HTTP endpoint for git clones.
>  	You can add "http://$HTTP_HOST$SCRIPT_NAME/$CGIT_REPO_URL" to clone-url
>  	to expose this feature. If you use an alternate way of serving git
>  	repositories, you may wish to disable this. Default value: "1".
>  
> +enable-html-serving::
> +	Flag which, when set to "1", will allow the /plain handler to serve
> +	mimetype headers that result in the file being treated as HTML by the
> +	browser. When set to "0", such file types are returned instead as
> +	text/plain or application/octet-stream. Default value: "0". See also:
> +	"repo.enable-html-serving".
> +
>  enable-index-links::
>  	Flag which, when set to "1", will make cgit generate extra links for
>  	each repo in the repository index (specifically, to the "summary",
> @@ -195,27 +212,10 @@ enable-subject-links::
>  	in commit view. Default value: "0". See also:
>  	"repo.enable-subject-links".
>  
> -enable-html-serving::
> -	Flag which, when set to "1", will allow the /plain handler to serve
> -	mimetype headers that result in the file being treated as HTML by the
> -	browser. When set to "0", such file types are returned instead as
> -	text/plain or application/octet-stream. Default value: "0". See also:
> -	"repo.enable-html-serving".
> -
>  enable-tree-linenumbers::
>  	Flag which, when set to "1", will make cgit generate linenumber links
>  	for plaintext blobs printed in the tree view. Default value: "1".
>  
> -enable-git-config::
> -	Flag which, when set to "1", will allow cgit to use git config to set
> -	any repo specific settings. This option is used in conjunction with
> -	"scan-path", and must be defined prior, to augment repo-specific
> -	settings. The keys gitweb.owner, gitweb.category, gitweb.description,
> -	and gitweb.homepage will map to the cgit keys repo.owner, repo.section,
> -	repo.desc, and repo.homepage respectively. All git config keys that begin
> -	with "cgit." will be mapped to the corresponding "repo." key in cgit.
> -	Default value: "0". See also: scan-path, section-from-path.
> -
>  favicon::
>  	Url used as link to a shortcut icon for cgit. It is suggested to use
>  	the value "/favicon.ico" since certain browsers will ignore other
> @@ -251,19 +251,14 @@ logo-link::
>  	calculated url of the repository index page will be used. Default
>  	value: none.
>  
> -owner-filter::
> -	Specifies a command which will be invoked to format the Owner
> -	column of the main page.  The command will get the owner on STDIN,
> -	and the STDOUT from the command will be included verbatim in the
> -	table.  This can be used to link to additional context such as an
> -	owners home page.  When active this filter is used instead of the
> -	default owner query url.  Default value: none.
> -	See also: "FILTER API".
> -
>  max-atom-items::
>  	Specifies the number of items to display in atom feeds view. Default
>  	value: "10".
>  
> +max-blob-size::
> +	Specifies the maximum size of a blob to display HTML for in KBytes.
> +	Default value: "0" (limit disabled).
> +
>  max-commit-count::
>  	Specifies the number of entries to list per page in "log" view. Default
>  	value: "50".
> @@ -280,10 +275,6 @@ max-repodesc-length::
>  	Specifies the maximum number of repo description characters to display
>  	on the repository index page. Default value: "80".
>  
> -max-blob-size::
> -	Specifies the maximum size of a blob to display HTML for in KBytes.
> -	Default value: "0" (limit disabled).
> -
>  max-stats::
>  	Set the default maximum statistics period. Valid values are "week",
>  	"month", "quarter" and "year". If unspecified, statistics are
> @@ -319,6 +310,15 @@ noheader::
>  	Flag which, when set to "1", will make cgit omit the standard header
>  	on all pages. Default value: none. See also: "embedded".
>  
> +owner-filter::
> +	Specifies a command which will be invoked to format the Owner
> +	column of the main page.  The command will get the owner on STDIN,
> +	and the STDOUT from the command will be included verbatim in the
> +	table.  This can be used to link to additional context such as an
> +	owners home page.  When active this filter is used instead of the
> +	default owner query url.  Default value: none.
> +	See also: "FILTER API".
> +
>  project-list::
>  	A list of subdirectories inside of scan-path, relative to it, that
>  	should loaded as git repositories. This must be defined prior to
> @@ -481,9 +481,6 @@ repo.defbranch::
>  repo.desc::
>  	The value to show as repository description. Default value: none.
>  
> -repo.homepage::
> -	The value to show as repository homepage. Default value: none.
> -
>  repo.email-filter::
>  	Override the default email-filter. Default value: none. See also:
>  	"enable-filter-overrides". See also: "FILTER API".
> @@ -492,6 +489,10 @@ repo.enable-commit-graph::
>  	A flag which can be used to disable the global setting
>  	`enable-commit-graph'. Default value: none.
>  
> +repo.enable-html-serving::
> +	A flag which can be used to override the global setting
> +	`enable-html-serving`. Default value: none.
> +
>  repo.enable-log-filecount::
>  	A flag which can be used to disable the global setting
>  	`enable-log-filecount'. Default value: none.
> @@ -508,15 +509,14 @@ repo.enable-subject-links::
>  	A flag which can be used to override the global setting
>  	`enable-subject-links'. Default value: none.
>  
> -repo.enable-html-serving::
> -	A flag which can be used to override the global setting
> -	`enable-html-serving`. Default value: none.
> -
>  repo.hide::
>  	Flag which, when set to "1", hides the repository from the repository
>  	index. The repository can still be accessed by providing a direct path.
>  	Default value: "0". See also: "repo.ignore".
>  
> +repo.homepage::
> +	The value to show as repository homepage. Default value: none.
> +
>  repo.ignore::
>  	Flag which, when set to "1", ignores the repository. The repository
>  	is not shown in the index and cannot be accessed by providing a direct
> @@ -531,10 +531,6 @@ repo.logo-link::
>  	calculated url of the repository index page will be used. Default
>  	value: global logo-link.
>  
> -repo.owner-filter::
> -	Override the default owner-filter. Default value: none. See also:
> -	"enable-filter-overrides". See also: "FILTER API".
> -
>  repo.module-link::
>  	Text which will be used as the formatstring for a hyperlink when a
>  	submodule is printed in a directory listing. The arguments for the
> @@ -559,6 +555,10 @@ repo.owner::
>  	A value used to identify the owner of the repository. Default value:
>  	none.
>  
> +repo.owner-filter::
> +	Override the default owner-filter. Default value: none. See also:
> +	"enable-filter-overrides". See also: "FILTER API".
> +
>  repo.path::
>  	An absolute path to the repository directory. For non-bare repositories
>  	this is the .git-directory. Default value: none.
> @@ -574,6 +574,10 @@ repo.readme::
>  	are no non-public files located in the same directory as the readme
>  	file. Default value: <readme>.
>  
> +repo.section::
> +	Override the current section name for this repository. Default value:
> +	none.
> +
>  repo.snapshots::
>  	A mask of snapshot formats for this repo that cgit generates links for,
>  	restricted by the global "snapshots" setting. Default value:
> @@ -586,10 +590,6 @@ repo.snapshot-prefix::
>  	of "linux-stable-3.15.4".  Default value: <empty> meaning to use
>  	the repository basename.
>  
> -repo.section::
> -	Override the current section name for this repository. Default value:
> -	none.
> -
>  repo.source-filter::
>  	Override the default source-filter. Default value: none. See also:
>  	"enable-filter-overrides". See also: "FILTER API".
> @@ -662,30 +662,6 @@ about filter::
>  	The about text that is to be filtered is available on standard input
>  	and the filtered text is expected on standard output.
>  
> -commit filter::
> -	This filter is given no arguments. The commit message text that is to
> -	be filtered is available on standard input and the filtered text is
> -	expected on standard output.
> -
> -email filter::
> -	This filter is given two parameters: the email address of the relevant
> -	author and a string indicating the originating page. The filter will
> -	then receive the text string to format on standard input and is
> -	expected to write to standard output the formatted text to be included
> -	in the page.
> -
> -owner filter::
> -	This filter is given no arguments.  The owner text is available on
> -	standard input and the filter is expected to write to standard
> -	output.  The output is included in the Owner column.
> -
> -source filter::
> -	This filter is given a single parameter: the filename of the source
> -	file to filter. The filter can use the filename to determine (for
> -	example) the syntax highlighting mode. The contents of the source
> -	file that is to be filtered is available on standard input and the
> -	filtered contents is expected on standard output.
> -
>  auth filter::
>  	The authentication filter receives 12 parameters:
>  	  - filter action, explained below, which specifies which action the
> @@ -712,6 +688,30 @@ auth filter::
>  	Please see `filters/simple-authentication.lua` for a clear example
>  	script that may be modified.
>  
> +commit filter::
> +	This filter is given no arguments. The commit message text that is to
> +	be filtered is available on standard input and the filtered text is
> +	expected on standard output.
> +
> +email filter::
> +	This filter is given two parameters: the email address of the relevant
> +	author and a string indicating the originating page. The filter will
> +	then receive the text string to format on standard input and is
> +	expected to write to standard output the formatted text to be included
> +	in the page.
> +
> +owner filter::
> +	This filter is given no arguments.  The owner text is available on
> +	standard input and the filter is expected to write to standard
> +	output.  The output is included in the Owner column.
> +
> +source filter::
> +	This filter is given a single parameter: the filename of the source
> +	file to filter. The filter can use the filename to determine (for
> +	example) the syntax highlighting mode. The contents of the source
> +	file that is to be filtered is available on standard input and the
> +	filtered contents is expected on standard output.
> +
>  
>  All filters are handed the following environment variables:
>  
> 
> _______________________________________________
> CGit mailing list
> CGit at lists.zx2c4.com
> https://lists.zx2c4.com/mailman/listinfo/cgit


^ permalink raw reply	[flat|nested] 140+ messages in thread

* [PATCH v3 05/17] Parse render filters from the config
  2018-06-19  9:01                     ` [PATCH v3 05/17] Parse render filters from the config andy
@ 2018-06-19 21:37                       ` john
  0 siblings, 0 replies; 140+ messages in thread
From: john @ 2018-06-19 21:37 UTC (permalink / raw)


On Tue, Jun 19, 2018 at 05:01:51PM +0800, Andy Green wrote:
> From: John Keeping <john at keeping.me.uk>
> 
> Render filters will be used to present rendered content in the tree
> view, for example to display Markdown source rendered as HTML.
> 
> We will add support for using these from the tree view in the following
> commits.
> 
> AG: adapted so render.= can be used to specify the filter for files
> without any suffix
> 
> Signed-off-by: John Keeping <john at keeping.me.uk>
> Signed-off-by: Andy Green <andy at warmcat.com>

For your change,

Reviewed-by: John Keeping <john at keeping.me.uk>

> ---
>  cgit.c       |   19 +++++++++++++++++--
>  cgit.h       |    4 +++-
>  cgitrc.5.txt |   19 +++++++++++++++++++
>  filter.c     |    1 +
>  shared.c     |   19 +++++++++++++++++++
>  5 files changed, 59 insertions(+), 3 deletions(-)
> 
> diff --git a/cgit.c b/cgit.c
> index 0c9f3e9..e0e94d5 100644
> --- a/cgit.c
> +++ b/cgit.c
> @@ -27,6 +27,18 @@ static void add_mimetype(const char *name, const char *value)
>  	item->util = xstrdup(value);
>  }
>  
> +static void add_render_filter(const char *name, const char *cmd)
> +{
> +	struct string_list_item *item;
> +	struct cgit_filter *filter = cgit_new_filter(cmd, RENDER);
> +
> +	if (!filter)
> +		return;
> +
> +	item = string_list_insert(&ctx.cfg.render_filters, name);
> +	item->util = filter;
> +}
> +
>  static void process_cached_repolist(const char *path);
>  
>  static void repo_config(struct cgit_repo *repo, const char *name, const char *value)
> @@ -281,8 +293,10 @@ static void config_cb(const char *name, const char *value)
>  			ctx.cfg.branch_sort = 1;
>  		if (!strcmp(value, "name"))
>  			ctx.cfg.branch_sort = 0;
> -	} else if (skip_prefix(name, "mimetype.", &arg))
> -		add_mimetype(arg, value);
> +	} else if (starts_with(name, "mimetype."))
> +		add_mimetype(name + 9, value);
> +	else if (starts_with(name, "render."))
> +		add_render_filter(name + 7, value);
>  	else if (!strcmp(name, "include"))
>  		parse_configfile(expand_macros(value), config_cb);
>  }
> @@ -415,6 +429,7 @@ static void prepare_context(void)
>  	ctx.page.expires = ctx.page.modified;
>  	ctx.page.etag = NULL;
>  	string_list_init(&ctx.cfg.mimetypes, 1);
> +	string_list_init(&ctx.cfg.render_filters, 1);
>  	if (ctx.env.script_name)
>  		ctx.cfg.script_name = xstrdup(ctx.env.script_name);
>  	if (ctx.env.query_string)
> diff --git a/cgit.h b/cgit.h
> index 6feca68..3149946 100644
> --- a/cgit.h
> +++ b/cgit.h
> @@ -57,7 +57,7 @@ typedef enum {
>  } diff_type;
>  
>  typedef enum {
> -	ABOUT, COMMIT, SOURCE, EMAIL, AUTH, OWNER
> +	ABOUT, COMMIT, SOURCE, EMAIL, AUTH, OWNER, RENDER
>  } filter_type;
>  
>  struct cgit_filter {
> @@ -261,6 +261,7 @@ struct cgit_config {
>  	int branch_sort;
>  	int commit_sort;
>  	struct string_list mimetypes;
> +	struct string_list render_filters;
>  	struct cgit_filter *about_filter;
>  	struct cgit_filter *commit_filter;
>  	struct cgit_filter *source_filter;
> @@ -391,5 +392,6 @@ extern int readfile(const char *path, char **buf, size_t *size);
>  extern char *expand_macros(const char *txt);
>  
>  extern char *get_mimetype_for_filename(const char *filename);
> +extern struct cgit_filter *get_render_for_filename(const char *filename);
>  
>  #endif /* CGIT_H */
> diff --git a/cgitrc.5.txt b/cgitrc.5.txt
> index f6f6502..34b6186 100644
> --- a/cgitrc.5.txt
> +++ b/cgitrc.5.txt
> @@ -342,6 +342,18 @@ renamelimit::
>  	 "-1" uses the compiletime value in git (for further info, look at
>  	  `man git-diff`). Default value: "-1".
>  
> +render.<ext>::
> +	Specifies a command which will be invoked to render files with the
> +	extension `.<ext>`. The command will get the blob content on its STDIN
> +	and the name of the blob as its only command line argument. The STDOUT
> +	from the command will be included verbatim in the page content. If no
> +	render filter is available for a given file extension but the mimetype
> +	is specified then the content will be included as an iframe, otherwise
> +	the normal source rendering will be used.  Note <ext> may be empty, in
> +	which case the render filter is used on files with no suffix.
> ++
> +Default value: none. See also: "FILTER API".
> +
>  repository-sort::
>  	The way in which repositories in each section are sorted. Valid values
>  	are "name" for sorting by the repo name or "age" for sorting by the
> @@ -705,6 +717,13 @@ owner filter::
>  	standard input and the filter is expected to write to standard
>  	output.  The output is included in the Owner column.
>  
> +render filter::
> +	This filter is given a single parameter: the filename of the source
> +	file to render. The filter can use the filename to determine (for
> +	example) the syntax highlighting mode. The contents of the file that
> +	is to be rendered is available on standard input and the rendered
> +	content is expected on standard output.
> +
>  source filter::
>  	This filter is given a single parameter: the filename of the source
>  	file to filter. The filter can use the filename to determine (for
> diff --git a/filter.c b/filter.c
> index 70f5b74..4ae4aaa 100644
> --- a/filter.c
> +++ b/filter.c
> @@ -434,6 +434,7 @@ struct cgit_filter *cgit_new_filter(const char *cmd, filter_type filtertype)
>  
>  		case SOURCE:
>  		case ABOUT:
> +		case RENDER:
>  			argument_count = 1;
>  			break;
>  
> diff --git a/shared.c b/shared.c
> index d7c7636..665f8ed 100644
> --- a/shared.c
> +++ b/shared.c
> @@ -574,3 +574,22 @@ char *get_mimetype_for_filename(const char *filename)
>  	fclose(file);
>  	return NULL;
>  }
> +
> +struct cgit_filter *get_render_for_filename(const char *filename)
> +{
> +	char *ext;
> +	struct string_list_item *item;
> +
> +	if (!filename)
> +		return NULL;
> +
> +	ext = strrchr(filename, '.');
> +	if (!ext)
> +		ext = ".";
> +	++ext;

It took me a minute to realise that this wasn't looking for "render..",
is the following clearer?

	if (!ext)
		ext = "";
	else
		++ext;

> +	item = string_list_lookup(&ctx.cfg.render_filters, ext);
> +	if (item)
> +		return item->util;
> +
> +	return NULL;
> +}


^ permalink raw reply	[flat|nested] 140+ messages in thread

* [PATCH v3 08/17] ui-blame: free read_sha1_file() buffer after use
  2018-06-19  9:02                     ` [PATCH v3 08/17] ui-blame: free read_sha1_file() buffer after use andy
@ 2018-06-19 21:46                       ` john
  0 siblings, 0 replies; 140+ messages in thread
From: john @ 2018-06-19 21:46 UTC (permalink / raw)


On Tue, Jun 19, 2018 at 05:02:07PM +0800, Andy Green wrote:
> Signed-off-by: Andy Green <andy at warmcat.com>

Pushed to jk/for-jason (after rebasing onto master).

> ---
>  ui-blame.c |    5 ++++-
>  1 file changed, 4 insertions(+), 1 deletion(-)
> 
> diff --git a/ui-blame.c b/ui-blame.c
> index 8b56554..37e2c68 100644
> --- a/ui-blame.c
> +++ b/ui-blame.c
> @@ -154,7 +154,7 @@ static void print_object(const struct object_id *oid, const char *path,
>  		htmlf("<div class='error'>blob size (%ldKB)"
>  		      " exceeds display size limit (%dKB).</div>",
>  		      size / 1024, ctx.cfg.max_blob_size);
> -		return;
> +		goto cleanup;
>  	}
>  
>  	html("<table class='blame blob'>\n<tr>\n");
> @@ -213,6 +213,9 @@ static void print_object(const struct object_id *oid, const char *path,
>  	html("</tr>\n</table>\n");
>  
>  	cgit_print_layout_end();
> +
> +cleanup:
> +	free(buf);
>  }
>  
>  static int walk_tree(const struct object_id *oid, struct strbuf *base,


^ permalink raw reply	[flat|nested] 140+ messages in thread

* [PATCH v3 15/17] ui-shared: deduplicate some code in repolink
  2018-06-19  9:02                     ` [PATCH v3 15/17] ui-shared: deduplicate some code in repolink andy
@ 2018-06-19 21:48                       ` john
  0 siblings, 0 replies; 140+ messages in thread
From: john @ 2018-06-19 21:48 UTC (permalink / raw)


On Tue, Jun 19, 2018 at 05:02:42PM +0800, Andy Green wrote:
> 8 lines of code are duplicated in repolink, clean it
> so the common code appears once
> 
> Signed-off-by: Andy Green <andy at warmcat.com>

Reviewed-by: John Keeping <john at keeping.me.uk>

> ---
>  ui-shared.c |   26 ++++++++++----------------
>  1 file changed, 10 insertions(+), 16 deletions(-)
> 
> diff --git a/ui-shared.c b/ui-shared.c
> index d2985c8..21bbded 100644
> --- a/ui-shared.c
> +++ b/ui-shared.c
> @@ -241,28 +241,22 @@ static char *repolink(const char *title, const char *class, const char *page,
>  	if (ctx.cfg.virtual_root) {
>  		html_url_path(ctx.cfg.virtual_root);
>  		html_url_path(ctx.repo->url);
> -		if (ctx.repo->url[strlen(ctx.repo->url) - 1] != '/')
> -			html("/");
> -		if (page) {
> -			html_url_path(page);
> -			html("/");
> -			if (path)
> -				html_url_path(path);
> -		}
>  	} else {
>  		html_url_path(ctx.cfg.script_name);
>  		html("?url=");
>  		html_url_arg(ctx.repo->url);
> -		if (ctx.repo->url[strlen(ctx.repo->url) - 1] != '/')
> -			html("/");
> -		if (page) {
> -			html_url_arg(page);
> -			html("/");
> -			if (path)
> -				html_url_arg(path);
> -		}
>  		delim = "&amp;";
>  	}
> +
> +	if (ctx.repo->url[strlen(ctx.repo->url) - 1] != '/')
> +		html("/");
> +	if (page) {
> +		html_url_arg(page);
> +		html("/");
> +		if (path)
> +			html_url_arg(path);
> +	}
> +
>  	if (head && ctx.repo->defbranch && strcmp(head, ctx.repo->defbranch)) {
>  		html(delim);
>  		html("h=");
> 
> _______________________________________________
> CGit mailing list
> CGit at lists.zx2c4.com
> https://lists.zx2c4.com/mailman/listinfo/cgit


^ permalink raw reply	[flat|nested] 140+ messages in thread

* [PATCH v3 12/17] ui-tree: render any matching README file in tree view
  2018-06-19  9:02                     ` [PATCH v3 12/17] ui-tree: render any matching README file in tree view andy
@ 2018-06-19 21:49                       ` john
  2018-06-20  0:00                         ` andy
  0 siblings, 1 reply; 140+ messages in thread
From: john @ 2018-06-19 21:49 UTC (permalink / raw)


On Tue, Jun 19, 2018 at 05:02:27PM +0800, Andy Green wrote:
> While listing the items in tree view, we collect a list
> of any filenames that match any tree-readme entries from the
> config file.
> 
> After the tree view has been shown, we iterate through any
> collected readme files rendering them inline.

There's only one now, the commit message isn't quite accurate any more!

> Signed-off-by: Andy Green <andy at warmcat.com>
> Reviewed-by: John Keeping <john at keeping.me.uk>
> ---
>  ui-tree.c |   53 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
>  1 file changed, 52 insertions(+), 1 deletion(-)
> 
> diff --git a/ui-tree.c b/ui-tree.c
> index 1ccbb22..6ffd4dd 100644
> --- a/ui-tree.c
> +++ b/ui-tree.c
> @@ -1,6 +1,6 @@
>  /* ui-tree.c: functions for tree output
>   *
> - * Copyright (C) 2006-2017 cgit Development Team <cgit at lists.zx2c4.com>
> + * Copyright (C) 2006-2018 cgit Development Team <cgit at lists.zx2c4.com>
>   *
>   * Licensed under GNU General Public License v2
>   *   (see COPYING for full license text)
> @@ -12,8 +12,10 @@
>  #include "ui-shared.h"
>  
>  struct walk_tree_context {
> +	struct object_id inline_oid;
>  	char *curr_rev;
>  	char *match_path;
> +	char *inline_filename;
>  	int state;
>  	bool use_render;
>  };
> @@ -325,11 +327,19 @@ static int ls_item(const struct object_id *oid, struct strbuf *base,
>  				&fullpath);
>  	} else {
>  		char *ext = strrchr(name, '.');
> +
>  		strbuf_addstr(&class, "ls-blob");
>  		if (ext)
>  			strbuf_addf(&class, " %s", ext + 1);
> +
>  		cgit_tree_link(name, NULL, class.buf, ctx.qry.head,
>  			       walk_tree_ctx->curr_rev, fullpath.buf);
> +
> +		if (!walk_tree_ctx->inline_filename &&
> +		    string_list_has_string(&ctx.repo->inline_readme, name)) {
> +			walk_tree_ctx->inline_filename = xstrdup(pathname);
> +			oidcpy(&walk_tree_ctx->inline_oid, oid);
> +		}
>  	}
>  	htmlf("</td><td class='ls-size'>%li</td>", size);
>  
> @@ -367,7 +377,46 @@ static void ls_head(void)
>  
>  static void ls_tail(struct walk_tree_context *walk_tree_ctx)
>  {
> +	struct cgit_filter *render;
> +	enum object_type type;
> +	char *buf, *mimetype;
> +	unsigned long size;
> +
>  	html("</table>\n");
> +
> +	if (!walk_tree_ctx->inline_filename)
> +		goto done;
> +
> +	type = oid_object_info(the_repository, &walk_tree_ctx->inline_oid, &size);
> +	if (type == OBJ_BAD)
> +		goto done;
> +
> +	buf = read_object_file(&walk_tree_ctx->inline_oid, &type, &size);
> +	if (!buf)
> +		goto done;
> +
> +	/* create a vertical gap between tree nav / inline */
> +	html("<table class=\"tabs\"><tr><td></td></tr></table>");
> +
> +	render = get_render_for_filename(walk_tree_ctx->inline_filename);
> +	mimetype = render ? NULL : get_mimetype_for_filename(
> +				walk_tree_ctx->inline_filename);
> +
> +	htmlf("<h2>%s</h2>", walk_tree_ctx->inline_filename);
> +	html("<div class=blob>&nbsp;</div>\n");
> +
> +	if (render)
> +		render_buffer(render, walk_tree_ctx->inline_filename,
> +			      buf, size);
> +	else if (mimetype)
> +		include_file(walk_tree_ctx->inline_filename, mimetype);
> +	else
> +		print_buffer(walk_tree_ctx->inline_filename, buf, size);
> +
> +	free(mimetype);
> +	free(buf);
> +
> +done:
>  	cgit_print_layout_end();
>  }
>  
> @@ -478,4 +527,6 @@ void cgit_print_tree(const char *rev, char *path, bool use_render)
>  
>  cleanup:
>  	free(walk_tree_ctx.curr_rev);
> +	if (walk_tree_ctx.inline_filename)
> +		free(walk_tree_ctx.inline_filename);
>  }
> 
> _______________________________________________
> CGit mailing list
> CGit at lists.zx2c4.com
> https://lists.zx2c4.com/mailman/listinfo/cgit


^ permalink raw reply	[flat|nested] 140+ messages in thread

* [PATCH v3 16/17] ui-shared: add helper for generating non-urlencoded links
  2018-06-19  9:02                     ` [PATCH v3 16/17] ui-shared: add helper for generating non-urlencoded links andy
@ 2018-06-19 21:55                       ` john
  2018-06-20  0:07                         ` andy
  0 siblings, 1 reply; 140+ messages in thread
From: john @ 2018-06-19 21:55 UTC (permalink / raw)


On Tue, Jun 19, 2018 at 05:02:47PM +0800, Andy Green wrote:
> We are going to have to produce plain links in the next patch.
> But depending on config, the links are not simple.
> 
> Reproduce the logic in repolink() to generate correctly-
> formatted links in a strbuf, without urlencoding, in a reusable
> helper cgit_repo_create_url().
> 
> Signed-off-by: Andy Green <andy at warmcat.com>
> ---
>  ui-shared.c |   30 ++++++++++++++++++++++++++++++
>  ui-shared.h |    3 +++
>  2 files changed, 33 insertions(+)
> 
> diff --git a/ui-shared.c b/ui-shared.c
> index 21bbded..79c39a8 100644
> --- a/ui-shared.c
> +++ b/ui-shared.c
> @@ -221,6 +221,36 @@ void cgit_index_link(const char *name, const char *title, const char *class,
>  	site_link(NULL, name, title, class, pattern, sort, ofs, always_root);
>  }
>  
> +char *cgit_repo_create_url(struct strbuf *sb_pre, struct strbuf *sb_post,
> +			    const char *page, const char *head, const char *path)
> +{
> +	const char *delim = "?";
> +	struct strbuf *sb = sb_pre;

Does this variable serve any point?  Why not rename the parameter?

> +
> +	if (ctx.cfg.virtual_root)
> +		strbuf_addf(sb_pre, "%s%s", ctx.cfg.virtual_root, ctx.repo->url);

NIT: I think we normally put the braces in around a oneline if with a
multi-line else clause.

> +	else {
> +		strbuf_addstr(sb_pre, ctx.cfg.script_name);
> +		strbuf_addf(sb_post, "?url=%s", ctx.repo->url);
> +		sb = sb_post;
> +		delim = "&amp;";
> +	}
> +
> +	if (ctx.repo->url[strlen(ctx.repo->url) - 1] != '/')
> +		strbuf_addch(sb, '/');

Maybe add a blank line here since these if blocks are unrelated.

> +	if (page) {
> +		strbuf_addf(sb, "%s/", page);
> +		if (path)
> +			strbuf_addstr(sb, path);
> +	}
> +
> +	if (head && ctx.repo->defbranch && strcmp(head, ctx.repo->defbranch)) {
> +		strbuf_addf(sb_post, "%sh=%s", delim, head);
> +		delim = "&amp;";
> +	}
> +	return fmt("%s", delim);

delim is always a character constant, so I think we can just return it
as "const char *" here.  This also avoids any worry about the lifetime
of fmt()'s result.

> +}
> +
>  static char *repolink(const char *title, const char *class, const char *page,
>  		      const char *head, const char *path)
>  {
> diff --git a/ui-shared.h b/ui-shared.h
> index c105b3b..679d2f2 100644
> --- a/ui-shared.h
> +++ b/ui-shared.h
> @@ -59,6 +59,9 @@ extern void cgit_object_link(struct object *obj);
>  
>  extern void cgit_submodule_link(const char *class, char *path,
>  				const char *rev);
> +extern char *cgit_repo_create_url(struct strbuf *sb_pre, struct strbuf *sb_post,
> +				  const char *page, const char *head,
> +				  const char *path);
>  
>  extern void cgit_print_layout_start(void);
>  extern void cgit_print_layout_end(void);


^ permalink raw reply	[flat|nested] 140+ messages in thread

* [PATCH v3 17/17] render: adapt for providing extra filter args for plain
  2018-06-19  9:02                     ` [PATCH v3 17/17] render: adapt for providing extra filter args for plain andy
@ 2018-06-19 21:56                       ` john
  0 siblings, 0 replies; 140+ messages in thread
From: john @ 2018-06-19 21:56 UTC (permalink / raw)


On Tue, Jun 19, 2018 at 05:02:52PM +0800, Andy Green wrote:
> This changes the render filter exec part to provide a second
> and third argument, which are used by md2html to fix up the url
> path for "plain" for the repo, eg, "/cgit/plain/" and
> "?h=mybranch", as required by the modifications to md2html in
> the previous patches.
> 
> The combination means cgit becomes able to serve assets using
> markdown urls starting from the repo root dir, without mentioning
> any virtual url part specific to a cgit or other web rendering
> instance, while respecting the version context.
> 
> Eg, continuing the example of the arguments being
> "/cgit/plain/" and "?h=mybranch" from above, if the markdown has
> 
> ![overview](./doc-assets/overview.png)
> 
> the img src will be fixed up to
> 
> "/cgit/plain/doc-assets/overview.png?h=mybranch"
> 
> If the same document is viewed from a different rev in cgit, the
> processed markdown url will change to match the cgit context, even
> though the markdown relative URL is the same for all versions.
> 
> Signed-off-by: Andy Green <andy at warmcat.com>

Reviewed-by: John Keeping <john at keeping.me.uk>

> ---
>  filter.c  |    5 ++++-
>  ui-tree.c |   11 +++++++++--
>  2 files changed, 13 insertions(+), 3 deletions(-)
> 
> diff --git a/filter.c b/filter.c
> index 4ae4aaa..7c1f188 100644
> --- a/filter.c
> +++ b/filter.c
> @@ -424,6 +424,10 @@ struct cgit_filter *cgit_new_filter(const char *cmd, filter_type filtertype)
>  			argument_count = 12;
>  			break;
>  
> +		case RENDER:
> +			argument_count = 3;
> +			break;
> +
>  		case EMAIL:
>  			argument_count = 2;
>  			break;
> @@ -434,7 +438,6 @@ struct cgit_filter *cgit_new_filter(const char *cmd, filter_type filtertype)
>  
>  		case SOURCE:
>  		case ABOUT:
> -		case RENDER:
>  			argument_count = 1;
>  			break;
>  
> diff --git a/ui-tree.c b/ui-tree.c
> index 6ffd4dd..2e94755 100644
> --- a/ui-tree.c
> +++ b/ui-tree.c
> @@ -102,16 +102,23 @@ static void print_buffer(const char *basename, char *buf, unsigned long size)
>  }
>  
>  static void render_buffer(struct cgit_filter *render, const char *name,
> -		char *buf, unsigned long size)
> +			  char *buf, unsigned long size)
>  {
>  	char *filter_arg = xstrdup(name);
> +	struct strbuf sb_pre = STRBUF_INIT, sb_post = STRBUF_INIT;
> +
> +	cgit_repo_create_url(&sb_pre, &sb_post, "plain", ctx.qry.head, NULL);
> +
> +	fprintf(stderr, "'%s' '%s'\n", sb_pre.buf, sb_post.buf);
>  
>  	html("<div class='blob'>");
> -	cgit_open_filter(render, filter_arg);
> +	cgit_open_filter(render, filter_arg, sb_pre.buf, sb_post.buf);
>  	html_raw(buf, size);
>  	cgit_close_filter(render);
>  	html("</div>");
>  
> +	strbuf_release(&sb_pre);
> +	strbuf_release(&sb_post);
>  	free(filter_arg);
>  }
>  
> 
> _______________________________________________
> CGit mailing list
> CGit at lists.zx2c4.com
> https://lists.zx2c4.com/mailman/listinfo/cgit


^ permalink raw reply	[flat|nested] 140+ messages in thread

* [PATCH v3 12/17] ui-tree: render any matching README file in tree view
  2018-06-19 21:49                       ` john
@ 2018-06-20  0:00                         ` andy
  0 siblings, 0 replies; 140+ messages in thread
From: andy @ 2018-06-20  0:00 UTC (permalink / raw)




On 06/20/2018 05:49 AM, John Keeping wrote:
> On Tue, Jun 19, 2018 at 05:02:27PM +0800, Andy Green wrote:
>> While listing the items in tree view, we collect a list
>> of any filenames that match any tree-readme entries from the
>> config file.
>>
>> After the tree view has been shown, we iterate through any
>> collected readme files rendering them inline.
> 
> There's only one now, the commit message isn't quite accurate any more!

Right... the name changed as well... I updated it.

-Andy

>> Signed-off-by: Andy Green <andy at warmcat.com>
>> Reviewed-by: John Keeping <john at keeping.me.uk>
>> ---
>>   ui-tree.c |   53 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
>>   1 file changed, 52 insertions(+), 1 deletion(-)
>>
>> diff --git a/ui-tree.c b/ui-tree.c
>> index 1ccbb22..6ffd4dd 100644
>> --- a/ui-tree.c
>> +++ b/ui-tree.c
>> @@ -1,6 +1,6 @@
>>   /* ui-tree.c: functions for tree output
>>    *
>> - * Copyright (C) 2006-2017 cgit Development Team <cgit at lists.zx2c4.com>
>> + * Copyright (C) 2006-2018 cgit Development Team <cgit at lists.zx2c4.com>
>>    *
>>    * Licensed under GNU General Public License v2
>>    *   (see COPYING for full license text)
>> @@ -12,8 +12,10 @@
>>   #include "ui-shared.h"
>>   
>>   struct walk_tree_context {
>> +	struct object_id inline_oid;
>>   	char *curr_rev;
>>   	char *match_path;
>> +	char *inline_filename;
>>   	int state;
>>   	bool use_render;
>>   };
>> @@ -325,11 +327,19 @@ static int ls_item(const struct object_id *oid, struct strbuf *base,
>>   				&fullpath);
>>   	} else {
>>   		char *ext = strrchr(name, '.');
>> +
>>   		strbuf_addstr(&class, "ls-blob");
>>   		if (ext)
>>   			strbuf_addf(&class, " %s", ext + 1);
>> +
>>   		cgit_tree_link(name, NULL, class.buf, ctx.qry.head,
>>   			       walk_tree_ctx->curr_rev, fullpath.buf);
>> +
>> +		if (!walk_tree_ctx->inline_filename &&
>> +		    string_list_has_string(&ctx.repo->inline_readme, name)) {
>> +			walk_tree_ctx->inline_filename = xstrdup(pathname);
>> +			oidcpy(&walk_tree_ctx->inline_oid, oid);
>> +		}
>>   	}
>>   	htmlf("</td><td class='ls-size'>%li</td>", size);
>>   
>> @@ -367,7 +377,46 @@ static void ls_head(void)
>>   
>>   static void ls_tail(struct walk_tree_context *walk_tree_ctx)
>>   {
>> +	struct cgit_filter *render;
>> +	enum object_type type;
>> +	char *buf, *mimetype;
>> +	unsigned long size;
>> +
>>   	html("</table>\n");
>> +
>> +	if (!walk_tree_ctx->inline_filename)
>> +		goto done;
>> +
>> +	type = oid_object_info(the_repository, &walk_tree_ctx->inline_oid, &size);
>> +	if (type == OBJ_BAD)
>> +		goto done;
>> +
>> +	buf = read_object_file(&walk_tree_ctx->inline_oid, &type, &size);
>> +	if (!buf)
>> +		goto done;
>> +
>> +	/* create a vertical gap between tree nav / inline */
>> +	html("<table class=\"tabs\"><tr><td></td></tr></table>");
>> +
>> +	render = get_render_for_filename(walk_tree_ctx->inline_filename);
>> +	mimetype = render ? NULL : get_mimetype_for_filename(
>> +				walk_tree_ctx->inline_filename);
>> +
>> +	htmlf("<h2>%s</h2>", walk_tree_ctx->inline_filename);
>> +	html("<div class=blob>&nbsp;</div>\n");
>> +
>> +	if (render)
>> +		render_buffer(render, walk_tree_ctx->inline_filename,
>> +			      buf, size);
>> +	else if (mimetype)
>> +		include_file(walk_tree_ctx->inline_filename, mimetype);
>> +	else
>> +		print_buffer(walk_tree_ctx->inline_filename, buf, size);
>> +
>> +	free(mimetype);
>> +	free(buf);
>> +
>> +done:
>>   	cgit_print_layout_end();
>>   }
>>   
>> @@ -478,4 +527,6 @@ void cgit_print_tree(const char *rev, char *path, bool use_render)
>>   
>>   cleanup:
>>   	free(walk_tree_ctx.curr_rev);
>> +	if (walk_tree_ctx.inline_filename)
>> +		free(walk_tree_ctx.inline_filename);
>>   }
>>
>> _______________________________________________
>> CGit mailing list
>> CGit at lists.zx2c4.com
>> https://lists.zx2c4.com/mailman/listinfo/cgit


^ permalink raw reply	[flat|nested] 140+ messages in thread

* [PATCH v3 16/17] ui-shared: add helper for generating non-urlencoded links
  2018-06-19 21:55                       ` john
@ 2018-06-20  0:07                         ` andy
  0 siblings, 0 replies; 140+ messages in thread
From: andy @ 2018-06-20  0:07 UTC (permalink / raw)




On 06/20/2018 05:55 AM, John Keeping wrote:
> On Tue, Jun 19, 2018 at 05:02:47PM +0800, Andy Green wrote:
>> We are going to have to produce plain links in the next patch.
>> But depending on config, the links are not simple.
>>
>> Reproduce the logic in repolink() to generate correctly-
>> formatted links in a strbuf, without urlencoding, in a reusable
>> helper cgit_repo_create_url().
>>
>> Signed-off-by: Andy Green <andy at warmcat.com>
>> ---
>>   ui-shared.c |   30 ++++++++++++++++++++++++++++++
>>   ui-shared.h |    3 +++
>>   2 files changed, 33 insertions(+)
>>
>> diff --git a/ui-shared.c b/ui-shared.c
>> index 21bbded..79c39a8 100644
>> --- a/ui-shared.c
>> +++ b/ui-shared.c
>> @@ -221,6 +221,36 @@ void cgit_index_link(const char *name, const char *title, const char *class,
>>   	site_link(NULL, name, title, class, pattern, sort, ofs, always_root);
>>   }
>>   
>> +char *cgit_repo_create_url(struct strbuf *sb_pre, struct strbuf *sb_post,
>> +			    const char *page, const char *head, const char *path)
>> +{
>> +	const char *delim = "?";
>> +	struct strbuf *sb = sb_pre;
> 
> Does this variable serve any point?  Why not rename the parameter?

OK.

>> +
>> +	if (ctx.cfg.virtual_root)
>> +		strbuf_addf(sb_pre, "%s%s", ctx.cfg.virtual_root, ctx.repo->url);
> 
> NIT: I think we normally put the braces in around a oneline if with a
> multi-line else clause.

OK.

>> +	else {
>> +		strbuf_addstr(sb_pre, ctx.cfg.script_name);
>> +		strbuf_addf(sb_post, "?url=%s", ctx.repo->url);
>> +		sb = sb_post;
>> +		delim = "&amp;";

These shouldn't've been left urlencoded... I changed both to "&".

>> +	}
>> +
>> +	if (ctx.repo->url[strlen(ctx.repo->url) - 1] != '/')
>> +		strbuf_addch(sb, '/');
> 
> Maybe add a blank line here since these if blocks are unrelated.

OK.

>> +	if (page) {
>> +		strbuf_addf(sb, "%s/", page);
>> +		if (path)
>> +			strbuf_addstr(sb, path);
>> +	}
>> +
>> +	if (head && ctx.repo->defbranch && strcmp(head, ctx.repo->defbranch)) {
>> +		strbuf_addf(sb_post, "%sh=%s", delim, head);
>> +		delim = "&amp;";
>> +	}
>> +	return fmt("%s", delim);
> 
> delim is always a character constant, so I think we can just return it
> as "const char *" here.  This also avoids any worry about the lifetime
> of fmt()'s result.

I just copied this exit stuff from repolink... I agree return the const 
char * to rodata pointer is better.

Thanks for the review.

-Andy

>> +}
>> +
>>   static char *repolink(const char *title, const char *class, const char *page,
>>   		      const char *head, const char *path)
>>   {
>> diff --git a/ui-shared.h b/ui-shared.h
>> index c105b3b..679d2f2 100644
>> --- a/ui-shared.h
>> +++ b/ui-shared.h
>> @@ -59,6 +59,9 @@ extern void cgit_object_link(struct object *obj);
>>   
>>   extern void cgit_submodule_link(const char *class, char *path,
>>   				const char *rev);
>> +extern char *cgit_repo_create_url(struct strbuf *sb_pre, struct strbuf *sb_post,
>> +				  const char *page, const char *head,
>> +				  const char *path);
>>   
>>   extern void cgit_print_layout_start(void);
>>   extern void cgit_print_layout_end(void);


^ permalink raw reply	[flat|nested] 140+ messages in thread

* [PATCH v4 00/16] Render READMEs inline in tree view
  2018-06-13  2:01                 ` [PATCH 00/11] Render READMEs inline in tree view andy
                                     ` (12 preceding siblings ...)
  2018-06-19  9:01                   ` [PATCH v3 00/17] " andy
@ 2018-06-20 10:11                   ` andy
  2018-06-20 10:12                     ` [PATCH v4 01/16] manpage: fix sorting order andy
                                       ` (17 more replies)
  13 siblings, 18 replies; 140+ messages in thread
From: andy @ 2018-06-20 10:11 UTC (permalink / raw)


The following series adds config to allow rendering of
selected READMEs inline after the tree view, where
present in the directory being viewed.

Particularly you can use completely relative markdown to
inline pictures served from the current repo rev context,
eg,

![overview](./doc-assets/overview.png)

will "just work" showing the png from the current view
rev context; this format also works in github.

It builds on John Keeping's RENDER mode series from 2016.

Typical config to enable it, if you have a README.md
looks like

inline-readme=README.md
render.md=/usr/libexec/cgit/filters/html-converters/md2html

You can see examples of it in operation at

https://libwebsockets.org/git/libwebsockets/tree
https://libwebsockets.org/git/libwebsockets/tree/?h=v3.0-stable
https://warmcat.com/git/cgit/tree/

The expected basis these apply on top of is

 - jk/for-jason
 - ch/for-jason

You can find these patches on top of the expected basis here

https://warmcat.com/git/cgit/log/

v4 collects all the reviewed by and implements yesterday's comments
---

Andy Green (10):
      manpage: fix sorting order
      ui-tree: ls_tail: add walk table param
      config: add global inline-readme list
      config: add repo inline-readme list
      ui-tree: render any matching README file in tree view
      md2html: add asset postfix arg
      ui-shared: deduplicate some code in repolink
      ui-shared: add helper for generating non-urlencoded links
      render: adapt for providing extra filter args for plain
      md2html: change css name to not conflict with highlight

John Keeping (6):
      Use string list strdup_strings for mimetypes
      Add source page
      Parse render filters from the config
      ui-tree: split out buffer printing
      ui-tree: use render filters to display content
      md2html: add asset mapping


 cgit.c                          |   35 +++++-
 cgit.css                        |    5 +
 cgit.h                          |    6 +
 cgitrc.5.txt                    |  221 +++++++++++++++++++++++----------------
 cmd.c                           |    8 +
 filter.c                        |    4 +
 filters/html-converters/md2html |   61 ++++++++++-
 shared.c                        |   21 ++++
 ui-shared.c                     |   72 ++++++++++---
 ui-shared.h                     |    6 +
 ui-tree.c                       |  193 +++++++++++++++++++++++++++++++---
 ui-tree.h                       |    2 
 12 files changed, 498 insertions(+), 136 deletions(-)

--
Signature


^ permalink raw reply	[flat|nested] 140+ messages in thread

* [PATCH v4 01/16] manpage: fix sorting order
  2018-06-20 10:11                   ` [PATCH v4 00/16] Render READMEs inline in tree view andy
@ 2018-06-20 10:12                     ` andy
  2018-06-27 17:27                       ` Jason
  2018-06-20 10:12                     ` [PATCH v4 02/16] Use string list strdup_strings for mimetypes andy
                                       ` (16 subsequent siblings)
  17 siblings, 1 reply; 140+ messages in thread
From: andy @ 2018-06-20 10:12 UTC (permalink / raw)


You maybe didn't know you had OCD until you saw an
alpha sorted list that has stuff out of order in it.

Signed-off-by: Andy Green <andy at warmcat.com>
Reviewed-by: John Keeping <john at keeping.me.uk>
---
 cgitrc.5.txt |  176 +++++++++++++++++++++++++++++-----------------------------
 1 file changed, 88 insertions(+), 88 deletions(-)

diff --git a/cgitrc.5.txt b/cgitrc.5.txt
index acfae91..f6f6502 100644
--- a/cgitrc.5.txt
+++ b/cgitrc.5.txt
@@ -54,14 +54,10 @@ branch-sort::
 	list, and when set to "name" enables ordering by branch name. Default
 	value: "name".
 
-cache-root::
-	Path used to store the cgit cache entries. Default value:
-	"/var/cache/cgit". See also: "MACRO EXPANSION".
-
-cache-static-ttl::
+cache-about-ttl::
 	Number which specifies the time-to-live, in minutes, for the cached
-	version of repository pages accessed with a fixed SHA1. See also:
-	"CACHE". Default value: -1".
+	version of the repository about page. See also: "CACHE". Default
+	value: "15".
 
 cache-dynamic-ttl::
 	Number which specifies the time-to-live, in minutes, for the cached
@@ -73,6 +69,10 @@ cache-repo-ttl::
 	version of the repository summary page. See also: "CACHE". Default
 	value: "5".
 
+cache-root::
+	Path used to store the cgit cache entries. Default value:
+	"/var/cache/cgit". See also: "MACRO EXPANSION".
+
 cache-root-ttl::
 	Number which specifies the time-to-live, in minutes, for the cached
 	version of the repository index page. See also: "CACHE". Default
@@ -83,22 +83,22 @@ cache-scanrc-ttl::
 	of scanning a path for git repositories. See also: "CACHE". Default
 	value: "15".
 
-cache-about-ttl::
-	Number which specifies the time-to-live, in minutes, for the cached
-	version of the repository about page. See also: "CACHE". Default
-	value: "15".
-
-cache-snapshot-ttl::
-	Number which specifies the time-to-live, in minutes, for the cached
-	version of snapshots. See also: "CACHE". Default value: "5".
+case-sensitive-sort::
+	Sort items in the repo list case sensitively. Default value: "1".
+	See also: repository-sort, section-sort.
 
 cache-size::
 	The maximum number of entries in the cgit cache. When set to "0",
 	caching is disabled. See also: "CACHE". Default value: "0"
 
-case-sensitive-sort::
-	Sort items in the repo list case sensitively. Default value: "1".
-	See also: repository-sort, section-sort.
+cache-snapshot-ttl::
+	Number which specifies the time-to-live, in minutes, for the cached
+	version of snapshots. See also: "CACHE". Default value: "5".
+
+cache-static-ttl::
+	Number which specifies the time-to-live, in minutes, for the cached
+	version of repository pages accessed with a fixed SHA1. See also:
+	"CACHE". Default value: -1".
 
 clone-prefix::
 	Space-separated list of common prefixes which, when combined with a
@@ -159,12 +159,29 @@ enable-follow-links::
 	Flag which, when set to "1", allows users to follow a file in the log
 	view.  Default value: "0".
 
+enable-git-config::
+	Flag which, when set to "1", will allow cgit to use git config to set
+	any repo specific settings. This option is used in conjunction with
+	"scan-path", and must be defined prior, to augment repo-specific
+	settings. The keys gitweb.owner, gitweb.category, gitweb.description,
+	and gitweb.homepage will map to the cgit keys repo.owner, repo.section,
+	repo.desc, and repo.homepage respectively. All git config keys that begin
+	with "cgit." will be mapped to the corresponding "repo." key in cgit.
+	Default value: "0". See also: scan-path, section-from-path.
+
 enable-http-clone::
-	If set to "1", cgit will act as an dumb HTTP endpoint for git clones.
+	If set to "1", cgit will act as a dumb HTTP endpoint for git clones.
 	You can add "http://$HTTP_HOST$SCRIPT_NAME/$CGIT_REPO_URL" to clone-url
 	to expose this feature. If you use an alternate way of serving git
 	repositories, you may wish to disable this. Default value: "1".
 
+enable-html-serving::
+	Flag which, when set to "1", will allow the /plain handler to serve
+	mimetype headers that result in the file being treated as HTML by the
+	browser. When set to "0", such file types are returned instead as
+	text/plain or application/octet-stream. Default value: "0". See also:
+	"repo.enable-html-serving".
+
 enable-index-links::
 	Flag which, when set to "1", will make cgit generate extra links for
 	each repo in the repository index (specifically, to the "summary",
@@ -195,27 +212,10 @@ enable-subject-links::
 	in commit view. Default value: "0". See also:
 	"repo.enable-subject-links".
 
-enable-html-serving::
-	Flag which, when set to "1", will allow the /plain handler to serve
-	mimetype headers that result in the file being treated as HTML by the
-	browser. When set to "0", such file types are returned instead as
-	text/plain or application/octet-stream. Default value: "0". See also:
-	"repo.enable-html-serving".
-
 enable-tree-linenumbers::
 	Flag which, when set to "1", will make cgit generate linenumber links
 	for plaintext blobs printed in the tree view. Default value: "1".
 
-enable-git-config::
-	Flag which, when set to "1", will allow cgit to use git config to set
-	any repo specific settings. This option is used in conjunction with
-	"scan-path", and must be defined prior, to augment repo-specific
-	settings. The keys gitweb.owner, gitweb.category, gitweb.description,
-	and gitweb.homepage will map to the cgit keys repo.owner, repo.section,
-	repo.desc, and repo.homepage respectively. All git config keys that begin
-	with "cgit." will be mapped to the corresponding "repo." key in cgit.
-	Default value: "0". See also: scan-path, section-from-path.
-
 favicon::
 	Url used as link to a shortcut icon for cgit. It is suggested to use
 	the value "/favicon.ico" since certain browsers will ignore other
@@ -251,19 +251,14 @@ logo-link::
 	calculated url of the repository index page will be used. Default
 	value: none.
 
-owner-filter::
-	Specifies a command which will be invoked to format the Owner
-	column of the main page.  The command will get the owner on STDIN,
-	and the STDOUT from the command will be included verbatim in the
-	table.  This can be used to link to additional context such as an
-	owners home page.  When active this filter is used instead of the
-	default owner query url.  Default value: none.
-	See also: "FILTER API".
-
 max-atom-items::
 	Specifies the number of items to display in atom feeds view. Default
 	value: "10".
 
+max-blob-size::
+	Specifies the maximum size of a blob to display HTML for in KBytes.
+	Default value: "0" (limit disabled).
+
 max-commit-count::
 	Specifies the number of entries to list per page in "log" view. Default
 	value: "50".
@@ -280,10 +275,6 @@ max-repodesc-length::
 	Specifies the maximum number of repo description characters to display
 	on the repository index page. Default value: "80".
 
-max-blob-size::
-	Specifies the maximum size of a blob to display HTML for in KBytes.
-	Default value: "0" (limit disabled).
-
 max-stats::
 	Set the default maximum statistics period. Valid values are "week",
 	"month", "quarter" and "year". If unspecified, statistics are
@@ -319,6 +310,15 @@ noheader::
 	Flag which, when set to "1", will make cgit omit the standard header
 	on all pages. Default value: none. See also: "embedded".
 
+owner-filter::
+	Specifies a command which will be invoked to format the Owner
+	column of the main page.  The command will get the owner on STDIN,
+	and the STDOUT from the command will be included verbatim in the
+	table.  This can be used to link to additional context such as an
+	owners home page.  When active this filter is used instead of the
+	default owner query url.  Default value: none.
+	See also: "FILTER API".
+
 project-list::
 	A list of subdirectories inside of scan-path, relative to it, that
 	should loaded as git repositories. This must be defined prior to
@@ -481,9 +481,6 @@ repo.defbranch::
 repo.desc::
 	The value to show as repository description. Default value: none.
 
-repo.homepage::
-	The value to show as repository homepage. Default value: none.
-
 repo.email-filter::
 	Override the default email-filter. Default value: none. See also:
 	"enable-filter-overrides". See also: "FILTER API".
@@ -492,6 +489,10 @@ repo.enable-commit-graph::
 	A flag which can be used to disable the global setting
 	`enable-commit-graph'. Default value: none.
 
+repo.enable-html-serving::
+	A flag which can be used to override the global setting
+	`enable-html-serving`. Default value: none.
+
 repo.enable-log-filecount::
 	A flag which can be used to disable the global setting
 	`enable-log-filecount'. Default value: none.
@@ -508,15 +509,14 @@ repo.enable-subject-links::
 	A flag which can be used to override the global setting
 	`enable-subject-links'. Default value: none.
 
-repo.enable-html-serving::
-	A flag which can be used to override the global setting
-	`enable-html-serving`. Default value: none.
-
 repo.hide::
 	Flag which, when set to "1", hides the repository from the repository
 	index. The repository can still be accessed by providing a direct path.
 	Default value: "0". See also: "repo.ignore".
 
+repo.homepage::
+	The value to show as repository homepage. Default value: none.
+
 repo.ignore::
 	Flag which, when set to "1", ignores the repository. The repository
 	is not shown in the index and cannot be accessed by providing a direct
@@ -531,10 +531,6 @@ repo.logo-link::
 	calculated url of the repository index page will be used. Default
 	value: global logo-link.
 
-repo.owner-filter::
-	Override the default owner-filter. Default value: none. See also:
-	"enable-filter-overrides". See also: "FILTER API".
-
 repo.module-link::
 	Text which will be used as the formatstring for a hyperlink when a
 	submodule is printed in a directory listing. The arguments for the
@@ -559,6 +555,10 @@ repo.owner::
 	A value used to identify the owner of the repository. Default value:
 	none.
 
+repo.owner-filter::
+	Override the default owner-filter. Default value: none. See also:
+	"enable-filter-overrides". See also: "FILTER API".
+
 repo.path::
 	An absolute path to the repository directory. For non-bare repositories
 	this is the .git-directory. Default value: none.
@@ -574,6 +574,10 @@ repo.readme::
 	are no non-public files located in the same directory as the readme
 	file. Default value: <readme>.
 
+repo.section::
+	Override the current section name for this repository. Default value:
+	none.
+
 repo.snapshots::
 	A mask of snapshot formats for this repo that cgit generates links for,
 	restricted by the global "snapshots" setting. Default value:
@@ -586,10 +590,6 @@ repo.snapshot-prefix::
 	of "linux-stable-3.15.4".  Default value: <empty> meaning to use
 	the repository basename.
 
-repo.section::
-	Override the current section name for this repository. Default value:
-	none.
-
 repo.source-filter::
 	Override the default source-filter. Default value: none. See also:
 	"enable-filter-overrides". See also: "FILTER API".
@@ -662,30 +662,6 @@ about filter::
 	The about text that is to be filtered is available on standard input
 	and the filtered text is expected on standard output.
 
-commit filter::
-	This filter is given no arguments. The commit message text that is to
-	be filtered is available on standard input and the filtered text is
-	expected on standard output.
-
-email filter::
-	This filter is given two parameters: the email address of the relevant
-	author and a string indicating the originating page. The filter will
-	then receive the text string to format on standard input and is
-	expected to write to standard output the formatted text to be included
-	in the page.
-
-owner filter::
-	This filter is given no arguments.  The owner text is available on
-	standard input and the filter is expected to write to standard
-	output.  The output is included in the Owner column.
-
-source filter::
-	This filter is given a single parameter: the filename of the source
-	file to filter. The filter can use the filename to determine (for
-	example) the syntax highlighting mode. The contents of the source
-	file that is to be filtered is available on standard input and the
-	filtered contents is expected on standard output.
-
 auth filter::
 	The authentication filter receives 12 parameters:
 	  - filter action, explained below, which specifies which action the
@@ -712,6 +688,30 @@ auth filter::
 	Please see `filters/simple-authentication.lua` for a clear example
 	script that may be modified.
 
+commit filter::
+	This filter is given no arguments. The commit message text that is to
+	be filtered is available on standard input and the filtered text is
+	expected on standard output.
+
+email filter::
+	This filter is given two parameters: the email address of the relevant
+	author and a string indicating the originating page. The filter will
+	then receive the text string to format on standard input and is
+	expected to write to standard output the formatted text to be included
+	in the page.
+
+owner filter::
+	This filter is given no arguments.  The owner text is available on
+	standard input and the filter is expected to write to standard
+	output.  The output is included in the Owner column.
+
+source filter::
+	This filter is given a single parameter: the filename of the source
+	file to filter. The filter can use the filename to determine (for
+	example) the syntax highlighting mode. The contents of the source
+	file that is to be filtered is available on standard input and the
+	filtered contents is expected on standard output.
+
 
 All filters are handed the following environment variables:
 



^ permalink raw reply	[flat|nested] 140+ messages in thread

* [PATCH v4 02/16] Use string list strdup_strings for mimetypes
  2018-06-20 10:11                   ` [PATCH v4 00/16] Render READMEs inline in tree view andy
  2018-06-20 10:12                     ` [PATCH v4 01/16] manpage: fix sorting order andy
@ 2018-06-20 10:12                     ` andy
  2018-06-27 17:28                       ` Jason
  2018-06-20 10:12                     ` [PATCH v4 03/16] Add source page andy
                                       ` (15 subsequent siblings)
  17 siblings, 1 reply; 140+ messages in thread
From: andy @ 2018-06-20 10:12 UTC (permalink / raw)


From: John Keeping <john at keeping.me.uk>

There's no need to do this manually with the string list API will do it
for us.

Signed-off-by: John Keeping <john at keeping.me.uk>
---
 cgit.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/cgit.c b/cgit.c
index 223dfc8..0c9f3e9 100644
--- a/cgit.c
+++ b/cgit.c
@@ -23,7 +23,7 @@ static void add_mimetype(const char *name, const char *value)
 {
 	struct string_list_item *item;
 
-	item = string_list_insert(&ctx.cfg.mimetypes, xstrdup(name));
+	item = string_list_insert(&ctx.cfg.mimetypes, name);
 	item->util = xstrdup(value);
 }
 
@@ -414,7 +414,7 @@ static void prepare_context(void)
 	ctx.page.modified = time(NULL);
 	ctx.page.expires = ctx.page.modified;
 	ctx.page.etag = NULL;
-	memset(&ctx.cfg.mimetypes, 0, sizeof(struct string_list));
+	string_list_init(&ctx.cfg.mimetypes, 1);
 	if (ctx.env.script_name)
 		ctx.cfg.script_name = xstrdup(ctx.env.script_name);
 	if (ctx.env.query_string)



^ permalink raw reply	[flat|nested] 140+ messages in thread

* [PATCH v4 03/16] Add source page
  2018-06-20 10:11                   ` [PATCH v4 00/16] Render READMEs inline in tree view andy
  2018-06-20 10:12                     ` [PATCH v4 01/16] manpage: fix sorting order andy
  2018-06-20 10:12                     ` [PATCH v4 02/16] Use string list strdup_strings for mimetypes andy
@ 2018-06-20 10:12                     ` andy
  2018-06-20 10:12                     ` [PATCH v4 04/16] Parse render filters from the config andy
                                       ` (14 subsequent siblings)
  17 siblings, 0 replies; 140+ messages in thread
From: andy @ 2018-06-20 10:12 UTC (permalink / raw)


From: John Keeping <john at keeping.me.uk>

We are about to introduce rendering of content for the tree view.  This
source page will allow bypassing the renderer and accessing the content
of the current tree view.

Signed-off-by: John Keeping <john at keeping.me.uk>
---
 cmd.c       |    6 ++++++
 ui-shared.c |   14 ++++++++++++++
 ui-shared.h |    3 +++
 3 files changed, 23 insertions(+)

diff --git a/cmd.c b/cmd.c
index 63f0ae5..56e21df 100644
--- a/cmd.c
+++ b/cmd.c
@@ -138,6 +138,11 @@ static void refs_fn(void)
 	cgit_print_refs();
 }
 
+static void source_fn(void)
+{
+	cgit_print_tree(ctx.qry.sha1, ctx.qry.path);
+}
+
 static void snapshot_fn(void)
 {
 	cgit_print_snapshot(ctx.qry.head, ctx.qry.sha1, ctx.qry.path,
@@ -187,6 +192,7 @@ struct cgit_cmd *cgit_get_cmd(void)
 		def_cmd(refs, 1, 0, 0),
 		def_cmd(repolist, 0, 0, 0),
 		def_cmd(snapshot, 1, 0, 0),
+		def_cmd(source, 1, 1, 0),
 		def_cmd(stats, 1, 1, 0),
 		def_cmd(summary, 1, 0, 0),
 		def_cmd(tag, 1, 0, 0),
diff --git a/ui-shared.c b/ui-shared.c
index ba88106..d2985c8 100644
--- a/ui-shared.c
+++ b/ui-shared.c
@@ -307,6 +307,12 @@ void cgit_tree_link(const char *name, const char *title, const char *class,
 	reporevlink("tree", name, title, class, head, rev, path);
 }
 
+void cgit_source_link(const char *name, const char *title, const char *class,
+		    const char *head, const char *rev, const char *path)
+{
+	reporevlink("source", name, title, class, head, rev, path);
+}
+
 void cgit_plain_link(const char *name, const char *title, const char *class,
 		     const char *head, const char *rev, const char *path)
 {
@@ -489,6 +495,10 @@ static void cgit_self_link(char *name, const char *title, const char *class)
 		cgit_tree_link(name, title, class, ctx.qry.head,
 			       ctx.qry.has_sha1 ? ctx.qry.sha1 : NULL,
 			       ctx.qry.path);
+	else if (!strcmp(ctx.qry.page, "source"))
+		cgit_source_link(name, title, class, ctx.qry.head,
+				 ctx.qry.has_sha1 ? ctx.qry.sha1 : NULL,
+				 ctx.qry.path);
 	else if (!strcmp(ctx.qry.page, "plain"))
 		cgit_plain_link(name, title, class, ctx.qry.head,
 				ctx.qry.has_sha1 ? ctx.qry.sha1 : NULL,
@@ -1003,6 +1013,10 @@ void cgit_print_pageheader(void)
 		if (ctx.qry.page && !strcmp(ctx.qry.page, "blame"))
 			cgit_blame_link("blame", NULL, hc("blame"), ctx.qry.head,
 				        ctx.qry.sha1, ctx.qry.vpath);
+		else if (ctx.qry.page && !strcmp(ctx.qry.page, "source"))
+			cgit_source_link("tree", NULL, hc("source"),
+					 ctx.qry.head, ctx.qry.sha1,
+					 ctx.qry.vpath);
 		else
 			cgit_tree_link("tree", NULL, hc("tree"), ctx.qry.head,
 				       ctx.qry.sha1, ctx.qry.vpath);
diff --git a/ui-shared.h b/ui-shared.h
index 4d5978b..c105b3b 100644
--- a/ui-shared.h
+++ b/ui-shared.h
@@ -23,6 +23,9 @@ extern void cgit_tag_link(const char *name, const char *title,
 extern void cgit_tree_link(const char *name, const char *title,
 			   const char *class, const char *head,
 			   const char *rev, const char *path);
+extern void cgit_source_link(const char *name, const char *title,
+			     const char *class, const char *head,
+			     const char *rev, const char *path);
 extern void cgit_plain_link(const char *name, const char *title,
 			    const char *class, const char *head,
 			    const char *rev, const char *path);



^ permalink raw reply	[flat|nested] 140+ messages in thread

* [PATCH v4 04/16] Parse render filters from the config
  2018-06-20 10:11                   ` [PATCH v4 00/16] Render READMEs inline in tree view andy
                                       ` (2 preceding siblings ...)
  2018-06-20 10:12                     ` [PATCH v4 03/16] Add source page andy
@ 2018-06-20 10:12                     ` andy
  2018-06-20 10:12                     ` [PATCH v4 05/16] ui-tree: split out buffer printing andy
                                       ` (13 subsequent siblings)
  17 siblings, 0 replies; 140+ messages in thread
From: andy @ 2018-06-20 10:12 UTC (permalink / raw)


From: John Keeping <john at keeping.me.uk>

Render filters will be used to present rendered content in the tree
view, for example to display Markdown source rendered as HTML.

We will add support for using these from the tree view in the following
commits.

AG: adapted so render.= can be used to specify the filter for files
without any suffix

Signed-off-by: John Keeping <john at keeping.me.uk>
Signed-off-by: Andy Green <andy at warmcat.com>
Reviewed-by: John Keeping <john at keeping.me.uk>
---
 cgit.c       |   19 +++++++++++++++++--
 cgit.h       |    4 +++-
 cgitrc.5.txt |   19 +++++++++++++++++++
 filter.c     |    1 +
 shared.c     |   19 +++++++++++++++++++
 5 files changed, 59 insertions(+), 3 deletions(-)

diff --git a/cgit.c b/cgit.c
index 0c9f3e9..e0e94d5 100644
--- a/cgit.c
+++ b/cgit.c
@@ -27,6 +27,18 @@ static void add_mimetype(const char *name, const char *value)
 	item->util = xstrdup(value);
 }
 
+static void add_render_filter(const char *name, const char *cmd)
+{
+	struct string_list_item *item;
+	struct cgit_filter *filter = cgit_new_filter(cmd, RENDER);
+
+	if (!filter)
+		return;
+
+	item = string_list_insert(&ctx.cfg.render_filters, name);
+	item->util = filter;
+}
+
 static void process_cached_repolist(const char *path);
 
 static void repo_config(struct cgit_repo *repo, const char *name, const char *value)
@@ -281,8 +293,10 @@ static void config_cb(const char *name, const char *value)
 			ctx.cfg.branch_sort = 1;
 		if (!strcmp(value, "name"))
 			ctx.cfg.branch_sort = 0;
-	} else if (skip_prefix(name, "mimetype.", &arg))
-		add_mimetype(arg, value);
+	} else if (starts_with(name, "mimetype."))
+		add_mimetype(name + 9, value);
+	else if (starts_with(name, "render."))
+		add_render_filter(name + 7, value);
 	else if (!strcmp(name, "include"))
 		parse_configfile(expand_macros(value), config_cb);
 }
@@ -415,6 +429,7 @@ static void prepare_context(void)
 	ctx.page.expires = ctx.page.modified;
 	ctx.page.etag = NULL;
 	string_list_init(&ctx.cfg.mimetypes, 1);
+	string_list_init(&ctx.cfg.render_filters, 1);
 	if (ctx.env.script_name)
 		ctx.cfg.script_name = xstrdup(ctx.env.script_name);
 	if (ctx.env.query_string)
diff --git a/cgit.h b/cgit.h
index 6feca68..3149946 100644
--- a/cgit.h
+++ b/cgit.h
@@ -57,7 +57,7 @@ typedef enum {
 } diff_type;
 
 typedef enum {
-	ABOUT, COMMIT, SOURCE, EMAIL, AUTH, OWNER
+	ABOUT, COMMIT, SOURCE, EMAIL, AUTH, OWNER, RENDER
 } filter_type;
 
 struct cgit_filter {
@@ -261,6 +261,7 @@ struct cgit_config {
 	int branch_sort;
 	int commit_sort;
 	struct string_list mimetypes;
+	struct string_list render_filters;
 	struct cgit_filter *about_filter;
 	struct cgit_filter *commit_filter;
 	struct cgit_filter *source_filter;
@@ -391,5 +392,6 @@ extern int readfile(const char *path, char **buf, size_t *size);
 extern char *expand_macros(const char *txt);
 
 extern char *get_mimetype_for_filename(const char *filename);
+extern struct cgit_filter *get_render_for_filename(const char *filename);
 
 #endif /* CGIT_H */
diff --git a/cgitrc.5.txt b/cgitrc.5.txt
index f6f6502..34b6186 100644
--- a/cgitrc.5.txt
+++ b/cgitrc.5.txt
@@ -342,6 +342,18 @@ renamelimit::
 	 "-1" uses the compiletime value in git (for further info, look at
 	  `man git-diff`). Default value: "-1".
 
+render.<ext>::
+	Specifies a command which will be invoked to render files with the
+	extension `.<ext>`. The command will get the blob content on its STDIN
+	and the name of the blob as its only command line argument. The STDOUT
+	from the command will be included verbatim in the page content. If no
+	render filter is available for a given file extension but the mimetype
+	is specified then the content will be included as an iframe, otherwise
+	the normal source rendering will be used.  Note <ext> may be empty, in
+	which case the render filter is used on files with no suffix.
++
+Default value: none. See also: "FILTER API".
+
 repository-sort::
 	The way in which repositories in each section are sorted. Valid values
 	are "name" for sorting by the repo name or "age" for sorting by the
@@ -705,6 +717,13 @@ owner filter::
 	standard input and the filter is expected to write to standard
 	output.  The output is included in the Owner column.
 
+render filter::
+	This filter is given a single parameter: the filename of the source
+	file to render. The filter can use the filename to determine (for
+	example) the syntax highlighting mode. The contents of the file that
+	is to be rendered is available on standard input and the rendered
+	content is expected on standard output.
+
 source filter::
 	This filter is given a single parameter: the filename of the source
 	file to filter. The filter can use the filename to determine (for
diff --git a/filter.c b/filter.c
index 70f5b74..4ae4aaa 100644
--- a/filter.c
+++ b/filter.c
@@ -434,6 +434,7 @@ struct cgit_filter *cgit_new_filter(const char *cmd, filter_type filtertype)
 
 		case SOURCE:
 		case ABOUT:
+		case RENDER:
 			argument_count = 1;
 			break;
 
diff --git a/shared.c b/shared.c
index d7c7636..665f8ed 100644
--- a/shared.c
+++ b/shared.c
@@ -574,3 +574,22 @@ char *get_mimetype_for_filename(const char *filename)
 	fclose(file);
 	return NULL;
 }
+
+struct cgit_filter *get_render_for_filename(const char *filename)
+{
+	char *ext;
+	struct string_list_item *item;
+
+	if (!filename)
+		return NULL;
+
+	ext = strrchr(filename, '.');
+	if (!ext)
+		ext = ".";
+	++ext;
+	item = string_list_lookup(&ctx.cfg.render_filters, ext);
+	if (item)
+		return item->util;
+
+	return NULL;
+}



^ permalink raw reply	[flat|nested] 140+ messages in thread

* [PATCH v4 05/16] ui-tree: split out buffer printing
  2018-06-20 10:11                   ` [PATCH v4 00/16] Render READMEs inline in tree view andy
                                       ` (3 preceding siblings ...)
  2018-06-20 10:12                     ` [PATCH v4 04/16] Parse render filters from the config andy
@ 2018-06-20 10:12                     ` andy
  2018-06-20 10:12                     ` [PATCH v4 06/16] ui-tree: use render filters to display content andy
                                       ` (12 subsequent siblings)
  17 siblings, 0 replies; 140+ messages in thread
From: andy @ 2018-06-20 10:12 UTC (permalink / raw)


From: John Keeping <john at keeping.me.uk>

Signed-off-by: John Keeping <john at keeping.me.uk>
---
 ui-tree.c |   25 +++++++++++++++----------
 1 file changed, 15 insertions(+), 10 deletions(-)

diff --git a/ui-tree.c b/ui-tree.c
index e6b3074..d26e35e 100644
--- a/ui-tree.c
+++ b/ui-tree.c
@@ -84,6 +84,20 @@ static void print_binary_buffer(char *buf, unsigned long size)
 	html("</table>\n");
 }
 
+static void print_buffer(const char *basename, char *buf, unsigned long size)
+{
+	if (ctx.cfg.max_blob_size && size / 1024 > ctx.cfg.max_blob_size) {
+		htmlf("<div class='error'>blob size (%ldKB) exceeds display size limit (%dKB).</div>",
+				size / 1024, ctx.cfg.max_blob_size);
+		return;
+	}
+
+	if (buffer_is_binary(buf, size))
+		print_binary_buffer(buf, size);
+	else
+		print_text_buffer(basename, buf, size);
+}
+
 static void print_object(const struct object_id *oid, char *path, const char *basename, const char *rev)
 {
 	enum object_type type;
@@ -117,16 +131,7 @@ static void print_object(const struct object_id *oid, char *path, const char *ba
 	}
 	html(")\n");
 
-	if (ctx.cfg.max_blob_size && size / 1024 > ctx.cfg.max_blob_size) {
-		htmlf("<div class='error'>blob size (%ldKB) exceeds display size limit (%dKB).</div>",
-				size / 1024, ctx.cfg.max_blob_size);
-		return;
-	}
-
-	if (buffer_is_binary(buf, size))
-		print_binary_buffer(buf, size);
-	else
-		print_text_buffer(basename, buf, size);
+	print_buffer(basename, buf, size);
 
 	free(buf);
 }



^ permalink raw reply	[flat|nested] 140+ messages in thread

* [PATCH v4 06/16] ui-tree: use render filters to display content
  2018-06-20 10:11                   ` [PATCH v4 00/16] Render READMEs inline in tree view andy
                                       ` (4 preceding siblings ...)
  2018-06-20 10:12                     ` [PATCH v4 05/16] ui-tree: split out buffer printing andy
@ 2018-06-20 10:12                     ` andy
  2018-06-20 10:12                     ` [PATCH v4 07/16] ui-tree: ls_tail: add walk table param andy
                                       ` (11 subsequent siblings)
  17 siblings, 0 replies; 140+ messages in thread
From: andy @ 2018-06-20 10:12 UTC (permalink / raw)


From: John Keeping <john at keeping.me.uk>

This allows applying filters to files in the repository, for example to
render Markdown or AsciiDoc as HTML.

Signed-off-by: John Keeping <john at keeping.me.uk>
---
 cgit.css  |    5 +++
 cmd.c     |    4 +-
 ui-tree.c |  104 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++----
 ui-tree.h |    2 +
 4 files changed, 105 insertions(+), 10 deletions(-)

diff --git a/cgit.css b/cgit.css
index 43f6a5a..61bbd49 100644
--- a/cgit.css
+++ b/cgit.css
@@ -274,6 +274,11 @@ div#cgit div#blob {
 	border: solid 1px black;
 }
 
+div#cgit iframe {
+	width: 100%;
+	height: 40em;
+}
+
 div#cgit div.error {
 	color: red;
 	font-weight: bold;
diff --git a/cmd.c b/cmd.c
index 56e21df..ca48b2f 100644
--- a/cmd.c
+++ b/cmd.c
@@ -140,7 +140,7 @@ static void refs_fn(void)
 
 static void source_fn(void)
 {
-	cgit_print_tree(ctx.qry.sha1, ctx.qry.path);
+	cgit_print_tree(ctx.qry.sha1, ctx.qry.path, false);
 }
 
 static void snapshot_fn(void)
@@ -166,7 +166,7 @@ static void tag_fn(void)
 
 static void tree_fn(void)
 {
-	cgit_print_tree(ctx.qry.sha1, ctx.qry.path);
+	cgit_print_tree(ctx.qry.sha1, ctx.qry.path, true);
 }
 
 #define def_cmd(name, want_repo, want_vpath, is_clone) \
diff --git a/ui-tree.c b/ui-tree.c
index d26e35e..721c812 100644
--- a/ui-tree.c
+++ b/ui-tree.c
@@ -15,6 +15,7 @@ struct walk_tree_context {
 	char *curr_rev;
 	char *match_path;
 	int state;
+	bool use_render;
 };
 
 static void print_text_buffer(const char *name, char *buf, unsigned long size)
@@ -98,10 +99,69 @@ static void print_buffer(const char *basename, char *buf, unsigned long size)
 		print_text_buffer(basename, buf, size);
 }
 
-static void print_object(const struct object_id *oid, char *path, const char *basename, const char *rev)
+static void render_buffer(struct cgit_filter *render, const char *name,
+		char *buf, unsigned long size)
+{
+	char *filter_arg = xstrdup(name);
+
+	html("<div class='blob'>");
+	cgit_open_filter(render, filter_arg);
+	html_raw(buf, size);
+	cgit_close_filter(render);
+	html("</div>");
+
+	free(filter_arg);
+}
+
+static void include_file(const char *path, const char *mimetype)
+{
+	const char *delim = "?";
+
+	html("<div class='blob'>");
+
+	if (!strncmp(mimetype, "image/", 6)) {
+		html("<img alt='");
+		html_attr(path);
+		html("' src='");
+	} else {
+		html("<iframe sandbox='allow-scripts' src='");
+	}
+
+	if (ctx.cfg.virtual_root) {
+		html_url_path(ctx.cfg.virtual_root);
+		html_url_path(ctx.repo->url);
+		if (ctx.repo->url[strlen(ctx.repo->url) - 1] != '/')
+			html("/");
+		html("plain/");
+		html_url_path(path);
+	} else {
+		html_url_path(ctx.cfg.script_name);
+		html("?url=");
+		html_url_arg(ctx.repo->url);
+		if (ctx.repo->url[strlen(ctx.repo->url) - 1] != '/')
+			html("/");
+		html("plain/");
+		if (path)
+			html_url_arg(path);
+		delim = "&";
+	}
+	if (ctx.qry.head && ctx.repo->defbranch &&
+	    strcmp(ctx.qry.head, ctx.repo->defbranch)) {
+		html(delim);
+		html("h=");
+		html_url_arg(ctx.qry.head);
+		delim = "&";
+	}
+
+	html("'></div>");
+}
+
+static void print_object(const struct object_id *oid, char *path, const char *basename,
+			 const char *rev, bool use_render)
 {
 	enum object_type type;
-	char *buf;
+	struct cgit_filter *render;
+	char *buf, *mimetype;
 	unsigned long size;
 
 	type = oid_object_info(the_repository, oid, &size);
@@ -118,22 +178,49 @@ static void print_object(const struct object_id *oid, char *path, const char *ba
 		return;
 	}
 
+	render = get_render_for_filename(path);
+	mimetype = render ? NULL : get_mimetype_for_filename(path);
+
 	cgit_set_title_from_path(path);
 
+	/*
+	 * If we don't have a render filter or a mimetype, we won't include the
+	 * file in the page.
+	 */
+	if (!render && !mimetype)
+		use_render = false;
+
 	cgit_print_layout_start();
 	htmlf("blob: %s (", oid_to_hex(oid));
 	cgit_plain_link("plain", NULL, NULL, ctx.qry.head,
 		        rev, path);
+
 	if (ctx.cfg.enable_blame) {
 		html(") (");
 		cgit_blame_link("blame", NULL, NULL, ctx.qry.head,
 			        rev, path);
 	}
+	if (use_render) {
+		html(", ");
+		cgit_source_link("source", NULL, NULL, ctx.qry.head,
+				rev, path);
+	} else if (render || mimetype) {
+		html(", ");
+		cgit_tree_link("render", NULL, NULL, ctx.qry.head,
+			       rev, path);
+	}
 	html(")\n");
 
-	print_buffer(basename, buf, size);
-
+	if (use_render) {
+		if (render)
+			render_buffer(render, basename, buf, size);
+		else
+			include_file(path, mimetype);
+	} else
+		print_buffer(basename, buf, size);
+ 
 	free(buf);
+	free(mimetype);
 }
 
 struct single_tree_ctx {
@@ -325,8 +412,10 @@ static int walk_tree(const struct object_id *oid, struct strbuf *base,
 			return READ_TREE_RECURSIVE;
 		} else {
 			walk_tree_ctx->state = 2;
-			print_object(oid, buffer.buf, pathname, walk_tree_ctx->curr_rev);
+			print_object(oid, buffer.buf, pathname, walk_tree_ctx->curr_rev,
+				     walk_tree_ctx->use_render);
 			strbuf_release(&buffer);
+
 			return 0;
 		}
 	}
@@ -339,7 +428,7 @@ static int walk_tree(const struct object_id *oid, struct strbuf *base,
  *   rev:  the commit pointing at the root tree object
  *   path: path to tree or blob
  */
-void cgit_print_tree(const char *rev, char *path)
+void cgit_print_tree(const char *rev, char *path, bool use_render)
 {
 	struct object_id oid;
 	struct commit *commit;
@@ -353,7 +442,8 @@ void cgit_print_tree(const char *rev, char *path)
 	};
 	struct walk_tree_context walk_tree_ctx = {
 		.match_path = path,
-		.state = 0
+		.state = 0,
+		.use_render = use_render,
 	};
 
 	if (!rev)
diff --git a/ui-tree.h b/ui-tree.h
index bbd34e3..a0fc8e2 100644
--- a/ui-tree.h
+++ b/ui-tree.h
@@ -1,6 +1,6 @@
 #ifndef UI_TREE_H
 #define UI_TREE_H
 
-extern void cgit_print_tree(const char *rev, char *path);
+extern void cgit_print_tree(const char *rev, char *path, bool use_render);
 
 #endif /* UI_TREE_H */



^ permalink raw reply	[flat|nested] 140+ messages in thread

* [PATCH v4 07/16] ui-tree: ls_tail: add walk table param
  2018-06-20 10:11                   ` [PATCH v4 00/16] Render READMEs inline in tree view andy
                                       ` (5 preceding siblings ...)
  2018-06-20 10:12                     ` [PATCH v4 06/16] ui-tree: use render filters to display content andy
@ 2018-06-20 10:12                     ` andy
  2018-06-20 10:12                     ` [PATCH v4 08/16] config: add global inline-readme list andy
                                       ` (10 subsequent siblings)
  17 siblings, 0 replies; 140+ messages in thread
From: andy @ 2018-06-20 10:12 UTC (permalink / raw)


Arrange that walk_tree_ctx is available in ls_tail, we
will make use of it shortly.

Signed-off-by: Andy Green <andy at warmcat.com>
Reviewed-by: John Keeping <john at keeping.me.uk>
---
 ui-tree.c |    6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/ui-tree.c b/ui-tree.c
index 721c812..1ccbb22 100644
--- a/ui-tree.c
+++ b/ui-tree.c
@@ -365,7 +365,7 @@ static void ls_head(void)
 	html("</tr>\n");
 }
 
-static void ls_tail(void)
+static void ls_tail(struct walk_tree_context *walk_tree_ctx)
 {
 	html("</table>\n");
 	cgit_print_layout_end();
@@ -387,7 +387,7 @@ static void ls_tree(const struct object_id *oid, char *path, struct walk_tree_co
 
 	ls_head();
 	read_tree_recursive(tree, "", 0, 1, &paths, ls_item, walk_tree_ctx);
-	ls_tail();
+	ls_tail(walk_tree_ctx);
 }
 
 
@@ -470,7 +470,7 @@ void cgit_print_tree(const char *rev, char *path, bool use_render)
 
 	read_tree_recursive(commit->maybe_tree, "", 0, 0, &paths, walk_tree, &walk_tree_ctx);
 	if (walk_tree_ctx.state == 1)
-		ls_tail();
+		ls_tail(&walk_tree_ctx);
 	else if (walk_tree_ctx.state == 2)
 		cgit_print_layout_end();
 	else



^ permalink raw reply	[flat|nested] 140+ messages in thread

* [PATCH v4 08/16] config: add global inline-readme list
  2018-06-20 10:11                   ` [PATCH v4 00/16] Render READMEs inline in tree view andy
                                       ` (6 preceding siblings ...)
  2018-06-20 10:12                     ` [PATCH v4 07/16] ui-tree: ls_tail: add walk table param andy
@ 2018-06-20 10:12                     ` andy
  2018-06-20 10:12                     ` [PATCH v4 09/16] config: add repo " andy
                                       ` (9 subsequent siblings)
  17 siblings, 0 replies; 140+ messages in thread
From: andy @ 2018-06-20 10:12 UTC (permalink / raw)


Allows the user to specify a list of filenames that should be
rendered inline with tree view, if present in the directory.

Signed-off-by: Andy Green <andy at warmcat.com>
---
 cgit.c       |    5 ++++-
 cgit.h       |    1 +
 cgitrc.5.txt |   10 ++++++++++
 3 files changed, 15 insertions(+), 1 deletion(-)

diff --git a/cgit.c b/cgit.c
index e0e94d5..bf62199 100644
--- a/cgit.c
+++ b/cgit.c
@@ -1,6 +1,6 @@
 /* cgit.c: cgi for the git scm
  *
- * Copyright (C) 2006-2014 cgit Development Team <cgit at lists.zx2c4.com>
+ * Copyright (C) 2006-2018 cgit Development Team <cgit at lists.zx2c4.com>
  *
  * Licensed under GNU General Public License v2
  *   (see COPYING for full license text)
@@ -297,6 +297,8 @@ static void config_cb(const char *name, const char *value)
 		add_mimetype(name + 9, value);
 	else if (starts_with(name, "render."))
 		add_render_filter(name + 7, value);
+	else if (!strcmp(name, "inline-readme"))
+		string_list_insert(&ctx.cfg.inline_readme, value);
 	else if (!strcmp(name, "include"))
 		parse_configfile(expand_macros(value), config_cb);
 }
@@ -430,6 +432,7 @@ static void prepare_context(void)
 	ctx.page.etag = NULL;
 	string_list_init(&ctx.cfg.mimetypes, 1);
 	string_list_init(&ctx.cfg.render_filters, 1);
+	string_list_init(&ctx.cfg.inline_readme, 1);
 	if (ctx.env.script_name)
 		ctx.cfg.script_name = xstrdup(ctx.env.script_name);
 	if (ctx.env.query_string)
diff --git a/cgit.h b/cgit.h
index 3149946..79605e7 100644
--- a/cgit.h
+++ b/cgit.h
@@ -261,6 +261,7 @@ struct cgit_config {
 	int branch_sort;
 	int commit_sort;
 	struct string_list mimetypes;
+	struct string_list inline_readme;
 	struct string_list render_filters;
 	struct cgit_filter *about_filter;
 	struct cgit_filter *commit_filter;
diff --git a/cgitrc.5.txt b/cgitrc.5.txt
index 34b6186..7ca8de9 100644
--- a/cgitrc.5.txt
+++ b/cgitrc.5.txt
@@ -238,6 +238,16 @@ include::
 	Name of a configfile to include before the rest of the current config-
 	file is parsed. Default value: none. See also: "MACRO EXPANSION".
 
+inline-readme::
+	Append given filename to the list of filenames to be rendered after the
+	tree navigation in tree view, if present in the directory being viewed.  Eg,
+	'inline-readme=README.md'.  You may also want a corresponding render.
+	entry for the readme suffix, eg,
+	'render.md=/usr/libexec/cgit/filters/html-converters/md2html'.  Repos will
+	use the list defined with 'inline-readme' by default, however they can
+	individually also choose to ignore this global list, and create a
+	repo-specific list by using 'repo.inline-readme'.
+
 local-time::
 	Flag which, if set to "1", makes cgit print commit and tag times in the
 	servers timezone. Default value: "0".



^ permalink raw reply	[flat|nested] 140+ messages in thread

* [PATCH v4 09/16] config: add repo inline-readme list
  2018-06-20 10:11                   ` [PATCH v4 00/16] Render READMEs inline in tree view andy
                                       ` (7 preceding siblings ...)
  2018-06-20 10:12                     ` [PATCH v4 08/16] config: add global inline-readme list andy
@ 2018-06-20 10:12                     ` andy
  2018-06-20 10:12                     ` [PATCH v4 10/16] ui-tree: render any matching README file in tree view andy
                                       ` (8 subsequent siblings)
  17 siblings, 0 replies; 140+ messages in thread
From: andy @ 2018-06-20 10:12 UTC (permalink / raw)


This allows the user to choose to override any global
inline-readme list for a specific repo, using the
same kind of semantics as the other repo overrides.

Signed-off-by: Andy Green <andy at warmcat.com>
Reviewed-by: John Keeping <john at keeping.me.uk>
---
 cgit.c       |    7 ++++++-
 cgit.h       |    1 +
 cgitrc.5.txt |   10 ++++++++++
 shared.c     |    2 ++
 4 files changed, 19 insertions(+), 1 deletion(-)

diff --git a/cgit.c b/cgit.c
index bf62199..bdb2fad 100644
--- a/cgit.c
+++ b/cgit.c
@@ -105,7 +105,12 @@ static void repo_config(struct cgit_repo *repo, const char *name, const char *va
 		repo->hide = atoi(value);
 	else if (!strcmp(name, "ignore"))
 		repo->ignore = atoi(value);
-	else if (ctx.cfg.enable_filter_overrides) {
+	else if (!strcmp(name, "inline-readme")) {
+		if (repo->inline_readme.items == ctx.cfg.inline_readme.items)
+			string_list_init(&repo->inline_readme, 1);
+
+		string_list_append(&repo->inline_readme, value);
+	} else if (ctx.cfg.enable_filter_overrides) {
 		if (!strcmp(name, "about-filter"))
 			repo->about_filter = cgit_new_filter(value, ABOUT);
 		else if (!strcmp(name, "commit-filter"))
diff --git a/cgit.h b/cgit.h
index 79605e7..99ea7a2 100644
--- a/cgit.h
+++ b/cgit.h
@@ -86,6 +86,7 @@ struct cgit_repo {
 	char *defbranch;
 	char *module_link;
 	struct string_list readme;
+	struct string_list inline_readme;
 	char *section;
 	char *clone_url;
 	char *logo;
diff --git a/cgitrc.5.txt b/cgitrc.5.txt
index 7ca8de9..62d7c2a 100644
--- a/cgitrc.5.txt
+++ b/cgitrc.5.txt
@@ -544,6 +544,16 @@ repo.ignore::
 	is not shown in the index and cannot be accessed by providing a direct
 	path. Default value: "0". See also: "repo.hide".
 
+repo.inline-readme::
+	Append given filename to the list of filenames to be rendered after the
+	tree navigation in tree view, if present in the directory being viewed.  Eg,
+	'repo.inline-readme=README.md'.  You may also want a corresponding render.
+	entry for the readme suffix, eg,
+	'render.md=/usr/libexec/cgit/filters/html-converters/md2html'.
+	If not given, the repo will use any global 'inline-readme=' configuration;
+	if any 'repo.inline-readme' are given only they are used for that repo,
+	and the global 'inline-readme=' list is ignored for that repo.
+
 repo.logo::
 	Url which specifies the source of an image which will be used as a logo
 	on this repo's pages. Default value: global logo.
diff --git a/shared.c b/shared.c
index 665f8ed..cd0782d 100644
--- a/shared.c
+++ b/shared.c
@@ -77,6 +77,8 @@ struct cgit_repo *cgit_add_repo(const char *url)
 	ret->clone_url = ctx.cfg.clone_url;
 	ret->submodules.strdup_strings = 1;
 	ret->hide = ret->ignore = 0;
+	ret->inline_readme = ctx.cfg.inline_readme;
+
 	return ret;
 }
 



^ permalink raw reply	[flat|nested] 140+ messages in thread

* [PATCH v4 10/16] ui-tree: render any matching README file in tree view
  2018-06-20 10:11                   ` [PATCH v4 00/16] Render READMEs inline in tree view andy
                                       ` (8 preceding siblings ...)
  2018-06-20 10:12                     ` [PATCH v4 09/16] config: add repo " andy
@ 2018-06-20 10:12                     ` andy
  2018-06-20 10:12                     ` [PATCH v4 11/16] md2html: add asset mapping andy
                                       ` (7 subsequent siblings)
  17 siblings, 0 replies; 140+ messages in thread
From: andy @ 2018-06-20 10:12 UTC (permalink / raw)


While listing the items in tree view, if we spot a filename
matching any inline-readme entries from the config file,
we stash the first one into walk_tree_context.

After the tree view has been shown, if there is a stashed
inline-readme we render it inline.

Signed-off-by: Andy Green <andy at warmcat.com>
Reviewed-by: John Keeping <john at keeping.me.uk>
---
 ui-tree.c |   53 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 52 insertions(+), 1 deletion(-)

diff --git a/ui-tree.c b/ui-tree.c
index 1ccbb22..6ffd4dd 100644
--- a/ui-tree.c
+++ b/ui-tree.c
@@ -1,6 +1,6 @@
 /* ui-tree.c: functions for tree output
  *
- * Copyright (C) 2006-2017 cgit Development Team <cgit at lists.zx2c4.com>
+ * Copyright (C) 2006-2018 cgit Development Team <cgit at lists.zx2c4.com>
  *
  * Licensed under GNU General Public License v2
  *   (see COPYING for full license text)
@@ -12,8 +12,10 @@
 #include "ui-shared.h"
 
 struct walk_tree_context {
+	struct object_id inline_oid;
 	char *curr_rev;
 	char *match_path;
+	char *inline_filename;
 	int state;
 	bool use_render;
 };
@@ -325,11 +327,19 @@ static int ls_item(const struct object_id *oid, struct strbuf *base,
 				&fullpath);
 	} else {
 		char *ext = strrchr(name, '.');
+
 		strbuf_addstr(&class, "ls-blob");
 		if (ext)
 			strbuf_addf(&class, " %s", ext + 1);
+
 		cgit_tree_link(name, NULL, class.buf, ctx.qry.head,
 			       walk_tree_ctx->curr_rev, fullpath.buf);
+
+		if (!walk_tree_ctx->inline_filename &&
+		    string_list_has_string(&ctx.repo->inline_readme, name)) {
+			walk_tree_ctx->inline_filename = xstrdup(pathname);
+			oidcpy(&walk_tree_ctx->inline_oid, oid);
+		}
 	}
 	htmlf("</td><td class='ls-size'>%li</td>", size);
 
@@ -367,7 +377,46 @@ static void ls_head(void)
 
 static void ls_tail(struct walk_tree_context *walk_tree_ctx)
 {
+	struct cgit_filter *render;
+	enum object_type type;
+	char *buf, *mimetype;
+	unsigned long size;
+
 	html("</table>\n");
+
+	if (!walk_tree_ctx->inline_filename)
+		goto done;
+
+	type = oid_object_info(the_repository, &walk_tree_ctx->inline_oid, &size);
+	if (type == OBJ_BAD)
+		goto done;
+
+	buf = read_object_file(&walk_tree_ctx->inline_oid, &type, &size);
+	if (!buf)
+		goto done;
+
+	/* create a vertical gap between tree nav / inline */
+	html("<table class=\"tabs\"><tr><td></td></tr></table>");
+
+	render = get_render_for_filename(walk_tree_ctx->inline_filename);
+	mimetype = render ? NULL : get_mimetype_for_filename(
+				walk_tree_ctx->inline_filename);
+
+	htmlf("<h2>%s</h2>", walk_tree_ctx->inline_filename);
+	html("<div class=blob>&nbsp;</div>\n");
+
+	if (render)
+		render_buffer(render, walk_tree_ctx->inline_filename,
+			      buf, size);
+	else if (mimetype)
+		include_file(walk_tree_ctx->inline_filename, mimetype);
+	else
+		print_buffer(walk_tree_ctx->inline_filename, buf, size);
+
+	free(mimetype);
+	free(buf);
+
+done:
 	cgit_print_layout_end();
 }
 
@@ -478,4 +527,6 @@ void cgit_print_tree(const char *rev, char *path, bool use_render)
 
 cleanup:
 	free(walk_tree_ctx.curr_rev);
+	if (walk_tree_ctx.inline_filename)
+		free(walk_tree_ctx.inline_filename);
 }



^ permalink raw reply	[flat|nested] 140+ messages in thread

* [PATCH v4 11/16] md2html: add asset mapping
  2018-06-20 10:11                   ` [PATCH v4 00/16] Render READMEs inline in tree view andy
                                       ` (9 preceding siblings ...)
  2018-06-20 10:12                     ` [PATCH v4 10/16] ui-tree: render any matching README file in tree view andy
@ 2018-06-20 10:12                     ` andy
  2018-06-27 17:32                       ` Jason
  2018-06-20 10:12                     ` [PATCH v4 12/16] md2html: add asset postfix arg andy
                                       ` (6 subsequent siblings)
  17 siblings, 1 reply; 140+ messages in thread
From: andy @ 2018-06-20 10:12 UTC (permalink / raw)


From: John Keeping <john at keeping.me.uk>

This remaps the "src" attribute on <img> elements according to a second
command line argument, you can try it out with:

	md2html <README.md README.md /path/to/plain/directory/

The trailing "/" is important.

This is useful when serving relative URLs from the repo in a readme.

Signed-off-by: John Keeping <john at keeping.me.uk>
---
 filters/html-converters/md2html |   50 ++++++++++++++++++++++++++++++++++++++-
 1 file changed, 49 insertions(+), 1 deletion(-)

diff --git a/filters/html-converters/md2html b/filters/html-converters/md2html
index ebf3856..eb5d977 100755
--- a/filters/html-converters/md2html
+++ b/filters/html-converters/md2html
@@ -2,7 +2,41 @@
 import markdown
 import sys
 import io
+from markdown.util import etree
 from pygments.formatters import HtmlFormatter
+from urllib.parse import urljoin
+
+
+class AssetMappingProcessor(markdown.treeprocessors.Treeprocessor):
+
+    def __init__(self, asset_prefix):
+        self.asset_prefix = asset_prefix
+
+    def run(self, root):
+        asset_prefix = self.asset_prefix
+        for img in root.iter('img'):
+            src = img.get('src')
+            if src is None:
+                continue
+            img.set('src', urljoin(asset_prefix, src))
+
+
+class AssetMappingExtension(markdown.extensions.Extension):
+
+    def __init__(self, **kwargs):
+        self.config = {'asset_prefix': ['', 'prefix for relative asset URLs']}
+        super(AssetMappingExtension, self).__init__(**kwargs)
+
+    def extendMarkdown(self, md, md_globals):
+        asset_prefix = self.getConfig('asset_prefix')
+        if not asset_prefix:
+            return
+
+        md.treeprocessors.add('asset_mapping',
+                              AssetMappingProcessor(asset_prefix),
+                              '_end')
+
+
 sys.stdin = io.TextIOWrapper(sys.stdin.buffer, encoding='utf-8')
 sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')
 sys.stdout.write('''
@@ -289,6 +323,20 @@ sys.stdout.write('''
 ''')
 sys.stdout.write("<div class='markdown-body'>")
 sys.stdout.flush()
+
+extensions = [
+    "markdown.extensions.fenced_code",
+    "markdown.extensions.codehilite",
+    "markdown.extensions.tables"
+]
+extension_configs = {
+    "markdown.extensions.codehilite":{"css_class":"highlight"}
+}
+
+if len(sys.argv) > 2:
+    extensions.append(AssetMappingExtension(asset_prefix=sys.argv[2]))
+
 # Note: you may want to run this through bleach for sanitization
-markdown.markdownFromFile(output_format="html5", extensions=["markdown.extensions.fenced_code", "markdown.extensions.codehilite", "markdown.extensions.tables"], extension_configs={"markdown.extensions.codehilite":{"css_class":"highlight"}})
+markdown.markdownFromFile(output_format="html5", extensions=extensions, extension_configs=extension_configs)
 sys.stdout.write("</div>")
+



^ permalink raw reply	[flat|nested] 140+ messages in thread

* [PATCH v4 12/16] md2html: add asset postfix arg
  2018-06-20 10:11                   ` [PATCH v4 00/16] Render READMEs inline in tree view andy
                                       ` (10 preceding siblings ...)
  2018-06-20 10:12                     ` [PATCH v4 11/16] md2html: add asset mapping andy
@ 2018-06-20 10:12                     ` andy
  2018-06-20 10:13                     ` [PATCH v4 13/16] ui-shared: deduplicate some code in repolink andy
                                       ` (5 subsequent siblings)
  17 siblings, 0 replies; 140+ messages in thread
From: andy @ 2018-06-20 10:12 UTC (permalink / raw)


Extend md2html with an optional third argument for URL postfix, like "?h=mybranch"

Signed-off-by: Andy Green <andy at warmcat.com>
---
 filters/html-converters/md2html |   19 +++++++++++++------
 1 file changed, 13 insertions(+), 6 deletions(-)

diff --git a/filters/html-converters/md2html b/filters/html-converters/md2html
index eb5d977..6f4f1b3 100755
--- a/filters/html-converters/md2html
+++ b/filters/html-converters/md2html
@@ -9,31 +9,35 @@ from urllib.parse import urljoin
 
 class AssetMappingProcessor(markdown.treeprocessors.Treeprocessor):
 
-    def __init__(self, asset_prefix):
+    def __init__(self, asset_prefix, asset_postfix):
         self.asset_prefix = asset_prefix
+        self.asset_postfix = asset_postfix
 
     def run(self, root):
         asset_prefix = self.asset_prefix
+        asset_postfix = self.asset_postfix
         for img in root.iter('img'):
             src = img.get('src')
             if src is None:
                 continue
-            img.set('src', urljoin(asset_prefix, src))
+            img.set('src', urljoin(urljoin(asset_prefix, src), asset_postfix))
 
 
 class AssetMappingExtension(markdown.extensions.Extension):
 
     def __init__(self, **kwargs):
-        self.config = {'asset_prefix': ['', 'prefix for relative asset URLs']}
+        self.config = {'asset_prefix':  ['', 'prefix for relative asset URLs'],
+                       'asset_postfix': ['', 'postfix for relative asset URLs']}
         super(AssetMappingExtension, self).__init__(**kwargs)
 
     def extendMarkdown(self, md, md_globals):
         asset_prefix = self.getConfig('asset_prefix')
-        if not asset_prefix:
+        asset_postfix = self.getConfig('asset_postfix')
+        if not (asset_prefix or asset_postfix):
             return
 
         md.treeprocessors.add('asset_mapping',
-                              AssetMappingProcessor(asset_prefix),
+                              AssetMappingProcessor(asset_prefix, asset_postfix),
                               '_end')
 
 
@@ -334,7 +338,10 @@ extension_configs = {
 }
 
 if len(sys.argv) > 2:
-    extensions.append(AssetMappingExtension(asset_prefix=sys.argv[2]))
+    args = {'asset_prefix': sys.argv[2]}
+    if len(sys.argv) > 3:
+        args['asset_postfix'] = sys.argv[3]
+    extensions.append(AssetMappingExtension(**args))
 
 # Note: you may want to run this through bleach for sanitization
 markdown.markdownFromFile(output_format="html5", extensions=extensions, extension_configs=extension_configs)



^ permalink raw reply	[flat|nested] 140+ messages in thread

* [PATCH v4 13/16] ui-shared: deduplicate some code in repolink
  2018-06-20 10:11                   ` [PATCH v4 00/16] Render READMEs inline in tree view andy
                                       ` (11 preceding siblings ...)
  2018-06-20 10:12                     ` [PATCH v4 12/16] md2html: add asset postfix arg andy
@ 2018-06-20 10:13                     ` andy
  2018-06-27 17:29                       ` Jason
  2018-06-20 10:13                     ` [PATCH v4 14/16] ui-shared: add helper for generating non-urlencoded links andy
                                       ` (4 subsequent siblings)
  17 siblings, 1 reply; 140+ messages in thread
From: andy @ 2018-06-20 10:13 UTC (permalink / raw)


8 lines of code are duplicated in repolink, clean it
so the common code appears once

Signed-off-by: Andy Green <andy at warmcat.com>
Reviewed-by: John Keeping <john at keeping.me.uk>
---
 ui-shared.c |   26 ++++++++++----------------
 1 file changed, 10 insertions(+), 16 deletions(-)

diff --git a/ui-shared.c b/ui-shared.c
index d2985c8..21bbded 100644
--- a/ui-shared.c
+++ b/ui-shared.c
@@ -241,28 +241,22 @@ static char *repolink(const char *title, const char *class, const char *page,
 	if (ctx.cfg.virtual_root) {
 		html_url_path(ctx.cfg.virtual_root);
 		html_url_path(ctx.repo->url);
-		if (ctx.repo->url[strlen(ctx.repo->url) - 1] != '/')
-			html("/");
-		if (page) {
-			html_url_path(page);
-			html("/");
-			if (path)
-				html_url_path(path);
-		}
 	} else {
 		html_url_path(ctx.cfg.script_name);
 		html("?url=");
 		html_url_arg(ctx.repo->url);
-		if (ctx.repo->url[strlen(ctx.repo->url) - 1] != '/')
-			html("/");
-		if (page) {
-			html_url_arg(page);
-			html("/");
-			if (path)
-				html_url_arg(path);
-		}
 		delim = "&amp;";
 	}
+
+	if (ctx.repo->url[strlen(ctx.repo->url) - 1] != '/')
+		html("/");
+	if (page) {
+		html_url_arg(page);
+		html("/");
+		if (path)
+			html_url_arg(path);
+	}
+
 	if (head && ctx.repo->defbranch && strcmp(head, ctx.repo->defbranch)) {
 		html(delim);
 		html("h=");



^ permalink raw reply	[flat|nested] 140+ messages in thread

* [PATCH v4 14/16] ui-shared: add helper for generating non-urlencoded links
  2018-06-20 10:11                   ` [PATCH v4 00/16] Render READMEs inline in tree view andy
                                       ` (12 preceding siblings ...)
  2018-06-20 10:13                     ` [PATCH v4 13/16] ui-shared: deduplicate some code in repolink andy
@ 2018-06-20 10:13                     ` andy
  2018-06-20 10:13                     ` [PATCH v4 15/16] render: adapt for providing extra filter args for plain andy
                                       ` (3 subsequent siblings)
  17 siblings, 0 replies; 140+ messages in thread
From: andy @ 2018-06-20 10:13 UTC (permalink / raw)


We are going to have to produce plain links in the next patch.
But depending on config, the links are not simple.

Reproduce the logic in repolink() to generate correctly-
formatted links in a strbuf, without urlencoding, in a reusable
helper cgit_repo_create_url().

Signed-off-by: Andy Green <andy at warmcat.com>
---
 ui-shared.c |   32 ++++++++++++++++++++++++++++++++
 ui-shared.h |    3 +++
 2 files changed, 35 insertions(+)

diff --git a/ui-shared.c b/ui-shared.c
index 21bbded..c9a34fb 100644
--- a/ui-shared.c
+++ b/ui-shared.c
@@ -221,6 +221,38 @@ void cgit_index_link(const char *name, const char *title, const char *class,
 	site_link(NULL, name, title, class, pattern, sort, ofs, always_root);
 }
 
+const char *cgit_repo_create_url(struct strbuf *sb, struct strbuf *sb_post,
+				 const char *page, const char *head,
+				 const char *path)
+{
+	const char *delim = "?";
+
+	if (ctx.cfg.virtual_root) {
+		strbuf_addf(sb, "%s%s", ctx.cfg.virtual_root, ctx.repo->url);
+	} else {
+		strbuf_addstr(sb, ctx.cfg.script_name);
+		sb = sb_post;
+		strbuf_addf(sb, "?url=%s", ctx.repo->url);
+		delim = "&";
+	}
+
+	if (ctx.repo->url[strlen(ctx.repo->url) - 1] != '/')
+		strbuf_addch(sb, '/');
+
+	if (page) {
+		strbuf_addf(sb, "%s/", page);
+		if (path)
+			strbuf_addstr(sb, path);
+	}
+
+	if (head && ctx.repo->defbranch && strcmp(head, ctx.repo->defbranch)) {
+		strbuf_addf(sb_post, "%sh=%s", delim, head);
+		delim = "&";
+	}
+
+	return delim;
+}
+
 static char *repolink(const char *title, const char *class, const char *page,
 		      const char *head, const char *path)
 {
diff --git a/ui-shared.h b/ui-shared.h
index c105b3b..e78b5fd 100644
--- a/ui-shared.h
+++ b/ui-shared.h
@@ -59,6 +59,9 @@ extern void cgit_object_link(struct object *obj);
 
 extern void cgit_submodule_link(const char *class, char *path,
 				const char *rev);
+extern const char *cgit_repo_create_url(struct strbuf *sb, struct strbuf *sb_post,
+					 const char *page, const char *head,
+					 const char *path);
 
 extern void cgit_print_layout_start(void);
 extern void cgit_print_layout_end(void);



^ permalink raw reply	[flat|nested] 140+ messages in thread

* [PATCH v4 15/16] render: adapt for providing extra filter args for plain
  2018-06-20 10:11                   ` [PATCH v4 00/16] Render READMEs inline in tree view andy
                                       ` (13 preceding siblings ...)
  2018-06-20 10:13                     ` [PATCH v4 14/16] ui-shared: add helper for generating non-urlencoded links andy
@ 2018-06-20 10:13                     ` andy
  2018-06-20 10:41                       ` andy
  2018-06-20 10:13                     ` [PATCH v4 16/16] md2html: change css name to not conflict with highlight andy
                                       ` (2 subsequent siblings)
  17 siblings, 1 reply; 140+ messages in thread
From: andy @ 2018-06-20 10:13 UTC (permalink / raw)


This changes the render filter exec part to provide a second
and third argument, which are used by md2html to fix up the url
path for "plain" for the repo, eg, "/cgit/plain/" and
"?h=mybranch", as required by the modifications to md2html in
the previous patches.

The combination means cgit becomes able to serve assets using
markdown urls starting from the repo root dir, without mentioning
any virtual url part specific to a cgit or other web rendering
instance, while respecting the version context.

Eg, continuing the example of the arguments being
"/cgit/plain/" and "?h=mybranch" from above, if the markdown has

![overview](./doc-assets/overview.png)

the img src will be fixed up to

"/cgit/plain/doc-assets/overview.png?h=mybranch"

If the same document is viewed from a different rev in cgit, the
processed markdown url will change to match the cgit context, even
though the markdown relative URL is the same for all versions.

Signed-off-by: Andy Green <andy at warmcat.com>
Reviewed-by: John Keeping <john at keeping.me.uk>
---
 cgitrc.5.txt |   16 +++++++++++-----
 filter.c     |    5 ++++-
 ui-tree.c    |   11 +++++++++--
 3 files changed, 24 insertions(+), 8 deletions(-)

diff --git a/cgitrc.5.txt b/cgitrc.5.txt
index 62d7c2a..99fc799 100644
--- a/cgitrc.5.txt
+++ b/cgitrc.5.txt
@@ -738,11 +738,17 @@ owner filter::
 	output.  The output is included in the Owner column.
 
 render filter::
-	This filter is given a single parameter: the filename of the source
-	file to render. The filter can use the filename to determine (for
-	example) the syntax highlighting mode. The contents of the file that
-	is to be rendered is available on standard input and the rendered
-	content is expected on standard output.
+	This filter is given a single required parameter: the filename of
+	the source file to render. The filter can use the filename to
+	determine (for example) the syntax highlighting mode. The
+	contents of the file that is to be rendered is available on standard
+	input and the rendered content is expected on standard output.  Two
+	additional optional parameters are the base URL path and optional
+	URL parameter arguments needed to adapt relative paths in the input
+	to absolute URLs pointing to the "plain" version of the file in the
+	repo rev context, eg, "/myvirt/reponame/plain" and "?h=mybranch"
+	could be used to convert input references like "pics/myfile.png" to
+	'<img src="/myvirt/reponame/plain/pics/myfile.png?h=mybranch">'
 
 source filter::
 	This filter is given a single parameter: the filename of the source
diff --git a/filter.c b/filter.c
index 4ae4aaa..7c1f188 100644
--- a/filter.c
+++ b/filter.c
@@ -424,6 +424,10 @@ struct cgit_filter *cgit_new_filter(const char *cmd, filter_type filtertype)
 			argument_count = 12;
 			break;
 
+		case RENDER:
+			argument_count = 3;
+			break;
+
 		case EMAIL:
 			argument_count = 2;
 			break;
@@ -434,7 +438,6 @@ struct cgit_filter *cgit_new_filter(const char *cmd, filter_type filtertype)
 
 		case SOURCE:
 		case ABOUT:
-		case RENDER:
 			argument_count = 1;
 			break;
 
diff --git a/ui-tree.c b/ui-tree.c
index 6ffd4dd..2e94755 100644
--- a/ui-tree.c
+++ b/ui-tree.c
@@ -102,16 +102,23 @@ static void print_buffer(const char *basename, char *buf, unsigned long size)
 }
 
 static void render_buffer(struct cgit_filter *render, const char *name,
-		char *buf, unsigned long size)
+			  char *buf, unsigned long size)
 {
 	char *filter_arg = xstrdup(name);
+	struct strbuf sb_pre = STRBUF_INIT, sb_post = STRBUF_INIT;
+
+	cgit_repo_create_url(&sb_pre, &sb_post, "plain", ctx.qry.head, NULL);
+
+	fprintf(stderr, "'%s' '%s'\n", sb_pre.buf, sb_post.buf);
 
 	html("<div class='blob'>");
-	cgit_open_filter(render, filter_arg);
+	cgit_open_filter(render, filter_arg, sb_pre.buf, sb_post.buf);
 	html_raw(buf, size);
 	cgit_close_filter(render);
 	html("</div>");
 
+	strbuf_release(&sb_pre);
+	strbuf_release(&sb_post);
 	free(filter_arg);
 }
 



^ permalink raw reply	[flat|nested] 140+ messages in thread

* [PATCH v4 16/16] md2html: change css name to not conflict with highlight
  2018-06-20 10:11                   ` [PATCH v4 00/16] Render READMEs inline in tree view andy
                                       ` (14 preceding siblings ...)
  2018-06-20 10:13                     ` [PATCH v4 15/16] render: adapt for providing extra filter args for plain andy
@ 2018-06-20 10:13                     ` andy
  2018-06-27 17:37                       ` Jason
  2018-06-23 11:04                     ` [PATCH v4 00/16] Render READMEs inline in tree view john
  2018-06-27 17:18                     ` Jason
  17 siblings, 1 reply; 140+ messages in thread
From: andy @ 2018-06-20 10:13 UTC (permalink / raw)


md2html gets pygments to define the css for "highlight", making display
of the blame view fragile against pygments version.  On Fedora 28 /
python3-pygments-2.2.0-10.fc28.noarch, "highlight" gets redefined so
it no longer displays at the top of its parent.

This patch changes the css class name used by md2html to "md2html_highlight"
so there is no conflict with other definitions of "highlight".

Signed-off-by: Andy Green <andy at warmcat.com>
---
 filters/html-converters/md2html |    6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/filters/html-converters/md2html b/filters/html-converters/md2html
index 6f4f1b3..00cf73a 100755
--- a/filters/html-converters/md2html
+++ b/filters/html-converters/md2html
@@ -305,7 +305,7 @@ sys.stdout.write('''
     border: none;
     background: transparent;
 }
-.markdown-body .highlight pre, .markdown-body pre {
+.markdown-body .md2html_highlight pre, .markdown-body pre {
     background-color: #f8f8f8;
     border: 1px solid #ccc;
     font-size: 13px;
@@ -321,7 +321,7 @@ sys.stdout.write('''
     border: none;
 }
 ''')
-sys.stdout.write(HtmlFormatter(style='pastie').get_style_defs('.highlight'))
+sys.stdout.write(HtmlFormatter(style='pastie').get_style_defs('.md2html_highlight'))
 sys.stdout.write('''
 </style>   
 ''')
@@ -334,7 +334,7 @@ extensions = [
     "markdown.extensions.tables"
 ]
 extension_configs = {
-    "markdown.extensions.codehilite":{"css_class":"highlight"}
+    "markdown.extensions.codehilite":{"css_class":"md2html_highlight"}
 }
 
 if len(sys.argv) > 2:



^ permalink raw reply	[flat|nested] 140+ messages in thread

* [PATCH v4 15/16] render: adapt for providing extra filter args for plain
  2018-06-20 10:13                     ` [PATCH v4 15/16] render: adapt for providing extra filter args for plain andy
@ 2018-06-20 10:41                       ` andy
  0 siblings, 0 replies; 140+ messages in thread
From: andy @ 2018-06-20 10:41 UTC (permalink / raw)




On 06/20/2018 06:13 PM, Andy Green wrote:

> diff --git a/ui-tree.c b/ui-tree.c
> index 6ffd4dd..2e94755 100644
> --- a/ui-tree.c
> +++ b/ui-tree.c
> @@ -102,16 +102,23 @@ static void print_buffer(const char *basename, char *buf, unsigned long size)
>   }
>   
>   static void render_buffer(struct cgit_filter *render, const char *name,
> -		char *buf, unsigned long size)
> +			  char *buf, unsigned long size)
>   {
>   	char *filter_arg = xstrdup(name);
> +	struct strbuf sb_pre = STRBUF_INIT, sb_post = STRBUF_INIT;
> +
> +	cgit_repo_create_url(&sb_pre, &sb_post, "plain", ctx.qry.head, NULL);
> +
> +	fprintf(stderr, "'%s' '%s'\n", sb_pre.buf, sb_post.buf);

Whoops... I removed this debugging line in the version here

https://warmcat.com/git/cgit/patch/?id=ab7ded33bfd6603537420bc3dd4ac96372134425

-Andy


^ permalink raw reply	[flat|nested] 140+ messages in thread

* [PATCH v4 00/16] Render READMEs inline in tree view
  2018-06-20 10:11                   ` [PATCH v4 00/16] Render READMEs inline in tree view andy
                                       ` (15 preceding siblings ...)
  2018-06-20 10:13                     ` [PATCH v4 16/16] md2html: change css name to not conflict with highlight andy
@ 2018-06-23 11:04                     ` john
  2018-06-23 11:10                       ` andy
  2018-06-27 17:18                     ` Jason
  17 siblings, 1 reply; 140+ messages in thread
From: john @ 2018-06-23 11:04 UTC (permalink / raw)


On Wed, Jun 20, 2018 at 06:11:57PM +0800, Andy Green wrote:
> The following series adds config to allow rendering of
> selected READMEs inline after the tree view, where
> present in the directory being viewed.
> 
> Particularly you can use completely relative markdown to
> inline pictures served from the current repo rev context,
> eg,
> 
> ![overview](./doc-assets/overview.png)
> 
> will "just work" showing the png from the current view
> rev context; this format also works in github.
> 
> It builds on John Keeping's RENDER mode series from 2016.
> 
> Typical config to enable it, if you have a README.md
> looks like
> 
> inline-readme=README.md
> render.md=/usr/libexec/cgit/filters/html-converters/md2html
> 
> You can see examples of it in operation at
> 
> https://libwebsockets.org/git/libwebsockets/tree
> https://libwebsockets.org/git/libwebsockets/tree/?h=v3.0-stable
> https://warmcat.com/git/cgit/tree/
> 
> The expected basis these apply on top of is
> 
>  - jk/for-jason
>  - ch/for-jason
> 
> You can find these patches on top of the expected basis here
> 
> https://warmcat.com/git/cgit/log/
> 
> v4 collects all the reviewed by and implements yesterday's comments

Other than the left-over debugging line you've already pointed out
yourself, this looks good to me.

I suggest you post a final version after the Git 2.18.0 update hits
master and we can get this merged.

> ---
> 
> Andy Green (10):
>       manpage: fix sorting order
>       ui-tree: ls_tail: add walk table param
>       config: add global inline-readme list
>       config: add repo inline-readme list
>       ui-tree: render any matching README file in tree view
>       md2html: add asset postfix arg
>       ui-shared: deduplicate some code in repolink
>       ui-shared: add helper for generating non-urlencoded links
>       render: adapt for providing extra filter args for plain
>       md2html: change css name to not conflict with highlight
> 
> John Keeping (6):
>       Use string list strdup_strings for mimetypes
>       Add source page
>       Parse render filters from the config
>       ui-tree: split out buffer printing
>       ui-tree: use render filters to display content
>       md2html: add asset mapping
> 
> 
>  cgit.c                          |   35 +++++-
>  cgit.css                        |    5 +
>  cgit.h                          |    6 +
>  cgitrc.5.txt                    |  221 +++++++++++++++++++++++----------------
>  cmd.c                           |    8 +
>  filter.c                        |    4 +
>  filters/html-converters/md2html |   61 ++++++++++-
>  shared.c                        |   21 ++++
>  ui-shared.c                     |   72 ++++++++++---
>  ui-shared.h                     |    6 +
>  ui-tree.c                       |  193 +++++++++++++++++++++++++++++++---
>  ui-tree.h                       |    2 
>  12 files changed, 498 insertions(+), 136 deletions(-)
> 
> --
> Signature
> _______________________________________________
> CGit mailing list
> CGit at lists.zx2c4.com
> https://lists.zx2c4.com/mailman/listinfo/cgit


^ permalink raw reply	[flat|nested] 140+ messages in thread

* [PATCH v4 00/16] Render READMEs inline in tree view
  2018-06-23 11:04                     ` [PATCH v4 00/16] Render READMEs inline in tree view john
@ 2018-06-23 11:10                       ` andy
  0 siblings, 0 replies; 140+ messages in thread
From: andy @ 2018-06-23 11:10 UTC (permalink / raw)




On 06/23/2018 07:04 PM, John Keeping wrote:
> On Wed, Jun 20, 2018 at 06:11:57PM +0800, Andy Green wrote:
>> The following series adds config to allow rendering of
>> selected READMEs inline after the tree view, where
>> present in the directory being viewed.
>>
>> Particularly you can use completely relative markdown to
>> inline pictures served from the current repo rev context,
>> eg,
>>
>> ![overview](./doc-assets/overview.png)
>>
>> will "just work" showing the png from the current view
>> rev context; this format also works in github.
>>
>> It builds on John Keeping's RENDER mode series from 2016.
>>
>> Typical config to enable it, if you have a README.md
>> looks like
>>
>> inline-readme=README.md
>> render.md=/usr/libexec/cgit/filters/html-converters/md2html
>>
>> You can see examples of it in operation at
>>
>> https://libwebsockets.org/git/libwebsockets/tree
>> https://libwebsockets.org/git/libwebsockets/tree/?h=v3.0-stable
>> https://warmcat.com/git/cgit/tree/
>>
>> The expected basis these apply on top of is
>>
>>   - jk/for-jason
>>   - ch/for-jason
>>
>> You can find these patches on top of the expected basis here
>>
>> https://warmcat.com/git/cgit/log/
>>
>> v4 collects all the reviewed by and implements yesterday's comments
> 
> Other than the left-over debugging line you've already pointed out
> yourself, this looks good to me.
> 
> I suggest you post a final version after the Git 2.18.0 update hits
> master and we can get this merged.

Great, will do.

-Andy



^ permalink raw reply	[flat|nested] 140+ messages in thread

* [PATCH v4 00/16] Render READMEs inline in tree view
  2018-06-20 10:11                   ` [PATCH v4 00/16] Render READMEs inline in tree view andy
                                       ` (16 preceding siblings ...)
  2018-06-23 11:04                     ` [PATCH v4 00/16] Render READMEs inline in tree view john
@ 2018-06-27 17:18                     ` Jason
  2018-06-27 17:26                       ` Fancier Source view [Was: Re: [PATCH v4 00/16] Render READMEs inline in tree view] Jason
                                         ` (2 more replies)
  17 siblings, 3 replies; 140+ messages in thread
From: Jason @ 2018-06-27 17:18 UTC (permalink / raw)


Hey Andy,

Thanks for this patchset. It looks like this is shaping up into a nice
direction. However, I'm a bit concerned about our nobs becoming
slightly overlapping and incoherent, and I think that with this
series, we should also unify how we handle rendering.

With the current state of this series, cgit would have the following options:

- render.<ext>
- inline-readme
- render-filter
- about-filter
- commit-filter
- source-filter
- owner-filter
- readme=file
- readme=:file

Whoa nelly. Of these, about-filter, commit-filter, source-filter, and
owner-filter all have analogs in the repo.* namespace, which makes
sense; it seems this was omitted from the render-filter introduced by
this series. The thing that unifies about-filter, commit-filter,
source-filter, and owner-filter is that they all modify some aspect of
the rendered output, either via fork/exec or via lua.

In adding readme files under the tree view, the obvious observation is
that this is pretty much the same type of rendering that we're doing
in about-filter.

In adding rendering of arbitrary files in blob view, this is
essentially a fancy source view, with the one caveat of our
interesting handling of line numbers.

So, I'd propose the following re-organization (and after we nail it
down, we can bikeshed about compatibility with old configs, but for
now let's focus on ideal design):

- We retain commit-filter, source-filter, and owner-filter as we have them now.
- We rename about-filter to readme-filter.
- We remove `readme` and instead introduce `readme-filename`, which
can be specified multiple times as is habit. This would simply take
the set of filenames considered to be readme files (readme.md,
readme.txt, etc). [Bikeshed discussion: case insensitive?]
- We introduce an options at the global level and at the .repo level
of `about-readme=/path/to/absolute/file` and `about-readme=<BRANCH>:`
and `about-readme=:`. The first would replace our original usage of
`readme=/path/to=file`, and the second would replace the use of
`readme=branch:whatever`, specifying an explicit branch (like
cgit.git's wiki branch), and the third would indicate the default
branch.
- We introduce an option at the global level and at the .repo level of
`tree-readme=1/0` to display (or not) the readme under each tree.
- We do not introduce render-filter. We do not introduce render.<ext>;
such extension selection is successfully handled by the various
filters themselves already.

John, Christian -- what are your thoughts on this?

Regards,
Jason


^ permalink raw reply	[flat|nested] 140+ messages in thread

* Fancier Source view [Was: Re: [PATCH v4 00/16] Render READMEs inline in tree view]
  2018-06-27 17:18                     ` Jason
@ 2018-06-27 17:26                       ` Jason
  2018-06-27 20:05                         ` john
  2018-06-27 19:51                       ` [PATCH v4 00/16] Render READMEs inline in tree view john
  2018-06-27 22:36                       ` andy
  2 siblings, 1 reply; 140+ messages in thread
From: Jason @ 2018-06-27 17:26 UTC (permalink / raw)


Splitting out this issue into a different thread, because I think it's
orthogonal to the other topic.

On Wed, Jun 27, 2018 at 7:18 PM Jason A. Donenfeld <Jason at zx2c4.com> wrote:
> In adding rendering of arbitrary files in blob view, this is
> essentially a fancy source view, with the one caveat of our
> interesting handling of line numbers.

People click a .c file and they get pygments highlighting. That's
good. People click a .pdf or a .md and they get either a hexdump or a
highlighted .md source. Github has made different behavior more
popular -- namely, rendering the .pdf and the .md. The obvious way to
handle this is augmenting the source-view to spit something different
out.

Alternatively, my previously proposed readme-filter could be renamed
to render-filter, and we could do everything in one place with one
filter, and decide exclusively on the basis of filetype.

Either way, we have this issue of line numbers. We have a few ways of
handling this:

a. Not print them ever when a source-filter/render-filter is
specified, leaving that up to the renderer to do.
b. If the renderer doesn't want line numbers, it can return a special
exit code (197, for example) to indicate that to cgit.
c. If the renderer doesn't want line numbers, it can just omit some
!important css to remove them at the end.
d. We introduce a maze of filetype selection rendering logic options.
e. Something else?

I'm most inclined to go with a or b, but neither seems entirely
appealing. Thoughts?

Jason


^ permalink raw reply	[flat|nested] 140+ messages in thread

* [PATCH v4 01/16] manpage: fix sorting order
  2018-06-20 10:12                     ` [PATCH v4 01/16] manpage: fix sorting order andy
@ 2018-06-27 17:27                       ` Jason
  0 siblings, 0 replies; 140+ messages in thread
From: Jason @ 2018-06-27 17:27 UTC (permalink / raw)


Merged, thanks.


^ permalink raw reply	[flat|nested] 140+ messages in thread

* [PATCH v4 02/16] Use string list strdup_strings for mimetypes
  2018-06-20 10:12                     ` [PATCH v4 02/16] Use string list strdup_strings for mimetypes andy
@ 2018-06-27 17:28                       ` Jason
  0 siblings, 0 replies; 140+ messages in thread
From: Jason @ 2018-06-27 17:28 UTC (permalink / raw)


Thanks John, merged.


^ permalink raw reply	[flat|nested] 140+ messages in thread

* [PATCH v4 13/16] ui-shared: deduplicate some code in repolink
  2018-06-20 10:13                     ` [PATCH v4 13/16] ui-shared: deduplicate some code in repolink andy
@ 2018-06-27 17:29                       ` Jason
  2018-06-27 17:50                         ` Jason
  0 siblings, 1 reply; 140+ messages in thread
From: Jason @ 2018-06-27 17:29 UTC (permalink / raw)


Merged, thanks.


^ permalink raw reply	[flat|nested] 140+ messages in thread

* [PATCH v4 11/16] md2html: add asset mapping
  2018-06-20 10:12                     ` [PATCH v4 11/16] md2html: add asset mapping andy
@ 2018-06-27 17:32                       ` Jason
  2018-06-27 20:00                         ` john
  0 siblings, 1 reply; 140+ messages in thread
From: Jason @ 2018-06-27 17:32 UTC (permalink / raw)


On Wed, Jun 20, 2018 at 12:13 PM Andy Green <andy at warmcat.com> wrote:

>         md2html <README.md README.md /path/to/plain/directory/
>
> The trailing "/" is important.

Can we make it not important? That is, if the type is always
explicitly a directory, treat it as such using the usual file name
joining logic.

Alternatively, and perhaps better, don't introduce a second argument.
Just pass the full file path in the first argument, and have asset
mapping always work it out in the right way.

Jason


^ permalink raw reply	[flat|nested] 140+ messages in thread

* [PATCH v4 16/16] md2html: change css name to not conflict with highlight
  2018-06-20 10:13                     ` [PATCH v4 16/16] md2html: change css name to not conflict with highlight andy
@ 2018-06-27 17:37                       ` Jason
  2018-06-27 21:58                         ` andy
  0 siblings, 1 reply; 140+ messages in thread
From: Jason @ 2018-06-27 17:37 UTC (permalink / raw)


Hi Andy,

This seems like an obvious thing to merge, but I'm actually not so
certain I understand its necessity. md2html uses the highlight class.
Our css uses the highlight class. You're saying this conflicts with
something? From where? Third-party CSS? If that's the case, and if
it's a serious problem to recon with, do we then want to just
namespace all of our classes as .cgit subclasses, or as
.cgit-highlight, .cgit-whatever prefixes?

Jason


^ permalink raw reply	[flat|nested] 140+ messages in thread

* [PATCH v4 13/16] ui-shared: deduplicate some code in repolink
  2018-06-27 17:29                       ` Jason
@ 2018-06-27 17:50                         ` Jason
  0 siblings, 0 replies; 140+ messages in thread
From: Jason @ 2018-06-27 17:50 UTC (permalink / raw)


And, reverted.

The code is not the same; this broke tests. html_url_arg != html_url_path.


^ permalink raw reply	[flat|nested] 140+ messages in thread

* [PATCH v4 00/16] Render READMEs inline in tree view
  2018-06-27 17:18                     ` Jason
  2018-06-27 17:26                       ` Fancier Source view [Was: Re: [PATCH v4 00/16] Render READMEs inline in tree view] Jason
@ 2018-06-27 19:51                       ` john
  2018-06-27 22:48                         ` andy
  2018-06-27 23:22                         ` Jason
  2018-06-27 22:36                       ` andy
  2 siblings, 2 replies; 140+ messages in thread
From: john @ 2018-06-27 19:51 UTC (permalink / raw)


Hi Jason,

On Wed, Jun 27, 2018 at 07:18:57PM +0200, Jason A. Donenfeld wrote:
> With the current state of this series, cgit would have the following options:
> 
> - render.<ext>
> - inline-readme
> - render-filter

This one is only a concept, not a configuration value (just a note since
I couldn't remember introducing it!)

> - about-filter
> - commit-filter
> - source-filter
> - owner-filter
> - readme=file
> - readme=:file
> 
> Whoa nelly. Of these, about-filter, commit-filter, source-filter, and
> owner-filter all have analogs in the repo.* namespace, which makes
> sense; it seems this was omitted from the render-filter introduced by
> this series. The thing that unifies about-filter, commit-filter,
> source-filter, and owner-filter is that they all modify some aspect of
> the rendered output, either via fork/exec or via lua.
> 
> In adding readme files under the tree view, the obvious observation is
> that this is pretty much the same type of rendering that we're doing
> in about-filter.
> 
> In adding rendering of arbitrary files in blob view, this is
> essentially a fancy source view, with the one caveat of our
> interesting handling of line numbers.
> 
> So, I'd propose the following re-organization (and after we nail it
> down, we can bikeshed about compatibility with old configs, but for
> now let's focus on ideal design):

I'll comment on the proposals inline below, but before doing that let me
try to remember why "render.<ext>" exists in the first place (it's a
couple of years since I wrote that patch so I'm not entirely sure this
is the rationale I had at the time!)

Thinking though it now, I think about-filter and the render-filter
concept are equivalent.  And for the purpose of putting an inline
directory readme in the tree view, that may be sufficient.

However, my series was adding a new UI mode and there are a couple of
requirements there that I can't see a way to fix without render.<ext> or
something equivalent [1]:

- It is desirable to have the existing source view in addition to the
  rendered content, preferably with syntax highlighting via the source
  filter; for example Markdown, HTML or SVG can be sensibly viewed in
  both ways

- For some content types, the easiest way to render it is to simply
  include the file with an iframe; this is the case for images and PDFs
  at the moment

Now, if the render filter can say "I don't support this" and can do so
reasonably efficiently, we can use that to control whether render mode
is enabled and whether we use the "fallback to mimetype" to include an
iframe.  Or with the asset path extension to the filter arguments, we
could have the filter generate the <iframe> element itself [2].

> - We retain commit-filter, source-filter, and owner-filter as we have them now.
> - We rename about-filter to readme-filter.

I agree with unifying the concepts, but might want to bikeshed the name
since if we go for render mode on all files then it applies to a bit
more than just readme files.

> - We remove `readme` and instead introduce `readme-filename`, which
> can be specified multiple times as is habit. This would simply take
> the set of filenames considered to be readme files (readme.md,
> readme.txt, etc). [Bikeshed discussion: case insensitive?]
> - We introduce an options at the global level and at the .repo level
> of `about-readme=/path/to/absolute/file` and `about-readme=<BRANCH>:`
> and `about-readme=:`. The first would replace our original usage of
> `readme=/path/to=file`, and the second would replace the use of
> `readme=branch:whatever`, specifying an explicit branch (like
> cgit.git's wiki branch), and the third would indicate the default
> branch.

I think a distinction between repo-level readme and readme that can
apply to each directory is useful.  We can probably also fall back to
directory-level readme config using the default branch and root
directory if the repo-level config is unset.

I'm not sure there's much value in removing blob references from
about-readme, although extending it to allow specifying a tree and then
looking for the readme filename would be neat.

> - We introduce an option at the global level and at the .repo level of
> `tree-readme=1/0` to display (or not) the readme under each tree.

Agree.

> - We do not introduce render-filter. We do not introduce render.<ext>;
> such extension selection is successfully handled by the various
> filters themselves already.

Agree on render-filter, but we need a better proposal for how to handle
the <iframe> case and the "render not supported" case if we want to do
those outside the filter.


[1] This could be the exit status of the render filter, but I'm not sure
    how well the "probe" mode will fit it
[2] We do load the content redundantly in this case and we'll have to
    make sure that our SIGPIPE handling is correct if the filter exits
    without reading all of its stdin, but that's probably acceptable


Regards,
John


^ permalink raw reply	[flat|nested] 140+ messages in thread

* [PATCH v4 11/16] md2html: add asset mapping
  2018-06-27 17:32                       ` Jason
@ 2018-06-27 20:00                         ` john
  0 siblings, 0 replies; 140+ messages in thread
From: john @ 2018-06-27 20:00 UTC (permalink / raw)


On Wed, Jun 27, 2018 at 07:32:56PM +0200, Jason A. Donenfeld wrote:
> On Wed, Jun 20, 2018 at 12:13 PM Andy Green <andy at warmcat.com> wrote:
> 
> >         md2html <README.md README.md /path/to/plain/directory/
> >
> > The trailing "/" is important.
> 
> Can we make it not important? That is, if the type is always
> explicitly a directory, treat it as such using the usual file name
> joining logic.

Seems sensible.  This was originally posted as a proof of concept, so
would benefit from a bit of tidying.

I'm not actually sure if it does the right think when cfg.virtual_root
is NULL so we may need something a bit more complicated than this (and I
can't see a way that doesn't require the filter to handle both types of
URL).

> Alternatively, and perhaps better, don't introduce a second argument.
> Just pass the full file path in the first argument, and have asset
> mapping always work it out in the right way.

It depends how we think about the first argument.  The URL of the
"current page" when we call the filter will be something like:

	/repo/tree/subdir/README.md

but the asset path should point to:

	/repo/plain/subdir/

We could just say it's the URL of the input file, which is actually
quite nice if we want the filter to be able to replace the content with
an iframe.

However, I think there's a big benefit in backwards compatibility if we
keep the first argument as a file name and don't change it to a URL.
But that doesn't stop us making the new argument into a URL to the file.


Regards,
John


^ permalink raw reply	[flat|nested] 140+ messages in thread

* Fancier Source view [Was: Re: [PATCH v4 00/16] Render READMEs inline in tree view]
  2018-06-27 17:26                       ` Fancier Source view [Was: Re: [PATCH v4 00/16] Render READMEs inline in tree view] Jason
@ 2018-06-27 20:05                         ` john
  0 siblings, 0 replies; 140+ messages in thread
From: john @ 2018-06-27 20:05 UTC (permalink / raw)


On Wed, Jun 27, 2018 at 07:26:13PM +0200, Jason A. Donenfeld wrote:
> Splitting out this issue into a different thread, because I think it's
> orthogonal to the other topic.
> 
> On Wed, Jun 27, 2018 at 7:18 PM Jason A. Donenfeld <Jason at zx2c4.com> wrote:
> > In adding rendering of arbitrary files in blob view, this is
> > essentially a fancy source view, with the one caveat of our
> > interesting handling of line numbers.
> 
> People click a .c file and they get pygments highlighting. That's
> good. People click a .pdf or a .md and they get either a hexdump or a
> highlighted .md source. Github has made different behavior more
> popular -- namely, rendering the .pdf and the .md. The obvious way to
> handle this is augmenting the source-view to spit something different
> out.
> 
> Alternatively, my previously proposed readme-filter could be renamed
> to render-filter, and we could do everything in one place with one
> filter, and decide exclusively on the basis of filetype.
> 
> Either way, we have this issue of line numbers. We have a few ways of
> handling this:
> 
> a. Not print them ever when a source-filter/render-filter is
> specified, leaving that up to the renderer to do.
> b. If the renderer doesn't want line numbers, it can return a special
> exit code (197, for example) to indicate that to cgit.
> c. If the renderer doesn't want line numbers, it can just omit some
> !important css to remove them at the end.
> d. We introduce a maze of filetype selection rendering logic options.
> e. Something else?
> 
> I'm most inclined to go with a or b, but neither seems entirely
> appealing. Thoughts?

d. is basically what we have with "render.<ext>" in this series, but I
think e. might be better.  Specifically, I think we shouldn't conflate
source and rendered views because syntax highlighted Markdown, or SVG,
or HTML is still potentially useful.

If source and rendered views are distinct, then source view always has
line numbers (or it's a hex dump) and we just need the filter to return
a special exit status to mean "this file is unsupported", and we disable
the rendered view when that happens.

As an extension, we could disable the source view if rendering is
supported and the file looks like binary, so that the hex dump isn't
available when we have a better option.


John


^ permalink raw reply	[flat|nested] 140+ messages in thread

* [PATCH v4 16/16] md2html: change css name to not conflict with highlight
  2018-06-27 17:37                       ` Jason
@ 2018-06-27 21:58                         ` andy
  2018-06-28  8:32                           ` john
  0 siblings, 1 reply; 140+ messages in thread
From: andy @ 2018-06-27 21:58 UTC (permalink / raw)




On 06/28/2018 01:37 AM, Jason A. Donenfeld wrote:
> Hi Andy,
> 
> This seems like an obvious thing to merge, but I'm actually not so
> certain I understand its necessity. md2html uses the highlight class.
> Our css uses the highlight class. You're saying this conflicts with
> something? From where? Third-party CSS? If that's the case, and if

I'm saying blame renders wrongly on Fedora 28 for these reasons and the 
patch fixes it.

> it's a serious problem to recon with, do we then want to just
> namespace all of our classes as .cgit subclasses, or as
> .cgit-highlight, .cgit-whatever prefixes?

I dunno what you want to do about it, but I wanted it to render 
correctly on Fedora 28, which this patch is enough to do.

-Andy



^ permalink raw reply	[flat|nested] 140+ messages in thread

* [PATCH v4 00/16] Render READMEs inline in tree view
  2018-06-27 17:18                     ` Jason
  2018-06-27 17:26                       ` Fancier Source view [Was: Re: [PATCH v4 00/16] Render READMEs inline in tree view] Jason
  2018-06-27 19:51                       ` [PATCH v4 00/16] Render READMEs inline in tree view john
@ 2018-06-27 22:36                       ` andy
  2018-06-27 22:46                         ` Jason
  2 siblings, 1 reply; 140+ messages in thread
From: andy @ 2018-06-27 22:36 UTC (permalink / raw)




On 06/28/2018 01:18 AM, Jason A. Donenfeld wrote:
> Hey Andy,
> 
> Thanks for this patchset. It looks like this is shaping up into a nice
> direction. However, I'm a bit concerned about our nobs becoming
> slightly overlapping and incoherent, and I think that with this
> series, we should also unify how we handle rendering.

Well, I can understand that from your POV.

However I also have a POV... "This series" represents my attempt to 
align cgit to a piece of github that my users will definitely miss. 
Nobody is paying me to do it and I don't have an endless budget of time 
to lavish on it (and it seems, neither do you...).

If cgit can't do what I need in a reasonable timescale, even with my 
contribution, my choices are:

  - become a cgit developer until the happy day comes

  - maintaining my own OOT branch until it can natively do the same thing

  - use something else

> With the current state of this series, cgit would have the following options:
> 
> - render.<ext>
> - inline-readme
> - render-filter
> - about-filter
> - commit-filter
> - source-filter
> - owner-filter
> - readme=file
> - readme=:file
> 
> Whoa nelly. Of these, about-filter, commit-filter, source-filter, and
> owner-filter all have analogs in the repo.* namespace, which makes
> sense; it seems this was omitted from the render-filter introduced by
> this series. The thing that unifies about-filter, commit-filter,
> source-filter, and owner-filter is that they all modify some aspect of
> the rendered output, either via fork/exec or via lua.
> 
> In adding readme files under the tree view, the obvious observation is
> that this is pretty much the same type of rendering that we're doing
> in about-filter.

Yeah, about has lost all meaning if this series gets in.

> In adding rendering of arbitrary files in blob view, this is
> essentially a fancy source view, with the one caveat of our
> interesting handling of line numbers.
> 
> So, I'd propose the following re-organization (and after we nail it
> down, we can bikeshed about compatibility with old configs, but for
> now let's focus on ideal design):
> 
> - We retain commit-filter, source-filter, and owner-filter as we have them now.
> - We rename about-filter to readme-filter.
> - We remove `readme` and instead introduce `readme-filename`, which
> can be specified multiple times as is habit. This would simply take
> the set of filenames considered to be readme files (readme.md,
> readme.txt, etc). [Bikeshed discussion: case insensitive?]

... what's actually wrong with aligning with The Github Way?

> - We introduce an options at the global level and at the .repo level
> of `about-readme=/path/to/absolute/file` and `about-readme=<BRANCH> > and `about-readme=:`. The first would replace our original usage of

How "about" just drop about-*, and the about tab, ui-about-* etc.

Set the readme names using both [repo.]about-readme= for compatibility 
and [repo.]readme=

Almost all projects have a README of some kind at the root of their 
source tree.  It was a standard layout for decades.  So this just 
replaces about.  And aligns with github.

> `readme=/path/to=file`, and the second would replace the use of
> `readme=branch:whatever`, specifying an explicit branch (like
> cgit.git's wiki branch), and the third would indicate the default
> branch.

... and don't do that, just show the inline README for the rev context.

> - We introduce an option at the global level and at the .repo level of
> `tree-readme=1/0` to display (or not) the readme under each tree.

... just always display any compatible readme a la github.

> - We do not introduce render-filter. We do not introduce render.<ext>;
> such extension selection is successfully handled by the various
> filters themselves already.

That I don't know much about.  However, we can at least get rid of or 
repurpose about filter for this, if about if going away.

The copyright message says cgit has been around 22 years... since then 
programmers have been born and since the age of 12 their view of git has 
been shaped only by github.  It's not that hard to overstate its 
importance but in a few ways, unless something in cgit is really better, 
the way forward is to align, or align and improve... IMHO.

-Andy

> John, Christian -- what are your thoughts on this?
> 
> Regards,
> Jason
> 


^ permalink raw reply	[flat|nested] 140+ messages in thread

* [PATCH v4 00/16] Render READMEs inline in tree view
  2018-06-27 22:36                       ` andy
@ 2018-06-27 22:46                         ` Jason
  2018-06-27 23:08                           ` andy
  0 siblings, 1 reply; 140+ messages in thread
From: Jason @ 2018-06-27 22:46 UTC (permalink / raw)


Hi Andy,

I'm happy to engage technically here in order to find the best way of
going about this. However,

> Nobody is paying me to do it and I don't have an endless budget of time
> to lavish on it (and it seems, neither do you...).
> If cgit can't do what I need in a reasonable timescale, even with my
> contribution, my choices are:
> been shaped only by github.  It's not that hard to overstate its
> importance but in a few ways, unless something in cgit is really better,
> the way forward is to align, or align and improve... IMHO.

I don't see the relevance of whether or not you're paid and how much
time you have to implement things, or what predictions are about sink
or swim with regards to Github.

I think the general ideas you've presented in these patchsets are good
ones, and now it's time to collaborate on the best way to go about
doing it. Part of what we're encountering here is the fact that cgit
hasn't originally had a robust display/hosting intent; it was mostly
around showing the state of the git repository. Now we're trying to
grow beyond that. Hence, I'd like to organize this in a sensible way
so that such rendering capabilities are available at the heart of
cgit, rather than haphazardly added on with a smattering of
contradictory configuration switches. In spite of your pay grade, your
time budget, or your timescale, I'm going to make sure this gets done
in the right way.

Jason


^ permalink raw reply	[flat|nested] 140+ messages in thread

* [PATCH v4 00/16] Render READMEs inline in tree view
  2018-06-27 19:51                       ` [PATCH v4 00/16] Render READMEs inline in tree view john
@ 2018-06-27 22:48                         ` andy
  2018-06-27 23:22                         ` Jason
  1 sibling, 0 replies; 140+ messages in thread
From: andy @ 2018-06-27 22:48 UTC (permalink / raw)




On 06/28/2018 03:51 AM, John Keeping wrote:
> Hi Jason,
> 
> On Wed, Jun 27, 2018 at 07:18:57PM +0200, Jason A. Donenfeld wrote:
>> With the current state of this series, cgit would have the following options:
>>
>> - render.<ext>
>> - inline-readme
>> - render-filter
> 
> This one is only a concept, not a configuration value (just a note since
> I couldn't remember introducing it!)
> 
>> - about-filter
>> - commit-filter
>> - source-filter
>> - owner-filter
>> - readme=file
>> - readme=:file
>>
>> Whoa nelly. Of these, about-filter, commit-filter, source-filter, and
>> owner-filter all have analogs in the repo.* namespace, which makes
>> sense; it seems this was omitted from the render-filter introduced by
>> this series. The thing that unifies about-filter, commit-filter,
>> source-filter, and owner-filter is that they all modify some aspect of
>> the rendered output, either via fork/exec or via lua.
>>
>> In adding readme files under the tree view, the obvious observation is
>> that this is pretty much the same type of rendering that we're doing
>> in about-filter.
>>
>> In adding rendering of arbitrary files in blob view, this is
>> essentially a fancy source view, with the one caveat of our
>> interesting handling of line numbers.
>>
>> So, I'd propose the following re-organization (and after we nail it
>> down, we can bikeshed about compatibility with old configs, but for
>> now let's focus on ideal design):
> 
> I'll comment on the proposals inline below, but before doing that let me
> try to remember why "render.<ext>" exists in the first place (it's a
> couple of years since I wrote that patch so I'm not entirely sure this
> is the rationale I had at the time!)
> 
> Thinking though it now, I think about-filter and the render-filter
> concept are equivalent.  And for the purpose of putting an inline
> directory readme in the tree view, that may be sufficient.

That's also how it seems to be having meddled about in there a bit now. 
In fact just globally the whole "about" thing is a less flexible version 
of what this is trying to do.

> However, my series was adding a new UI mode and there are a couple of
> requirements there that I can't see a way to fix without render.<ext> or
> something equivalent [1]:
> 
> - It is desirable to have the existing source view in addition to the
>    rendered content, preferably with syntax highlighting via the source
>    filter; for example Markdown, HTML or SVG can be sensibly viewed in
>    both ways
> 
> - For some content types, the easiest way to render it is to simply
>    include the file with an iframe; this is the case for images and PDFs
>    at the moment
> 
> Now, if the render filter can say "I don't support this" and can do so
> reasonably efficiently, we can use that to control whether render mode
> is enabled and whether we use the "fallback to mimetype" to include an
> iframe.  Or with the asset path extension to the filter arguments, we
> could have the filter generate the <iframe> element itself [2].
> 
>> - We retain commit-filter, source-filter, and owner-filter as we have them now.
>> - We rename about-filter to readme-filter.
> 
> I agree with unifying the concepts, but might want to bikeshed the name
> since if we go for render mode on all files then it applies to a bit
> more than just readme files.

Just ejecting about* and replace with render will do it and keep the 
number of implementations related to this at 1.

>> - We remove `readme` and instead introduce `readme-filename`, which
>> can be specified multiple times as is habit. This would simply take
>> the set of filenames considered to be readme files (readme.md,
>> readme.txt, etc). [Bikeshed discussion: case insensitive?]
>> - We introduce an options at the global level and at the .repo level
>> of `about-readme=/path/to/absolute/file` and `about-readme=<BRANCH>:`
>> and `about-readme=:`. The first would replace our original usage of
>> `readme=/path/to=file`, and the second would replace the use of
>> `readme=branch:whatever`, specifying an explicit branch (like
>> cgit.git's wiki branch), and the third would indicate the default
>> branch.
> 
> I think a distinction between repo-level readme and readme that can
> apply to each directory is useful.  We can probably also fall back to
> directory-level readme config using the default branch and root
> directory if the repo-level config is unset.

It doesn't sound too hard but when would I use it?  Is it a case where 
rendering a list of matches would solve it?

-Andy

> I'm not sure there's much value in removing blob references from
> about-readme, although extending it to allow specifying a tree and then
> looking for the readme filename would be neat.
> 
>> - We introduce an option at the global level and at the .repo level of
>> `tree-readme=1/0` to display (or not) the readme under each tree.
> 
> Agree.
> 
>> - We do not introduce render-filter. We do not introduce render.<ext>;
>> such extension selection is successfully handled by the various
>> filters themselves already.
> 
> Agree on render-filter, but we need a better proposal for how to handle
> the <iframe> case and the "render not supported" case if we want to do
> those outside the filter.
> 
> 
> [1] This could be the exit status of the render filter, but I'm not sure
>      how well the "probe" mode will fit it
> [2] We do load the content redundantly in this case and we'll have to
>      make sure that our SIGPIPE handling is correct if the filter exits
>      without reading all of its stdin, but that's probably acceptable
> 
> 
> Regards,
> John
> 


^ permalink raw reply	[flat|nested] 140+ messages in thread

* [PATCH v4 00/16] Render READMEs inline in tree view
  2018-06-27 22:46                         ` Jason
@ 2018-06-27 23:08                           ` andy
  0 siblings, 0 replies; 140+ messages in thread
From: andy @ 2018-06-27 23:08 UTC (permalink / raw)




On 06/28/2018 06:46 AM, Jason A. Donenfeld wrote:
> Hi Andy,
> 
> I'm happy to engage technically here in order to find the best way of
> going about this. However,
> 
>> Nobody is paying me to do it and I don't have an endless budget of time
>> to lavish on it (and it seems, neither do you...).
>> If cgit can't do what I need in a reasonable timescale, even with my
>> contribution, my choices are:
>> been shaped only by github.  It's not that hard to overstate its
>> importance but in a few ways, unless something in cgit is really better,
>> the way forward is to align, or align and improve... IMHO.
> 
> I don't see the relevance of whether or not you're paid and how much
> time you have to implement things, or what predictions are about sink
> or swim with regards to Github.

Mmm I could tell from your reply it's irrelevant to you.

That's why I pointed it out, because it's very relevant to me and will 
inform what I choose to do.

> I think the general ideas you've presented in these patchsets are good
> ones, and now it's time to collaborate on the best way to go about
> doing it. Part of what we're encountering here is the fact that cgit
> hasn't originally had a robust display/hosting intent; it was mostly
> around showing the state of the git repository. Now we're trying to
> grow beyond that. Hence, I'd like to organize this in a sensible way
> so that such rendering capabilities are available at the heart of
> cgit, rather than haphazardly added on with a smattering of

It's not that I don't understand the reasoning.  There is a lot of cruft 
because the project has been around a long while.  But it's not my cruft.

> contradictory configuration switches. In spite of your pay grade, your
> time budget, or your timescale, I'm going to make sure this gets done
> in the right way.
I also run a FOSS project that has been around for years and have dealt 
with hundreds of contributions.

These features have been around for 10 years in github and still not in 
cgit, done right or wrong.  I think everyone will be better off if we 
can find a way.

-Andy

> Jason
> 


^ permalink raw reply	[flat|nested] 140+ messages in thread

* [PATCH v4 00/16] Render READMEs inline in tree view
  2018-06-27 19:51                       ` [PATCH v4 00/16] Render READMEs inline in tree view john
  2018-06-27 22:48                         ` andy
@ 2018-06-27 23:22                         ` Jason
  2018-06-28  8:28                           ` john
  1 sibling, 1 reply; 140+ messages in thread
From: Jason @ 2018-06-27 23:22 UTC (permalink / raw)


Hey John,

Thanks tons for your input, as always.

On Wed, Jun 27, 2018 at 9:51 PM John Keeping <john at keeping.me.uk> wrote:
> - It is desirable to have the existing source view in addition to the
>   rendered content, preferably with syntax highlighting via the source
>   filter; for example Markdown, HTML or SVG can be sensibly viewed in
>   both ways

Got it, so this is the big kicker. Essentially we need a nice way for
the render filter to fallback to the source filter, as you said, with
then a `&source=1` override (and link) if a user explicitly wants the
source, in order to have both views. That seems like a good idea. This
would solve the issue with line numbers as well.

But how to implement this efficiently? With the lua filters, it really
doesn't matter, but with the exec filters, we perhaps incur the
penalty of exec'ing twice. Maybe that's acceptable, though. The other
approach would be for the source-filter to print its own line numbers,
and so the render filter itself could just fall back to calling
internally the source filter, and perhaps even indicating what it did
via the exit code, but I think I like this idea less. A third option
is to do this selection entirely within cgit via mimetype/fileext
selection, while I was initially hesitant about this, maybe this is an
okay approach after all.

Assuming we go with the first approach -- of the renderer fallback --
we would then have:

- render-filter (nee about-filter)
- source-filter

Then, if render-filter returns an exit code, cgit assumes we're in
source filter mode.

>
> - For some content types, the easiest way to render it is to simply
>   include the file with an iframe; this is the case for images and PDFs
>   at the moment
>
> Now, if the render filter can say "I don't support this" and can do so
> reasonably efficiently, we can use that to control whether render mode
> is enabled and whether we use the "fallback to mimetype" to include an
> iframe.  Or with the asset path extension to the filter arguments, we
> could have the filter generate the <iframe> element itself [2].

This should certainly be up to the actual render script. This means
we'll need to path sensible blob paths so that the render script can
correctly fill in <img src="..." or populate a pdf.js output
correctly.

> I agree with unifying the concepts, but might want to bikeshed the name
> since if we go for render mode on all files then it applies to a bit
> more than just readme files.

You're right about that. render-filter it is then.

> I think a distinction between repo-level readme and readme that can
> apply to each directory is useful.  We can probably also fall back to
> directory-level readme config using the default branch and root
> directory if the repo-level config is unset.
>
> I'm not sure there's much value in removing blob references from
> about-readme, although extending it to allow specifying a tree and then
> looking for the readme filename would be neat.

Yes, right. So, about-readme takes these values:

about-readme=/path/to/absolute/file/not/in/a/git/repo
about-readme=BRANCH:file/in/branch.md
about-readme=BRANCH:    # selects a "readme" file from BRANCH
about-readme=:file/in/default/branch/stuff.md   # selects stuff.md
from default branch
about-readme=:    # selects a "readme" file from the default branch

This winds up being pretty powerful and relatively simple to
implement. What is a "readme" file? Well, that's given by
readme-filename, as mentioned earlier.

Organizationally, since now we're going to be introducing rendering
into quite a few places, I think we should do this in ui-render.c.

Putting all of this together, we now have the following:

- We retain commit-filter, source-filter, and owner-filter as we have them now.
- We rename about-filter to render-filter.
- render-filter receives a fuller filename with useful path
information for printing out iframes, img tags, and so forth.
- We remove readme and instead introduce readme-filename instead.
- We introduce a global and a .repo level about-readme that takes the
above syntax.
- We introduce tree-readme=1/0.
- Viewing files in /tree defaults to render-filter. If that returns
error, it falls back to source-filter.
- Viewing files with /tree?source=1 goes straight to source-filter.
- When source-filter is used, cgit prints its usual line numbers.
- If source-filter fails, we print our nice hexdump or plaintext printer.
- When render-filter is used, cgit shows in the top bar a helpful link
to go to the source view.

Does that seem like a good synthesis of ideas? Or still more things to consider?

Jason


^ permalink raw reply	[flat|nested] 140+ messages in thread

* [PATCH v4 00/16] Render READMEs inline in tree view
  2018-06-27 23:22                         ` Jason
@ 2018-06-28  8:28                           ` john
  2018-07-03 19:34                             ` Jason
  0 siblings, 1 reply; 140+ messages in thread
From: john @ 2018-06-28  8:28 UTC (permalink / raw)


On Thu, Jun 28, 2018 at 01:22:34AM +0200, Jason A. Donenfeld wrote:
> Hey John,
> 
> Thanks tons for your input, as always.
> 
> On Wed, Jun 27, 2018 at 9:51 PM John Keeping <john at keeping.me.uk> wrote:
> > - It is desirable to have the existing source view in addition to the
> >   rendered content, preferably with syntax highlighting via the source
> >   filter; for example Markdown, HTML or SVG can be sensibly viewed in
> >   both ways
> 
> Got it, so this is the big kicker. Essentially we need a nice way for
> the render filter to fallback to the source filter, as you said, with
> then a `&source=1` override (and link) if a user explicitly wants the
> source, in order to have both views. That seems like a good idea. This
> would solve the issue with line numbers as well.
> 
> But how to implement this efficiently? With the lua filters, it really
> doesn't matter, but with the exec filters, we perhaps incur the
> penalty of exec'ing twice. Maybe that's acceptable, though. The other
> approach would be for the source-filter to print its own line numbers,
> and so the render filter itself could just fall back to calling
> internally the source filter, and perhaps even indicating what it did
> via the exit code, but I think I like this idea less. A third option
> is to do this selection entirely within cgit via mimetype/fileext
> selection, while I was initially hesitant about this, maybe this is an
> okay approach after all.
> 
> Assuming we go with the first approach -- of the renderer fallback --
> we would then have:
> 
> - render-filter (nee about-filter)
> - source-filter
> 
> Then, if render-filter returns an exit code, cgit assumes we're in
> source filter mode.

Yeah, I don't think there's any way to avoid exec'ing twice in source
view - we need to run the source filter for output and we need the
render filter to tell us whether we should output a link to the rendered
content.

If we've been asked to render and can render, then the render filter can
just run and exit normally, but if it wants to say "unsupported" then we
have to exec the source filter as well.

There is an alternative if we're willing to move away from simple
filters and introduce a new filter type which provides headers before
its output, for example:

	Mode: source
	Supported-modes: source, render

	<content...>

I'm not convinced that this is a good thing, but the only other way to
avoid exec'ing two processes is to configure in CGit.  My hesitation
with that is that the only way we have to do that is via file extensions
and I don't really like tying everything to a file extension ("README"
is a perfectly fine filename and we should be able to display that as
rendered Asciidoc if that's what it is).

> > - For some content types, the easiest way to render it is to simply
> >   include the file with an iframe; this is the case for images and PDFs
> >   at the moment
> >
> > Now, if the render filter can say "I don't support this" and can do so
> > reasonably efficiently, we can use that to control whether render mode
> > is enabled and whether we use the "fallback to mimetype" to include an
> > iframe.  Or with the asset path extension to the filter arguments, we
> > could have the filter generate the <iframe> element itself [2].
> 
> This should certainly be up to the actual render script. This means
> we'll need to path sensible blob paths so that the render script can
> correctly fill in <img src="..." or populate a pdf.js output
> correctly.

That's what the asset-path feature elsewhere in this series does,
especially if we take your idea of passing the URL path to the file
being rendered.  So we should make that change and pass the path to the
file instead of just a directory.

> > I agree with unifying the concepts, but might want to bikeshed the name
> > since if we go for render mode on all files then it applies to a bit
> > more than just readme files.
> 
> You're right about that. render-filter it is then.
> 
> > I think a distinction between repo-level readme and readme that can
> > apply to each directory is useful.  We can probably also fall back to
> > directory-level readme config using the default branch and root
> > directory if the repo-level config is unset.
> >
> > I'm not sure there's much value in removing blob references from
> > about-readme, although extending it to allow specifying a tree and then
> > looking for the readme filename would be neat.
> 
> Yes, right. So, about-readme takes these values:
> 
> about-readme=/path/to/absolute/file/not/in/a/git/repo
> about-readme=BRANCH:file/in/branch.md
> about-readme=BRANCH:    # selects a "readme" file from BRANCH
> about-readme=:file/in/default/branch/stuff.md   # selects stuff.md
> from default branch
> about-readme=:    # selects a "readme" file from the default branch
> 
> This winds up being pretty powerful and relatively simple to
> implement. What is a "readme" file? Well, that's given by
> readme-filename, as mentioned earlier.
> 
> Organizationally, since now we're going to be introducing rendering
> into quite a few places, I think we should do this in ui-render.c.
> 
> Putting all of this together, we now have the following:
> 
> - We retain commit-filter, source-filter, and owner-filter as we have them now.
> - We rename about-filter to render-filter.
> - render-filter receives a fuller filename with useful path
> information for printing out iframes, img tags, and so forth.
> - We remove readme and instead introduce readme-filename instead.
> - We introduce a global and a .repo level about-readme that takes the
> above syntax.
> - We introduce tree-readme=1/0.
> - Viewing files in /tree defaults to render-filter. If that returns
> error, it falls back to source-filter.
> - Viewing files with /tree?source=1 goes straight to source-filter.

It's /source/ instead of /tree/ in the current series and I think that's
better than a query parameter since this is a somewhat different view.

> - When source-filter is used, cgit prints its usual line numbers.
> - If source-filter fails, we print our nice hexdump or plaintext printer.

These two are "source-filter usage is unchange", right?

> - When render-filter is used, cgit shows in the top bar a helpful link
> to go to the source view.
> 
> Does that seem like a good synthesis of ideas? Or still more things to consider?

Yes, that looks good to me, modulo figuring out exactly how
render-filter operates.


John


^ permalink raw reply	[flat|nested] 140+ messages in thread

* [PATCH v4 16/16] md2html: change css name to not conflict with highlight
  2018-06-27 21:58                         ` andy
@ 2018-06-28  8:32                           ` john
  0 siblings, 0 replies; 140+ messages in thread
From: john @ 2018-06-28  8:32 UTC (permalink / raw)


On Thu, Jun 28, 2018 at 05:58:42AM +0800, Andy Green wrote:
> On 06/28/2018 01:37 AM, Jason A. Donenfeld wrote:
> > This seems like an obvious thing to merge, but I'm actually not so
> > certain I understand its necessity. md2html uses the highlight class.
> > Our css uses the highlight class. You're saying this conflicts with
> > something? From where? Third-party CSS? If that's the case, and if
> 
> I'm saying blame renders wrongly on Fedora 28 for these reasons and the 
> patch fixes it.
> 
> > it's a serious problem to recon with, do we then want to just
> > namespace all of our classes as .cgit subclasses, or as
> > .cgit-highlight, .cgit-whatever prefixes?
> 
> I dunno what you want to do about it, but I wanted it to render 
> correctly on Fedora 28, which this patch is enough to do.

From the original discussion, I concluded that the problem is that
both Pygments and md2html use "highlight" as a CSS class and previously
we never output both of these on the same page.

For some reason, Andy is getting both of these outputting their styles
in ui-blame.  I can't see how md2html output is ending up in that page
though.


John


^ permalink raw reply	[flat|nested] 140+ messages in thread

* [PATCH v4 00/16] Render READMEs inline in tree view
  2018-06-28  8:28                           ` john
@ 2018-07-03 19:34                             ` Jason
  2018-07-03 19:53                               ` john
  0 siblings, 1 reply; 140+ messages in thread
From: Jason @ 2018-07-03 19:34 UTC (permalink / raw)


Hey John,

On Thu, Jun 28, 2018 at 10:29 AM John Keeping <john at keeping.me.uk> wrote:
> Yeah, I don't think there's any way to avoid exec'ing twice in source
> view - we need to run the source filter for output and we need the
> render filter to tell us whether we should output a link to the rendered
> content.

Let's do it this way then. Since rendering anyway usually amounts to:

case "$(printf '%s' "$1" | tr '[:upper:]' '[:lower:]')" in
        *.markdown|*.mdown|*.md|*.mkd) exec ./md2html; ;;
        *.rst) exec ./rst2html; ;;
        *.[1-9]) exec ./man2html; ;;
        *.htm|*.html) exec cat; ;;
        *.txt|*) exec ./txt2html; ;;
esac

Then we can just reimplement the dispatcher in Lua, and this whole
issue goes away.

> That's what the asset-path feature elsewhere in this series does,
> especially if we take your idea of passing the URL path to the file
> being rendered.  So we should make that change and pass the path to the
> file instead of just a directory.

Right.

> It's /source/ instead of /tree/ in the current series and I think that's
> better than a query parameter since this is a somewhat different view.

I saw that. And indeed that seems like a good way of doing it.

>
> > - When source-filter is used, cgit prints its usual line numbers.
> > - If source-filter fails, we print our nice hexdump or plaintext printer.
>
> These two are "source-filter usage is unchange", right?

Yes.

> Yes, that looks good to me, modulo figuring out exactly how
> render-filter operates.

render-filter will operate the same way as the current about-filter,
with two exceptions:

- If it returns error 127, then it means rendering wasn't supported
and we should fall back to source view (in the case of it being loaded
from /tree).
- It is passed a full path to the raw files, so that it can generate
correct relative includes.

I think with that settled (if you agree), the previous series can be
reworked to function in this manner? The full plan is looking like:

- We retain commit-filter, source-filter, and owner-filter as we have them now.
- We rename about-filter to render-filter.
- render-filter gets passed a fuller filename with useful path
information for printing out iframes, img tags, and so forth.
- render-filter returns 127 if it does not have a renderer for that file.
- Viewing files in /tree defaults to render-filter. If that returns
127, it falls back to source-filter.
- Viewing files in /source goes straight to source-filter and skips
render-filter.
- When render-filter is used in /tree, cgit shows in the top bar a
helpful link to go to /source.
- We remove readme and instead introduce readme-filename instead.
- We introduce a global and a .repo level about-readme that takes the
above syntax.
- We introduce tree-readme=1/0.


^ permalink raw reply	[flat|nested] 140+ messages in thread

* [PATCH v4 00/16] Render READMEs inline in tree view
  2018-07-03 19:34                             ` Jason
@ 2018-07-03 19:53                               ` john
  2018-07-03 19:58                                 ` Jason
  0 siblings, 1 reply; 140+ messages in thread
From: john @ 2018-07-03 19:53 UTC (permalink / raw)


On Tue, Jul 03, 2018 at 09:34:26PM +0200, Jason A. Donenfeld wrote:
> On Thu, Jun 28, 2018 at 10:29 AM John Keeping <john at keeping.me.uk> wrote:
> > Yeah, I don't think there's any way to avoid exec'ing twice in source
> > view - we need to run the source filter for output and we need the
> > render filter to tell us whether we should output a link to the rendered
> > content.
> 
> Let's do it this way then. Since rendering anyway usually amounts to:
> 
> case "$(printf '%s' "$1" | tr '[:upper:]' '[:lower:]')" in
>         *.markdown|*.mdown|*.md|*.mkd) exec ./md2html; ;;
>         *.rst) exec ./rst2html; ;;
>         *.[1-9]) exec ./man2html; ;;
>         *.htm|*.html) exec cat; ;;
>         *.txt|*) exec ./txt2html; ;;
> esac
> 
> Then we can just reimplement the dispatcher in Lua, and this whole
> issue goes away.

That sounds sensible, although the dispatcher will be getting a bit more
complicated to support the file formats for which we want to output an
<img> or <iframe> tag.

> > That's what the asset-path feature elsewhere in this series does,
> > especially if we take your idea of passing the URL path to the file
> > being rendered.  So we should make that change and pass the path to the
> > file instead of just a directory.
> 
> Right.
> 
> > It's /source/ instead of /tree/ in the current series and I think that's
> > better than a query parameter since this is a somewhat different view.
> 
> I saw that. And indeed that seems like a good way of doing it.
> 
> >
> > > - When source-filter is used, cgit prints its usual line numbers.
> > > - If source-filter fails, we print our nice hexdump or plaintext printer.
> >
> > These two are "source-filter usage is unchange", right?
> 
> Yes.
> 
> > Yes, that looks good to me, modulo figuring out exactly how
> > render-filter operates.
> 
> render-filter will operate the same way as the current about-filter,
> with two exceptions:
> 
> - If it returns error 127, then it means rendering wasn't supported
> and we should fall back to source view (in the case of it being loaded
> from /tree).
> - It is passed a full path to the raw files, so that it can generate
> correct relative includes.
> 
> I think with that settled (if you agree), the previous series can be
> reworked to function in this manner? The full plan is looking like:
> 
> - We retain commit-filter, source-filter, and owner-filter as we have them now.
> - We rename about-filter to render-filter.
> - render-filter gets passed a fuller filename with useful path
> information for printing out iframes, img tags, and so forth.
> - render-filter returns 127 if it does not have a renderer for that file.
> - Viewing files in /tree defaults to render-filter. If that returns
> 127, it falls back to source-filter.
> - Viewing files in /source goes straight to source-filter and skips
> render-filter.
> - When render-filter is used in /tree, cgit shows in the top bar a
> helpful link to go to /source.
> - We remove readme and instead introduce readme-filename instead.
> - We introduce a global and a .repo level about-readme that takes the
> above syntax.
> - We introduce tree-readme=1/0.

Yes, this sounds good to me.

I think backwards compatibility also falls out quite easily in this
approach:

- "about-filter" becomes a deprecated alias for "render-filter"
- "readme" becomes a deprecated alias for "about-readme"

If I can have one more bikeshed... I wonder if "about-content" is better
than "about-readme", the latter feels a bit like we're saying this same
thing twice.


^ permalink raw reply	[flat|nested] 140+ messages in thread

* [PATCH v4 00/16] Render READMEs inline in tree view
  2018-07-03 19:53                               ` john
@ 2018-07-03 19:58                                 ` Jason
  0 siblings, 0 replies; 140+ messages in thread
From: Jason @ 2018-07-03 19:58 UTC (permalink / raw)


On Tue, Jul 3, 2018 at 9:53 PM John Keeping <john at keeping.me.uk> wrote:
> If I can have one more bikeshed... I wonder if "about-content" is better
> than "about-readme", the latter feels a bit like we're saying this same
> thing twice.

Bikeshed granted. :) Yes, that sounds sensible.


^ permalink raw reply	[flat|nested] 140+ messages in thread

* [PATCH v2 02/15] gcc8.1: fix strncat warning
  2018-06-18  2:57                 ` [PATCH v2 02/15] gcc8.1: fix strncat warning andy
@ 2018-07-03 23:45                   ` Jason
  2018-07-03 23:47                     ` andy
  0 siblings, 1 reply; 140+ messages in thread
From: Jason @ 2018-07-03 23:45 UTC (permalink / raw)


Hi Andy,

I can't actually reproduce this with gcc 8.1.0. Could you send me the
output of your `gcc -v`?

Thanks,
Jason


^ permalink raw reply	[flat|nested] 140+ messages in thread

* [PATCH v2 02/15] gcc8.1: fix strncat warning
  2018-07-03 23:45                   ` Jason
@ 2018-07-03 23:47                     ` andy
  2018-07-03 23:50                       ` Jason
  0 siblings, 1 reply; 140+ messages in thread
From: andy @ 2018-07-03 23:47 UTC (permalink / raw)




On 07/04/2018 07:45 AM, Jason A. Donenfeld wrote:
> Hi Andy,
> 
> I can't actually reproduce this with gcc 8.1.0. Could you send me the
> output of your `gcc -v`?

$ gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-redhat-linux/8/lto-wrapper
OFFLOAD_TARGET_NAMES=nvptx-none
OFFLOAD_TARGET_DEFAULT=1
Target: x86_64-redhat-linux
Configured with: ../configure --enable-bootstrap 
--enable-languages=c,c++,fortran,objc,obj-c++,ada,go,lto --prefix=/usr 
--mandir=/usr/share/man --infodir=/usr/share/info 
--with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-shared 
--enable-threads=posix --enable-checking=release --enable-multilib 
--with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions 
--enable-gnu-unique-object --enable-linker-build-id 
--with-gcc-major-version-only --with-linker-hash-style=gnu 
--enable-plugin --enable-initfini-array --with-isl --enable-libmpx 
--enable-offload-targets=nvptx-none --without-cuda-driver 
--enable-gnu-indirect-function --enable-cet --with-tune=generic 
--with-arch_32=i686 --build=x86_64-redhat-linux
Thread model: posix
gcc version 8.1.1 20180502 (Red Hat 8.1.1-1) (GCC)


$ rpm -q gcc
gcc-8.1.1-1.fc28.x86_64

It's the current package on Fedora 28.

-Andy

> Thanks,
> Jason
> 


^ permalink raw reply	[flat|nested] 140+ messages in thread

* [PATCH v2 02/15] gcc8.1: fix strncat warning
  2018-07-03 23:47                     ` andy
@ 2018-07-03 23:50                       ` Jason
  0 siblings, 0 replies; 140+ messages in thread
From: Jason @ 2018-07-03 23:50 UTC (permalink / raw)


On Wed, Jul 4, 2018 at 1:48 AM Andy Green <andy at warmcat.com> wrote:
> $ rpm -q gcc
> gcc-8.1.1-1.fc28.x86_64
>
> It's the current package on Fedora 28.

8.1.1, thanks.


^ permalink raw reply	[flat|nested] 140+ messages in thread

end of thread, other threads:[~2018-07-03 23:50 UTC | newest]

Thread overview: 140+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-06-11  7:08 Rendering of README.md inline with inner tree view dirs andy
2018-06-11  7:31 ` list
2018-06-11  7:38   ` andy
2018-06-11  7:53     ` list
2018-06-11  8:05       ` andy
2018-06-11 15:38         ` john
2018-06-12  5:53           ` andy
2018-06-12  8:35             ` list
2018-06-12  9:24               ` john
2018-06-12  9:27                 ` andy
2018-06-12 12:07                   ` john
2018-06-12  9:31             ` john
2018-06-13  1:47               ` andy
2018-06-13  2:01                 ` [PATCH 00/11] Render READMEs inline in tree view andy
2018-06-13  2:01                   ` [PATCH 01/11] Use string list strdup_strings for mimetypes andy
2018-06-13  2:01                   ` [PATCH 02/11] Add source page andy
2018-06-13  2:01                   ` [PATCH 03/11] Parse render filters from the config andy
2018-06-13  2:01                   ` [PATCH 04/11] ui-tree: split out buffer printing andy
2018-06-13  2:01                   ` [PATCH 05/11] ui-tree: use render fileters to display content andy
2018-06-16 14:26                     ` john
2018-06-16 23:16                       ` andy
2018-06-13  2:02                   ` [PATCH 06/11] ui-tree: free read_sha1_file() buffer after use andy
2018-06-16 14:24                     ` john
2018-06-13  2:02                   ` [PATCH 07/11] ui-blame: " andy
2018-06-16 14:23                     ` john
2018-06-16 23:17                       ` andy
2018-06-13  2:02                   ` [PATCH 08/11] ui-tree: print_object: add is_inline param andy
2018-06-16 14:38                     ` john
2018-06-13  2:02                   ` [PATCH 09/11] ui-tree: ls_tail: add walk table param andy
2018-06-16 14:38                     ` john
2018-06-13  2:02                   ` [PATCH 10/11] config: add tree-readme list andy
2018-06-16 14:44                     ` john
2018-06-13  2:02                   ` [PATCH 11/11] ui-tree: render any matching README file in tree view andy
2018-06-16 14:58                     ` john
2018-06-14  3:47                   ` [PATCH 00/11] Render READMEs inline " andy
2018-06-16 14:17                     ` john
2018-06-19  9:01                   ` [PATCH v3 00/17] " andy
2018-06-19  9:01                     ` [PATCH v3 01/17] manpage: fix sorting order andy
2018-06-19 21:35                       ` john
2018-06-19  9:01                     ` [PATCH v3 02/17] blame: css: make blame highlight div absolute and at parent top andy
2018-06-19  9:01                     ` [PATCH v3 03/17] Use string list strdup_strings for mimetypes andy
2018-06-19  9:01                     ` [PATCH v3 04/17] Add source page andy
2018-06-19  9:01                     ` [PATCH v3 05/17] Parse render filters from the config andy
2018-06-19 21:37                       ` john
2018-06-19  9:01                     ` [PATCH v3 06/17] ui-tree: split out buffer printing andy
2018-06-19  9:02                     ` [PATCH v3 07/17] ui-tree: use render filters to display content andy
2018-06-19  9:02                     ` [PATCH v3 08/17] ui-blame: free read_sha1_file() buffer after use andy
2018-06-19 21:46                       ` john
2018-06-19  9:02                     ` [PATCH v3 09/17] ui-tree: ls_tail: add walk table param andy
2018-06-19  9:02                     ` [PATCH v3 10/17] config: add global inline-readme list andy
2018-06-19  9:02                     ` [PATCH v3 11/17] config: add repo " andy
2018-06-19  9:02                     ` [PATCH v3 12/17] ui-tree: render any matching README file in tree view andy
2018-06-19 21:49                       ` john
2018-06-20  0:00                         ` andy
2018-06-19  9:02                     ` [PATCH v3 13/17] md2html: add asset mapping andy
2018-06-19  9:02                     ` [PATCH v3 14/17] md2html-add-asset-postfix-arg andy
2018-06-19  9:02                     ` [PATCH v3 15/17] ui-shared: deduplicate some code in repolink andy
2018-06-19 21:48                       ` john
2018-06-19  9:02                     ` [PATCH v3 16/17] ui-shared: add helper for generating non-urlencoded links andy
2018-06-19 21:55                       ` john
2018-06-20  0:07                         ` andy
2018-06-19  9:02                     ` [PATCH v3 17/17] render: adapt for providing extra filter args for plain andy
2018-06-19 21:56                       ` john
2018-06-20 10:11                   ` [PATCH v4 00/16] Render READMEs inline in tree view andy
2018-06-20 10:12                     ` [PATCH v4 01/16] manpage: fix sorting order andy
2018-06-27 17:27                       ` Jason
2018-06-20 10:12                     ` [PATCH v4 02/16] Use string list strdup_strings for mimetypes andy
2018-06-27 17:28                       ` Jason
2018-06-20 10:12                     ` [PATCH v4 03/16] Add source page andy
2018-06-20 10:12                     ` [PATCH v4 04/16] Parse render filters from the config andy
2018-06-20 10:12                     ` [PATCH v4 05/16] ui-tree: split out buffer printing andy
2018-06-20 10:12                     ` [PATCH v4 06/16] ui-tree: use render filters to display content andy
2018-06-20 10:12                     ` [PATCH v4 07/16] ui-tree: ls_tail: add walk table param andy
2018-06-20 10:12                     ` [PATCH v4 08/16] config: add global inline-readme list andy
2018-06-20 10:12                     ` [PATCH v4 09/16] config: add repo " andy
2018-06-20 10:12                     ` [PATCH v4 10/16] ui-tree: render any matching README file in tree view andy
2018-06-20 10:12                     ` [PATCH v4 11/16] md2html: add asset mapping andy
2018-06-27 17:32                       ` Jason
2018-06-27 20:00                         ` john
2018-06-20 10:12                     ` [PATCH v4 12/16] md2html: add asset postfix arg andy
2018-06-20 10:13                     ` [PATCH v4 13/16] ui-shared: deduplicate some code in repolink andy
2018-06-27 17:29                       ` Jason
2018-06-27 17:50                         ` Jason
2018-06-20 10:13                     ` [PATCH v4 14/16] ui-shared: add helper for generating non-urlencoded links andy
2018-06-20 10:13                     ` [PATCH v4 15/16] render: adapt for providing extra filter args for plain andy
2018-06-20 10:41                       ` andy
2018-06-20 10:13                     ` [PATCH v4 16/16] md2html: change css name to not conflict with highlight andy
2018-06-27 17:37                       ` Jason
2018-06-27 21:58                         ` andy
2018-06-28  8:32                           ` john
2018-06-23 11:04                     ` [PATCH v4 00/16] Render READMEs inline in tree view john
2018-06-23 11:10                       ` andy
2018-06-27 17:18                     ` Jason
2018-06-27 17:26                       ` Fancier Source view [Was: Re: [PATCH v4 00/16] Render READMEs inline in tree view] Jason
2018-06-27 20:05                         ` john
2018-06-27 19:51                       ` [PATCH v4 00/16] Render READMEs inline in tree view john
2018-06-27 22:48                         ` andy
2018-06-27 23:22                         ` Jason
2018-06-28  8:28                           ` john
2018-07-03 19:34                             ` Jason
2018-07-03 19:53                               ` john
2018-07-03 19:58                                 ` Jason
2018-06-27 22:36                       ` andy
2018-06-27 22:46                         ` Jason
2018-06-27 23:08                           ` andy
2018-06-16 14:12                 ` Rendering of README.md inline with inner tree view dirs john
2018-06-16 17:35                   ` john
2018-06-18  2:22                     ` andy
2018-06-18  2:56               ` [PATCH v2 00/15] Render READMEs inline in tree view andy
2018-06-18  2:57                 ` [PATCH v2 01/15] manpage: fix sorting order andy
2018-06-18  2:57                 ` [PATCH v2 02/15] gcc8.1: fix strncat warning andy
2018-07-03 23:45                   ` Jason
2018-07-03 23:47                     ` andy
2018-07-03 23:50                       ` Jason
2018-06-18  2:57                 ` [PATCH v2 03/15] Use string list strdup_strings for mimetypes andy
2018-06-18  2:57                 ` [PATCH v2 04/15] Add source page andy
2018-06-18 19:08                   ` john
2018-06-18 19:27                     ` andy
2018-06-18  2:57                 ` [PATCH v2 05/15] Parse render filters from the config andy
2018-06-18  2:57                 ` [PATCH v2 06/15] ui-tree: split out buffer printing andy
2018-06-18  2:57                 ` [PATCH v2 07/15] ui-tree: use render filters to display content andy
2018-06-18  2:57                 ` [PATCH v2 08/15] ui-blame: free read_sha1_file() buffer after use andy
2018-06-18  2:58                 ` [PATCH v2 09/15] ui-tree: ls_tail: add walk table param andy
2018-06-18  2:58                 ` [PATCH v2 10/15] config: add global inline-readme list andy
2018-06-18 19:32                   ` john
2018-06-18  2:58                 ` [PATCH v2 11/15] config: add repo " andy
2018-06-18 19:30                   ` john
2018-06-18  2:58                 ` [PATCH v2 12/15] ui-tree: render any matching README file in tree view andy
2018-06-18 19:36                   ` john
2018-06-19  1:55                     ` andy
2018-06-19  8:31                       ` john
2018-06-19  8:38                         ` andy
2018-06-18  2:58                 ` [PATCH v2 13/15] md2html: add asset mapping andy
2018-06-18  2:58                 ` [PATCH v2 14/15] md2html-add-asset-postfix-arg andy
2018-06-18 19:21                   ` john
2018-06-19  3:55                     ` andy
2018-06-19  8:34                       ` john
2018-06-18  2:58                 ` [PATCH v2 15/15] render: adapt for providing extra filter args for plain andy
2018-06-18 19:25                   ` john
2018-06-19  3:34                     ` andy

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).