aboutsummaryrefslogtreecommitdiff
path: root/lib/App/Rakuman.pm6
blob: 6fe775727511e6749ba9c022ee10b1a7de421705 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
#! /usr/bin/env false

use v6.d;

use JSON::Fast;
use File::Temp;

unit module App::Rakuman;

#| Render a local file's Pod6 document.
multi sub rakuman (
	Str:D $path,
	Bool:D :$skip-pager = False,
	Bool:D :$try-resolving where !*,
	--> Int
) is export {
	# Extract only the relevant parts
	my ($filename, $filehandle) = tempfile;

	for $path.IO.lines {
		state $pod = False;

		if ($_.trim.fc eq '=begin pod') {
			$pod++;
			$filehandle.say('=begin pod');
			next;
		}

		if (!$pod) {
			next;
		}

		if ($_.trim.fc eq '=end pod') {
			$filehandle.say('=end pod');
			$filehandle.close();
			last;
		}

		$filehandle.say($_);
	}

	my $command = "'$*EXECUTABLE' -Ilib --doc=Rakuman '$filename'";

	if (!$skip-pager) {
		my Str $pager = %*ENV<PAGER> // ($*DISTRO.is-win ?? 'more' !! 'less -r');

		$command ~= " | $pager";
	}

	shell $command;

	0;
}

#| Render an Pod6 document of an installed module.
multi sub rakuman (
	Str:D $module,
	Bool:D :$skip-pager = False,
	Bool:D :$try-resolving where *,
	--> Int
) is export {
	my $path = rakuman-resolve($module);

	# Ensure a module was resolved.
	if (!$path) {
		note "No file found for $module";
		return 3;
	}

	# Run rakuman with the resolved file.
	samewith($path.absolute, :$skip-pager, :!try-resolving);
}

sub rakuman-resolve (
	#| The name of the module that needs to be resolved to its file on disk.
	Str:D $module,
	--> IO::Path
) is export {
	my $file = rakuman-list-installed-compunits(){$module};

	return IO::Path unless $file;

	$*REPO
		.repo-chain
		.grep(*.?prefix.?e)
		.map({
			.?prefix // .path-spec.?path
		})
		.map(*.child("sources/$file"))
		.grep(*.f)
		.first
}

sub rakuman-list-installed-compunits (
	--> Associative
) is export {
	# Most of this massive chain is taken with a lot of inspiration from the zef
	# module, specifically the code that handles the locate functionality.
	$*REPO
		.repo-chain
		.grep(*.?prefix.?e)
		.map({
			.?prefix // .path-spec.?path
		})
		.map(*.child('dist'))
		.grep(*.e)
		.map( *.IO.dir.grep(*.IO.f).Slip)
		.map({
			my %provides = $_.slurp.&from-json<provides>;

			%provides
				.keys
				.map({
					$_ => %provides{$_}.first.value<file>
				})
				.Slip
		})
		.Hash
}

=begin pod

=NAME    App::Rakuman
=AUTHOR  Patrick Spek <p.spek@tyil.work>
=VERSION 0.0.0

=head1 Synopsis

=item1 rakuman [--skip-pager] <file>
=item1 rakuman [--skip-pager] <module>

=head1 Description

Read the main Pod6 documentation of a Raku file or module.

=head1 Examples

Invoke C<rakuman> on a file or installed module.

    rakuman App::Rakuman
    rakuman program.raku

You can make tell it not to open the output in a pager by adding
C<--skip-pager> to the command.

    rakuman --skip-pager App::Rakuman

=head1 Configuration

Rakuman allows configuration through environment variables. These all start
with C<RAKUMAN>.

=head2 Code block highlighting

Code block highlighting is enabled by default if you have C<pygmentize>
installed and executable from your C<$PATH>. If you prefer to not have
highlighting, or are experience slow performance in files with many highlighted
code blocks, you can disable this through C<$RAKUMAN_PYGMENTIZE>.

    RAKUMAN_PYGMENTIZE=0 rakuman …

=head2 Tab sizes

Tab sizes default to B<8> characters wide. This can be altered through the
C<$RAKUMAN_TAB_SIZE> variable.

    RAKUMAN_TAB_SIZE=4 rakuman …

=head2 Line length

The lines get wrapped at B<79> characters by default. The
C<$RAKUMAN_LINE_LENGTH> variable allows you to alter this.

    RAKUMAN_LINE_LENGTH=120 rakuman …

=end pod

# vim: ft=perl6 noet