Package: codestripper
CodeStripperNew version of the CodeStripper that was previously used, which can be found athttps://github.com/sebivenlo/codestripper.The reason for the switch is to not be dependent on Ant as a build system and the possibility to easily add more tags.Available tagsCommandTag(s)DescriptionAddcs:add:<text>Add thetext(without the tag in front)Ignorecs:ignoreIgnore the entire file, only valid on the first lineRemove linecs:removeRemove the lineRemove rangecs:remove:start/cs:remove:endRemove all text in between tagsReplacecs:replace:<replacement>Replace the text in front by thereplacement, keeps whitespaceUncommentcs:uncomment:start/cs:uncomment:endUncomment all lines in between tagsLegacyTo support the old CodeStripper, the legacy tagStart Solution::replacewith::/End Solution::replacewith::is still supported for now. This tag does both theRemoveandReplacein one go.Command Line PropertiesCodeStripper can be used as a Python Module and as a command line tool. The command line tool has the following interface.FlagLong formDescriptionDefault valueRequired<positional>Nonefiles to include for code stripping (glob)NoneTrue-e--excludefiles to exclude for code stripping (glob)NoneFalse-c--commentcomment symbol(s) for the given language//False-o--outputthe output directory to store the stripped filesoutFalse-r--recursivedo NOT use recursive globs for include/excludeTrueFalse-v--verbosityincrease output verbosityNoneFalse-d--dryexecute a dry runFalseFalse-w--working-directoryset the working directory for include/excludepwdFalseExamplesThis section contains examples for all supported tags.AddInput:publicclassTest{//cs:add:private final String test = "test";}Output:publicclassTest{privatefinalStringtest="test";}IgnoreInput://cs:ignorepublicclassTest{privatefinalStringtest="test";}Output: No output, file is ignoredRemove lineInput:publicclassTest{privatefinalStringtest="test";//cs:remove}Output:publicclassTest{}Remove rangeInput:publicclassTest{//cs:remove:startprivatefinalStringtest="test";privatefinalintcount=0;//cs:remove:endprivatefinalbooleankeep=true;}Output:publicclassTest{privatefinalbooleankeep=true;}ReplaceInput:publicclassTest{privatefinalbooleankeep=false;//cs:replace://TODO: add fields}Output:publicclassTest{//TODO: add fields}UncommentInput:publicclassTest{//cs:uncomment:start//private final String example = "example";//private final boolean isTestCode = true;//cs:uncomment:end}Output:publicclassTest{privatefinalStringexample="example";privatefinalbooleanisTestCode=true;}Adding a new tagIt is possible to add custom tags. There a two types of tags:SingleTagthat works on one line only andRangeTagthat works on a range of lines. Tags are defined as follows:classDiagram
    Tag <|-- SingleTag
    SingleTag <|-- RangeOpenTag
    SingleTag <|-- RangeCloseTag
    Tag <|-- RangeTag
    
    class Tag{
        <<Abstract>>
        +offset: int
        +start: int
        +end: int
        +is_valid()*: bool
        +execute()*: Optional[str]
    }
    class SingleTag{
        +regex: str
        +param_start: int
        +param_end: int
        +regex_start: int
        +regex_end: int
        +leading_characters: str
        +parameter: str
        +whitespace: str
        +SingleTag(data: TagData)
    }
    class RangeOpenTag{
        +RangeOpen(parent: Type, data: TagData)
    }
    class RangeCloseTag{
        +RangeOpen(parent: Type, data: TagData)
    }
    class RangeTag{
        +inset: int
        +start: int
        +end: int
        +open_tag: RangeOpenTag
        +close_tag: RangeCloseTag
        +RangeTag(open_tag: RangeOpenTag, close_tag: RangeCloseTag)
        +add_tags(tags: Iterable[Tag])
    }The idea is that every tag has the following methods:is_valid: whether the tag is validexecute: handle the text for this tagRangeTagwork in the following way:RangeOpenTag: Specifies the open regex and handles the opening line. Defines the type of parent it belongs to (so that the tokenizer can match open and close tag)RangeCloseTag: Specifies the close regex and handles the closing line. Defines the type of parent it belongs to (so that the tokenizer can match open and close tag)RangeTag: Handles lines in between the open and close tag. Has access to both the open and close tag that were matched by the tokenizer.Create a custom tag:Create a new file for your tag(s)Depending on if you create aSingleTagorRangeTagSingleTag:classTestTag(SingleTag):regex=r'<regex>'# Regex that should match the tagdef__init__(self,data:TagData)->None:super().__init__(data)defexecute(self,content:str)->Optional[str]:# Manipulate the line# None means the line is removeddefis_valid(self)->bool:# Return wether the tag is validRangeTag: Range needs aRangeOpenTag,RangeCloseTagand aRangeTagclassTestOpenTag(RangeOpenTag):regex=r'<regex>'# Regex that should match the open tagdef__init__(self,data:TagData)->None:super().__init__(TestRangeTag,data)# Type of RangeTag is belong todefexecute(self,content:str)->Optional[str]:# Manipulate the line# None means the line is removeddefis_valid(self)->bool:# Return wether the tag is validclassTestCloseTag(RangeCloseTag):# Same as RangeOpenTagclassTestRangeTag(RangeTag):regex=None# The matching is done based on open/close tagdef__init__(self,open_tag:RangeOpenTag,close_tag:RangeCloseTag):super().__init__(open_tag,close_tag)defexecute(self,content:str)->Union[str,None]:# Manipulate lines between the tagsAdd the new tag(s) to thedefault_tagsin thetokenizer,default_tags:Set[Type[SingleTag]]={IgnoreFileTag,RemoveOpenTag,...,TestTag,TestOpenTag}:warning:Only theSingleTag(s) need to be added, not theRangeTag