NAME
Text::Fragment - Manipulate fragments in text
VERSION
This document describes version 0.06 of Text::Fragment (from Perl
distribution Text-Fragment), released on 2014-11-17.
SYNOPSIS
use Text::Fragment qw(list_fragments
get_fragment
set_fragment_attrs
insert_fragment
delete_fragment);
my $text = <<_;
foo = "some value"
baz = 0
_
To insert a fragment:
my $res = insert_fragment(text=>$text, id=>'bar', payload=>'bar = 2');
"$res->[2]{text}" will now contain:
foo = "some value"
baz = 0
bar = 2 # FRAGMENT id=bar
To replace a fragment:
$res = insert_fragment(text=>$res->[2], id='bar', payload=>'bar = 3');
"$res->[2]{text}" will now contain:
foo = "some value"
baz = 0
bar = 3 # FRAGMENT id=bar
and "$res->[2]{orig_payload}" will contain the payload before being
replaced:
bar = 2
To delete a fragment:
$res = delete_fragment(text=>$res->[2], id=>'bar');
To list fragments:
$res = list_fragment(text=>$text);
To get a fragment:
$res = get_fragment(text=>$text, id=>'bar');
To set fragment attributes:
$res = se_fragment_attrs(text=>$text, id=>'bar', attrs=>{name=>'val', ...});
DESCRIPTION
A fragment is a single line or a group of lines (called payload) with a
metadata encoded in the comment that is put adjacent to it (for a single
line fragment) or enclosing it (for a multiline fragment). Fragments are
usually used in configuration files or code. Here is the structure of a
single-line fragment:
<payload> # <label> <attrs>
Here is the structure of a multi-line fragment:
# BEGIN <label> <attrs>
<payload>
# END <label> [<attrs>]
Label is by default "FRAGMENT" but can be other string. Attributes are a
sequence of "name=val" separated by whitespace, where name must be
alphanums only and val is zero or more non-whitespace characters. There
must at least be an attribute with name "id", it is used to identify
fragment and allow the fragment to be easily replaced/modified/deleted
from text. Attributes are optional in the ending comment.
Comment character used is by default "#" ("shell"-style comment), but
other comment styles are supported (see below).
Examples of single-line fragments (the second example uses "c"-style
comment and the third uses "cpp"-style comment):
RSYNC_ENABLE=1 # FRAGMENT id=enable
some text /* FRAGMENT id=id2 */
some text // FRAGMENT id=id3 foo=1 bar=2
An example of multi-line fragment (using "html"-style comment instead of
"shell"):
<!-- BEGIN FRAGMENT id=id4 -->
some
lines
of
text
<!-- END FRAGMENT id=id4 -->
Another example (using "ini"-style comment):
; BEGIN FRAGMENT id=default-settings
register_globals=On
extension=mysql.so
extension=gd.so
memory_limit=256M
post_max_size=64M
upload_max_filesize=64M
browscap=/c/share/php/browscap.ini
allow_url_fopen=0
; END FRAGMENT
FUNCTIONS
delete_fragment(%args) -> [status, msg, result, meta]
Delete fragment in text.
If there are multiple occurences of fragment (which is considered an
abnormal condition), all occurences will be deleted.
Newline deletion behaviour: if fragment at the bottom of text does not
end with newline (which is considered bad style), the text after the
fragment is deleted will also not end with newline.
Arguments ('*' denotes required arguments):
* comment_style => *str* (default: "shell")
Comment style.
* id* => *str*
Fragment ID.
* label => *code|str* (default: "FRAGMENT")
Comment label.
* text* => *str*
The text to delete fragment from.
Return value:
Returns an enveloped result (an array).
First element (status) is an integer containing HTTP status code (200
means OK, 4xx caller error, 5xx function error). Second element (msg) is
a string containing error message, or 'OK' if status is 200. Third
element (result) is optional, the actual result. Fourth element (meta)
is called result metadata and is optional, a hash that contains extra
information.
A hash of result (hash)
Will return status 200 if operation is successful and text is deleted.
The result is a hash with the following keys: `text` will contain the
new text, `orig_payload` will contain the original fragment payload
before being deleted, `orig_fragment` will contain the original
fragment. If there are multiple occurences (which is considered an
abnormal condition), only the last deleted fragment will be returned in
`orig_payload` and `orig_fragment`.
Will return status 304 if nothing is changed (i.e. when the fragment
that needs to be deleted already does not exist in the text).
get_fragment(%args) -> [status, msg, result, meta]
Get fragment with a certain ID in text.
If there are multiple occurences of the fragment with the same ID ,
Arguments ('*' denotes required arguments):
* comment_style => *str* (default: "shell")
Comment style.
* id* => *str*
Fragment ID.
* label => *str* (default: "FRAGMENT")
Comment label.
* text* => *str*
The text which contain fragments.
Return value:
Returns an enveloped result (an array).
First element (status) is an integer containing HTTP status code (200
means OK, 4xx caller error, 5xx function error). Second element (msg) is
a string containing error message, or 'OK' if status is 200. Third
element (result) is optional, the actual result. Fourth element (meta)
is called result metadata and is optional, a hash that contains extra
information.
Fragment (array)
Will return status 200 if fragment is found. Result will be a hash with
the following keys: `raw` (string), `payload` (string), `attrs` (hash),
`id` (string, can also be found in attributes).
Return 404 if fragment is not found.
insert_fragment(%args) -> [status, msg, result, meta]
Insert or replace a fragment in text.
Newline insertion behaviour: if fragment is inserted at the bottom and
text does not end with newline (which is considered bad style), the
inserted fragment will also not end with newline. Except when original
text is an empty string, in which case an ending newline will still be
added.
Arguments ('*' denotes required arguments):
* attrs => *hash* (default: {})
* comment_style => *str* (default: "shell")
Comment style.
* good_pattern => *str*
Regex pattern which if found means fragment need not be inserted.
* id* => *str*
Fragment ID.
* label => *str* (default: "FRAGMENT")
Comment label.
* payload* => *str*
Fragment content.
* replace_pattern => *str*
Regex pattern which if found will be used for placement of fragment.
If fragment needs to be inserted into file, then if
"replace_pattern" is defined then it will be searched. If found,
fragment will be placed to replace the pattern. Otherwise, fragment
will be inserted at the end (or beginning, see "top_style") of file.
* text* => *str*
The text to insert fragment into.
* top_style => *bool* (default: 0)
Whether to append fragment at beginning of file instead of at the
end.
Default is false, which means to append at the end of file.
Note that this only has effect if "replace_pattern" is not defined
or replace pattern is not found in file. Otherwise, fragment will be
inserted to replace the pattern.
Return value:
Returns an enveloped result (an array).
First element (status) is an integer containing HTTP status code (200
means OK, 4xx caller error, 5xx function error). Second element (msg) is
a string containing error message, or 'OK' if status is 200. Third
element (result) is optional, the actual result. Fourth element (meta)
is called result metadata and is optional, a hash that contains extra
information.
A hash of result (hash)
Will return status 200 if operation is successful and text is changed.
The result is a hash with the following keys: `text` will contain the
new text, `orig_payload` will contain the original payload before being
removed/replaced, `orig_fragment` will contain the original fragment (or
the text that matches `replace_pattern`).
Will return status 304 if nothing is changed (i.e. if fragment with the
same payload that needs to be inserted already exists in the text).
list_fragments(%args) -> [status, msg, result, meta]
List fragments in text.
Arguments ('*' denotes required arguments):
* comment_style => *str* (default: "shell")
Comment style.
* label => *str* (default: "FRAGMENT")
Comment label.
* text* => *str*
The text which contain fragments.
Return value:
Returns an enveloped result (an array).
First element (status) is an integer containing HTTP status code (200
means OK, 4xx caller error, 5xx function error). Second element (msg) is
a string containing error message, or 'OK' if status is 200. Third
element (result) is optional, the actual result. Fourth element (meta)
is called result metadata and is optional, a hash that contains extra
information.
List of fragments (array)
Will return status 200 if operation is successful. Result will be an
array of fragments, where each fragment is a hash containing these keys:
`raw` (string), `payload` (string), `attrs` (hash), `id` (string, can
also be found in attributes).
set_fragment_attrs(%args) -> [status, msg, result, meta]
Set/unset attributes of a fragment.
If there are multiple occurences of the fragment with the same ID ,
Arguments ('*' denotes required arguments):
* attrs* => *hash*
To delete an attribute in the fragment, you can set the value to
undef.
* comment_style => *str* (default: "shell")
Comment style.
* id* => *str*
Fragment ID.
* label => *str* (default: "FRAGMENT")
Comment label.
* text* => *str*
The text which contain fragments.
Return value:
Returns an enveloped result (an array).
First element (status) is an integer containing HTTP status code (200
means OK, 4xx caller error, 5xx function error). Second element (msg) is
a string containing error message, or 'OK' if status is 200. Third
element (result) is optional, the actual result. Fourth element (meta)
is called result metadata and is optional, a hash that contains extra
information.
New text and other data (array)
Will return status 200 if fragment is found. Result will be a hash
containing these keys: `text` (string, the modified text), `orig_attrs`
(hash, the old attributes before being modified).
Return 404 if fragment is not found.
HOMEPAGE
Please visit the project's homepage at
<https://metacpan.org/release/Text-Fragment>.
SOURCE
Source repository is at
<https://github.com/sharyanto/perl-Text-Fragment>.
BUGS
Please report any bugs or feature requests on the bugtracker website
<https://rt.cpan.org/Public/Dist/Display.html?Name=Text-Fragment>
When submitting a bug or request, please include a test-file or a patch
to an existing test-file that illustrates the bug or desired feature.
AUTHOR
perlancar <perlancar@cpan.org>
COPYRIGHT AND LICENSE
This software is copyright (c) 2014 by perlancar@cpan.org.
This is free software; you can redistribute it and/or modify it under
the same terms as the Perl 5 programming language system itself.