App-Codit

 view release on metacpan or  search on metacpan

Changes  view on Meta::CPAN

	- Updated manual and documentation.
	- Auto complete is in the tool menu.

0.18 Tue Feb 25 2025
	- Added 'Report a problem' option to the menus.
	- Moved all functionality for showing spaces and tabs, fix indentation and remove trailing spaces, to Tk::CodeText.
	- Simplified plugin SearchReplace.
	- Plugin colors works with several notations/formats.

0.17 Sat Feb 08 2025
	- Modified font selection in settings.
	- Adapted plugins to the modifications in base class Callback of Tk::AppWindow 0.21

0.16 Sun Jan 19 2025
	- Corrected bug in pod
	- Plugin PodViewer has sytem link color
	- Fixed bug in plugin SearchReplace
	- App::Codit::CodeTextManager differentiates between different kinds of log calls.
	- Added documentation App::Codit::Commands and App:Codit::ConfigVariables.
	- Removed -contentinsertbg option. The insert background is automatically set to the foreground color.
	- Changed the -P command line argument of the codit executable to -np. Windows handles them case insensitive.

lib/App/Codit.pm  view on Meta::CPAN

			'-contentactivedelay',
			'-contentautobrackets',
			'-contentautocomplete',
			'-contentautoindent',
			'-contentbackground',
			'-contentbgdspace',
			'-contentbgdtab',
			'-contentbookmarkcolor',
			'-contentfindbg',
			'-contentfindfg',
#			'-contentfont',
			'-contentfontfamily',
			'-contentfontsize',
			'-contentforeground',
			'-contentindent',
			'-contentmatchbg',
			'-contentmatchfg',
			'-contentshowspaces',
			'-contentsyntax',
			'-contenttabs',
			'-contentwrap',
			'-showfolds',
			'-shownumbers',
			'-showstatus',
			'-highlight_themefile',
		],

		#configure the settings panel
		-useroptions => [
			'*page' => 'Editing',
			'*section' => 'Font',
			-contentfontfamily => ['list', 'Family', -filter => 1,	-values => sub { return sort $self->fontFams }
		],
			'*column',
			-contentfontsize => ['spin', 'Size'],
			'*end',
			'*section' => 'Editor settings',
			'*frame',
			-contentautoindent => ['boolean', 'Auto indent'],
			'*column',
			-contentautobrackets => ['boolean', 'Auto brackets'],
			'*column',
			-contentshowspaces => ['boolean', 'Show spaces'],
			'*end',
			'*frame',

lib/App/Codit/CodeTextManager.pm  view on Meta::CPAN

		-contentautoindent => [{-autoindent => $xt}],
		-contentbackground => [{-background => $xt}],
		-contentbgdspace => [{-spacebackground => $text}],
		-contentbgdtab => [{-tabbackground => $text}],
		-contentbookmarkcolor => [{-bookmarkcolor => $text}],
		-contentfindbg => ['PASSIVE'],
		-contentfindfg => ['PASSIVE'],
		-contentmatchbg => ['PASSIVE'],
		-contentmatchfg => ['PASSIVE'],
		-contentforeground => [{-foreground => $xt}],
#		-contentfont => [{-font => $xt}],
		-contentfontfamily => ['PASSIVE'],
		-contentfontsize => ['PASSIVE'],
		-contentindent => [{-indentstyle => $xt}],
		-contentposition => [{-position => $text}],
		-contentshowspaces => [{-showspaces => $text}],
		-contentsyntax => [{-syntax => $text}],
		-contenttabs => [{-tabs => $xt}],
		-contentwrap => [{-wrap => $xt}],
		-showfolds => [$text],
		-shownumbers => [$text],
		-showstatus => [$text],
		-highlight_themefile => [{ -themefile => $text}],

lib/App/Codit/CodeTextManager.pm  view on Meta::CPAN

	my @matchoptions = ();
	my $mbg = $self->cget('-contentmatchbg');
	push @matchoptions, '-background', $mbg if  (defined $mbg) and ($mbg ne '');
	my $mfg = $self->cget('-contentmatchfg');
	push @matchoptions, '-foreground', $mfg if  (defined $mfg) and ($mfg ne '');;
	$widg->configure('-matchoptions', \@matchoptions) if @matchoptions;
	
	#configuring insert background
	$widg->configure('-insertbackground', $widg->cget('-foreground'));
	
	#configuring font
	my $xt = $widg->Subwidget('XText');
	my $fam = $self->cget('-contentfontfamily');
	$fam = 'Courier' unless defined $fam;
	my $siz = $self->cget('-contentfontsize');
	$siz = 10 unless defined $siz;
	$widg->configure(-font => "{$fam} $siz");

	#configuring showspaces. Hack, do not know why this is needed.
	$widg->configure(-showspaces => $self->Extension->configGet('-contentshowspaces'));
}

sub doClear {
	$_[0]->CWidg->clear
}

sub doExport {

lib/App/Codit/CoditTagsEditor.pm  view on Meta::CPAN

use base qw(Tk::Derived Tk::Frame);
Construct Tk::Widget 'CoditTagsEditor';

sub Populate {
	my ($self,$args) = @_;
	
	my $dbackground = delete $args->{'-defaultbackground'};
	die 'You must specify the -defaultbackground option' unless defined $dbackground;
	my $dforeground = delete $args->{'-defaultforeground'};
	die 'You must specify the -defaultforeground option' unless defined $dforeground;
	my $dfont = delete $args->{'-defaultfont'};
	die 'You must specify the -defaultfont option' unless defined $dfont;
	my $ext = delete	$args->{'-extension'};
	die 'You must specify the -extension option' unless defined $ext;
	my $hist = delete	$args->{'-historyfile'};
	die 'You must specify the -historyfile option' unless defined $hist;
	my $themefile = delete $args->{'-themefile'};
	die 'You must specify the -themefile option' unless defined $themefile;
	
	$self->SUPER::Populate($args);
	my $te = $self->TagsEditor(
		-defaultbackground => $dbackground,
		-defaultforeground => $dforeground,
		-defaultfont => $dfont,
		-historyfile => $hist,
	)->pack(-expand => 1, -fill => 'both');
	$self->Advertise(TE => $te);

	my $toolframe =  $self->Frame(
	)->pack(-fill => 'x');
	$toolframe->Button(
		-command => sub {
			my ($file) = $ext->pickFileSave(
				-loadfilter => '.ctt',

lib/App/Codit/ConfigVariables.pod  view on Meta::CPAN

=item B<-useroptions> I<hookable> in L<Tk::AppWindow::Ext::Settings>

Name of the settings file. Default is I<settingsrc>. A typical setup might look
like this:

 -useroptions => [
    '*page' => 'Editing',
    '*section' => 'User interface',
    -contentforeground => ['color', 'Foreground'],
    -contentbackground => ['color', 'Background'],
    -contentfont => ['font', 'Font'],
    '*end',
    '*section' => 'Editor settings',
    -contenttabs => ['text', 'Tab size'],
    -contentwrap => ['radio', 'Wrap', [qw[none char word]]],
    '*end',
    '*page' => 'Icons',
    -icontheme => ['list', 'Icon theme', 'available_icon_themes'],
    -iconsize => ['list', 'Icon size', 'available_icon_sizes'],
    '*page' => 'Bars',
    '*section' => 'Menubar',

lib/App/Codit/Ext/CoditMDI.pm  view on Meta::CPAN

			my $themefile = shift;
			my @list = $self->docList;
			for (@list) {
				my $d = $self->docGet($_);
				$d->configure(-highlight_themefile => $themefile);
				$d->configureTags;
			}
		},
		-defaultbackground => $doc->cget('-contentbackground'),
		-defaultforeground => $doc->cget('-contentforeground'),
		-defaultfont => $doc->CWidg->Subwidget('XText')->cget('-font'),
		-historyfile => $historyfile,
		-extension => $self,
		-themefile => $themefile,
	);
	return (
		'Highlighting' => ['CoditTagsEditor', @opt]
	)
}

sub ToolItems {

lib/App/Codit/Plugins/Exporter.pm  view on Meta::CPAN

color of the Tk::CodeText widget is set.

=item B<Theme file>

Select the Tk::CodeText theme file (extension '.ctt') to use for syntax highlighting.
By default the theme file used in the Tk::CodeText widget is set. You can create your
custom theme file through Menu->Codit->Settings and select the highlighting panel.

=item B<Font>

Set the font used to draw text in your image. By default the font
of the Tk::CodeText widget is set.

=item B<Line numbers>

Tick this if you want line numbers displayed in the left column.

=item B<Tab size>

Set the size of tabs in characters.

lib/App/Codit/Plugins/Exporter.pm  view on Meta::CPAN

	my $widg = $mdi->docWidget;

	my $folder = $self->configGet('-configfolder');
	if (-e "$folder/export2pngrc") {
		my $cff = $self->extGet('ConfigFolder');
		%iv = $cff->loadHash('export2pngrc', 'exporterpng');
	} else {
		$iv{'background'} = $widg->Subwidget('XText')->cget('-background');
		$iv{'foreground'} = $widg->Subwidget('XText')->cget('-foreground');
		$iv{'themefile'} = $self->extGet('ConfigFolder')->ConfigFolder . '/highlight_theme.ctt';
		$iv{'font'} = $self->configGet('-contentfont');
		$iv{'linenumbers'} = 1;
		$iv{'margins'} = 10;
		$iv{'maxwidth'} = 0;
		$iv{'tabsize'} = 3;
	}
	$iv{'outfile'} = "$name.png";

	#popping the form
	my %options = $self->popForm(
#		-acceptempty => 1,

lib/App/Codit/Plugins/Exporter.pm  view on Meta::CPAN

			'*section' => 'Output',
			outfile => ['file', 'File', -width => 50],
			'*end',
			'*section' => 'Theme',
			'*frame',
			background => ['color', 'Background', -width => 8],
			'*column',
			foreground => ['color', 'Foreground', -width => 8],
			'*end',
			themefile => ['file', 'Theme file'],
			font => ['font', 'Font'],
			'*end',
			'*section' => 'Features',
			linenumbers => ['boolean', 'Line numbers'],
			tabsize => ['spin', 'Tab size', -width => 6],
			'*column',
			maxwidth => ['spin', 'Max width', -width => 6],
			margins => ['spin', 'Margins', -width => 6],
			'*end',
		],
		-title => 'Export to PNG',

lib/App/Codit/Plugins/Exporter.pm  view on Meta::CPAN

	for (1 .. $options{'tabsize'}) { $tabstr = "$tabstr " }
	$self->background(Imager::Color->new($options{'background'}));
	$self->imargin($options{'margins'});
	$self->linenumbers($options{'linenumbers'});
	$self->linecolumn(length($widg->linenumber('end - 1c')));
	$self->maxwidth($options{'maxwidth'});
	$self->tabstring($tabstr);

	#converting data
	my $art = $self->extGet('Art');
	my $l = $self->Label(-font => $options{'font'});
	my $f = $l->cget('-font');
	my $fntnorm = $widg->fontCompose($f, -slant => 'roman', -weight => 'normal');
	my $fntbold = $widg->fontCompose($f, -slant => 'roman', -weight => 'bold');
	my $fntbolditalic = $widg->fontCompose($f, -slant => 'italic', -weight => 'bold');
	my $fntitalic = $widg->fontCompose($f, -slant => 'italic', -weight => 'normal');

	my $linespace = $self->fontMetrics($f, '-linespace');
	my $desc = $self->fontMetrics($f, '-descent');

	$l->destroy;

	my $foreground =  Imager::Color->new($options{'foreground'});

	$self->xpos($self->imargin);
	$self->ypos($self->imargin + $linespace - $desc);
	$self->iwidth($self->imargin * 2);
	$self->iheight(($self->imargin * 2) + $linespace);

lib/App/Codit/Plugins/Exporter.pm  view on Meta::CPAN

	my %tags = ();
	for ($theme->tagList) {
		my $tag = $_;
#		print "tag: $tag\n";
		my %options = ();
		my $bold = $theme->getItem($tag, '-weight');
		$bold = 0 unless defined $bold;
		my $slant = $theme->getItem($tag, '-slant');
		$slant = 0 unless defined $slant;
		if ($bold and $slant) {
#			print "  setting font bold/italic\n";
			$options{'-font'} = $fntbolditalic
		} elsif ($bold) {
#			print "  setting font bold\n";
			$options{'-font'} = $fntbold
		} elsif ($slant) {
#			print "  setting font italic\n";
			$options{'-font'} = $fntitalic
		} else {
#			print "  normal font remains\n";
			$options{'-font'} = $fntnorm
		}
		my $fg = $theme->getItem($tag, '-foreground');
		if ($fg ne '') {
#			print "  setting foreground $fg\n";
			$options{'-foreground'} = Imager::Color->new($fg);
		} else {
#			print "  default foreground remains\n";
			$options{'-foreground'} = $foreground;
		}
		my $bg = $theme->getItem($tag, '-background');

lib/App/Codit/Plugins/Exporter.pm  view on Meta::CPAN


		my $line = $widg->get($linestart, $lineend);
		if ($syntax eq 'None') {
			$self->iprint($line, $fntnorm, $foreground);
		} else {
			my @h = $hl->ParseRaw($line);
			while (@h) {
				my $string = shift @h;
				my $tag = shift @h;
				my $t = $tags{$tag};
				$self->iprint($string, $t->{'-font'}, $t->{'-foreground'}, $t->{'-background'});
			};
			$self->iprint("\n", $fntnorm, $foreground) if $line =~ /\n$/;
		}
		$count++;
		$self->update;
	}
	$self->mdi->progressRemove('exporter');
	
	my $out = $self->inew($self->iwidth, $self->iheight);
	$out->paste(src => $self->image);

lib/App/Codit/Plugins/Exporter.pm  view on Meta::CPAN



sub inew {
	my ($self, $width, $height) = @_;
	my $new = Imager->new(xsize => $width, ysize => $height, channels => 4);
	$new->flood_fill(x => 0, y => 0, color => $self->background);
	return $new
}

sub inewline {
	my ($self, $font) = @_;
	my $linespace = $self->fontMetrics($font, '-linespace');
	my $height = $self->iheight + $linespace;
	my $new = $self->inew($self->iwidth, $height);
	$new->paste(src => $self->image);
	$self->image($new);
	$self->ypos($self->ypos + $linespace);
	$self->xpos($self->imargin);
	$self->iheight($height);
}

sub iprint {
	my ($self, $string, $font, $fg, $bg) = @_;
	my $cur = $self->image;
	my $ifont = $self->extGet('Art')->imagerFont($font);
	my $newline = 0;
	my $part = '';
	while ($string ne '') {
		if ($string =~ s/^([^\n]*)\n//) {
			$newline = 1;
			$part = $1;
		} else {
			$part = $string;
			$string = '';
		}

		#replace tabs
		my $tab = $self->tabstring;
		$part =~ s/\t/$tab/g;

		#wrap if bigger than maxwidth
		my $partsize = $self->fontMeasure($font, $part);
		my $linesize = $self->xpos + $partsize + $self->imargin;
		my $mw = $self->maxwidth;
		if (($mw > 0) and ($mw < $linesize)) { #bigger than maxwidth
			while ($mw < $linesize) {
				my $section = '';
				while (($self->xpos + $self->fontMeasure($font, $section) + $self->imargin) < $mw) {
					$section = $section . substr($part, 0, 1);
					$part = substr($part, 1);
				}
				$self->iprints($section, $font, $fg, $bg);
				$self->inewline($font);
				$self->iprintln(' ', $font, $fg) if $self->linenumbers;
				$partsize = $self->fontMeasure($font, $part);
				$linesize = $self->xpos + $partsize + $self->imargin;
			}
		}


		#output part
		$self->iprints($part, $font, $fg, $bg);

		#output newline
		$self->inewline($font) if ($newline);

		$part = '';
		$newline = 0;
	}
}

sub iprintln {
	my ($self, $line, $font, $foreground) = @_;
	my $lc = $self->linecolumn;
	while (length($line) < $lc) { $line = " $line" };
	$self->iprint("$line ", $font, $foreground);
}

sub iprints {
	my ($self, $string, $font, $fg, $bg) = @_;
	my $ifont = $self->extGet('Art')->imagerFont($font);
	my $partsize = $self->fontMeasure($font, $string);
	my $linesize = $self->xpos + $partsize + $self->imargin;
	if ($linesize > $self->iwidth) { #need to enlarge in x direction?
		my $new = $self->inew($linesize, $self->iheight);
		$new->paste(src => $self->image);
		$self->image($new);
		$self->iwidth($linesize);
	}
	
	if (defined $bg) { #paint background
		my $linespace = $self->fontMetrics($font, '-linespace');
		my $descent = $self->fontMetrics($font, '-descent');
		my $x1 = $self->xpos;
		my $x2 = $x1 + $partsize;
		my $y2 = $self->ypos + $descent;
		my $y1 = $y2 - $linespace;
		$self->image->polygon(
			points => [[$x1, $y1], [$x2, $y1], [$x2, $y2], [$x1, $y2]],
			color => $bg,
		);
	}

	$self->image->string(
		x => $self->xpos,
		y => $self->ypos,
		font => $ifont,
		string => $string,
		color => $fg,
		aa => 1,
	);
	$self->xpos($self->xpos + $partsize);
}

sub iwidth {
	my $self = shift;
	$self->{IWIDTH} = shift if @_;

lib/App/Codit/Plugins/PodViewer.pm  view on Meta::CPAN

	$self->{MODIFIEDSAVE} = {};
	$self->{VIEWER} = undef;
	$self->{VISIBLE} = 0;

	my $page = $self->ToolBottomPageAdd('Pod', 'documentation', undef, 'Show the documentation in your file');
	$self->sidebars->pageSelectCall('Pod', sub {
		$self->after(10, sub { $self->Refresh })
	});
	my $art = $self->extGet('Art');

	#Getting the correct font
	my $l = $page->Label;
	my $lfont = $l->cget('-font');
	my $family = $l->fontActual($lfont, '-family');
	my $size = $l->fontActual($lfont, '-size');
	my $font = $l->Font(-family => $family, -size => $size);
	$l->destroy;

	#creating the viewer widget
	my @vopt = ();
	for (
		['-nextimage', 'go-next', 'Next'],
		['-previmage', 'go-previous', 'Previous'],
		['-zoominimage', 'zoom-in', 'Zoom in'],
		['-zoomoutimage', 'zoom-out', 'Zoom out'],
		['-zoomresetimage', 'zoom-original', 'Zoom reset'],
	) {
		my ($opt, $icon, $text) = @$_;
		my $img = $art->getIcon($icon, 22);
		push @vopt, $opt, $art->createCompound(
			-image => $img,
			-text => $text,
		) if defined $img;
	}
	my $pod = $page->PodViewerFull(@vopt,
		-font => $font,
		-linkcolor => $self->configGet('-linkcolor'),
	)->pack(-expand => 1, -fill => 'both');
	my $sb = $self->sidebars;
	$sb->pageSelectCall('Pod', sub { $self->after(100, ['Refresh', $self]) });
	$self->{PODWIDGET} = $pod;

	return $self;
}


lib/App/Codit/Plugins/Snippets.pm  view on Meta::CPAN

	)->pack(@padding, -fill => 'x');
	my @to = ();
	my $text = $sf->Scrolled('XText', @to,
		-scrollbars => 'osoe',
		-tabs => '8m',
		-wrap => 'none',
		-height => 4,
		-width => 20,
	)->pack(@padding, -expand => 1, -fill => 'both');
	$self->after(200, sub {
		$text->configure('-font', $self->mdi->docWidget->cget('-font'))
	});
	$self->{TEXT} = $text;

	$self->listRefresh;
	return $self;
}

sub _list {
	return $_[0]->{LIST}
}

t/030-App-Codit-CoditTagsEditor.t  view on Meta::CPAN


createapp(
);

my $editor;
if (defined $app) {
	$editor = $app->CoditTagsEditor(
		-extension => $app,
		-defaultbackground => '#FFFFFF',
		-defaultforeground => '#000000',
		-defaultfont => $app->Font(-family => 'Hack', -size => 12),
		-historyfile => 't/color_history',
		-themefile => 'blib/lib/App/Codit/highlight_theme.ctt',
	)->pack(-expand => 1, -fill => 'both');
}

push @tests , [ sub { return defined $editor }, 1, 'CoditTagsEditor created'];


starttesting;



( run in 2.131 seconds using v1.01-cache-2.11-cpan-ceb78f64989 )